From fc20680b95da65f952012f3370e5d316f0ba237d Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 25 Aug 2020 16:21:41 +0200 Subject: [PATCH 01/24] params: begin v1.9.21 release cycle --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 5102f2fb7b..f827bcd62e 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 1 // Major version component of the current release - VersionMinor = 9 // Minor version component of the current release - VersionPatch = 20 // Patch version component of the current release - VersionMeta = "stable" // Version metadata to append to the version string + VersionMajor = 1 // Major version component of the current release + VersionMinor = 9 // Minor version component of the current release + VersionPatch = 21 // Patch version component of the current release + VersionMeta = "unstable" // Version metadata to append to the version string ) // Version holds the textual version string. From 92b12ee6c6ebf32507a2834b2913bd557a416209 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 26 Aug 2020 09:37:00 +0200 Subject: [PATCH 02/24] accounts/abi/bind/backends: Disallow AdjustTime for non-empty blocks (#21334) * accounts/abi/bind/backends: Disallow timeshift for non-empty blocks * accounts/abi/bind/backends: added tests for adjust time * accounts/abi/bind/simulated: added comments, fixed test for AdjustTime * accounts/abi/bind/backends: updated comment --- accounts/abi/bind/backends/simulated.go | 8 ++-- accounts/abi/bind/backends/simulated_test.go | 41 +++++++++++++++++++- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 4b9372a201..973d95531d 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -675,14 +675,16 @@ func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *type } // AdjustTime adds a time shift to the simulated clock. +// It can only be called on empty blocks. func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { b.mu.Lock() defer b.mu.Unlock() + if len(b.pendingBlock.Transactions()) != 0 { + return errors.New("Could not adjust time on non-empty block") + } + blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { - for _, tx := range b.pendingBlock.Transactions() { - block.AddTx(tx) - } block.OffsetTime(int64(adjustment.Seconds())) }) statedb, _ := b.blockchain.State() diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index d14a88e8bb..9087d74bc6 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -143,8 +143,7 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) { defer sim.Close() prevTime := sim.pendingBlock.Time() - err := sim.AdjustTime(time.Second) - if err != nil { + if err := sim.AdjustTime(time.Second); err != nil { t.Error(err) } newTime := sim.pendingBlock.Time() @@ -154,6 +153,44 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) { } } +func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + // Create tx and send + tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + sim.SendTransaction(context.Background(), signedTx) + // AdjustTime should fail on non-empty block + if err := sim.AdjustTime(time.Second); err == nil { + t.Error("Expected adjust time to error on non-empty block") + } + sim.Commit() + + prevTime := sim.pendingBlock.Time() + if err := sim.AdjustTime(time.Minute); err != nil { + t.Error(err) + } + newTime := sim.pendingBlock.Time() + if newTime-prevTime != uint64(time.Minute.Seconds()) { + t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime) + } + // Put a transaction after adjusting time + tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx2, err := types.SignTx(tx2, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + sim.SendTransaction(context.Background(), signedTx2) + sim.Commit() + newTime = sim.pendingBlock.Time() + if newTime-prevTime >= uint64(time.Minute.Seconds()) { + t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime) + } +} + func TestSimulatedBackend_BalanceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(10000000000) From d8da0b3d81d6623e0e500de11f50c2858e1fb9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 26 Aug 2020 13:05:06 +0300 Subject: [PATCH 03/24] core/state, eth, trie: stabilize memory use, fix memory leak --- core/state/statedb.go | 2 +- core/state/sync.go | 6 ++-- eth/downloader/downloader.go | 11 +++++-- trie/committer.go | 4 +-- trie/sync.go | 60 +++++++++++++++++++++++++----------- trie/trie.go | 2 +- trie/trie_test.go | 2 +- 7 files changed, 58 insertions(+), 29 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index cd020e6543..36f7d863af 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -847,7 +847,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { // The onleaf func is called _serially_, so we can reuse the same account // for unmarshalling every time. var account Account - root, err := s.trie.Commit(func(leaf []byte, parent common.Hash) error { + root, err := s.trie.Commit(func(path []byte, leaf []byte, parent common.Hash) error { if err := rlp.DecodeBytes(leaf, &account); err != nil { return nil } diff --git a/core/state/sync.go b/core/state/sync.go index 052cfad7bb..1018b78e5e 100644 --- a/core/state/sync.go +++ b/core/state/sync.go @@ -28,13 +28,13 @@ import ( // NewStateSync create a new state trie download scheduler. func NewStateSync(root common.Hash, database ethdb.KeyValueReader, bloom *trie.SyncBloom) *trie.Sync { var syncer *trie.Sync - callback := func(leaf []byte, parent common.Hash) error { + callback := func(path []byte, leaf []byte, parent common.Hash) error { var obj Account if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil { return err } - syncer.AddSubTrie(obj.Root, 64, parent, nil) - syncer.AddCodeEntry(common.BytesToHash(obj.CodeHash), 64, parent) + syncer.AddSubTrie(obj.Root, path, parent, nil) + syncer.AddCodeEntry(common.BytesToHash(obj.CodeHash), path, parent) return nil } syncer = trie.NewSync(root, database, callback, bloom) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 4c5b270b7c..f5bdb3c234 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -1611,7 +1611,13 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error { // Start syncing state of the reported head block. This should get us most of // the state of the pivot block. sync := d.syncState(latest.Root) - defer sync.Cancel() + defer func() { + // The `sync` object is replaced every time the pivot moves. We need to + // defer close the very last active one, hence the lazy evaluation vs. + // calling defer sync.Cancel() !!! + sync.Cancel() + }() + closeOnErr := func(s *stateSync) { if err := s.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled { d.queue.Close() // wake up Results @@ -1674,9 +1680,8 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error { // If new pivot block found, cancel old state retrieval and restart if oldPivot != P { sync.Cancel() - sync = d.syncState(P.Header.Root) - defer sync.Cancel() + go closeOnErr(sync) oldPivot = P } diff --git a/trie/committer.go b/trie/committer.go index 2f3d2a4633..fc8b7ceda5 100644 --- a/trie/committer.go +++ b/trie/committer.go @@ -226,12 +226,12 @@ func (c *committer) commitLoop(db *Database) { switch n := n.(type) { case *shortNode: if child, ok := n.Val.(valueNode); ok { - c.onleaf(child, hash) + c.onleaf(nil, child, hash) } case *fullNode: for i := 0; i < 16; i++ { if child, ok := n.Children[i].(valueNode); ok { - c.onleaf(child, hash) + c.onleaf(nil, child, hash) } } } diff --git a/trie/sync.go b/trie/sync.go index af99466416..147307fe71 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -34,14 +34,19 @@ var ErrNotRequested = errors.New("not requested") // node it already processed previously. var ErrAlreadyProcessed = errors.New("already processed") +// maxFetchesPerDepth is the maximum number of pending trie nodes per depth. The +// role of this value is to limit the number of trie nodes that get expanded in +// memory if the node was configured with a significant number of peers. +const maxFetchesPerDepth = 16384 + // request represents a scheduled or already in-flight state retrieval request. type request struct { + path []byte // Merkle path leading to this node for prioritization hash common.Hash // Hash of the node data content to retrieve data []byte // Data content of the node, cached until all subtrees complete code bool // Whether this is a code entry parents []*request // Parent state nodes referencing this entry (notify all upon completion) - depth int // Depth level within the trie the node is located to prioritise DFS deps int // Number of dependencies before allowed to commit this node callback LeafCallback // Callback to invoke if a leaf node it reached on this branch @@ -89,6 +94,7 @@ type Sync struct { nodeReqs map[common.Hash]*request // Pending requests pertaining to a trie node hash codeReqs map[common.Hash]*request // Pending requests pertaining to a code hash queue *prque.Prque // Priority queue with the pending requests + fetches map[int]int // Number of active fetches per trie node depth bloom *SyncBloom // Bloom filter for fast state existence checks } @@ -100,14 +106,15 @@ func NewSync(root common.Hash, database ethdb.KeyValueReader, callback LeafCallb nodeReqs: make(map[common.Hash]*request), codeReqs: make(map[common.Hash]*request), queue: prque.New(nil), + fetches: make(map[int]int), bloom: bloom, } - ts.AddSubTrie(root, 0, common.Hash{}, callback) + ts.AddSubTrie(root, nil, common.Hash{}, callback) return ts } // AddSubTrie registers a new trie to the sync code, rooted at the designated parent. -func (s *Sync) AddSubTrie(root common.Hash, depth int, parent common.Hash, callback LeafCallback) { +func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, callback LeafCallback) { // Short circuit if the trie is empty or already known if root == emptyRoot { return @@ -128,8 +135,8 @@ func (s *Sync) AddSubTrie(root common.Hash, depth int, parent common.Hash, callb } // Assemble the new sub-trie sync request req := &request{ + path: path, hash: root, - depth: depth, callback: callback, } // If this sub-trie has a designated parent, link them together @@ -147,7 +154,7 @@ func (s *Sync) AddSubTrie(root common.Hash, depth int, parent common.Hash, callb // AddCodeEntry schedules the direct retrieval of a contract code that should not // be interpreted as a trie node, but rather accepted and stored into the database // as is. -func (s *Sync) AddCodeEntry(hash common.Hash, depth int, parent common.Hash) { +func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash) { // Short circuit if the entry is empty or already known if hash == emptyState { return @@ -170,9 +177,9 @@ func (s *Sync) AddCodeEntry(hash common.Hash, depth int, parent common.Hash) { } // Assemble the new sub-trie sync request req := &request{ - hash: hash, - code: true, - depth: depth, + path: path, + hash: hash, + code: true, } // If this sub-trie has a designated parent, link them together if parent != (common.Hash{}) { @@ -190,7 +197,18 @@ func (s *Sync) AddCodeEntry(hash common.Hash, depth int, parent common.Hash) { func (s *Sync) Missing(max int) []common.Hash { var requests []common.Hash for !s.queue.Empty() && (max == 0 || len(requests) < max) { - requests = append(requests, s.queue.PopItem().(common.Hash)) + // Retrieve th enext item in line + item, prio := s.queue.Peek() + + // If we have too many already-pending tasks for this depth, throttle + depth := int(prio >> 56) + if s.fetches[depth] > maxFetchesPerDepth { + break + } + // Item is allowed to be scheduled, add it to the task list + s.queue.Pop() + s.fetches[depth]++ + requests = append(requests, item.(common.Hash)) } return requests } @@ -285,7 +303,11 @@ func (s *Sync) schedule(req *request) { // is a trie node and code has same hash. In this case two elements // with same hash and same or different depth will be pushed. But it's // ok the worst case is the second response will be treated as duplicated. - s.queue.Push(req.hash, int64(req.depth)) + prio := int64(len(req.path)) << 56 // depth >= 128 will never happen, storage leaves will be included in their parents + for i := 0; i < 14 && i < len(req.path); i++ { + prio |= int64(15-req.path[i]) << (52 - i*4) // 15-nibble => lexicographic order + } + s.queue.Push(req.hash, prio) } // children retrieves all the missing children of a state trie entry for future @@ -293,23 +315,23 @@ func (s *Sync) schedule(req *request) { func (s *Sync) children(req *request, object node) ([]*request, error) { // Gather all the children of the node, irrelevant whether known or not type child struct { - node node - depth int + path []byte + node node } var children []child switch node := (object).(type) { case *shortNode: children = []child{{ - node: node.Val, - depth: req.depth + len(node.Key), + node: node.Val, + path: append(append([]byte(nil), req.path...), node.Key...), }} case *fullNode: for i := 0; i < 17; i++ { if node.Children[i] != nil { children = append(children, child{ - node: node.Children[i], - depth: req.depth + 1, + node: node.Children[i], + path: append(append([]byte(nil), req.path...), byte(i)), }) } } @@ -322,7 +344,7 @@ func (s *Sync) children(req *request, object node) ([]*request, error) { // Notify any external watcher of a new key/value node if req.callback != nil { if node, ok := (child.node).(valueNode); ok { - if err := req.callback(node, req.hash); err != nil { + if err := req.callback(req.path, node, req.hash); err != nil { return nil, err } } @@ -346,9 +368,9 @@ func (s *Sync) children(req *request, object node) ([]*request, error) { } // Locally unknown node, schedule for retrieval requests = append(requests, &request{ + path: child.path, hash: hash, parents: []*request{req}, - depth: child.depth, callback: req.callback, }) } @@ -364,9 +386,11 @@ func (s *Sync) commit(req *request) (err error) { if req.code { s.membatch.codes[req.hash] = req.data delete(s.codeReqs, req.hash) + s.fetches[len(req.path)]-- } else { s.membatch.nodes[req.hash] = req.data delete(s.nodeReqs, req.hash) + s.fetches[len(req.path)]-- } // Check all parents for completion for _, parent := range req.parents { diff --git a/trie/trie.go b/trie/trie.go index 26c3f2c29b..7ccd37f872 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -38,7 +38,7 @@ var ( // LeafCallback is a callback type invoked when a trie operation reaches a leaf // node. It's used by state sync and commit to allow handling external references // between account and storage tries. -type LeafCallback func(leaf []byte, parent common.Hash) error +type LeafCallback func(path []byte, leaf []byte, parent common.Hash) error // Trie is a Merkle Patricia Trie. // The zero value is an empty trie with no database. diff --git a/trie/trie_test.go b/trie/trie_test.go index 588562146a..2356b7a746 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -565,7 +565,7 @@ func BenchmarkCommitAfterHash(b *testing.B) { benchmarkCommitAfterHash(b, nil) }) var a account - onleaf := func(leaf []byte, parent common.Hash) error { + onleaf := func(path []byte, leaf []byte, parent common.Hash) error { rlp.DecodeBytes(leaf, &a) return nil } From 16d7eae1c8390576057a859ea4330fba895dca40 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 26 Aug 2020 12:20:12 +0200 Subject: [PATCH 04/24] eth: updated comments (#21490) --- eth/api.go | 2 +- eth/api_tracer.go | 2 +- eth/bloombits.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eth/api.go b/eth/api.go index b3415f923c..d65a8efa0d 100644 --- a/eth/api.go +++ b/eth/api.go @@ -354,7 +354,7 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, // AccountRangeMaxResults is the maximum number of results to be returned per call const AccountRangeMaxResults = 256 -// AccountRangeAt enumerates all accounts in the given block and start point in paging request +// AccountRange enumerates all accounts in the given block and start point in paging request func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start []byte, maxResults int, nocode, nostorage, incompletes bool) (state.IteratorDump, error) { var stateDb *state.StateDB var err error diff --git a/eth/api_tracer.go b/eth/api_tracer.go index c5a8ada109..51c2408c24 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -401,7 +401,7 @@ func (api *PrivateDebugAPI) TraceBlockFromFile(ctx context.Context, file string, return api.TraceBlock(ctx, blob, config) } -// TraceBadBlockByHash returns the structured logs created during the execution of +// TraceBadBlock returns the structured logs created during the execution of // EVM against a block pulled from the pool of bad ones and returns them as a JSON // object. func (api *PrivateDebugAPI) TraceBadBlock(ctx context.Context, hash common.Hash, config *TraceConfig) ([]*txTraceResult, error) { diff --git a/eth/bloombits.go b/eth/bloombits.go index f8b77f9cff..bd34bd7b69 100644 --- a/eth/bloombits.go +++ b/eth/bloombits.go @@ -137,7 +137,7 @@ func (b *BloomIndexer) Commit() error { return batch.Write() } -// PruneSections returns an empty error since we don't support pruning here. +// Prune returns an empty error since we don't support pruning here. func (b *BloomIndexer) Prune(threshold uint64) error { return nil } From 856307d8bbbe20e6d45f4a2a017233a5543b30f7 Mon Sep 17 00:00:00 2001 From: ucwong Date: Wed, 26 Aug 2020 21:53:12 +0800 Subject: [PATCH 05/24] go.mod | goleveldb latest update (#21448) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * go.mod | goleveldb latest update * go.mod update * leveldb options * go.mod: double check Co-authored-by: Péter Szilágyi --- go.mod | 11 +++++------ go.sum | 60 +++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 17 deletions(-) mode change 100644 => 100755 go.mod mode change 100644 => 100755 go.sum diff --git a/go.mod b/go.mod old mode 100644 new mode 100755 index 2299eb5017..0b22fe6389 --- a/go.mod +++ b/go.mod @@ -25,9 +25,8 @@ require ( github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 - github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c + github.com/golang/protobuf v1.4.2 github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26 - github.com/google/go-cmp v0.3.1 // indirect github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989 github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 github.com/hashicorp/golang-lru v0.5.4 @@ -55,14 +54,14 @@ require ( github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect github.com/stretchr/testify v1.4.0 - github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d + github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 - golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect + golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect golang.org/x/sync v0.0.0-20181108010431-42b317875d0f - golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd - golang.org/x/text v0.3.2 + golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 + golang.org/x/text v0.3.3 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 diff --git a/go.sum b/go.sum old mode 100644 new mode 100755 index 4c46eeb5af..695a9d75c9 --- a/go.sum +++ b/go.sum @@ -67,6 +67,8 @@ github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepB github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= @@ -81,14 +83,22 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c h1:zqAKixg3cTcIasAMJV+EcfVbWwLpOZ7LeoWJvcuD/5Q= -github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26 h1:lMm2hD9Fy0ynom5+85/pbdkiYcBqM1JWmhpAXLmy0fw= github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989 h1:giknQ4mEuDFmmHSrGcbargOuLHQGtywqo4mheITex54= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 h1:E0whKxgp2ojts0FDgUA8dl62bmH0LxKanMoBr6MDTDM= @@ -136,15 +146,19 @@ github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hz github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c h1:1RHs3tNxjXGHeul8z2t6H2N2TlAqpKe5yryJztRx4Jk= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 h1:goeTyGkArOZIVOMA0dQbyuPWGNQJZGPwPu/QS9GlpnA= @@ -184,8 +198,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs= -github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= +github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= +github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -197,8 +211,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -206,14 +222,34 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 h1:AvbQYmiaaaza3cW3QXRyPo5kYgpFIzOAfeAAN7m3qQ4= +golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= @@ -228,8 +264,10 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= From 05280a7ae3f47adc8aeb9130c7f5404a42fb3a55 Mon Sep 17 00:00:00 2001 From: libotony Date: Thu, 27 Aug 2020 17:33:45 +0800 Subject: [PATCH 06/24] eth/tracers: revert reason in call_tracer + error for failed internal calls (#21387) * tests: add testdata of call tracer * eth/tracers: return revert reason in call_tracer * eth/tracers: regenerate assets * eth/tracers: add error message even if no exec occurrs, fixes #21438 Co-authored-by: Martin Holst Swende --- eth/tracers/internal/tracers/assets.go | 12 ++-- eth/tracers/internal/tracers/call_tracer.js | 15 ++-- .../testdata/call_tracer_inner_instafail.json | 72 +++++++++++++++++++ .../testdata/call_tracer_revert_reason.json | 64 +++++++++++++++++ eth/tracers/tracers_test.go | 24 ++++++- 5 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 eth/tracers/testdata/call_tracer_inner_instafail.json create mode 100644 eth/tracers/testdata/call_tracer_revert_reason.json diff --git a/eth/tracers/internal/tracers/assets.go b/eth/tracers/internal/tracers/assets.go index d0a0bf7c1a..c2da1ed1f8 100644 --- a/eth/tracers/internal/tracers/assets.go +++ b/eth/tracers/internal/tracers/assets.go @@ -2,8 +2,8 @@ // sources: // 4byte_tracer.js (2.933kB) // bigram_tracer.js (1.712kB) -// call_tracer.js (8.643kB) -// evmdis_tracer.js (4.194kB) +// call_tracer.js (8.704kB) +// evmdis_tracer.js (4.195kB) // noop_tracer.js (1.271kB) // opcount_tracer.js (1.372kB) // prestate_tracer.js (4.234kB) @@ -117,7 +117,7 @@ func bigram_tracerJs() (*asset, error) { return a, nil } -var _call_tracerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x59\x5f\x6f\x1b\xb7\xb2\x7f\x96\x3e\xc5\x24\x0f\xb5\x84\x28\x92\x93\xf4\xf6\x02\x76\xd5\x0b\x5d\x47\x49\x0d\xb8\x71\x60\x2b\x0d\x82\x20\x0f\xd4\xee\xac\xc4\x9a\x4b\x6e\x49\xae\xe4\x3d\xa9\xbf\xfb\xc1\x0c\xb9\xab\xd5\x1f\x3b\x6e\x0f\xce\x41\xcf\x8b\xa0\x5d\xce\x0c\x87\x33\xbf\xf9\xc7\x1d\x8d\xe0\xcc\x14\x95\x95\x8b\xa5\x87\x97\xc7\x2f\xfe\x17\x66\x4b\x84\x85\x79\x8e\x7e\x89\x16\xcb\x1c\x26\xa5\x5f\x1a\xeb\xba\xa3\x11\xcc\x96\xd2\x41\x26\x15\x82\x74\x50\x08\xeb\xc1\x64\xe0\x77\xe8\x95\x9c\x5b\x61\xab\x61\x77\x34\x0a\x3c\x07\x97\x49\x42\x66\x11\xc1\x99\xcc\xaf\x85\xc5\x13\xa8\x4c\x09\x89\xd0\x60\x31\x95\xce\x5b\x39\x2f\x3d\x82\xf4\x20\x74\x3a\x32\x16\x72\x93\xca\xac\x22\x91\xd2\x43\xa9\x53\xb4\xbc\xb5\x47\x9b\xbb\x5a\x8f\xb7\xef\x3e\xc0\x05\x3a\x87\x16\xde\xa2\x46\x2b\x14\xbc\x2f\xe7\x4a\x26\x70\x21\x13\xd4\x0e\x41\x38\x28\xe8\x8d\x5b\x62\x0a\x73\x16\x47\x8c\x6f\x48\x95\xeb\xa8\x0a\xbc\x31\xa5\x4e\x85\x97\x46\x0f\x00\x25\x69\x0e\x2b\xb4\x4e\x1a\x0d\xaf\xea\xad\xa2\xc0\x01\x18\x4b\x42\x7a\xc2\xd3\x01\x2c\x98\x82\xf8\xfa\x20\x74\x05\x4a\xf8\x0d\xeb\x23\x0c\xb2\x39\x77\x0a\x52\xf3\x36\x4b\x53\x20\xf8\xa5\xf0\x74\xea\xb5\x54\x0a\xe6\x08\xa5\xc3\xac\x54\x03\x92\x36\x2f\x3d\x7c\x3c\x9f\xfd\x7c\xf9\x61\x06\x93\x77\x9f\xe0\xe3\xe4\xea\x6a\xf2\x6e\xf6\xe9\x14\xd6\xd2\x2f\x4d\xe9\x01\x57\x18\x44\xc9\xbc\x50\x12\x53\x58\x0b\x6b\x85\xf6\x15\x98\x8c\x24\xfc\x32\xbd\x3a\xfb\x79\xf2\x6e\x36\xf9\xff\xf3\x8b\xf3\xd9\x27\x30\x16\xde\x9c\xcf\xde\x4d\xaf\xaf\xe1\xcd\xe5\x15\x4c\xe0\xfd\xe4\x6a\x76\x7e\xf6\xe1\x62\x72\x05\xef\x3f\x5c\xbd\xbf\xbc\x9e\x0e\xe1\x1a\x49\x2b\x24\xfe\x6f\xdb\x3c\x63\xef\x59\x84\x14\xbd\x90\xca\xd5\x96\xf8\x64\x4a\x70\x4b\x53\xaa\x14\x96\x62\x85\x60\x31\x41\xb9\xc2\x14\x04\x24\xa6\xa8\x1e\xed\x54\x92\x25\x94\xd1\x0b\x3e\xf3\xbd\x80\x84\xf3\x0c\xb4\xf1\x03\x70\x88\xf0\xe3\xd2\xfb\xe2\x64\x34\x5a\xaf\xd7\xc3\x85\x2e\x87\xc6\x2e\x46\x2a\x88\x73\xa3\x9f\x86\x5d\x92\x99\x08\xa5\x66\x56\x24\x68\xc9\x39\x02\xb2\x92\xcc\xaf\xcc\x5a\x83\xb7\x42\x3b\x91\x90\xab\xe9\x7f\xc2\x60\x14\x1e\xf0\x96\x9e\xbc\x23\xd0\x82\xc5\xc2\x58\xfa\xaf\x54\x8d\x33\xa9\x3d\x5a\x2d\x14\xcb\x76\x90\x8b\x14\x61\x5e\x81\x68\x0b\x1c\xb4\x0f\x43\x30\x0a\xee\x06\xa9\x33\x63\x73\x86\xe5\xb0\xfb\xb5\xdb\x89\x1a\x3a\x2f\x92\x1b\x52\x90\xe4\x27\xa5\xb5\xa8\x3d\x99\xb2\xb4\x4e\xae\x90\x49\x20\xd0\x44\x7b\x4e\x7f\xfd\x05\xf0\x16\x93\x32\x48\xea\x34\x42\x4e\xe0\xf3\xd7\xbb\x2f\x83\x2e\x8b\x4e\xd1\x25\xa8\x53\x4c\xf9\x7c\x37\x0e\xd6\x4b\xb6\x28\xac\xf1\x68\x85\xf0\x5b\xe9\x7c\x8b\x26\xb3\x26\x07\xa1\xc1\x94\x84\xf8\xb6\x75\xa4\xf6\x86\x05\x0a\xfa\xaf\xd1\xb2\x46\xc3\x6e\xa7\x61\x3e\x81\x4c\x28\x87\x71\x5f\xe7\xb1\xa0\xd3\x48\xbd\x32\x37\x24\xd9\x58\x82\xb0\xad\xc0\x14\x89\x49\x63\x30\xd0\x39\x9a\x63\xa0\x1b\x76\x3b\xc4\x77\x02\x59\xa9\x79\xdb\x9e\x32\x8b\x01\xa4\xf3\x3e\x7c\xed\x76\x48\xec\x99\x28\x7c\x69\x91\xed\x89\xd6\x1a\xeb\x40\xe6\x39\xa6\x52\x78\x54\x55\xb7\xd3\x59\x09\x1b\x16\x60\x0c\xca\x2c\x86\x0b\xf4\x53\x7a\xec\xf5\x4f\xbb\x9d\x8e\xcc\xa0\x17\x56\x9f\x8c\xc7\x9c\x7d\x32\xa9\x31\x0d\xe2\x3b\x7e\x29\xdd\x30\x13\xa5\xf2\xcd\xbe\xc4\xd4\xb1\xe8\x4b\xab\xe9\xef\x5d\xd0\xe2\x23\x82\xd1\xaa\x82\x84\xb2\x8c\x98\x53\x78\xba\xca\x79\xcc\xe3\xe1\xdc\x00\x32\xe1\xc8\x84\x32\x83\x35\x42\x61\xf1\x79\xb2\x44\xf2\x9d\x4e\x30\x6a\xe9\x2a\xc7\x4e\x1d\x03\xed\x36\x34\xc5\xd0\x9b\x77\x65\x3e\x47\xdb\xeb\xc3\x77\x70\x7c\x9b\x1d\xf7\x61\x3c\xe6\x3f\xb5\xee\x91\x27\xea\x4b\x52\x4c\x11\x0f\xca\xfc\xd7\xde\x4a\xbd\x08\x67\x8d\xba\x9e\x67\x20\x40\xe3\x1a\x12\xa3\x19\xd4\xe4\x95\x39\x4a\xbd\x80\xc4\xa2\xf0\x98\x0e\x40\xa4\x29\x78\x13\x90\xd7\xe0\x6c\x7b\x4b\xf8\xee\x3b\xe8\xd1\x66\x63\x38\x3a\xbb\x9a\x4e\x66\xd3\x23\xf8\xe3\x0f\x08\x6f\x9e\x86\x37\x2f\x9f\xf6\x5b\x9a\x49\x7d\x99\x65\x51\x39\x16\x38\x2c\x10\x6f\x7a\x2f\xfa\xc3\x95\x50\x25\x5e\x66\x41\xcd\x48\x3b\xd5\x29\x8c\x23\xcf\xb3\x5d\x9e\x97\x5b\x3c\xc4\x34\x1a\xc1\xc4\x39\xcc\xe7\x0a\xf7\x03\x32\x46\x2c\x07\xaf\xf3\x94\xb1\x08\x7d\x89\xc9\x0b\x85\x84\xaa\x7a\xd7\x68\x7e\xd6\xb8\xe3\xab\x02\x4f\x00\x00\x4c\x31\xe0\x17\x14\x0b\xfc\xc2\x9b\x9f\xf1\x96\x7d\x54\x9b\x90\x50\x35\x49\x53\x8b\xce\xf5\xfa\xfd\x40\x2e\x75\x51\xfa\x93\x2d\xf2\x1c\x73\x63\xab\xa1\xa3\x84\xd4\xe3\xa3\x0d\xc2\x49\x6b\x9e\x85\x70\xe7\x9a\x78\x22\x52\xdf\x0a\xd7\xdb\x2c\x9d\x19\xe7\x4f\xea\x25\x7a\xa8\xd7\xd8\x16\xc4\x76\x74\x7c\x7b\xb4\x6f\xad\xe3\xfe\x06\x09\x2f\x7e\xe8\x13\xcb\xdd\x69\x83\xef\x26\x4d\x0c\x8b\xd2\x2d\x7b\x0c\xa7\xcd\xea\x26\x15\x8c\xc1\xdb\x12\x0f\xc2\x9f\x21\xb5\x0f\x27\x87\x2a\xa3\x5c\xe2\x6d\x99\x30\xac\x16\x82\x33\x0d\x47\xba\xa0\xcc\xeb\xca\x39\xdb\xdc\x1b\xb3\x8f\xae\x08\xae\xeb\xe9\xc5\x9b\xd7\xd3\xeb\xd9\xd5\x87\xb3\xd9\x51\x0b\x4e\x0a\x33\x4f\x4a\x6d\x9f\x41\xa1\x5e\xf8\x25\xeb\x4f\xe2\xb6\x57\x3f\x13\xcf\xf3\x17\x5f\xc2\x1b\x18\x1f\x08\xf9\xce\xc3\x1c\xf0\xf9\x0b\xcb\xbe\xdb\x37\xdf\x36\x69\x30\xe6\xd7\x00\x22\x53\xdc\xb5\x13\xc7\x81\x58\xcc\xd1\x2f\x4d\xca\xc9\x31\x11\x21\xbf\xd6\x56\x4c\x8d\xc6\x3f\x1f\x91\x93\x8b\x8b\x56\x3c\xf2\xf3\xd9\xe5\xeb\x76\x8c\x1e\xbd\x9e\x5e\x4c\xdf\x4e\x66\xd3\x5d\xda\xeb\xd9\x64\x76\x7e\xc6\x6f\xeb\xf0\x1d\x8d\xe0\xfa\x46\x16\x9c\x65\x39\x77\x99\xbc\xe0\x76\xb1\xd1\xd7\x0d\xc0\x2f\x0d\x35\x62\x36\x16\x91\x4c\xe8\xa4\x4e\xee\xae\x76\x9a\x37\xe4\x32\x53\xc7\xca\x7e\x2a\x68\x03\xb5\xdf\xb8\x51\xba\xf7\x16\xe3\xa6\x69\xcf\x9b\x5a\xaf\x8d\x41\x83\x47\x38\x01\x72\x92\xe9\x3d\xfe\x90\xf0\x7f\x70\x0c\x27\xf0\x22\x66\x92\x07\x52\xd5\x4b\x78\x46\xe2\xff\x42\xc2\x7a\x75\x80\xf3\xef\x99\xb6\xbc\x61\xe2\x9a\xdc\x9b\xff\x7c\x3a\x33\xa5\xbf\xcc\xb2\x13\xd8\x35\xe2\xf7\x7b\x46\x6c\xe8\x2f\x50\xef\xd3\xff\xcf\x1e\xfd\x26\xf5\x11\xaa\x4c\x01\x4f\xf6\x20\x12\x12\xcf\x93\x9d\x38\x88\xc6\xe5\x16\x87\xa5\xc1\xf8\x9e\x64\xfb\x72\x1b\xc3\xf7\x65\x8b\x7f\x29\xd9\x1e\x6c\xd5\xa8\x21\xdb\x6e\xc6\x06\x60\xd1\x5b\x89\x2b\x1a\xb7\x8e\x1c\x8b\xa4\xa6\xd5\xac\x85\x4e\x70\x08\x1f\x31\x48\xd4\x88\x9c\x5c\x62\x93\x4b\x3d\x0a\xf7\x7d\xd4\xa8\xc6\x71\x85\x21\x26\xb8\x17\xb5\x08\xb9\xa8\x68\x5c\xc9\x4a\x7d\x53\xc1\x42\x38\x48\x2b\x2d\x72\x99\xb8\x20\x8f\x1b\x5c\x8b\x0b\x61\x59\xac\xc5\xdf\x4b\x74\x34\xfb\x10\x90\x45\xe2\x4b\xa1\x54\x05\x0b\x49\x03\x0c\x71\xf7\x5e\xbe\x3a\x3e\x06\xe7\x65\x81\x3a\x1d\xc0\x0f\xaf\x46\x3f\x7c\x0f\xb6\x54\xd8\x1f\x76\x5b\x69\xbc\x39\x6a\xf4\x06\x2d\x44\xf4\xbc\xc6\xc2\x2f\x7b\x7d\xf8\xe9\x9e\x7a\x70\x4f\x72\x3f\x48\x0b\xcf\xe1\xc5\x97\x21\xe9\x35\xde\xc2\x6d\xf0\x24\xa0\x72\x18\xa5\xd1\xd0\x77\xf9\xfa\xb2\x77\x23\xac\x50\x62\x8e\xfd\x13\x1e\x02\xd9\x56\x6b\x11\xa7\x00\x72\x0a\x14\x4a\x48\x0d\x22\x49\x4c\xa9\x3d\x19\xbe\x6e\xe8\x55\x45\xf9\xfd\xc8\xd7\xf2\x78\x5e\x12\x49\x82\xce\xd5\xe9\x9e\xbd\x46\xea\x88\x9c\xb8\x41\x6a\x27\x53\x6c\x79\x85\xb2\x83\xe1\xd4\x1c\x29\x68\x9c\xac\x05\xe6\xc6\xd1\x26\x73\x84\xb5\xa5\xe1\xc3\x49\x9d\xf0\xf4\x9d\x22\x59\xdb\x81\xd1\x20\x40\x19\x1e\xf9\x39\xc6\x41\xd8\x85\x1b\x86\x7c\x4f\xdb\x52\xce\xd1\x66\x3d\xdc\x06\x72\x1b\xaa\xdc\xe6\xef\xb4\x03\x1a\xf0\x56\x3a\xcf\x5d\x25\x69\x29\x1d\x04\x24\x4b\xbd\x18\x40\x61\x0a\xce\xd3\xdf\x2a\x67\x31\x59\x5f\x4d\x7f\x9d\x5e\x35\xc5\xff\xf1\x4e\xac\xfb\xfe\xa7\xcd\x58\x04\x96\x66\x0e\x8f\xe9\xd3\x03\x8d\xfc\x01\x40\x8d\xef\x01\x14\xc9\xdf\xd4\xc6\xf7\xad\xe3\x28\xe1\xfc\xc6\x31\x0b\x0c\x33\x4d\x5b\x01\x57\x2a\xef\x76\x72\xf7\x6e\x72\x30\x45\x5d\x21\x48\x29\x4e\x3b\x94\xd8\x77\xbb\xed\xad\x85\x4d\xd3\xbd\xc1\xe7\x79\xcb\xc6\x6b\x6e\xb9\x02\x51\x2b\x35\xf0\x7a\xdd\xbb\x89\x50\x0d\x58\x77\x53\x7a\x82\x03\xd5\xef\x4d\xf2\x5b\x08\xf7\xc1\xb1\xd7\x63\xfa\x9b\xcb\xc5\xb9\xf6\xbd\x7a\xf1\x5c\xc3\x73\xa8\x1f\x28\xa9\xc3\xf3\xad\x28\x3a\x90\x1d\x3b\x29\x2a\xf4\x08\x1b\x11\xa7\xb0\xf3\x8a\x04\x05\x73\xb0\xd1\x2c\xfa\xfd\xe2\x7c\x1c\xa5\x91\xc1\x9e\x58\xf4\x43\xfc\xbd\x14\xca\xf5\x8e\x9b\x66\x21\x9c\xc0\x1b\x2e\x6f\xe3\xa6\xc0\xd5\x15\x90\x78\xb6\xda\x8f\x28\x30\xb0\x45\x6b\xd4\x6c\xe9\x3c\x54\xad\x14\x1f\x94\x10\x45\xc4\xb4\xd1\xf8\x32\x02\xf3\x50\xff\xd9\x69\x13\xc0\xd3\xa6\x21\xc8\x84\x54\xa5\xc5\xa7\xa7\x70\x20\xed\xb8\xd2\x66\x22\x61\x5f\x3a\x04\x9e\x58\x1d\x38\x93\xe3\xd2\xac\x83\x02\x87\x92\xd7\x3e\x38\x1a\x1c\xec\x94\x0f\xbe\x7a\x11\x0e\x4a\x27\x16\xd8\x02\x47\x63\xf0\xda\x51\x07\xc7\xe8\xbf\x0c\x9d\x67\xcd\xe3\x37\x50\x14\x76\xf9\x26\x34\x1e\xc2\xc6\x41\x2f\xef\x75\x39\x35\x11\xf7\x3a\xad\x87\x5a\xd5\xd0\x8a\x34\xc8\xf9\x33\x7e\xff\xf7\x38\x3e\x78\x3e\xfe\x3e\x36\xd0\x76\x69\xc3\x19\xb7\x89\xc3\x49\x37\xed\xcd\xb7\x51\xd0\xac\xde\x07\x80\xfb\x3a\x27\x82\xaa\xfe\x0d\x13\xbf\x81\x2b\x37\x3b\xf4\x54\x58\x5c\x49\x53\x52\x1d\xc3\xff\xa6\xc9\xb0\xe9\xfc\xee\xba\x9d\xbb\x78\x45\xc6\xee\x6b\xdf\x91\xad\x97\xf1\x8a\x37\x34\x4d\xad\x2a\x62\xb8\xc4\xc6\x9b\xb3\x2c\x5c\xbe\x76\x98\xff\x81\xbb\xb2\x18\xef\xde\x14\xd4\x15\xc4\x22\xa5\x2c\x8a\xb4\x6a\xea\xe2\x20\xf4\x23\xb0\x14\x3a\x8d\x33\x89\x48\x53\x49\xf2\x18\x8b\xa4\xa1\x58\x08\xa9\xbb\x07\xcd\xf8\xcd\x62\x7c\x08\x19\x7b\x2d\x6e\xbb\x9e\xc6\x59\x92\x06\x3f\xd6\xb8\xfb\x88\xba\xb9\x13\x4b\xbb\xd7\x7e\xf1\xe6\xd0\x68\x57\xe6\xdc\x10\x83\x58\x09\xa9\x04\x0d\x61\xdc\x68\xe9\x14\x12\x85\x42\x87\xcb\x7e\xcc\xbc\x59\xa1\x75\xdd\x47\x80\xfc\xaf\x60\x7c\x27\x39\xd6\x8f\xd1\x1c\x8f\x8f\xd9\xc7\x46\x6c\x38\xfe\x1b\x25\xbc\x8f\xf0\x6a\x99\x37\x44\x96\xf4\xfc\x1d\x08\xb5\xef\x3e\x2e\xa4\xb8\x75\x22\x9a\x9f\xe0\xb8\xd5\x9e\xff\x5d\x82\x6c\x1f\x62\x17\x4d\x9b\x16\x0f\xef\x8d\x19\x80\x42\xc1\xc3\x52\xfd\x95\xa6\x6e\x4b\x1f\x9a\xdd\xea\xe8\x0d\x8d\xdd\x5e\xf8\xf2\xf5\xd6\x12\xeb\x8b\x90\xd0\xe1\xcf\x11\x35\x48\x8f\x56\xd0\x58\x44\xe8\x8a\x1f\x16\x48\x4b\xc7\xe2\xd8\x2f\x92\x82\x2e\x0a\x8e\xb7\xfc\x54\x9f\xa5\x5e\x0c\xbb\x9d\xf0\xbe\x15\xef\x89\xbf\xdd\xc4\x7b\x28\x86\xcc\x19\xaf\x06\x9a\x9b\x81\xc4\xdf\x72\xd3\xc8\xd3\xf3\xce\xf5\x00\xad\xd1\xab\x30\x5a\xef\x5c\x06\x30\x63\xbc\x10\xd8\xbd\x73\xa4\x35\x7e\xb7\x05\x70\x26\x5d\x08\x17\xc4\xec\x84\x84\xbf\xdd\x8f\x88\x9a\x81\x82\xe1\xe4\x30\x03\x2d\x1d\x60\xda\xb9\xa0\x20\x62\x7e\x15\x56\x43\x61\x3f\x69\xaf\x86\x57\xf1\xa0\x32\x6f\xd9\x46\xe6\x6c\x9b\xbb\xd3\xc3\x49\xee\xb8\xc6\xe3\xe1\x64\x46\x36\x6f\x00\x7b\x0f\x6b\x7b\xe4\xd8\x27\x79\x28\x55\xb2\xf4\x3a\xb3\xdd\xc3\xca\xd2\x5b\xad\x87\xbf\x7d\xbc\xc8\x86\xb8\xad\xe2\x16\xcd\x21\x21\x31\xcf\x44\xba\x60\xd9\x5a\x40\x40\x75\xd0\x95\x11\x2d\xff\x81\x51\x62\x3b\x7e\xea\x25\xb0\x18\xbe\x43\x70\x43\x4a\xe1\x63\xe6\x5c\xfc\x4b\x47\xd3\xe4\x26\x2e\x52\x74\xd2\x62\x0a\x99\x44\x95\x82\x49\xd1\xf2\xac\xfa\x9b\x33\x3a\x7c\x71\x42\x2b\x49\x62\xf8\xb2\x16\x3e\x72\xf3\xf7\x3e\x2d\x13\xf4\x15\x64\x28\xf8\xd3\x91\x37\x50\x08\xe7\x20\x47\x41\xd3\x69\x56\x2a\x55\x81\xb1\x29\x92\xf0\x66\x5c\xa3\x90\x34\x50\x3a\xb4\x0e\xd6\x4b\x13\xcb\x24\x77\x69\x05\x35\x9d\xd2\x0f\xe2\x8d\x8c\x74\x85\x12\x15\x48\x4f\x25\x39\x1e\xaa\x1d\xa5\xcd\xf7\x1a\xfe\xe8\x63\xa8\xea\xee\x87\x68\x3d\xd8\x6d\xc7\x28\xbf\xa6\xa7\xed\xe8\x8c\x73\xcd\x76\x5c\x6e\xee\xaa\xb6\x83\xb0\x2e\x1b\xdb\x91\xd6\x2e\x42\xdb\xe1\xc4\x2b\xfc\xb4\x1d\x48\xad\x7e\x99\x17\x18\x1c\x0d\x03\x3f\xed\x84\x16\x6b\x19\x63\x2b\x7c\x9d\x6c\xc8\xf9\x69\x10\x01\x43\x5e\xec\x91\x71\x6e\xb0\xa2\x4c\x1c\x6c\xd4\x2a\x2b\xe1\xc5\xe7\x1b\xac\xbe\x1c\xae\x22\x11\x8e\x2d\xba\xa6\x6c\xd4\x90\x0e\x6b\x0f\x04\x72\xa3\x85\x1c\x1f\x9f\x82\xfc\xb1\xcd\x50\x57\x3e\x90\xcf\x9e\xd5\x7b\xb6\xd7\x3f\xcb\x2f\x75\x74\x36\x88\xdf\x59\xef\x6f\x69\x14\x63\x24\xd0\x50\x50\x74\xef\xba\xff\x0c\x00\x00\xff\xff\x00\x24\x55\x1f\xc3\x21\x00\x00") +var _call_tracerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x59\xdf\x73\xdb\x36\xf2\x7f\x96\xfe\x8a\x4d\x1e\x6a\x69\xa2\x48\x4a\xd2\x6f\xbf\x33\x76\xd5\x1b\x9d\xa3\xa4\x9e\x71\xe3\x8c\xad\x34\x93\xc9\xe4\x01\x22\x97\x12\x6a\x08\x60\x01\xd0\x32\x2f\xf5\xff\x7e\xb3\x0b\x90\x22\x25\xd9\xf1\xf5\x6e\x6e\x7a\x6f\x24\xb1\xbb\x58\xec\x7e\xf6\x17\x38\x1a\xc1\xa9\xc9\x4b\x2b\x97\x2b\x0f\x2f\xc7\x2f\xfe\x1f\xe6\x2b\x84\xa5\x79\x8e\x7e\x85\x16\x8b\x35\x4c\x0b\xbf\x32\xd6\x75\x47\x23\x98\xaf\xa4\x83\x4c\x2a\x04\xe9\x20\x17\xd6\x83\xc9\xc0\xef\xd0\x2b\xb9\xb0\xc2\x96\xc3\xee\x68\x14\x78\x0e\x2e\x93\x84\xcc\x22\x82\x33\x99\xdf\x08\x8b\xc7\x50\x9a\x02\x12\xa1\xc1\x62\x2a\x9d\xb7\x72\x51\x78\x04\xe9\x41\xe8\x74\x64\x2c\xac\x4d\x2a\xb3\x92\x44\x4a\x0f\x85\x4e\xd1\xf2\xd6\x1e\xed\xda\x55\x7a\xbc\x7d\xf7\x01\xce\xd1\x39\xb4\xf0\x16\x35\x5a\xa1\xe0\x7d\xb1\x50\x32\x81\x73\x99\xa0\x76\x08\xc2\x41\x4e\x5f\xdc\x0a\x53\x58\xb0\x38\x62\x7c\x43\xaa\x5c\x45\x55\xe0\x8d\x29\x74\x2a\xbc\x34\x7a\x00\x28\x49\x73\xb8\x41\xeb\xa4\xd1\xf0\xaa\xda\x2a\x0a\x1c\x80\xb1\x24\xa4\x27\x3c\x1d\xc0\x82\xc9\x89\xaf\x0f\x42\x97\xa0\x84\xdf\xb2\x3e\xc2\x20\xdb\x73\xa7\x20\x35\x6f\xb3\x32\x39\x82\x5f\x09\x4f\xa7\xde\x48\xa5\x60\x81\x50\x38\xcc\x0a\x35\x20\x69\x8b\xc2\xc3\xc7\xb3\xf9\xcf\x17\x1f\xe6\x30\x7d\xf7\x09\x3e\x4e\x2f\x2f\xa7\xef\xe6\x9f\x4e\x60\x23\xfd\xca\x14\x1e\xf0\x06\x83\x28\xb9\xce\x95\xc4\x14\x36\xc2\x5a\xa1\x7d\x09\x26\x23\x09\xbf\xcc\x2e\x4f\x7f\x9e\xbe\x9b\x4f\xff\x7e\x76\x7e\x36\xff\x04\xc6\xc2\x9b\xb3\xf9\xbb\xd9\xd5\x15\xbc\xb9\xb8\x84\x29\xbc\x9f\x5e\xce\xcf\x4e\x3f\x9c\x4f\x2f\xe1\xfd\x87\xcb\xf7\x17\x57\xb3\x21\x5c\x21\x69\x85\xc4\xff\x6d\x9b\x67\xec\x3d\x8b\x90\xa2\x17\x52\xb9\xca\x12\x9f\x4c\x01\x6e\x65\x0a\x95\xc2\x4a\xdc\x20\x58\x4c\x50\xde\x60\x0a\x02\x12\x93\x97\x8f\x76\x2a\xc9\x12\xca\xe8\x25\x9f\xf9\x5e\x40\xc2\x59\x06\xda\xf8\x01\x38\x44\xf8\x71\xe5\x7d\x7e\x3c\x1a\x6d\x36\x9b\xe1\x52\x17\x43\x63\x97\x23\x15\xc4\xb9\xd1\x4f\xc3\x2e\xc9\x4c\x84\x52\x73\x2b\x12\xb4\xe4\x1c\x01\x59\x41\xe6\x57\x66\xa3\xc1\x5b\xa1\x9d\x48\xc8\xd5\xf4\x9c\x30\x18\x85\x07\xbc\xa5\x37\xef\x08\xb4\x60\x31\x37\x96\x9e\x95\xaa\x70\x26\xb5\x47\xab\x85\x62\xd9\x0e\xd6\x22\x45\x58\x94\x20\x9a\x02\x07\xcd\xc3\x10\x8c\x82\xbb\x41\xea\xcc\xd8\x35\xc3\x72\xd8\xfd\xda\xed\x44\x0d\x9d\x17\xc9\x35\x29\x48\xf2\x93\xc2\x5a\xd4\x9e\x4c\x59\x58\x27\x6f\x90\x49\x20\xd0\x44\x7b\xce\x7e\xfd\x05\xf0\x16\x93\x22\x48\xea\xd4\x42\x8e\xe1\xf3\xd7\xbb\x2f\x83\x2e\x8b\x4e\xd1\x25\xa8\x53\x4c\xf9\x7c\xd7\x0e\x36\x2b\xb6\x28\x6c\xf0\xe8\x06\xe1\xb7\xc2\xf9\x06\x4d\x66\xcd\x1a\x84\x06\x53\x10\xe2\x9b\xd6\x91\xda\x1b\x16\x28\xe8\x59\xa3\x65\x8d\x86\xdd\x4e\xcd\x7c\x0c\x99\x50\x0e\xe3\xbe\xce\x63\x4e\xa7\x91\xfa\xc6\x5c\x93\x64\x63\x09\xc2\xb6\x04\x93\x27\x26\x8d\xc1\x40\xe7\xa8\x8f\x81\x6e\xd8\xed\x10\xdf\x31\x64\x85\xe6\x6d\x7b\xca\x2c\x07\x90\x2e\xfa\xf0\xb5\xdb\x21\xb1\xa7\x22\xf7\x85\x45\xb6\x27\x5a\x6b\xac\x03\xb9\x5e\x63\x2a\x85\x47\x55\x76\x3b\x9d\x1b\x61\xc3\x02\x4c\x40\x99\xe5\x70\x89\x7e\x46\xaf\xbd\xfe\x49\xb7\xd3\x91\x19\xf4\xc2\xea\x93\xc9\x84\xb3\x4f\x26\x35\xa6\x41\x7c\xc7\xaf\xa4\x1b\x66\xa2\x50\xbe\xde\x97\x98\x3a\x16\x7d\x61\x35\x3d\xde\x05\x2d\x3e\x22\x18\xad\x4a\x48\x28\xcb\x88\x05\x85\xa7\x2b\x9d\xc7\x75\x3c\x9c\x1b\x40\x26\x1c\x99\x50\x66\xb0\x41\xc8\x2d\x3e\x4f\x56\x48\xbe\xd3\x09\x46\x2d\x5d\xe9\xd8\xa9\x13\xa0\xdd\x86\x26\x1f\x7a\xf3\xae\x58\x2f\xd0\xf6\xfa\xf0\x1d\x8c\x6f\xb3\x71\x1f\x26\x13\x7e\xa8\x74\x8f\x3c\x51\x5f\x92\x62\xf2\x78\x50\xe6\xbf\xf2\x56\xea\x65\x38\x6b\xd4\xf5\x2c\x03\x01\x1a\x37\x90\x18\xcd\xa0\x26\xaf\x2c\x50\xea\x25\x24\x16\x85\xc7\x74\x00\x22\x4d\xc1\x9b\x80\xbc\x1a\x67\xed\x2d\xe1\xbb\xef\xa0\x47\x9b\x4d\xe0\xe8\xf4\x72\x36\x9d\xcf\x8e\xe0\x8f\x3f\x20\x7c\x79\x1a\xbe\xbc\x7c\xda\x6f\x68\x26\xf5\x45\x96\x45\xe5\x58\xe0\x30\x47\xbc\xee\xbd\xe8\x0f\x6f\x84\x2a\xf0\x22\x0b\x6a\x46\xda\x99\x4e\x61\x12\x79\x9e\xed\xf2\xbc\x6c\xf1\x10\xd3\x68\x04\x53\xe7\x70\xbd\x50\xb8\x1f\x90\x31\x62\x39\x78\x9d\xa7\x8c\x45\xe8\x4b\xcc\x3a\x57\x48\xa8\xaa\x76\x8d\xe6\x67\x8d\x3b\xbe\xcc\xf1\x18\x00\xc0\xe4\x03\xfe\x40\xb1\xc0\x1f\xbc\xf9\x19\x6f\xd9\x47\x95\x09\x09\x55\xd3\x34\xb5\xe8\x5c\xaf\xdf\x0f\xe4\x52\xe7\x85\x3f\x6e\x91\xaf\x71\x6d\x6c\x39\x74\x94\x90\x7a\x7c\xb4\x41\x38\x69\xc5\xb3\x14\xee\x4c\x13\x4f\x44\xea\x5b\xe1\x7a\xdb\xa5\x53\xe3\xfc\x71\xb5\x44\x2f\xd5\x1a\xdb\x82\xd8\x8e\xc6\xb7\x47\xfb\xd6\x1a\xf7\xb7\x48\x78\xf1\x43\x9f\x58\xee\x4e\x6a\x7c\xd7\x69\x62\x98\x17\x6e\xd5\x63\x38\x6d\x57\xb7\xa9\x60\x02\xde\x16\x78\x10\xfe\x0c\xa9\x7d\x38\x39\x54\x19\xe5\x12\x6f\x8b\x84\x61\xb5\x14\x9c\x69\x38\xd2\x05\x65\x5e\x57\x2c\xd8\xe6\xde\x98\x7d\x74\x45\x70\x5d\xcd\xce\xdf\xbc\x9e\x5d\xcd\x2f\x3f\x9c\xce\x8f\x1a\x70\x52\x98\x79\x52\xaa\x7d\x06\x85\x7a\xe9\x57\xac\x3f\x89\x6b\xaf\x7e\x26\x9e\xe7\x2f\xbe\x84\x2f\x30\x39\x10\xf2\x9d\x87\x39\xe0\xf3\x17\x96\x7d\xb7\x6f\xbe\x36\x69\x30\xe6\xd7\x00\x22\x93\xdf\x35\x13\xc7\x81\x58\x5c\xa3\x5f\x99\x94\x93\x63\x22\x42\x7e\xad\xac\x98\x1a\x8d\xff\x7a\x44\x4e\xcf\xcf\x1b\xf1\xc8\xef\xa7\x17\xaf\x9b\x31\x7a\xf4\x7a\x76\x3e\x7b\x3b\x9d\xcf\x76\x69\xaf\xe6\xd3\xf9\xd9\x29\x7f\xad\xc2\x77\x34\x82\xab\x6b\x99\x73\x96\xe5\xdc\x65\xd6\x39\xb7\x8b\xb5\xbe\x6e\x00\x7e\x65\xa8\x11\xb3\xb1\x88\x64\x42\x27\x55\x72\x77\x95\xd3\xbc\x21\x97\x99\x2a\x56\xf6\x53\x41\x13\xa8\xfd\xda\x8d\xd2\xbd\xb7\x18\x37\x4d\x7b\xde\x54\x7a\x6d\x0d\x1a\x3c\xc2\x09\x90\x93\x4c\xef\xf1\x87\x84\xbf\xc1\x18\x8e\xe1\x45\xcc\x24\x0f\xa4\xaa\x97\xf0\x8c\xc4\xff\x89\x84\xf5\xea\x00\xe7\x5f\x33\x6d\x79\xc3\xc4\x15\xb9\x37\xff\xfd\x74\x66\x0a\x7f\x91\x65\xc7\xb0\x6b\xc4\xef\xf7\x8c\x58\xd3\x9f\xa3\xde\xa7\xff\xbf\x3d\xfa\x6d\xea\x23\x54\x99\x1c\x9e\xec\x41\x24\x24\x9e\x27\x3b\x71\x10\x8d\xcb\x2d\x0e\x4b\x83\xc9\x3d\xc9\xf6\x65\x1b\xc3\xf7\x65\x8b\x7f\x2b\xd9\x1e\x6c\xd5\xa8\x21\x6b\x37\x63\x03\xb0\xe8\xad\xc4\x1b\x1a\xb7\x8e\x1c\x8b\xa4\xa6\xd5\x6c\x84\x4e\x70\x08\x1f\x31\x48\xd4\x88\x9c\x5c\x62\x93\x4b\x3d\x0a\xf7\x7d\xd4\xa8\xc6\x71\x85\x21\x26\xb8\x17\xb5\x08\x6b\x51\xd2\xb8\x92\x15\xfa\xba\x84\xa5\x70\x90\x96\x5a\xac\x65\xe2\x82\x3c\x6e\x70\x2d\x2e\x85\x65\xb1\x16\x7f\x2f\xd0\xd1\xec\x43\x40\x16\x89\x2f\x84\x52\x25\x2c\x25\x0d\x30\xc4\xdd\x7b\xf9\x6a\x3c\x06\xe7\x65\x8e\x3a\x1d\xc0\x0f\xaf\x46\x3f\x7c\x0f\xb6\x50\xd8\x1f\x76\x1b\x69\xbc\x3e\x6a\xf4\x06\x2d\x44\xf4\xbc\xc6\xdc\xaf\x7a\x7d\xf8\xe9\x9e\x7a\x70\x4f\x72\x3f\x48\x0b\xcf\xe1\xc5\x97\x21\xe9\x35\x69\xe1\x36\x78\x12\x50\x39\x8c\xd2\x68\xe8\xbb\x78\x7d\xd1\xbb\x16\x56\x28\xb1\xc0\xfe\x31\x0f\x81\x6c\xab\x8d\x88\x53\x00\x39\x05\x72\x25\xa4\x06\x91\x24\xa6\xd0\x9e\x0c\x5f\x35\xf4\xaa\xa4\xfc\x7e\xe4\x2b\x79\x3c\x2f\x89\x24\x41\xe7\xaa\x74\xcf\x5e\x23\x75\xc4\x9a\xb8\x41\x6a\x27\x53\x6c\x78\x85\xb2\x83\xe1\xd4\x1c\x29\x68\x9c\xac\x04\xae\x8d\xa3\x4d\x16\x08\x1b\x4b\xc3\x87\x93\x3a\xe1\xe9\x3b\x45\xb2\xb6\x03\xa3\x41\x80\x32\x3c\xf2\x73\x8c\x83\xb0\x4b\x37\x0c\xf9\x9e\xb6\xa5\x9c\xa3\xcd\x66\xd8\x06\x72\x13\xaa\xdc\xe6\xef\xb4\x03\x1a\xf0\x56\x3a\xcf\x5d\x25\x69\x29\x1d\x04\x24\x4b\xbd\x1c\x40\x6e\x72\xce\xd3\xdf\x2a\x67\x31\x59\x5f\xce\x7e\x9d\x5d\xd6\xc5\xff\xf1\x4e\xac\xfa\xfe\xa7\xf5\x58\x04\x96\x66\x0e\x8f\xe9\xd3\x03\x8d\xfc\x01\x40\x4d\xee\x01\x14\xc9\xdf\xd6\xc6\xf7\x8d\xe3\x28\xe1\xfc\xd6\x31\x4b\x0c\x33\x4d\x53\x01\x57\x28\xef\x76\x72\xf7\x6e\x72\x30\x79\x55\x21\x48\x29\x4e\x3b\x94\xd8\x77\xbb\xed\xd6\xc2\xb6\xe9\xde\xe2\xf3\xac\x61\xe3\x0d\xb7\x5c\x81\xa8\x91\x1a\x78\xbd\xea\xdd\x44\xa8\x06\xac\xbb\x29\x3c\xc1\x81\xea\xf7\x36\xf9\x2d\x85\xfb\xe0\xd8\xeb\x31\xfd\x2d\xe4\xf2\x4c\xfb\x5e\xb5\x78\xa6\xe1\x39\x54\x2f\x94\xd4\xe1\x79\x2b\x8a\x0e\x64\xc7\x4e\x8a\x0a\x3d\xc2\x56\xc4\x09\xec\x7c\x22\x41\xc1\x1c\x6c\x34\x8b\x7e\xbf\x38\x8f\xa3\x34\x32\xd8\x13\x8b\x7e\x88\xbf\x17\x42\xb9\xde\xb8\x6e\x16\xc2\x09\xbc\xe1\xf2\x36\xa9\x0b\x5c\x55\x01\x89\xa7\xd5\x7e\x44\x81\x81\x2d\x5a\xa3\x62\x4b\x17\xa1\x6a\xa5\xf8\xa0\x84\x28\x22\xa6\x8d\xda\x97\x11\x98\x87\xfa\xcf\x4e\x93\x00\x9e\xd6\x0d\x41\x26\xa4\x2a\x2c\x3e\x3d\x81\x03\x69\xc7\x15\x36\x13\x09\xfb\xd2\x21\xf0\xc4\xea\xc0\x99\x35\xae\xcc\x26\x28\x70\x28\x79\xed\x83\xa3\xc6\xc1\x4e\xf9\xe0\xab\x17\xe1\xa0\x70\x62\x89\x0d\x70\xd4\x06\xaf\x1c\x75\x70\x8c\xfe\xd3\xd0\x79\x56\xbf\x3e\x02\x45\x77\xff\x19\x78\xec\xf8\x79\xaf\xcf\xa9\x88\xb8\xdb\x69\xbc\x54\xca\x86\x66\xe4\xaf\xe5\xf8\x47\x47\xd8\x2e\x6d\x38\x5a\x9b\x38\x1c\x70\xdb\xd7\x7c\xdb\xfd\xf5\xea\x7d\x9e\xbf\xaf\x65\x22\x8c\xea\xdf\x30\xf1\x5b\x9c\x72\x97\x43\x6f\xb9\xc5\x1b\x69\x0a\x2a\x60\xf8\xbf\x34\x12\xd6\x2d\xdf\x5d\xb7\x73\x17\xef\xc6\xd8\x6f\xcd\xcb\xb1\xcd\x2a\xde\xed\x86\x6e\xa9\x51\x3e\x0c\xd7\xd6\x78\x65\x96\x85\x5b\xd7\x0e\xf3\x3f\x70\x49\x16\x03\xdd\x9b\x9c\xda\x81\x58\x9d\x94\x45\x91\x96\x75\x41\x1c\x84\x46\x04\x56\x42\xa7\x71\x18\x11\x69\x2a\x49\x1e\x83\x90\x34\x14\x4b\x21\x75\xf7\xa0\x19\xbf\x59\x85\x0f\x21\x63\xaf\xb7\x6d\x16\xd2\x38\x44\xd2\xc4\xc7\x1a\x77\x1f\x51\x30\x77\x82\x68\xf7\xbe\x2f\x5e\x19\x1a\xed\x8a\x35\x77\xc2\x20\x6e\x84\x54\x82\xa6\x2f\xee\xb0\x74\x0a\x89\x42\xa1\xc3\x2d\x3f\x66\xde\xdc\xa0\x75\xdd\x47\x80\xfc\xcf\x60\x7c\x27\x2b\x56\xaf\xd1\x1c\x8f\x8f\xd9\xc7\x46\x6c\x38\xfe\x1b\x25\xbc\x8f\xf0\x6a\x98\x37\x44\x96\xf4\xfc\x03\x08\xb5\xef\x3e\x2e\xa4\xb8\x67\x22\x9a\x9f\x60\xdc\xe8\xcb\xff\x2a\x41\xb6\x0f\xb1\xf3\xba\x3f\x8b\x87\xf7\xc6\x0c\x40\xa1\xe0\x29\xa9\xfa\x3d\x53\xf5\xa3\x0f\x0d\x6d\x55\xf4\x86\x8e\x6e\x2f\x7c\xf9\x5e\x6b\x85\xd5\x0d\x48\x68\xed\x17\x88\x1a\xa4\x47\x2b\x68\x1e\x22\x74\xc5\x3f\x0a\xa4\xa5\x63\x71\xec\x17\x49\x41\x17\x05\xc7\xeb\x7d\x2a\xcc\x52\x2f\x87\xdd\x4e\xf8\xde\x88\xf7\xc4\xdf\x6e\xe3\x3d\x54\x40\xe6\x8c\x77\x02\xf5\x95\x40\xe2\x6f\xb9\x5b\xe4\xb1\x79\xe7\x5e\x80\xd6\xe8\x53\x98\xa9\x77\x6e\x01\x98\x31\xde\x04\xec\x5e\x36\xd2\x1a\x7f\x6b\x01\x9c\x49\x97\xc2\x05\x31\x3b\x21\xe1\x6f\xf7\x23\xa2\x62\xa0\x60\x38\x3e\xcc\x40\x4b\x07\x98\x76\x6e\x26\x88\x98\x3f\x85\xd5\x50\xcf\x8f\x9b\xab\xe1\x53\x3c\xa8\x5c\x37\x6c\x23\xd7\x6c\x9b\xbb\x93\xc3\x49\x6e\x5c\xe1\xf1\x70\x32\x23\x9b\xd7\x80\xbd\x87\xb5\x39\x6b\xec\x93\x3c\x94\x2a\x59\x7a\x95\xd9\xee\x61\x65\xe9\x8d\x96\xc3\xdf\x3e\x5e\x64\x4d\xdc\x54\xb1\x45\xd3\x12\xc2\xb7\x8d\x7b\xcb\x87\x26\x2d\x1a\x54\x22\x61\xd5\x5c\x4d\x26\x4f\xc7\xb7\xf5\xcf\x81\x98\xab\x5a\x34\x95\x12\x21\x32\xc2\x79\x39\x2a\xe4\x3f\x30\x6e\xdb\x8c\xc1\x6a\x09\x2c\x86\x9f\x18\xdc\xcd\x52\x08\x9a\x05\x37\x10\x85\xa3\x51\x74\x1b\x5b\x29\x3a\x69\x31\x85\x4c\xa2\x4a\xc1\xa4\x68\x79\xd0\xfd\xcd\x19\x1d\x7e\x57\xa1\x95\x24\x31\xfc\x96\x0b\x7f\xc8\xf9\x67\xa1\x96\x09\xfa\x12\x32\x14\xfc\xdf\xc9\x1b\xc8\x85\x73\xb0\x46\x41\xa3\x6d\x56\x28\x55\x82\xb1\x29\x92\xf0\x7a\xd6\xa3\xb0\x36\x50\x38\xb4\x0e\x36\x2b\x13\x4b\x2d\xb7\x78\x39\x75\xab\xd2\x0f\xe2\x75\x8e\x74\xb9\x12\x25\x48\x4f\x65\x3d\x1e\xaa\x19\xe9\xf5\xcf\x1e\xfe\x63\x64\xc8\xc0\xfb\x61\x5e\x4d\x85\xed\x38\xe7\xcf\xf4\xd6\x8e\xf0\x38\x14\xb5\x63\x7b\x7b\xd1\xd5\x0e\xe4\xaa\xf4\xb4\xa3\xb5\x59\xc8\xda\x21\xc9\x2b\xfc\xd6\x0e\xc6\x46\xab\xcd\x0b\x8c\xa0\x9a\x81\xdf\x76\xc2\x93\xb5\x8c\xf1\x19\x7e\x6d\xd6\xe4\xfc\x36\x88\x80\x21\x2f\xf6\xc8\x38\xd7\x58\x52\x36\x0f\x36\x6a\x94\xa6\xf0\xe1\xf3\x35\x96\x5f\x0e\x57\xa2\x08\xc7\x06\x5d\x5d\x7a\xaa\xb0\x08\x6b\x0f\x24\x83\x5a\x0b\x39\x19\x9f\x80\xfc\xb1\xc9\x50\x55\x4f\x90\xcf\x9e\x55\x7b\x36\xd7\x3f\xcb\x2f\x55\x84\xd7\x88\xdf\x59\xef\xb7\x34\x8a\x31\x12\x68\x28\x28\xba\x77\xdd\x7f\x06\x00\x00\xff\xff\x5a\x43\x33\xde\x00\x22\x00\x00") func call_tracerJsBytes() ([]byte, error) { return bindataRead( @@ -133,11 +133,11 @@ func call_tracerJs() (*asset, error) { } info := bindataFileInfo{name: "call_tracer.js", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe9, 0xef, 0x68, 0xda, 0xd8, 0x9, 0xf5, 0xd5, 0x71, 0xa8, 0x8a, 0xfb, 0x30, 0xe8, 0xf0, 0x72, 0x14, 0x36, 0x6b, 0x62, 0x5a, 0x4e, 0xff, 0x16, 0xdc, 0xd3, 0x2c, 0x68, 0x7b, 0x79, 0x9f, 0xd3}} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4d, 0x39, 0xde, 0xc6, 0x79, 0xff, 0xe3, 0x5d, 0x47, 0xed, 0xbd, 0xf4, 0x21, 0xe8, 0xc9, 0x4, 0xe0, 0xe0, 0xe4, 0x76, 0x88, 0x25, 0x7f, 0x4f, 0x30, 0xfe, 0x30, 0x1f, 0x8c, 0x4d, 0x76, 0x3d}} return a, nil } -var _evmdis_tracerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\xdf\x6f\xda\xca\x12\x7e\x86\xbf\x62\x94\x27\x50\x29\x60\x63\x08\x38\x27\x47\xe2\xa6\xf4\x1c\xae\xd2\x24\x02\x72\x8f\x2a\x94\x87\x05\xc6\xb0\xaa\xf1\x5a\xbb\x6b\x72\xb8\x55\xfe\xf7\xab\xd9\x59\x03\xf9\x75\xdb\x4a\xa7\x0f\x3b\xb5\x77\xbe\x6f\xbe\x9d\x19\xcf\x92\x56\x0b\xae\x54\xbe\xd7\x72\xbd\xb1\x10\xb6\x83\x73\x98\x6d\x10\xd6\xea\x23\xda\x0d\x6a\x2c\xb6\x30\x2c\xec\x46\x69\x53\x6d\xb5\x60\xb6\x91\x06\x12\x99\x22\x48\x03\xb9\xd0\x16\x54\x02\xf6\x85\x7f\x2a\x17\x5a\xe8\x7d\xb3\xda\x6a\x31\xe6\xcd\x6d\x62\x48\x34\x22\x18\x95\xd8\x47\xa1\x31\x86\xbd\x2a\x60\x29\x32\xd0\xb8\x92\xc6\x6a\xb9\x28\x2c\x82\xb4\x20\xb2\x55\x4b\x69\xd8\xaa\x95\x4c\xf6\x44\x29\x2d\x14\xd9\x0a\xb5\x0b\x6d\x51\x6f\x4d\xa9\xe3\x8f\x9b\x7b\xb8\x46\x63\x50\xc3\x1f\x98\xa1\x16\x29\xdc\x15\x8b\x54\x2e\xe1\x5a\x2e\x31\x33\x08\xc2\x40\x4e\x6f\xcc\x06\x57\xb0\x70\x74\x04\xfc\x4c\x52\xa6\x5e\x0a\x7c\x56\x45\xb6\x12\x56\xaa\xac\x01\x28\x49\x39\xec\x50\x1b\xa9\x32\xe8\x94\xa1\x3c\x61\x03\x94\x26\x92\x9a\xb0\x74\x00\x0d\x2a\x27\x5c\x1d\x44\xb6\x87\x54\xd8\x23\xf4\x27\x12\x72\x3c\xf7\x0a\x64\xe6\xc2\x6c\x54\x8e\x60\x37\xc2\xd2\xa9\x1f\x65\x9a\xc2\x02\xa1\x30\x98\x14\x69\x83\xd8\x16\x85\x85\xbf\xc6\xb3\x3f\x6f\xef\x67\x30\xbc\xf9\x0a\x7f\x0d\x27\x93\xe1\xcd\xec\xeb\x05\x3c\x4a\xbb\x51\x85\x05\xdc\x21\x53\xc9\x6d\x9e\x4a\x5c\xc1\xa3\xd0\x5a\x64\x76\x0f\x2a\x21\x86\x2f\xa3\xc9\xd5\x9f\xc3\x9b\xd9\xf0\x5f\xe3\xeb\xf1\xec\x2b\x28\x0d\x9f\xc7\xb3\x9b\xd1\x74\x0a\x9f\x6f\x27\x30\x84\xbb\xe1\x64\x36\xbe\xba\xbf\x1e\x4e\xe0\xee\x7e\x72\x77\x3b\x1d\x35\x61\x8a\xa4\x0a\x09\xff\xe3\x9c\x27\xae\x7a\x1a\x61\x85\x56\xc8\xd4\x94\x99\xf8\xaa\x0a\x30\x1b\x55\xa4\x2b\xd8\x88\x1d\x82\xc6\x25\xca\x1d\xae\x40\xc0\x52\xe5\xfb\x9f\x2e\x2a\x71\x89\x54\x65\x6b\x77\xe6\x77\x1b\x12\xc6\x09\x64\xca\x36\xc0\x20\xc2\x6f\x1b\x6b\xf3\xb8\xd5\x7a\x7c\x7c\x6c\xae\xb3\xa2\xa9\xf4\xba\x95\x32\x9d\x69\xfd\xde\xac\x12\x27\xee\xb6\x2b\x69\x66\x5a\x2c\x51\x83\x46\x5b\xe8\xcc\x80\x29\x92\x84\xfc\x2c\xc8\x2c\x51\x7a\xeb\xda\x04\x12\xad\xb6\x20\xc0\x92\x2f\x58\x05\x39\x6a\xda\xf4\x14\x1f\x8d\xdd\xa7\x4e\xe6\x4a\x1a\x61\x0c\x6e\x17\xe9\xbe\x59\xfd\x5e\xad\x18\x2b\x96\xdf\x62\x98\x7f\x57\xb9\x89\x61\xfe\xf0\xf4\xd0\xa8\x56\x2b\x59\x5e\x98\x0d\x9a\x18\xbe\xb7\x63\x68\x37\x20\x88\x21\x68\x40\xe8\xd6\x8e\x5b\x23\xb7\x76\xdd\xda\x73\xeb\xb9\x5b\xfb\x6e\x1d\xb8\x35\x68\xb3\x61\x74\xc0\x6e\x01\xfb\x05\xec\x18\xb0\x67\xc8\x9e\xa1\x8f\xc3\x81\x42\x8e\x14\x72\xa8\x90\x63\x85\xcc\xd2\x61\x97\x88\x59\x22\x66\xe9\x32\x4b\x97\x59\xba\xec\xd2\x65\x96\xae\x17\xdc\x75\xe7\xe9\x32\x4b\xf7\x9c\x9f\x98\xa5\xcb\x2c\x3d\x3e\x72\x8f\x01\x3d\x7f\x44\x06\xf4\x58\x7c\x8f\x01\x3d\x06\xf4\x19\xd0\xe7\xb0\xfd\x90\x9f\x3a\x6c\x98\xa5\xcf\x61\xfb\x3d\x36\x1c\xb6\xcf\x2c\x7d\x66\x19\xb0\xf8\x41\xe0\xf6\x06\x1c\x6f\xc0\xf1\x06\x3e\xab\x65\x5a\x7d\x5e\xdb\x3e\xb1\xed\xd0\xdb\x8e\xb7\x91\xb7\x5d\x6f\x7d\xe6\xdb\x3e\xf5\x6d\x9f\xfb\xb6\xe7\x3b\xd4\xc9\xf3\x05\x9e\x2f\xf0\x7c\x81\xe7\x0b\x3c\x5f\x59\xc9\xb2\x94\x65\x2d\x7d\x31\x03\x5f\xcd\xc0\x97\x33\xf0\xf5\x0c\x7c\x41\x03\x5f\xd1\xc0\x97\x34\xf0\x35\x0d\x42\xcf\x17\xf6\x63\x08\xc9\x0e\x62\xe8\x34\x20\xe8\xb4\x63\x88\xc8\x06\x31\x74\xc9\x86\x31\xf4\xc8\x76\x62\x38\x27\x1b\xc5\xd0\x27\xdb\x8d\x61\x40\x96\xf8\xa8\x6b\x3b\x44\x48\x8c\x1d\x52\x48\x94\x1d\x92\x48\x9c\x11\x69\x24\xd2\x88\x44\x12\x6b\x44\x2a\x89\x36\x22\x99\xc4\x1b\x45\xac\x23\xea\xb2\x8e\xa8\xc7\x3a\xa2\x73\xd6\x41\xdd\xe7\x00\x03\xd6\x41\xfd\x47\x3a\xa8\x01\x49\x87\xeb\x40\xd2\xe1\x7a\x90\x74\xb8\x2e\x24\x4a\xea\x43\xa7\xc3\x75\x22\x91\x52\x2f\x3a\x1d\xae\x1b\x89\xd6\xf5\x23\xf1\xfa\x8e\x0c\x7a\x81\xb7\xa1\xb7\x1d\x6f\x23\x67\xc3\xc8\x7f\x45\x91\xff\x8c\x22\xff\x1d\x45\x1d\xbf\xef\xfd\xdc\x47\xf0\x44\xdf\x79\xab\x05\x1a\x4d\x91\x5a\x1a\xfe\x32\xdb\xa9\x6f\x34\x9e\x37\x98\x81\x48\x53\x37\xc7\x54\xbe\x54\x2b\x34\x3c\x1f\x17\x88\x19\x48\x8b\x5a\xd0\x05\xa1\x76\xa8\xe9\x6e\x2c\x27\x93\xa3\x23\x4c\x22\x33\x91\x96\xc4\x7e\x86\xd2\x60\x92\xd9\xba\x59\xad\xf0\xfb\x18\x92\x22\x5b\xd2\xe8\xaa\xd5\xe1\xbb\xa7\x00\xbb\x91\xa6\xe9\x46\xd2\xbc\xfd\xd0\x54\xb9\xb9\x80\x52\x67\x22\xde\x92\x49\xd4\x62\x69\x0b\x91\x02\xfe\x8d\xcb\xc2\xcd\x42\x95\x80\xc8\xbc\x72\x48\x78\xe0\x57\x1c\xfe\x24\x6a\xaa\xd6\x0d\x58\x2d\x28\x78\x19\xc2\x58\xcc\x4f\x23\xd0\xb5\x81\x3b\xd4\xfb\x92\xcb\x5d\x83\x14\xf2\x3f\x5f\x7c\x38\x24\x6a\xc2\xbd\xc9\x5c\xad\x54\x76\x42\x43\xa2\xc5\x16\xe1\xf2\xf4\x74\xc7\xff\x36\x53\xcc\xd6\x76\x03\x1f\x21\x78\xb8\xa8\x7a\x04\x6a\xad\x34\x5c\x42\xaa\xd6\xcd\x35\xda\x11\x3d\xd6\xea\x17\xd5\x4a\x45\x26\x50\x73\xbb\x4c\x5f\x71\xdc\xf3\x33\xf7\xea\xec\x01\x2e\x19\x4a\x9e\x4f\x80\xa9\x41\x20\x80\xa7\xf9\x84\xb9\xdd\xd4\xea\x70\x79\x2a\xc5\xc7\xf7\x74\x2a\xa7\x4b\x05\x2e\xf9\xa9\xa2\xf2\x18\xe8\x1f\x11\xa8\xbc\x69\xd5\x4d\xb1\x5d\xa0\xae\xd5\x1b\x6e\x7b\x45\x84\x10\xc3\x73\x7e\xde\x2b\xcb\x3c\x7f\x70\xcf\x4f\x24\xc9\xa9\x77\x8a\xa9\xb6\xe5\xc9\x7f\x87\xb6\x8f\xee\xce\x9e\x6b\xdc\xa9\x1c\x2e\xe1\xe0\x38\x7f\x05\xe1\x64\x11\x22\x51\xba\x46\x28\x09\x97\xd0\xbe\x00\x09\xbf\xf1\xd9\xfc\x0d\x36\x67\xb6\xa6\xca\x1f\x2e\x40\x7e\xf8\x50\x77\xa0\x8a\x7f\xcb\x1a\x9b\xe4\xea\x72\xc4\x09\xc9\x11\xbf\xd5\x64\xbd\x69\xd5\xd4\x6a\x99\xad\x6b\x41\xaf\xee\x72\x5f\x79\xa2\xc5\x3c\x4a\xbb\x64\x7f\x97\x12\xef\x54\xf7\x67\x58\x0a\x83\x70\x76\x35\xbc\xbe\x3e\x8b\xe1\xf8\x70\x75\xfb\x69\x74\x16\x1f\x0e\x29\x33\x63\xe9\xe7\x2b\x97\xf8\x24\x6e\xa7\xde\xdc\x89\xb4\xc0\xdb\x84\xeb\x7d\x70\x97\xff\xc5\xd7\xde\xd1\x2b\x6f\x2e\xe0\xfc\x6c\x2d\x8c\x6b\x87\x17\x80\xf6\xbb\x00\xab\xde\xf2\x0f\x9e\xa7\xe1\x39\xc4\x31\xbd\x85\x0a\x4f\x50\x2f\x30\x32\xcb\x0b\x7b\xc0\x6c\x71\xab\xf4\xbe\x69\xe8\x87\x4f\xcd\xe7\xa4\x71\x48\xce\x07\x7f\xee\x17\x14\xc7\x5e\xcf\x8a\x34\x7d\xbe\xc7\x73\xe4\x9d\x4d\x95\x73\x4e\xe6\xbe\x77\x4e\x3e\x02\xd7\x02\xec\xe7\xa3\x2d\x34\x8a\x6f\x17\xc7\x8a\x7e\x1a\x5d\x8f\xfe\x18\xce\x46\xcf\x2a\x3b\x9d\x0d\x67\xe3\x2b\x7e\xf5\xe3\xda\x86\xbf\x54\xdb\xd7\x9d\x70\x3c\x87\x3b\x06\xbc\x6a\xc1\xb7\x5b\xe0\x97\x7b\xe0\x97\x9a\xe0\x58\xd0\x7f\xa2\xa2\xff\xbf\xa4\xff\x74\x4d\x27\xa3\xd9\xfd\xe4\xe6\xa4\x74\xf4\xe7\xca\x4f\x7c\x33\xde\xf5\xed\xba\x05\xaf\xdc\x79\x7c\xf9\x2b\xee\x8d\xc6\x57\x85\x6d\xb8\xd0\x1f\x4a\xd6\x77\xf4\x4e\x67\xb7\x77\xc7\xde\xbb\x1f\x5f\x8d\x0f\x43\xe5\x47\x31\xda\x0d\x68\xbf\xc3\xfa\xef\xfb\x2f\x77\x9f\x46\xd3\x99\x67\x2a\x33\x9b\x2f\x0f\x9f\xe9\x1a\xed\xdd\x55\xed\x64\x06\xca\xa4\x9c\x7f\xd2\xdc\x51\x9a\xcb\xe9\x77\x40\xa7\x98\x1d\xe0\xcf\x6e\x0e\xf8\x08\xed\xbf\xbb\x78\xe4\x3a\x0e\xf7\x97\x05\xf3\x37\x98\x23\x3e\xd6\xf5\xd9\x45\x7a\x3c\xdd\xf3\x3b\x88\xf1\xd5\xca\x53\xf5\xa9\xfa\xbf\x00\x00\x00\xff\xff\x51\x4b\xdc\x7e\x62\x10\x00\x00") +var _evmdis_tracerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\xdf\x6f\xda\xca\x12\x7e\x86\xbf\x62\x94\x27\x50\x29\x60\x63\x08\x38\x27\x47\xe2\xa6\xf4\x1c\xae\xd2\x24\x02\x72\x8f\x2a\x94\x87\x05\xc6\xb0\xaa\xf1\x5a\xbb\x6b\x72\xb8\x55\xfe\xf7\xab\xd9\x59\x03\xf9\x75\xdb\x4a\xa7\x0f\x3b\xb5\x77\xbe\x6f\xbe\x9d\x19\xcf\x92\x56\x0b\xae\x54\xbe\xd7\x72\xbd\xb1\x10\xb6\x83\x73\x98\x6d\x10\xd6\xea\x23\xda\x0d\x6a\x2c\xb6\x30\x2c\xec\x46\x69\x53\x6d\xb5\x60\xb6\x91\x06\x12\x99\x22\x48\x03\xb9\xd0\x16\x54\x02\xf6\x85\x7f\x2a\x17\x5a\xe8\x7d\xb3\xda\x6a\x31\xe6\xcd\x6d\x62\x48\x34\x22\x18\x95\xd8\x47\xa1\x31\x86\xbd\x2a\x60\x29\x32\xd0\xb8\x92\xc6\x6a\xb9\x28\x2c\x82\xb4\x20\xb2\x55\x4b\x69\xd8\xaa\x95\x4c\xf6\x44\x29\x2d\x14\xd9\x0a\xb5\x0b\x6d\x51\x6f\x4d\xa9\xe3\x8f\x9b\x7b\xb8\x46\x63\x50\xc3\x1f\x98\xa1\x16\x29\xdc\x15\x8b\x54\x2e\xe1\x5a\x2e\x31\x33\x08\xc2\x40\x4e\x6f\xcc\x06\x57\xb0\x70\x74\x04\xfc\x4c\x52\xa6\x5e\x0a\x7c\x56\x45\xb6\x12\x56\xaa\xac\x01\x28\x49\x39\xec\x50\x1b\xa9\x32\xe8\x94\xa1\x3c\x61\x03\x94\x26\x92\x9a\xb0\x74\x00\x0d\x2a\x27\x5c\x1d\x44\xb6\x87\x54\xd8\x23\xf4\x27\x12\x72\x3c\xf7\x0a\x64\xe6\xc2\x6c\x54\x8e\x60\x37\xc2\xd2\xa9\x1f\x65\x9a\xc2\x02\xa1\x30\x98\x14\x69\x83\xd8\x16\x85\x85\xbf\xc6\xb3\x3f\x6f\xef\x67\x30\xbc\xf9\x0a\x7f\x0d\x27\x93\xe1\xcd\xec\xeb\x05\x3c\x4a\xbb\x51\x85\x05\xdc\x21\x53\xc9\x6d\x9e\x4a\x5c\xc1\xa3\xd0\x5a\x64\x76\x0f\x2a\x21\x86\x2f\xa3\xc9\xd5\x9f\xc3\x9b\xd9\xf0\x5f\xe3\xeb\xf1\xec\x2b\x28\x0d\x9f\xc7\xb3\x9b\xd1\x74\x0a\x9f\x6f\x27\x30\x84\xbb\xe1\x64\x36\xbe\xba\xbf\x1e\x4e\xe0\xee\x7e\x72\x77\x3b\x1d\x35\x61\x8a\xa4\x0a\x09\xff\xe3\x9c\x27\xae\x7a\x1a\x61\x85\x56\xc8\xd4\x94\x99\xf8\xaa\x0a\x30\x1b\x55\xa4\x2b\xd8\x88\x1d\x82\xc6\x25\xca\x1d\xae\x40\xc0\x52\xe5\xfb\x9f\x2e\x2a\x71\x89\x54\x65\x6b\x77\xe6\x77\x1b\x12\xc6\x09\x64\xca\x36\xc0\x20\xc2\x6f\x1b\x6b\xf3\xb8\xd5\x7a\x7c\x7c\x6c\xae\xb3\xa2\xa9\xf4\xba\x95\x32\x9d\x69\xfd\xde\xac\x12\x27\xee\xb6\x2b\x69\x66\x5a\x2c\x51\x83\x46\x5b\xe8\xcc\x80\x29\x92\x44\x2e\x25\x66\x16\x64\x96\x28\xbd\x75\x7d\x02\x89\x56\x5b\x10\x60\xc9\x19\xac\x82\x1c\x35\x6d\x7a\x8e\x8f\xc6\xee\x53\xa7\x73\x25\x8d\x30\x06\xb7\x8b\x74\xdf\xac\x7e\xaf\x56\x8c\x15\xcb\x6f\x31\xcc\xbf\xab\xdc\xc4\x30\x7f\x78\x7a\x68\x54\xab\x95\x2c\x2f\xcc\x06\x4d\x0c\xdf\xdb\x31\xb4\x1b\x10\xc4\x10\x34\x20\x74\x6b\xc7\xad\x91\x5b\xbb\x6e\xed\xb9\xf5\xdc\xad\x7d\xb7\x0e\xdc\x1a\xb4\xd9\x30\x3a\x60\xb7\x80\xfd\x02\x76\x0c\xd8\x33\x64\xcf\xd0\xc7\xe1\x40\x21\x47\x0a\x39\x54\xc8\xb1\x42\x66\xe9\xb0\x4b\xc4\x2c\x11\xb3\x74\x99\xa5\xcb\x2c\x5d\x76\xe9\x32\x4b\xd7\x0b\xee\xba\xf3\x74\x99\xa5\x7b\xce\x4f\xcc\xd2\x65\x96\x1e\x1f\xb9\xc7\x80\x9e\x3f\x22\x03\x7a\x2c\xbe\xc7\x80\x1e\x03\xfa\x0c\xe8\x73\xd8\x7e\xc8\x4f\x1d\x36\xcc\xd2\xe7\xb0\xfd\x1e\x1b\x0e\xdb\x67\x96\x3e\xb3\x0c\x58\xfc\x20\x70\x7b\x03\x8e\x37\xe0\x78\x03\x9f\xd5\x32\xad\x3e\xaf\x6d\x9f\xd8\x76\xe8\x6d\xc7\xdb\xc8\xdb\xae\xb7\x3e\xf3\x6d\x9f\xfa\xb6\xcf\x7d\xdb\xf3\x1d\xea\xe4\xf9\x02\xcf\x17\x78\xbe\xc0\xf3\x05\x9e\xaf\xac\x64\x59\xca\xb2\x96\xbe\x98\x81\xaf\x66\xe0\xcb\x19\xf8\x7a\x06\xbe\xa0\x81\xaf\x68\xe0\x4b\x1a\xf8\x9a\x06\xa1\xe7\x0b\xfb\x31\x84\x64\x07\x31\x74\x1a\x10\x74\xda\x31\x44\x64\x83\x18\xba\x64\xc3\x18\x7a\x64\x3b\x31\x9c\x93\x8d\x62\xe8\x93\xed\xc6\x30\x20\x4b\x7c\xd4\xb5\x1d\x22\x24\xc6\x0e\x29\x24\xca\x0e\x49\x24\xce\x88\x34\x12\x69\x44\x22\x89\x35\x22\x95\x44\x1b\x91\x4c\xe2\x8d\x22\xd6\x11\x75\x59\x47\xd4\x63\x1d\xd1\x39\xeb\xa0\xee\x73\x80\x01\xeb\xa0\xfe\x23\x1d\xd4\x80\xa4\xc3\x75\x20\xe9\x70\x3d\x48\x3a\x5c\x17\x12\x25\xf5\xa1\xd3\xe1\x3a\x91\x48\xa9\x17\x9d\x0e\xd7\x8d\x44\xeb\xfa\x91\x78\x7d\x47\x06\xbd\xc0\xdb\xd0\xdb\x8e\xb7\x91\xb3\x61\xe4\xbf\xa2\xc8\x7f\x46\x91\xff\x8e\xa2\x8e\xdf\xf7\x7e\xee\x23\x78\xa2\xef\xbc\xd5\x02\x8d\xa6\x48\x2d\x4d\x7f\x99\xed\xd4\x37\x9a\xcf\x1b\xcc\x40\xa4\xa9\x1b\x64\x2a\x5f\xaa\x15\x1a\x1e\x90\x0b\xc4\x0c\xa4\x45\x2d\xe8\x86\x50\x3b\xd4\x74\x39\x96\xa3\xc9\xd1\x11\x26\x91\x99\x48\x4b\x62\x3f\x44\x69\x30\xc9\x6c\xdd\xac\x56\xf8\x7d\x0c\x49\x91\x2d\x69\x74\xd5\xea\xf0\xdd\x53\x80\xdd\x48\xd3\x74\x23\x69\xde\x7e\x68\xaa\xdc\x5c\x40\xa9\x33\x11\x6f\xc9\x24\x6a\xb1\xb4\x85\x48\x01\xff\xc6\x65\xe1\x66\xa1\x4a\x40\x64\x5e\x39\x24\x3c\xf1\x2b\x0e\x7f\x12\x35\x55\xeb\x06\xac\x16\x14\xbc\x0c\x61\x2c\xe6\xa7\x11\xe8\xde\xc0\x1d\xea\x7d\xc9\xe5\xee\x41\x0a\xf9\x9f\x2f\x3e\x1c\x12\x35\xe1\xde\x64\xae\x56\x2a\x3b\xa1\x21\xd1\x62\x8b\x70\x79\x7a\xba\xe3\x7f\x9b\x29\x66\x6b\xbb\x81\x8f\x10\x3c\x5c\x54\x3d\x02\xb5\x56\x1a\x2e\x21\x55\xeb\xe6\x1a\xed\x88\x1e\x6b\xf5\x8b\x6a\xa5\x22\x13\xa8\xb9\x5d\xa6\xaf\x38\xee\xf9\x99\x7b\x75\xf6\x00\x97\x0c\x25\xcf\x27\xc0\xd4\x20\x10\xc0\xd3\x7c\xc2\xdc\x6e\x6a\x75\xb8\x3c\x95\xe2\xe3\x7b\x3a\x95\xd3\xa5\x02\x97\xfc\x54\x51\x79\x0c\xf4\x8f\x08\x54\xde\xb4\xea\xa6\xd8\x2e\x50\xd7\xea\x0d\xb7\xbd\x22\x42\x88\xe1\x39\x3f\xef\x95\x65\x9e\x3f\xb8\xe7\x27\x92\xe4\xd4\x3b\xc5\x54\xdb\xf2\xe4\xbf\x43\xdb\x47\x77\x67\xcf\x35\xee\x54\x0e\x97\x70\x70\x9c\xbf\x82\x70\xb2\x08\x91\x28\x5d\x23\x94\x84\x4b\x68\x5f\x80\x84\xdf\xf8\x6c\xfe\x06\x9b\x33\x5b\x53\xe5\x0f\x17\x20\x3f\x7c\xa8\x3b\x50\xc5\xbf\x65\x8d\x4d\x72\x75\x39\xe2\x84\xe4\x88\xdf\x6a\xb2\xde\xb4\x6a\x6a\xb5\xcc\xd6\xb5\xa0\x57\x77\xb9\xaf\x3c\xd1\x62\x1e\xa5\x5d\xb2\xbf\x4b\x89\x77\xaa\xfb\x33\x2c\x85\x41\x38\xbb\x1a\x5e\x5f\x9f\xc5\x70\x7c\xb8\xba\xfd\x34\x3a\x8b\x0f\x87\x94\x99\xb1\xf4\xfb\x95\x4b\x7c\x12\xb7\x53\x6f\xee\x44\x5a\xe0\x6d\xc2\xf5\x3e\xb8\xcb\xff\xe2\x6b\xef\xe8\x95\x37\x17\x70\x7e\xb6\x16\xc6\xb5\xc3\x0b\x40\xfb\x5d\x80\x55\x6f\xf9\x07\xcf\xd3\xf0\x1c\xe2\x98\xde\x42\x85\x27\xa8\x17\x18\x99\xe5\x85\x3d\x60\xb6\xb8\x55\x7a\xdf\x34\xf4\xcb\xa7\xe6\x73\xd2\x38\x24\xe7\x83\x3f\xf7\x0b\x8a\x63\xaf\x67\x45\x9a\x3e\xdf\xe3\x39\xf2\xce\xa6\xca\x39\x27\x73\xdf\x3b\x27\x1f\x81\x6b\x01\xf6\xf3\xd1\x16\x1a\xc5\xb7\x8b\x63\x45\x3f\x8d\xae\x47\x7f\x0c\x67\xa3\x67\x95\x9d\xce\x86\xb3\xf1\x15\xbf\xfa\x71\x6d\xc3\x5f\xaa\xed\xeb\x4e\x38\x9e\xc3\x1d\x03\x5e\xb5\xe0\xdb\x2d\xf0\xcb\x3d\xf0\x4b\x4d\x70\x2c\xe8\x3f\x51\xd1\xff\x5f\xd2\x7f\xba\xa6\x93\xd1\xec\x7e\x72\x73\x52\x3a\xfa\x7b\xe5\x27\xbe\x19\xef\xfa\x76\xdd\x82\x57\xee\x3c\xbe\xfc\x15\xf7\x46\xe3\xab\xc2\x36\x5c\xe8\x0f\x25\xeb\x3b\x7a\xa7\xb3\xdb\xbb\x63\xef\xdd\x8f\xaf\xc6\x87\xa1\xf2\xa3\x18\xed\x06\xb4\xdf\x61\xfd\xf7\xfd\x97\xbb\x4f\xa3\xe9\xcc\x33\x95\x99\xcd\x97\x87\xcf\x74\x8d\xf6\xee\xaa\x76\x32\x03\x65\x52\xce\x3f\x69\xee\x28\xcd\xe5\xf4\x3b\xa0\x53\xcc\x0e\xf0\x67\x37\x07\x7c\x84\xf6\xdf\x5d\x3c\x72\x1d\x87\xfb\xcb\x82\xf9\x1b\xcc\x11\x1f\xeb\xfa\xec\x22\x3d\x9e\xee\xf9\x1d\xc4\xf8\x6a\xe5\xa9\xfa\x54\xfd\x5f\x00\x00\x00\xff\xff\xdf\x2f\xd9\xfa\x63\x10\x00\x00") func evmdis_tracerJsBytes() ([]byte, error) { return bindataRead( @@ -153,7 +153,7 @@ func evmdis_tracerJs() (*asset, error) { } info := bindataFileInfo{name: "evmdis_tracer.js", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd5, 0xe8, 0x96, 0xa1, 0x8b, 0xc, 0x68, 0x3c, 0xe8, 0x5d, 0x7e, 0xf0, 0xab, 0xfe, 0xec, 0xd1, 0xb, 0x3d, 0xfc, 0xc7, 0xac, 0xb5, 0xa, 0x41, 0x55, 0x0, 0x3a, 0x60, 0xa7, 0x8e, 0x46, 0x93}} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0xc8, 0x73, 0x8e, 0xfb, 0x1f, 0x84, 0x7d, 0x37, 0xd9, 0x26, 0x24, 0x37, 0xb8, 0x65, 0xb1, 0xed, 0xa0, 0x76, 0x9a, 0xf0, 0x8e, 0x3a, 0x9b, 0x20, 0x93, 0x27, 0x26, 0x2e, 0xc9, 0x9b, 0xde}} return a, nil } diff --git a/eth/tracers/internal/tracers/call_tracer.js b/eth/tracers/internal/tracers/call_tracer.js index f8b383cd96..352c309b49 100644 --- a/eth/tracers/internal/tracers/call_tracer.js +++ b/eth/tracers/internal/tracers/call_tracer.js @@ -132,13 +132,12 @@ // If the call was a contract call, retrieve the gas usage and output if (call.gas !== undefined) { call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost + call.gas - log.getGas()).toString(16); - - var ret = log.stack.peek(0); - if (!ret.equals(0)) { - call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen)); - } else if (call.error === undefined) { - call.error = "internal failure"; // TODO(karalabe): surface these faults somehow - } + } + var ret = log.stack.peek(0); + if (!ret.equals(0)) { + call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen)); + } else if (call.error === undefined) { + call.error = "internal failure"; // TODO(karalabe): surface these faults somehow } delete call.gasIn; delete call.gasCost; delete call.outOff; delete call.outLen; @@ -208,7 +207,7 @@ } else if (ctx.error !== undefined) { result.error = ctx.error; } - if (result.error !== undefined) { + if (result.error !== undefined && (result.error !== "execution reverted" || result.output ==="0x")) { delete result.output; } return this.finalize(result); diff --git a/eth/tracers/testdata/call_tracer_inner_instafail.json b/eth/tracers/testdata/call_tracer_inner_instafail.json new file mode 100644 index 0000000000..86070d1308 --- /dev/null +++ b/eth/tracers/testdata/call_tracer_inner_instafail.json @@ -0,0 +1,72 @@ +{ + "genesis": { + "difficulty": "117067574", + "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", + "gasLimit": "4712380", + "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486", + "miner": "0x0c062b329265c965deef1eede55183b3acb8f611", + "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d", + "nonce": "0x2b469722b8e28c45", + "number": "24973", + "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", + "timestamp": "1479891145", + "totalDifficulty": "1892250259406", + "alloc": { + "0x6c06b16512b332e6cd8293a2974872674716ce18": { + "balance": "0x0", + "nonce": "1", + "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056", + "storage": {} + }, + "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": { + "balance": "0x229ebbb36c3e0f20", + "nonce": "3", + "code": "0x", + "storage": {} + } + }, + "config": { + "chainId": 3, + "homesteadBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", + "eip155Block": 10, + "eip158Block": 10, + "byzantiumBlock": 1700000, + "constantinopleBlock": 4230000, + "petersburgBlock": 4939394, + "istanbulBlock": 6485846, + "muirGlacierBlock": 7117117, + "ethash": {} + } + }, + "context": { + "number": "24974", + "difficulty": "117067574", + "timestamp": "1479891162", + "gasLimit": "4712388", + "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914" + }, + "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745", + "result": { + "type": "CALL", + "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", + "to": "0x6c06b16512b332e6cd8293a2974872674716ce18", + "value": "0x0", + "gas": "0x1a466", + "gasUsed": "0x1dc6", + "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000", + "output": "0x", + "calls": [ + { + "type": "CALL", + "from": "0x6c06b16512b332e6cd8293a2974872674716ce18", + "to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", + "value": "0x14d1120d7b160000", + "error":"internal failure", + "input": "0x" + } + ] + } +} diff --git a/eth/tracers/testdata/call_tracer_revert_reason.json b/eth/tracers/testdata/call_tracer_revert_reason.json new file mode 100644 index 0000000000..094b044677 --- /dev/null +++ b/eth/tracers/testdata/call_tracer_revert_reason.json @@ -0,0 +1,64 @@ +{ + "context": { + "difficulty": "2", + "gasLimit": "8000000", + "miner": "0x0000000000000000000000000000000000000000", + "number": "3212651", + "timestamp": "1597246515" + }, + "genesis": { + "alloc": { + "0xf58833cf0c791881b494eb79d461e08a1f043f52": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033", + "nonce": "1", + "storage": { + "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": { + "balance": "0x57af9d6b3df812900", + "code": "0x", + "nonce": "6", + "storage": {} + } + }, + "config": { + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "IstanbulBlock":1561651, + "chainId": 5, + "daoForkSupport": true, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 10, + "eip158Block": 10, + "ethash": {}, + "homesteadBlock": 0 + }, + "difficulty": "3509749784", + "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", + "gasLimit": "4727564", + "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", + "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", + "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", + "nonce": "0x4eb12e19c16d43da", + "number": "2289805", + "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", + "timestamp": "1513601261", + "totalDifficulty": "7143276353481064" + }, + "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", + "result": { + "error": "execution reverted", + "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", + "gas": "0x2d7308", + "gasUsed": "0x588", + "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", + "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52", + "type": "CALL", + "value": "0x0", + "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000" + } +} diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index cd625be0fb..18f8eb12aa 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -269,9 +269,31 @@ func TestCallTracer(t *testing.T) { t.Fatalf("failed to unmarshal trace result: %v", err) } - if !reflect.DeepEqual(ret, test.Result) { + if !jsonEqual(ret, test.Result) { + // uncomment this for easier debugging + //have, _ := json.MarshalIndent(ret, "", " ") + //want, _ := json.MarshalIndent(test.Result, "", " ") + //t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", string(have), string(want)) t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) } }) } } + +// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to +// comparison +func jsonEqual(x, y interface{}) bool { + xTrace := new(callTrace) + yTrace := new(callTrace) + if xj, err := json.Marshal(x); err == nil { + json.Unmarshal(xj, xTrace) + } else { + return false + } + if yj, err := json.Marshal(y); err == nil { + json.Unmarshal(yj, yTrace) + } else { + return false + } + return reflect.DeepEqual(xTrace, yTrace) +} From 5883afb3ef1e121e8625c2e1f4e929f333a65dd5 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 28 Aug 2020 16:27:58 +0200 Subject: [PATCH 07/24] rpc: fix issue with null JSON-RPC messages (#21497) --- rpc/json.go | 13 ++++++++++--- rpc/testdata/invalid-batch.js | 3 +++ rpc/testdata/invalid-nonobj.js | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rpc/json.go b/rpc/json.go index 3be5d55f48..1daee3db82 100644 --- a/rpc/json.go +++ b/rpc/json.go @@ -202,15 +202,22 @@ func (c *jsonCodec) remoteAddr() string { return c.remote } -func (c *jsonCodec) readBatch() (msg []*jsonrpcMessage, batch bool, err error) { +func (c *jsonCodec) readBatch() (messages []*jsonrpcMessage, batch bool, err error) { // Decode the next JSON object in the input stream. // This verifies basic syntax, etc. var rawmsg json.RawMessage if err := c.decode(&rawmsg); err != nil { return nil, false, err } - msg, batch = parseMessage(rawmsg) - return msg, batch, nil + messages, batch = parseMessage(rawmsg) + for i, msg := range messages { + if msg == nil { + // Message is JSON 'null'. Replace with zero value so it + // will be treated like any other invalid message. + messages[i] = new(jsonrpcMessage) + } + } + return messages, batch, nil } func (c *jsonCodec) writeJSON(ctx context.Context, v interface{}) error { diff --git a/rpc/testdata/invalid-batch.js b/rpc/testdata/invalid-batch.js index f470574fb5..768dbc837e 100644 --- a/rpc/testdata/invalid-batch.js +++ b/rpc/testdata/invalid-batch.js @@ -10,5 +10,8 @@ --> [1,2,3] <-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}] +--> [null] +<-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}] + --> [{"jsonrpc":"2.0","id":1,"method":"test_echo","params":["foo",1]},55,{"jsonrpc":"2.0","id":2,"method":"unknown_method"},{"foo":"bar"}] <-- [{"jsonrpc":"2.0","id":1,"result":{"String":"foo","Int":1,"Args":null}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"the method unknown_method does not exist/is not available"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}] diff --git a/rpc/testdata/invalid-nonobj.js b/rpc/testdata/invalid-nonobj.js index 4b9f4d994c..ffdd4a5b87 100644 --- a/rpc/testdata/invalid-nonobj.js +++ b/rpc/testdata/invalid-nonobj.js @@ -2,3 +2,6 @@ --> 1 <-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}} + +--> null +<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}} From 12d8570322aa44833a7b42d042da2bd69b2bb22d Mon Sep 17 00:00:00 2001 From: Fuyang Deng Date: Tue, 1 Sep 2020 15:29:54 +0800 Subject: [PATCH 08/24] accounts/abi: fix a bug in getTypeSize method (#21501) * accounts/abi: fix a bug in getTypeSize method e.g. for "Tuple[2]" type, the element of the array is a tuple type and the size of the tuple may not be 32. * accounts/abi: add unit test of getTypeSize method --- accounts/abi/type.go | 2 +- accounts/abi/type_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 080cd6cd57..1b4ca318a1 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -386,7 +386,7 @@ func isDynamicType(t Type) bool { func getTypeSize(t Type) int { if t.T == ArrayTy && !isDynamicType(*t.Elem) { // Recursively calculate type size if it is a nested array - if t.Elem.T == ArrayTy { + if t.Elem.T == ArrayTy || t.Elem.T == TupleTy { return t.Size * getTypeSize(*t.Elem) } return t.Size * 32 diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index 566f991c54..48df3aa383 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -330,3 +330,39 @@ func TestInternalType(t *testing.T) { t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(kind))) } } + +func TestGetTypeSize(t *testing.T) { + var testCases = []struct { + typ string + components []ArgumentMarshaling + typSize int + }{ + // simple array + {"uint256[2]", nil, 32 * 2}, + {"address[3]", nil, 32 * 3}, + {"bytes32[4]", nil, 32 * 4}, + // array array + {"uint256[2][3][4]", nil, 32 * (2 * 3 * 4)}, + // array tuple + {"tuple[2]", []ArgumentMarshaling{{Name: "x", Type: "bytes32"}, {Name: "y", Type: "bytes32"}}, (32 * 2) * 2}, + // simple tuple + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "uint256"}, {Name: "y", Type: "uint256"}}, 32 * 2}, + // tuple array + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}}, 32 * 2}, + // tuple tuple + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32"}}}}, 32}, + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}, {Name: "y", Type: "uint256"}}}}, 32 * (2 + 1)}, + } + + for i, data := range testCases { + typ, err := NewType(data.typ, "", data.components) + if err != nil { + t.Errorf("type %q: failed to parse type string: %v", data.typ, err) + } + + result := getTypeSize(typ) + if result != data.typSize { + t.Errorf("case %d type %q: get type size error: actual: %d expected: %d", i, data.typ, result, data.typSize) + } + } +} From ff23e265cd2ff13f33e145071b317fc25f0a2b23 Mon Sep 17 00:00:00 2001 From: Hanjiang Yu Date: Tue, 1 Sep 2020 16:23:04 +0800 Subject: [PATCH 09/24] internal: fix personal.sign() (#21503) --- console/bridge.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/bridge.go b/console/bridge.go index 995448afb3..9303496b28 100644 --- a/console/bridge.go +++ b/console/bridge.go @@ -306,9 +306,9 @@ func (b *bridge) Sign(call jsre.Call) (goja.Value, error) { } // Send the request to the backend and return - sign, callable := goja.AssertFunction(getJeth(call.VM).Get("unlockAccount")) + sign, callable := goja.AssertFunction(getJeth(call.VM).Get("sign")) if !callable { - return nil, fmt.Errorf("jeth.unlockAccount is not callable") + return nil, fmt.Errorf("jeth.sign is not callable") } return sign(goja.Null(), message, account, passwd) } From 5cdb476dd19096bdf63085638bec9a58416c5bcd Mon Sep 17 00:00:00 2001 From: Giuseppe Bertone Date: Tue, 1 Sep 2020 11:02:12 +0200 Subject: [PATCH 10/24] "Downloader queue stats" is now provided once per minute (#21455) * "Downloader queue stats" is now a DEBUG information I think this info is more a DEBUG related information then an INFO. If it must remains an INFO, maybe it can be slow down to one time every 5 minutes or so. * Update queue.go "Downloader queue stats" information is now provided once every minute instead of once every 10 seconds. --- eth/downloader/queue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index aba4d5dbf7..7e88e10b01 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -382,7 +382,7 @@ func (q *queue) Results(block bool) []*fetchResult { throttleThreshold = q.resultCache.SetThrottleThreshold(throttleThreshold) // Log some info at certain times - if time.Since(q.lastStatLog) > 10*time.Second { + if time.Since(q.lastStatLog) > 60*time.Second { q.lastStatLog = time.Now() info := q.Stats() info = append(info, "throttle", throttleThreshold) From d90bbce954eb43bf8bb76e3e9b694b8c7953bb47 Mon Sep 17 00:00:00 2001 From: ucwong Date: Tue, 1 Sep 2020 18:56:22 +0800 Subject: [PATCH 11/24] go.mod : update goja dependency (#21432) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0b22fe6389..7e8d0d1b8c 100755 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea github.com/dlclark/regexp2 v1.2.0 // indirect github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf - github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87 + github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c github.com/fatih/color v1.3.0 github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc diff --git a/go.sum b/go.sum index 695a9d75c9..31c2c48221 100755 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87 h1:OMbqMXf9OAXzH1dDH82mQMrddBE8LIIwDtxeK4wE1/A= -github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ= +github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c h1:JHHhtb9XWJrGNMcrVP6vyzO4dusgi/HnceHTgxSejUM= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/fatih/color v1.3.0 h1:YehCCcyeQ6Km0D6+IapqPinWBK6y+0eB5umvZXK9WPs= From 3010f9fc759a9f461dfeba229622352f65186aaf Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 2 Sep 2020 11:01:46 +0200 Subject: [PATCH 12/24] eth/downloader: change intial download size (#21366) This changes how the downloader works, a little bit. Previously, when block sync started, we immediately started filling up to 8192 blocks. Usually this is fine, blocks are small in the early numbers. The threshold then is lowered as we measure the size of the blocks that are filled. However, if the node is shut down and restarts syncing while we're in a heavy segment, that might be bad. This PR introduces a more conservative initial threshold of 2K blocks instead. --- eth/downloader/downloader.go | 4 ++-- eth/downloader/downloader_test.go | 24 ++++++++++++------------ eth/downloader/queue.go | 14 ++++++++------ eth/downloader/queue_test.go | 6 +++--- eth/downloader/testchain_test.go | 2 +- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index f5bdb3c234..9c19543a46 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -219,7 +219,7 @@ func New(checkpoint uint64, stateDb ethdb.Database, stateBloom *trie.SyncBloom, stateBloom: stateBloom, mux: mux, checkpoint: checkpoint, - queue: newQueue(blockCacheItems), + queue: newQueue(blockCacheMaxItems, blockCacheInitialItems), peers: newPeerSet(), rttEstimate: uint64(rttMaxEstimate), rttConfidence: uint64(1000000), @@ -379,7 +379,7 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode d.stateBloom.Close() } // Reset the queue, peer set and wake channels to clean any internal leftover state - d.queue.Reset(blockCacheItems) + d.queue.Reset(blockCacheMaxItems, blockCacheInitialItems) d.peers.Reset() for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh} { diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 7c165c63c3..51d485761b 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -39,7 +39,7 @@ import ( func init() { fullMaxForkAncestry = 10000 lightMaxForkAncestry = 10000 - blockCacheItems = 1024 + blockCacheMaxItems = 1024 fsHeaderContCheck = 500 * time.Millisecond } @@ -544,7 +544,7 @@ func testCanonicalSynchronisation(t *testing.T, protocol int, mode SyncMode) { defer tester.terminate() // Create a small enough block chain to download - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) tester.newPeer("peer", protocol, chain) // Synchronise with the peer and make sure all relevant data was retrieved @@ -607,8 +607,8 @@ func testThrottling(t *testing.T, protocol int, mode SyncMode) { } tester.lock.Unlock() - if cached == blockCacheItems || - cached == blockCacheItems-reorgProtHeaderDelay || + if cached == blockCacheMaxItems || + cached == blockCacheMaxItems-reorgProtHeaderDelay || retrieved+cached+frozen == targetBlocks+1 || retrieved+cached+frozen == targetBlocks+1-reorgProtHeaderDelay { break @@ -619,8 +619,8 @@ func testThrottling(t *testing.T, protocol int, mode SyncMode) { tester.lock.RLock() retrieved = len(tester.ownBlocks) tester.lock.RUnlock() - if cached != blockCacheItems && cached != blockCacheItems-reorgProtHeaderDelay && retrieved+cached+frozen != targetBlocks+1 && retrieved+cached+frozen != targetBlocks+1-reorgProtHeaderDelay { - t.Fatalf("block count mismatch: have %v, want %v (owned %v, blocked %v, target %v)", cached, blockCacheItems, retrieved, frozen, targetBlocks+1) + if cached != blockCacheMaxItems && cached != blockCacheMaxItems-reorgProtHeaderDelay && retrieved+cached+frozen != targetBlocks+1 && retrieved+cached+frozen != targetBlocks+1-reorgProtHeaderDelay { + t.Fatalf("block count mismatch: have %v, want %v (owned %v, blocked %v, target %v)", cached, blockCacheMaxItems, retrieved, frozen, targetBlocks+1) } // Permit the blocked blocks to import @@ -873,7 +873,7 @@ func testMultiProtoSync(t *testing.T, protocol int, mode SyncMode) { defer tester.terminate() // Create a small enough block chain to download - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) // Create peers of every type tester.newPeer("peer 63", 63, chain) @@ -965,7 +965,7 @@ func testMissingHeaderAttack(t *testing.T, protocol int, mode SyncMode) { tester := newTester() defer tester.terminate() - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) brokenChain := chain.shorten(chain.len()) delete(brokenChain.headerm, brokenChain.chain[brokenChain.len()/2]) tester.newPeer("attack", protocol, brokenChain) @@ -997,7 +997,7 @@ func testShiftedHeaderAttack(t *testing.T, protocol int, mode SyncMode) { tester := newTester() defer tester.terminate() - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) // Attempt a full sync with an attacker feeding shifted headers brokenChain := chain.shorten(chain.len()) @@ -1202,7 +1202,7 @@ func testSyncProgress(t *testing.T, protocol int, mode SyncMode) { tester := newTester() defer tester.terminate() - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) // Set a sync init hook to catch progress changes starting := make(chan struct{}) @@ -1362,7 +1362,7 @@ func testFailedSyncProgress(t *testing.T, protocol int, mode SyncMode) { tester := newTester() defer tester.terminate() - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) // Set a sync init hook to catch progress changes starting := make(chan struct{}) @@ -1435,7 +1435,7 @@ func testFakedSyncProgress(t *testing.T, protocol int, mode SyncMode) { tester := newTester() defer tester.terminate() - chain := testChainBase.shorten(blockCacheItems - 15) + chain := testChainBase.shorten(blockCacheMaxItems - 15) // Set a sync init hook to catch progress changes starting := make(chan struct{}) diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 7e88e10b01..745f7c7480 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -40,9 +40,10 @@ const ( ) var ( - blockCacheItems = 8192 // Maximum number of blocks to cache before throttling the download - blockCacheMemory = 64 * 1024 * 1024 // Maximum amount of memory to use for block caching - blockCacheSizeWeight = 0.1 // Multiplier to approximate the average block size based on past ones + blockCacheMaxItems = 8192 // Maximum number of blocks to cache before throttling the download + blockCacheInitialItems = 2048 // Initial number of blocks to start fetching, before we know the sizes of the blocks + blockCacheMemory = 64 * 1024 * 1024 // Maximum amount of memory to use for block caching + blockCacheSizeWeight = 0.1 // Multiplier to approximate the average block size based on past ones ) var ( @@ -142,7 +143,7 @@ type queue struct { } // newQueue creates a new download queue for scheduling block retrieval. -func newQueue(blockCacheLimit int) *queue { +func newQueue(blockCacheLimit int, thresholdInitialSize int) *queue { lock := new(sync.RWMutex) q := &queue{ headerContCh: make(chan bool), @@ -151,12 +152,12 @@ func newQueue(blockCacheLimit int) *queue { active: sync.NewCond(lock), lock: lock, } - q.Reset(blockCacheLimit) + q.Reset(blockCacheLimit, thresholdInitialSize) return q } // Reset clears out the queue contents. -func (q *queue) Reset(blockCacheLimit int) { +func (q *queue) Reset(blockCacheLimit int, thresholdInitialSize int) { q.lock.Lock() defer q.lock.Unlock() @@ -175,6 +176,7 @@ func (q *queue) Reset(blockCacheLimit int) { q.receiptPendPool = make(map[string]*fetchRequest) q.resultCache = newResultStore(blockCacheLimit) + q.resultCache.SetThrottleThreshold(uint64(thresholdInitialSize)) } // Close marks the end of the sync, unblocking Results. diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go index 07862390f9..aedfba4565 100644 --- a/eth/downloader/queue_test.go +++ b/eth/downloader/queue_test.go @@ -97,7 +97,7 @@ func dummyPeer(id string) *peerConnection { } func TestBasics(t *testing.T) { - q := newQueue(10) + q := newQueue(10, 10) if !q.Idle() { t.Errorf("new queue should be idle") } @@ -174,7 +174,7 @@ func TestBasics(t *testing.T) { } func TestEmptyBlocks(t *testing.T) { - q := newQueue(10) + q := newQueue(10, 10) q.Prepare(1, FastSync) // Schedule a batch of headers @@ -244,7 +244,7 @@ func XTestDelivery(t *testing.T) { log.Root().SetHandler(log.StdoutHandler) } - q := newQueue(10) + q := newQueue(10, 10) var wg sync.WaitGroup q.Prepare(1, FastSync) wg.Add(1) diff --git a/eth/downloader/testchain_test.go b/eth/downloader/testchain_test.go index 26b6b6a460..66376502c5 100644 --- a/eth/downloader/testchain_test.go +++ b/eth/downloader/testchain_test.go @@ -39,7 +39,7 @@ var ( ) // The common prefix of all test chains: -var testChainBase = newTestChain(blockCacheItems+200, testGenesis) +var testChainBase = newTestChain(blockCacheMaxItems+200, testGenesis) // Different forks on top of the base chain: var testChainForkLightA, testChainForkLightB, testChainForkHeavy *testChain From eeaf1916330720d2b1c7071086a7fd6070e9eb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 28 Aug 2020 10:50:37 +0300 Subject: [PATCH 13/24] core, eth, trie: prepare trie sync for path based operation --- core/state/sync_test.go | 127 ++++++++++++++++++++++++------ eth/downloader/statesync.go | 153 +++++++++++++++++++++++++----------- trie/secure_trie.go | 6 ++ trie/sync.go | 66 ++++++++++++++-- trie/sync_test.go | 149 +++++++++++++++++++++++++++++------ trie/trie.go | 84 +++++++++++++++++++- 6 files changed, 480 insertions(+), 105 deletions(-) diff --git a/core/state/sync_test.go b/core/state/sync_test.go index 17670750ed..deb4b52b4c 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) @@ -44,7 +45,7 @@ func makeTestState() (Database, common.Hash, []*testAccount) { state, _ := New(common.Hash{}, db, nil) // Fill it with some arbitrary data - accounts := []*testAccount{} + var accounts []*testAccount for i := byte(0); i < 96; i++ { obj := state.GetOrNewStateObject(common.BytesToAddress([]byte{i})) acc := &testAccount{address: common.BytesToAddress([]byte{i})} @@ -59,6 +60,11 @@ func makeTestState() (Database, common.Hash, []*testAccount) { obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i}) acc.code = []byte{i, i, i, i, i} } + if i%5 == 0 { + for j := byte(0); j < 5; j++ { + obj.SetState(db, crypto.Keccak256Hash([]byte{i, i, i, i, i, j, j}), crypto.Keccak256Hash([]byte{i, i, i, i, i, j, j})) + } + } state.updateStateObject(obj) accounts = append(accounts, acc) } @@ -126,44 +132,94 @@ func checkStateConsistency(db ethdb.Database, root common.Hash) error { // Tests that an empty state is not scheduled for syncing. func TestEmptyStateSync(t *testing.T) { empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - if req := NewStateSync(empty, rawdb.NewMemoryDatabase(), trie.NewSyncBloom(1, memorydb.New())).Missing(1); len(req) != 0 { - t.Errorf("content requested for empty state: %v", req) + sync := NewStateSync(empty, rawdb.NewMemoryDatabase(), trie.NewSyncBloom(1, memorydb.New())) + if nodes, paths, codes := sync.Missing(1); len(nodes) != 0 || len(paths) != 0 || len(codes) != 0 { + t.Errorf(" content requested for empty state: %v, %v, %v", nodes, paths, codes) } } // Tests that given a root hash, a state can sync iteratively on a single thread, // requesting retrieval tasks and returning all of them in one go. -func TestIterativeStateSyncIndividual(t *testing.T) { testIterativeStateSync(t, 1, false) } -func TestIterativeStateSyncBatched(t *testing.T) { testIterativeStateSync(t, 100, false) } -func TestIterativeStateSyncIndividualFromDisk(t *testing.T) { testIterativeStateSync(t, 1, true) } -func TestIterativeStateSyncBatchedFromDisk(t *testing.T) { testIterativeStateSync(t, 100, true) } +func TestIterativeStateSyncIndividual(t *testing.T) { + testIterativeStateSync(t, 1, false, false) +} +func TestIterativeStateSyncBatched(t *testing.T) { + testIterativeStateSync(t, 100, false, false) +} +func TestIterativeStateSyncIndividualFromDisk(t *testing.T) { + testIterativeStateSync(t, 1, true, false) +} +func TestIterativeStateSyncBatchedFromDisk(t *testing.T) { + testIterativeStateSync(t, 100, true, false) +} +func TestIterativeStateSyncIndividualByPath(t *testing.T) { + testIterativeStateSync(t, 1, false, true) +} +func TestIterativeStateSyncBatchedByPath(t *testing.T) { + testIterativeStateSync(t, 100, false, true) +} -func testIterativeStateSync(t *testing.T, count int, commit bool) { +func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool) { // Create a random state to copy srcDb, srcRoot, srcAccounts := makeTestState() if commit { srcDb.TrieDB().Commit(srcRoot, false, nil) } + srcTrie, _ := trie.New(srcRoot, srcDb.TrieDB()) + // Create a destination state and sync with the scheduler dstDb := rawdb.NewMemoryDatabase() sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb)) - queue := append([]common.Hash{}, sched.Missing(count)...) - for len(queue) > 0 { - results := make([]trie.SyncResult, len(queue)) - for i, hash := range queue { + nodes, paths, codes := sched.Missing(count) + var ( + hashQueue []common.Hash + pathQueue []trie.SyncPath + ) + if !bypath { + hashQueue = append(append(hashQueue[:0], nodes...), codes...) + } else { + hashQueue = append(hashQueue[:0], codes...) + pathQueue = append(pathQueue[:0], paths...) + } + for len(hashQueue)+len(pathQueue) > 0 { + results := make([]trie.SyncResult, len(hashQueue)+len(pathQueue)) + for i, hash := range hashQueue { data, err := srcDb.TrieDB().Node(hash) if err != nil { data, err = srcDb.ContractCode(common.Hash{}, hash) } if err != nil { - t.Fatalf("failed to retrieve node data for %x", hash) + t.Fatalf("failed to retrieve node data for hash %x", hash) } results[i] = trie.SyncResult{Hash: hash, Data: data} } + for i, path := range pathQueue { + if len(path) == 1 { + data, _, err := srcTrie.TryGetNode(path[0]) + if err != nil { + t.Fatalf("failed to retrieve node data for path %x: %v", path, err) + } + results[len(hashQueue)+i] = trie.SyncResult{Hash: crypto.Keccak256Hash(data), Data: data} + } else { + var acc Account + if err := rlp.DecodeBytes(srcTrie.Get(path[0]), &acc); err != nil { + t.Fatalf("failed to decode account on path %x: %v", path, err) + } + stTrie, err := trie.New(acc.Root, srcDb.TrieDB()) + if err != nil { + t.Fatalf("failed to retriev storage trie for path %x: %v", path, err) + } + data, _, err := stTrie.TryGetNode(path[1]) + if err != nil { + t.Fatalf("failed to retrieve node data for path %x: %v", path, err) + } + results[len(hashQueue)+i] = trie.SyncResult{Hash: crypto.Keccak256Hash(data), Data: data} + } + } for _, result := range results { if err := sched.Process(result); err != nil { - t.Fatalf("failed to process result %v", err) + t.Errorf("failed to process result %v", err) } } batch := dstDb.NewBatch() @@ -171,7 +227,14 @@ func testIterativeStateSync(t *testing.T, count int, commit bool) { t.Fatalf("failed to commit data: %v", err) } batch.Write() - queue = append(queue[:0], sched.Missing(count)...) + + nodes, paths, codes = sched.Missing(count) + if !bypath { + hashQueue = append(append(hashQueue[:0], nodes...), codes...) + } else { + hashQueue = append(hashQueue[:0], codes...) + pathQueue = append(pathQueue[:0], paths...) + } } // Cross check that the two states are in sync checkStateAccounts(t, dstDb, srcRoot, srcAccounts) @@ -187,7 +250,9 @@ func TestIterativeDelayedStateSync(t *testing.T) { dstDb := rawdb.NewMemoryDatabase() sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb)) - queue := append([]common.Hash{}, sched.Missing(0)...) + nodes, _, codes := sched.Missing(0) + queue := append(append([]common.Hash{}, nodes...), codes...) + for len(queue) > 0 { // Sync only half of the scheduled nodes results := make([]trie.SyncResult, len(queue)/2+1) @@ -211,7 +276,9 @@ func TestIterativeDelayedStateSync(t *testing.T) { t.Fatalf("failed to commit data: %v", err) } batch.Write() - queue = append(queue[len(results):], sched.Missing(0)...) + + nodes, _, codes = sched.Missing(0) + queue = append(append(queue[len(results):], nodes...), codes...) } // Cross check that the two states are in sync checkStateAccounts(t, dstDb, srcRoot, srcAccounts) @@ -232,7 +299,8 @@ func testIterativeRandomStateSync(t *testing.T, count int) { sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb)) queue := make(map[common.Hash]struct{}) - for _, hash := range sched.Missing(count) { + nodes, _, codes := sched.Missing(count) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } for len(queue) > 0 { @@ -259,8 +327,10 @@ func testIterativeRandomStateSync(t *testing.T, count int) { t.Fatalf("failed to commit data: %v", err) } batch.Write() + queue = make(map[common.Hash]struct{}) - for _, hash := range sched.Missing(count) { + nodes, _, codes = sched.Missing(count) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } } @@ -279,7 +349,8 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) { sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb)) queue := make(map[common.Hash]struct{}) - for _, hash := range sched.Missing(0) { + nodes, _, codes := sched.Missing(0) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } for len(queue) > 0 { @@ -312,7 +383,11 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) { t.Fatalf("failed to commit data: %v", err) } batch.Write() - for _, hash := range sched.Missing(0) { + for _, result := range results { + delete(queue, result.Hash) + } + nodes, _, codes = sched.Missing(0) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } } @@ -341,8 +416,11 @@ func TestIncompleteStateSync(t *testing.T) { dstDb := rawdb.NewMemoryDatabase() sched := NewStateSync(srcRoot, dstDb, trie.NewSyncBloom(1, dstDb)) - added := []common.Hash{} - queue := append([]common.Hash{}, sched.Missing(1)...) + var added []common.Hash + + nodes, _, codes := sched.Missing(1) + queue := append(append([]common.Hash{}, nodes...), codes...) + for len(queue) > 0 { // Fetch a batch of state nodes results := make([]trie.SyncResult, len(queue)) @@ -382,7 +460,8 @@ func TestIncompleteStateSync(t *testing.T) { } } // Fetch the next batch to retrieve - queue = append(queue[:0], sched.Missing(1)...) + nodes, _, codes = sched.Missing(1) + queue = append(append(queue[:0], nodes...), codes...) } // Sanity check that removing any node from the database is detected for _, node := range added[1:] { diff --git a/eth/downloader/statesync.go b/eth/downloader/statesync.go index bf9e96fe2a..6745aa54ac 100644 --- a/eth/downloader/statesync.go +++ b/eth/downloader/statesync.go @@ -34,14 +34,15 @@ import ( // stateReq represents a batch of state fetch requests grouped together into // a single data retrieval network packet. type stateReq struct { - nItems uint16 // Number of items requested for download (max is 384, so uint16 is sufficient) - tasks map[common.Hash]*stateTask // Download tasks to track previous attempts - timeout time.Duration // Maximum round trip time for this to complete - timer *time.Timer // Timer to fire when the RTT timeout expires - peer *peerConnection // Peer that we're requesting from - delivered time.Time // Time when the packet was delivered (independent when we process it) - response [][]byte // Response data of the peer (nil for timeouts) - dropped bool // Flag whether the peer dropped off early + nItems uint16 // Number of items requested for download (max is 384, so uint16 is sufficient) + trieTasks map[common.Hash]*trieTask // Trie node download tasks to track previous attempts + codeTasks map[common.Hash]*codeTask // Byte code download tasks to track previous attempts + timeout time.Duration // Maximum round trip time for this to complete + timer *time.Timer // Timer to fire when the RTT timeout expires + peer *peerConnection // Peer that we're requesting from + delivered time.Time // Time when the packet was delivered (independent when we process it) + response [][]byte // Response data of the peer (nil for timeouts) + dropped bool // Flag whether the peer dropped off early } // timedOut returns if this request timed out. @@ -251,9 +252,11 @@ func (d *Downloader) spindownStateSync(active map[string]*stateReq, finished []* type stateSync struct { d *Downloader // Downloader instance to access and manage current peerset - sched *trie.Sync // State trie sync scheduler defining the tasks - keccak hash.Hash // Keccak256 hasher to verify deliveries with - tasks map[common.Hash]*stateTask // Set of tasks currently queued for retrieval + sched *trie.Sync // State trie sync scheduler defining the tasks + keccak hash.Hash // Keccak256 hasher to verify deliveries with + + trieTasks map[common.Hash]*trieTask // Set of trie node tasks currently queued for retrieval + codeTasks map[common.Hash]*codeTask // Set of byte code tasks currently queued for retrieval numUncommitted int bytesUncommitted int @@ -269,9 +272,16 @@ type stateSync struct { root common.Hash } -// stateTask represents a single trie node download task, containing a set of +// trieTask represents a single trie node download task, containing a set of +// peers already attempted retrieval from to detect stalled syncs and abort. +type trieTask struct { + path [][]byte + attempts map[string]struct{} +} + +// codeTask represents a single byte code download task, containing a set of // peers already attempted retrieval from to detect stalled syncs and abort. -type stateTask struct { +type codeTask struct { attempts map[string]struct{} } @@ -279,15 +289,16 @@ type stateTask struct { // yet start the sync. The user needs to call run to initiate. func newStateSync(d *Downloader, root common.Hash) *stateSync { return &stateSync{ - d: d, - sched: state.NewStateSync(root, d.stateDB, d.stateBloom), - keccak: sha3.NewLegacyKeccak256(), - tasks: make(map[common.Hash]*stateTask), - deliver: make(chan *stateReq), - cancel: make(chan struct{}), - done: make(chan struct{}), - started: make(chan struct{}), - root: root, + d: d, + sched: state.NewStateSync(root, d.stateDB, d.stateBloom), + keccak: sha3.NewLegacyKeccak256(), + trieTasks: make(map[common.Hash]*trieTask), + codeTasks: make(map[common.Hash]*codeTask), + deliver: make(chan *stateReq), + cancel: make(chan struct{}), + done: make(chan struct{}), + started: make(chan struct{}), + root: root, } } @@ -411,14 +422,15 @@ func (s *stateSync) assignTasks() { // Assign a batch of fetches proportional to the estimated latency/bandwidth cap := p.NodeDataCapacity(s.d.requestRTT()) req := &stateReq{peer: p, timeout: s.d.requestTTL()} - items := s.fillTasks(cap, req) + + nodes, _, codes := s.fillTasks(cap, req) // If the peer was assigned tasks to fetch, send the network request - if len(items) > 0 { - req.peer.log.Trace("Requesting new batch of data", "type", "state", "count", len(items), "root", s.root) + if len(nodes)+len(codes) > 0 { + req.peer.log.Trace("Requesting batch of state data", "nodes", len(nodes), "codes", len(codes), "root", s.root) select { case s.d.trackStateReq <- req: - req.peer.FetchNodeData(items) + req.peer.FetchNodeData(append(nodes, codes...)) // Unified retrieval under eth/6x case <-s.cancel: case <-s.d.cancelCh: } @@ -428,20 +440,34 @@ func (s *stateSync) assignTasks() { // fillTasks fills the given request object with a maximum of n state download // tasks to send to the remote peer. -func (s *stateSync) fillTasks(n int, req *stateReq) []common.Hash { +func (s *stateSync) fillTasks(n int, req *stateReq) (nodes []common.Hash, paths []trie.SyncPath, codes []common.Hash) { // Refill available tasks from the scheduler. - if len(s.tasks) < n { - new := s.sched.Missing(n - len(s.tasks)) - for _, hash := range new { - s.tasks[hash] = &stateTask{make(map[string]struct{})} + if fill := n - (len(s.trieTasks) + len(s.codeTasks)); fill > 0 { + nodes, paths, codes := s.sched.Missing(fill) + for i, hash := range nodes { + s.trieTasks[hash] = &trieTask{ + path: paths[i], + attempts: make(map[string]struct{}), + } + } + for _, hash := range codes { + s.codeTasks[hash] = &codeTask{ + attempts: make(map[string]struct{}), + } } } - // Find tasks that haven't been tried with the request's peer. - items := make([]common.Hash, 0, n) - req.tasks = make(map[common.Hash]*stateTask, n) - for hash, t := range s.tasks { + // Find tasks that haven't been tried with the request's peer. Prefer code + // over trie nodes as those can be written to disk and forgotten about. + nodes = make([]common.Hash, 0, n) + paths = make([]trie.SyncPath, 0, n) + codes = make([]common.Hash, 0, n) + + req.trieTasks = make(map[common.Hash]*trieTask, n) + req.codeTasks = make(map[common.Hash]*codeTask, n) + + for hash, t := range s.codeTasks { // Stop when we've gathered enough requests - if len(items) == n { + if len(nodes)+len(codes) == n { break } // Skip any requests we've already tried from this peer @@ -450,12 +476,30 @@ func (s *stateSync) fillTasks(n int, req *stateReq) []common.Hash { } // Assign the request to this peer t.attempts[req.peer.id] = struct{}{} - items = append(items, hash) - req.tasks[hash] = t - delete(s.tasks, hash) + codes = append(codes, hash) + req.codeTasks[hash] = t + delete(s.codeTasks, hash) } - req.nItems = uint16(len(items)) - return items + for hash, t := range s.trieTasks { + // Stop when we've gathered enough requests + if len(nodes)+len(codes) == n { + break + } + // Skip any requests we've already tried from this peer + if _, ok := t.attempts[req.peer.id]; ok { + continue + } + // Assign the request to this peer + t.attempts[req.peer.id] = struct{}{} + + nodes = append(nodes, hash) + paths = append(paths, t.path) + + req.trieTasks[hash] = t + delete(s.trieTasks, hash) + } + req.nItems = uint16(len(nodes) + len(codes)) + return nodes, paths, codes } // process iterates over a batch of delivered state data, injecting each item @@ -487,11 +531,28 @@ func (s *stateSync) process(req *stateReq) (int, error) { default: return successful, fmt.Errorf("invalid state node %s: %v", hash.TerminalString(), err) } - delete(req.tasks, hash) + // Delete from both queues (one delivery is enough for the syncer) + delete(req.trieTasks, hash) + delete(req.codeTasks, hash) } // Put unfulfilled tasks back into the retry queue npeers := s.d.peers.Len() - for hash, task := range req.tasks { + for hash, task := range req.trieTasks { + // If the node did deliver something, missing items may be due to a protocol + // limit or a previous timeout + delayed delivery. Both cases should permit + // the node to retry the missing items (to avoid single-peer stalls). + if len(req.response) > 0 || req.timedOut() { + delete(task.attempts, req.peer.id) + } + // If we've requested the node too many times already, it may be a malicious + // sync where nobody has the right data. Abort. + if len(task.attempts) >= npeers { + return successful, fmt.Errorf("trie node %s failed with all peers (%d tries, %d peers)", hash.TerminalString(), len(task.attempts), npeers) + } + // Missing item, place into the retry queue. + s.trieTasks[hash] = task + } + for hash, task := range req.codeTasks { // If the node did deliver something, missing items may be due to a protocol // limit or a previous timeout + delayed delivery. Both cases should permit // the node to retry the missing items (to avoid single-peer stalls). @@ -501,10 +562,10 @@ func (s *stateSync) process(req *stateReq) (int, error) { // If we've requested the node too many times already, it may be a malicious // sync where nobody has the right data. Abort. if len(task.attempts) >= npeers { - return successful, fmt.Errorf("state node %s failed with all peers (%d tries, %d peers)", hash.TerminalString(), len(task.attempts), npeers) + return successful, fmt.Errorf("byte code %s failed with all peers (%d tries, %d peers)", hash.TerminalString(), len(task.attempts), npeers) } // Missing item, place into the retry queue. - s.tasks[hash] = task + s.codeTasks[hash] = task } return successful, nil } @@ -533,7 +594,7 @@ func (s *stateSync) updateStats(written, duplicate, unexpected int, duration tim s.d.syncStatsState.unexpected += uint64(unexpected) if written > 0 || duplicate > 0 || unexpected > 0 { - log.Info("Imported new state entries", "count", written, "elapsed", common.PrettyDuration(duration), "processed", s.d.syncStatsState.processed, "pending", s.d.syncStatsState.pending, "retry", len(s.tasks), "duplicate", s.d.syncStatsState.duplicate, "unexpected", s.d.syncStatsState.unexpected) + log.Info("Imported new state entries", "count", written, "elapsed", common.PrettyDuration(duration), "processed", s.d.syncStatsState.processed, "pending", s.d.syncStatsState.pending, "trieretry", len(s.trieTasks), "coderetry", len(s.codeTasks), "duplicate", s.d.syncStatsState.duplicate, "unexpected", s.d.syncStatsState.unexpected) } if written > 0 { rawdb.WriteFastTrieProgress(s.d.stateDB, s.d.syncStatsState.processed) diff --git a/trie/secure_trie.go b/trie/secure_trie.go index ae1bbc6aa9..87b364fb1b 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -79,6 +79,12 @@ func (t *SecureTrie) TryGet(key []byte) ([]byte, error) { return t.trie.TryGet(t.hashKey(key)) } +// TryGetNode attempts to retrieve a trie node by compact-encoded path. It is not +// possible to use keybyte-encoding as the path might contain odd nibbles. +func (t *SecureTrie) TryGetNode(path []byte) ([]byte, int, error) { + return t.trie.TryGetNode(path) +} + // Update associates key with value in the trie. Subsequent calls to // Get will return value. If value has length zero, any existing value // is deleted from the trie and calls to Get will return nil. diff --git a/trie/sync.go b/trie/sync.go index 147307fe71..bc93ddd3fb 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -52,6 +52,39 @@ type request struct { callback LeafCallback // Callback to invoke if a leaf node it reached on this branch } +// SyncPath is a path tuple identifying a particular trie node either in a single +// trie (account) or a layered trie (account -> storage). +// +// Content wise the tuple either has 1 element if it addresses a node in a single +// trie or 2 elements if it addresses a node in a stacked trie. +// +// To support aiming arbitrary trie nodes, the path needs to support odd nibble +// lengths. To avoid transferring expanded hex form over the network, the last +// part of the tuple (which needs to index into the middle of a trie) is compact +// encoded. In case of a 2-tuple, the first item is always 32 bytes so that is +// simple binary encoded. +// +// Examples: +// - Path 0x9 -> {0x19} +// - Path 0x99 -> {0x0099} +// - Path 0x01234567890123456789012345678901012345678901234567890123456789019 -> {0x0123456789012345678901234567890101234567890123456789012345678901, 0x19} +// - Path 0x012345678901234567890123456789010123456789012345678901234567890199 -> {0x0123456789012345678901234567890101234567890123456789012345678901, 0x0099} +type SyncPath [][]byte + +// newSyncPath converts an expanded trie path from nibble form into a compact +// version that can be sent over the network. +func newSyncPath(path []byte) SyncPath { + // If the hash is from the account trie, append a single item, if it + // is from the a storage trie, append a tuple. Note, the length 64 is + // clashing between account leaf and storage root. It's fine though + // because having a trie node at 64 depth means a hash collision was + // found and we're long dead. + if len(path) < 64 { + return SyncPath{hexToCompact(path)} + } + return SyncPath{hexToKeybytes(path[:64]), hexToCompact(path[64:])} +} + // SyncResult is a response with requested data along with it's hash. type SyncResult struct { Hash common.Hash // Hash of the originally unknown trie node @@ -193,10 +226,16 @@ func (s *Sync) AddCodeEntry(hash common.Hash, path []byte, parent common.Hash) { s.schedule(req) } -// Missing retrieves the known missing nodes from the trie for retrieval. -func (s *Sync) Missing(max int) []common.Hash { - var requests []common.Hash - for !s.queue.Empty() && (max == 0 || len(requests) < max) { +// Missing retrieves the known missing nodes from the trie for retrieval. To aid +// both eth/6x style fast sync and snap/1x style state sync, the paths of trie +// nodes are returned too, as well as separate hash list for codes. +func (s *Sync) Missing(max int) (nodes []common.Hash, paths []SyncPath, codes []common.Hash) { + var ( + nodeHashes []common.Hash + nodePaths []SyncPath + codeHashes []common.Hash + ) + for !s.queue.Empty() && (max == 0 || len(nodeHashes)+len(codeHashes) < max) { // Retrieve th enext item in line item, prio := s.queue.Peek() @@ -208,9 +247,16 @@ func (s *Sync) Missing(max int) []common.Hash { // Item is allowed to be scheduled, add it to the task list s.queue.Pop() s.fetches[depth]++ - requests = append(requests, item.(common.Hash)) + + hash := item.(common.Hash) + if req, ok := s.nodeReqs[hash]; ok { + nodeHashes = append(nodeHashes, hash) + nodePaths = append(nodePaths, newSyncPath(req.path)) + } else { + codeHashes = append(codeHashes, hash) + } } - return requests + return nodeHashes, nodePaths, codeHashes } // Process injects the received data for requested item. Note it can @@ -322,9 +368,13 @@ func (s *Sync) children(req *request, object node) ([]*request, error) { switch node := (object).(type) { case *shortNode: + key := node.Key + if hasTerm(key) { + key = key[:len(key)-1] + } children = []child{{ node: node.Val, - path: append(append([]byte(nil), req.path...), node.Key...), + path: append(append([]byte(nil), req.path...), key...), }} case *fullNode: for i := 0; i < 17; i++ { @@ -344,7 +394,7 @@ func (s *Sync) children(req *request, object node) ([]*request, error) { // Notify any external watcher of a new key/value node if req.callback != nil { if node, ok := (child.node).(valueNode); ok { - if err := req.callback(req.path, node, req.hash); err != nil { + if err := req.callback(child.path, node, req.hash); err != nil { return nil, err } } diff --git a/trie/sync_test.go b/trie/sync_test.go index 34f3990576..39e0f9575e 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -21,14 +21,15 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb/memorydb" ) // makeTestTrie create a sample test trie to test node-wise reconstruction. -func makeTestTrie() (*Database, *Trie, map[string][]byte) { +func makeTestTrie() (*Database, *SecureTrie, map[string][]byte) { // Create an empty trie triedb := NewDatabase(memorydb.New()) - trie, _ := New(common.Hash{}, triedb) + trie, _ := NewSecure(common.Hash{}, triedb) // Fill it with some arbitrary data content := make(map[string][]byte) @@ -59,7 +60,7 @@ func makeTestTrie() (*Database, *Trie, map[string][]byte) { // content map. func checkTrieContents(t *testing.T, db *Database, root []byte, content map[string][]byte) { // Check root availability and trie contents - trie, err := New(common.BytesToHash(root), db) + trie, err := NewSecure(common.BytesToHash(root), db) if err != nil { t.Fatalf("failed to create trie at %x: %v", root, err) } @@ -76,7 +77,7 @@ func checkTrieContents(t *testing.T, db *Database, root []byte, content map[stri // checkTrieConsistency checks that all nodes in a trie are indeed present. func checkTrieConsistency(db *Database, root common.Hash) error { // Create and iterate a trie rooted in a subnode - trie, err := New(root, db) + trie, err := NewSecure(root, db) if err != nil { return nil // Consider a non existent state consistent } @@ -94,18 +95,21 @@ func TestEmptySync(t *testing.T) { emptyB, _ := New(emptyRoot, dbB) for i, trie := range []*Trie{emptyA, emptyB} { - if req := NewSync(trie.Hash(), memorydb.New(), nil, NewSyncBloom(1, memorydb.New())).Missing(1); len(req) != 0 { - t.Errorf("test %d: content requested for empty trie: %v", i, req) + sync := NewSync(trie.Hash(), memorydb.New(), nil, NewSyncBloom(1, memorydb.New())) + if nodes, paths, codes := sync.Missing(1); len(nodes) != 0 || len(paths) != 0 || len(codes) != 0 { + t.Errorf("test %d: content requested for empty trie: %v, %v, %v", i, nodes, paths, codes) } } } // Tests that given a root hash, a trie can sync iteratively on a single thread, // requesting retrieval tasks and returning all of them in one go. -func TestIterativeSyncIndividual(t *testing.T) { testIterativeSync(t, 1) } -func TestIterativeSyncBatched(t *testing.T) { testIterativeSync(t, 100) } +func TestIterativeSyncIndividual(t *testing.T) { testIterativeSync(t, 1, false) } +func TestIterativeSyncBatched(t *testing.T) { testIterativeSync(t, 100, false) } +func TestIterativeSyncIndividualByPath(t *testing.T) { testIterativeSync(t, 1, true) } +func TestIterativeSyncBatchedByPath(t *testing.T) { testIterativeSync(t, 100, true) } -func testIterativeSync(t *testing.T, count int) { +func testIterativeSync(t *testing.T, count int, bypath bool) { // Create a random trie to copy srcDb, srcTrie, srcData := makeTestTrie() @@ -114,16 +118,33 @@ func testIterativeSync(t *testing.T, count int) { triedb := NewDatabase(diskdb) sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) - queue := append([]common.Hash{}, sched.Missing(count)...) - for len(queue) > 0 { - results := make([]SyncResult, len(queue)) - for i, hash := range queue { + nodes, paths, codes := sched.Missing(count) + var ( + hashQueue []common.Hash + pathQueue []SyncPath + ) + if !bypath { + hashQueue = append(append(hashQueue[:0], nodes...), codes...) + } else { + hashQueue = append(hashQueue[:0], codes...) + pathQueue = append(pathQueue[:0], paths...) + } + for len(hashQueue)+len(pathQueue) > 0 { + results := make([]SyncResult, len(hashQueue)+len(pathQueue)) + for i, hash := range hashQueue { data, err := srcDb.Node(hash) if err != nil { - t.Fatalf("failed to retrieve node data for %x: %v", hash, err) + t.Fatalf("failed to retrieve node data for hash %x: %v", hash, err) } results[i] = SyncResult{hash, data} } + for i, path := range pathQueue { + data, _, err := srcTrie.TryGetNode(path[0]) + if err != nil { + t.Fatalf("failed to retrieve node data for path %x: %v", path, err) + } + results[len(hashQueue)+i] = SyncResult{crypto.Keccak256Hash(data), data} + } for _, result := range results { if err := sched.Process(result); err != nil { t.Fatalf("failed to process result %v", err) @@ -134,7 +155,14 @@ func testIterativeSync(t *testing.T, count int) { t.Fatalf("failed to commit data: %v", err) } batch.Write() - queue = append(queue[:0], sched.Missing(count)...) + + nodes, paths, codes = sched.Missing(count) + if !bypath { + hashQueue = append(append(hashQueue[:0], nodes...), codes...) + } else { + hashQueue = append(hashQueue[:0], codes...) + pathQueue = append(pathQueue[:0], paths...) + } } // Cross check that the two tries are in sync checkTrieContents(t, triedb, srcTrie.Hash().Bytes(), srcData) @@ -151,7 +179,9 @@ func TestIterativeDelayedSync(t *testing.T) { triedb := NewDatabase(diskdb) sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) - queue := append([]common.Hash{}, sched.Missing(10000)...) + nodes, _, codes := sched.Missing(10000) + queue := append(append([]common.Hash{}, nodes...), codes...) + for len(queue) > 0 { // Sync only half of the scheduled nodes results := make([]SyncResult, len(queue)/2+1) @@ -172,7 +202,9 @@ func TestIterativeDelayedSync(t *testing.T) { t.Fatalf("failed to commit data: %v", err) } batch.Write() - queue = append(queue[len(results):], sched.Missing(10000)...) + + nodes, _, codes = sched.Missing(10000) + queue = append(append(queue[len(results):], nodes...), codes...) } // Cross check that the two tries are in sync checkTrieContents(t, triedb, srcTrie.Hash().Bytes(), srcData) @@ -194,7 +226,8 @@ func testIterativeRandomSync(t *testing.T, count int) { sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) queue := make(map[common.Hash]struct{}) - for _, hash := range sched.Missing(count) { + nodes, _, codes := sched.Missing(count) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } for len(queue) > 0 { @@ -218,8 +251,10 @@ func testIterativeRandomSync(t *testing.T, count int) { t.Fatalf("failed to commit data: %v", err) } batch.Write() + queue = make(map[common.Hash]struct{}) - for _, hash := range sched.Missing(count) { + nodes, _, codes = sched.Missing(count) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } } @@ -239,7 +274,8 @@ func TestIterativeRandomDelayedSync(t *testing.T) { sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) queue := make(map[common.Hash]struct{}) - for _, hash := range sched.Missing(10000) { + nodes, _, codes := sched.Missing(10000) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } for len(queue) > 0 { @@ -270,7 +306,8 @@ func TestIterativeRandomDelayedSync(t *testing.T) { for _, result := range results { delete(queue, result.Hash) } - for _, hash := range sched.Missing(10000) { + nodes, _, codes = sched.Missing(10000) + for _, hash := range append(nodes, codes...) { queue[hash] = struct{}{} } } @@ -289,7 +326,8 @@ func TestDuplicateAvoidanceSync(t *testing.T) { triedb := NewDatabase(diskdb) sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) - queue := append([]common.Hash{}, sched.Missing(0)...) + nodes, _, codes := sched.Missing(0) + queue := append(append([]common.Hash{}, nodes...), codes...) requested := make(map[common.Hash]struct{}) for len(queue) > 0 { @@ -316,7 +354,9 @@ func TestDuplicateAvoidanceSync(t *testing.T) { t.Fatalf("failed to commit data: %v", err) } batch.Write() - queue = append(queue[:0], sched.Missing(0)...) + + nodes, _, codes = sched.Missing(0) + queue = append(append(queue[:0], nodes...), codes...) } // Cross check that the two tries are in sync checkTrieContents(t, triedb, srcTrie.Hash().Bytes(), srcData) @@ -334,7 +374,10 @@ func TestIncompleteSync(t *testing.T) { sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) var added []common.Hash - queue := append([]common.Hash{}, sched.Missing(1)...) + + nodes, _, codes := sched.Missing(1) + queue := append(append([]common.Hash{}, nodes...), codes...) + for len(queue) > 0 { // Fetch a batch of trie nodes results := make([]SyncResult, len(queue)) @@ -366,7 +409,8 @@ func TestIncompleteSync(t *testing.T) { } } // Fetch the next batch to retrieve - queue = append(queue[:0], sched.Missing(1)...) + nodes, _, codes = sched.Missing(1) + queue = append(append(queue[:0], nodes...), codes...) } // Sanity check that removing any node from the database is detected for _, node := range added[1:] { @@ -380,3 +424,58 @@ func TestIncompleteSync(t *testing.T) { diskdb.Put(key, value) } } + +// Tests that trie nodes get scheduled lexicographically when having the same +// depth. +func TestSyncOrdering(t *testing.T) { + // Create a random trie to copy + srcDb, srcTrie, srcData := makeTestTrie() + + // Create a destination trie and sync with the scheduler, tracking the requests + diskdb := memorydb.New() + triedb := NewDatabase(diskdb) + sched := NewSync(srcTrie.Hash(), diskdb, nil, NewSyncBloom(1, diskdb)) + + nodes, paths, _ := sched.Missing(1) + queue := append([]common.Hash{}, nodes...) + reqs := append([]SyncPath{}, paths...) + + for len(queue) > 0 { + results := make([]SyncResult, len(queue)) + for i, hash := range queue { + data, err := srcDb.Node(hash) + if err != nil { + t.Fatalf("failed to retrieve node data for %x: %v", hash, err) + } + results[i] = SyncResult{hash, data} + } + for _, result := range results { + if err := sched.Process(result); err != nil { + t.Fatalf("failed to process result %v", err) + } + } + batch := diskdb.NewBatch() + if err := sched.Commit(batch); err != nil { + t.Fatalf("failed to commit data: %v", err) + } + batch.Write() + + nodes, paths, _ = sched.Missing(1) + queue = append(queue[:0], nodes...) + reqs = append(reqs, paths...) + } + // Cross check that the two tries are in sync + checkTrieContents(t, triedb, srcTrie.Hash().Bytes(), srcData) + + // Check that the trie nodes have been requested path-ordered + for i := 0; i < len(reqs)-1; i++ { + if len(reqs[i]) > 1 || len(reqs[i+1]) > 1 { + // In the case of the trie tests, there's no storage so the tuples + // must always be single items. 2-tuples should be tested in state. + t.Errorf("Invalid request tuples: len(%v) or len(%v) > 1", reqs[i], reqs[i+1]) + } + if bytes.Compare(compactToHex(reqs[i][0]), compactToHex(reqs[i+1][0])) > 0 { + t.Errorf("Invalid request order: %v before %v", compactToHex(reqs[i][0]), compactToHex(reqs[i+1][0])) + } + } +} diff --git a/trie/trie.go b/trie/trie.go index 7ccd37f872..1e1749a4ff 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" ) var ( @@ -102,8 +103,7 @@ func (t *Trie) Get(key []byte) []byte { // The value bytes must not be modified by the caller. // If a node was not found in the database, a MissingNodeError is returned. func (t *Trie) TryGet(key []byte) ([]byte, error) { - key = keybytesToHex(key) - value, newroot, didResolve, err := t.tryGet(t.root, key, 0) + value, newroot, didResolve, err := t.tryGet(t.root, keybytesToHex(key), 0) if err == nil && didResolve { t.root = newroot } @@ -146,6 +146,86 @@ func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode } } +// TryGetNode attempts to retrieve a trie node by compact-encoded path. It is not +// possible to use keybyte-encoding as the path might contain odd nibbles. +func (t *Trie) TryGetNode(path []byte) ([]byte, int, error) { + item, newroot, resolved, err := t.tryGetNode(t.root, compactToHex(path), 0) + if err != nil { + return nil, resolved, err + } + if resolved > 0 { + t.root = newroot + } + if item == nil { + return nil, resolved, nil + } + enc, err := rlp.EncodeToBytes(item) + if err != nil { + log.Error("Encoding existing trie node failed", "err", err) + return nil, resolved, err + } + return enc, resolved, err +} + +func (t *Trie) tryGetNode(origNode node, path []byte, pos int) (item node, newnode node, resolved int, err error) { + // If we reached the requested path, return the current node + if pos >= len(path) { + // Don't return collapsed hash nodes though + if _, ok := origNode.(hashNode); !ok { + // Short nodes have expanded keys, compact them before returning + item := origNode + if sn, ok := item.(*shortNode); ok { + item = &shortNode{ + Key: hexToCompact(sn.Key), + Val: sn.Val, + } + } + return item, origNode, 0, nil + } + } + // Path still needs to be traversed, descend into children + switch n := (origNode).(type) { + case nil: + // Non-existent path requested, abort + return nil, nil, 0, nil + + case valueNode: + // Path prematurely ended, abort + return nil, nil, 0, nil + + case *shortNode: + if len(path)-pos < len(n.Key) || !bytes.Equal(n.Key, path[pos:pos+len(n.Key)]) { + // Path branches off from short node + return nil, n, 0, nil + } + item, newnode, resolved, err = t.tryGetNode(n.Val, path, pos+len(n.Key)) + if err == nil && resolved > 0 { + n = n.copy() + n.Val = newnode + } + return item, n, resolved, err + + case *fullNode: + item, newnode, resolved, err = t.tryGetNode(n.Children[path[pos]], path, pos+1) + if err == nil && resolved > 0 { + n = n.copy() + n.Children[path[pos]] = newnode + } + return item, n, resolved, err + + case hashNode: + child, err := t.resolveHash(n, path[:pos]) + if err != nil { + return nil, n, 1, err + } + item, newnode, resolved, err := t.tryGetNode(child, path, pos) + return item, newnode, resolved + 1, err + + default: + panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode)) + } +} + // Update associates key with value in the trie. Subsequent calls to // Get will return value. If value has length zero, any existing value // is deleted from the trie and calls to Get will return nil. From de971cc8457601691e97045f30e1419ecc2ac103 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 7 Sep 2020 10:52:01 +0200 Subject: [PATCH 14/24] eth: added trace_call to trace on top of arbitrary blocks (#21338) * eth: Added TraceTransactionPending * eth: Implement Trace_Call, remove traceTxPending * eth: debug_call -> debug_traceCall, recompute tx environment if pruned * eth: fix nil panic * eth: improve block retrieving logic in tracers * internal/web3ext: add debug_traceCall to console --- eth/api.go | 7 +++++- eth/api_tracer.go | 49 +++++++++++++++++++++++++++++++------ internal/web3ext/web3ext.go | 6 +++++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/eth/api.go b/eth/api.go index d65a8efa0d..76118e2d7f 100644 --- a/eth/api.go +++ b/eth/api.go @@ -412,7 +412,12 @@ type storageEntry struct { // StorageRangeAt returns the storage at the given block height and transaction index. func (api *PrivateDebugAPI) StorageRangeAt(blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) { - _, _, statedb, err := api.computeTxEnv(blockHash, txIndex, 0) + // Retrieve the block + block := api.eth.blockchain.GetBlockByHash(blockHash) + if block == nil { + return StorageRangeResult{}, fmt.Errorf("block %#x not found", blockHash) + } + _, _, statedb, err := api.computeTxEnv(block, txIndex, 0) if err != nil { return StorageRangeResult{}, err } diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 51c2408c24..748280951c 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -711,7 +711,12 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha if config != nil && config.Reexec != nil { reexec = *config.Reexec } - msg, vmctx, statedb, err := api.computeTxEnv(blockHash, int(index), reexec) + // Retrieve the block + block := api.eth.blockchain.GetBlockByHash(blockHash) + if block == nil { + return nil, fmt.Errorf("block %#x not found", blockHash) + } + msg, vmctx, statedb, err := api.computeTxEnv(block, int(index), reexec) if err != nil { return nil, err } @@ -719,6 +724,40 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha return api.traceTx(ctx, msg, vmctx, statedb, config) } +// TraceCall lets you trace a given eth_call. It collects the structured logs created during the execution of EVM +// if the given transaction was added on top of the provided block and returns them as a JSON object. +// You can provide -2 as a block number to trace on top of the pending block. +func (api *PrivateDebugAPI) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceConfig) (interface{}, error) { + // First try to retrieve the state + statedb, header, err := api.eth.APIBackend.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if err != nil { + // Try to retrieve the specified block + var block *types.Block + if hash, ok := blockNrOrHash.Hash(); ok { + block = api.eth.blockchain.GetBlockByHash(hash) + } else if number, ok := blockNrOrHash.Number(); ok { + block = api.eth.blockchain.GetBlockByNumber(uint64(number)) + } + if block == nil { + return nil, fmt.Errorf("block %v not found: %v", blockNrOrHash, err) + } + // try to recompute the state + reexec := defaultTraceReexec + if config != nil && config.Reexec != nil { + reexec = *config.Reexec + } + _, _, statedb, err = api.computeTxEnv(block, 0, reexec) + if err != nil { + return nil, err + } + } + + // Execute the trace + msg := args.ToMessage(api.eth.APIBackend.RPCGasCap()) + vmctx := core.NewEVMContext(msg, header, api.eth.blockchain, nil) + return api.traceTx(ctx, msg, vmctx, statedb, config) +} + // traceTx configures a new tracer according to the provided configuration, and // executes the given message in the provided environment. The return value will // be tracer dependent. @@ -786,12 +825,8 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v } // computeTxEnv returns the execution environment of a certain transaction. -func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, error) { +func (api *PrivateDebugAPI) computeTxEnv(block *types.Block, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, error) { // Create the parent state database - block := api.eth.blockchain.GetBlockByHash(blockHash) - if block == nil { - return nil, vm.Context{}, nil, fmt.Errorf("block %#x not found", blockHash) - } parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { return nil, vm.Context{}, nil, fmt.Errorf("parent %#x not found", block.ParentHash()) @@ -824,5 +859,5 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number())) } - return nil, vm.Context{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, blockHash) + return nil, vm.Context{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash()) } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 80ac92fe4a..41d8657787 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -429,6 +429,12 @@ web3._extend({ params: 2, inputFormatter: [null, null] }), + new web3._extend.Method({ + name: 'traceCall', + call: 'debug_traceCall', + params: 3, + inputFormatter: [null, null, null] + }), new web3._extend.Method({ name: 'preimage', call: 'debug_preimage', From c5d28f0b2765e65f1b5cd733d7190d36a7410e32 Mon Sep 17 00:00:00 2001 From: Osoro Bironga Date: Mon, 7 Sep 2020 14:07:15 +0300 Subject: [PATCH 15/24] accounts: abi/bid/backends; cleaned doc errors, camelCase refactors and anonymous variable assignments (#21514) Co-authored-by: Osoro Bironga --- accounts/abi/bind/backends/simulated.go | 132 +++++++++---------- accounts/abi/bind/backends/simulated_test.go | 20 +-- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 973d95531d..a43cb94678 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -45,7 +45,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) -// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend. +// This nil assignment ensures at compile time that SimulatedBackend implements bind.ContractBackend. var _ bind.ContractBackend = (*SimulatedBackend)(nil) var ( @@ -55,7 +55,7 @@ var ( ) // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in -// the background. Its main purpose is to allow easily testing contract bindings. +// the background. Its main purpose is to allow for easy testing of contract bindings. // Simulated backend implements the following interfaces: // ChainReader, ChainStateReader, ContractBackend, ContractCaller, ContractFilterer, ContractTransactor, // DeployBackend, GasEstimator, GasPricer, LogFilterer, PendingContractCaller, TransactionReader, and TransactionSender @@ -123,10 +123,10 @@ func (b *SimulatedBackend) Rollback() { func (b *SimulatedBackend) rollback() { blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {}) - statedb, _ := b.blockchain.State() + stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] - b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database(), nil) + b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) } // stateByBlockNumber retrieves a state by a given blocknumber. @@ -146,12 +146,12 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return nil, err } - return statedb.GetCode(contract), nil + return stateDB.GetCode(contract), nil } // BalanceAt returns the wei balance of a certain account in the blockchain. @@ -159,12 +159,12 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return nil, err } - return statedb.GetBalance(contract), nil + return stateDB.GetBalance(contract), nil } // NonceAt returns the nonce of a certain account in the blockchain. @@ -172,12 +172,12 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return 0, err } - return statedb.GetNonce(contract), nil + return stateDB.GetNonce(contract), nil } // StorageAt returns the value of key in the storage of an account in the blockchain. @@ -185,17 +185,17 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return nil, err } - val := statedb.GetState(contract, key) + val := stateDB.GetState(contract, key) return val[:], nil } // TransactionReceipt returns the receipt of a transaction. -func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { +func (b *SimulatedBackend) TransactionReceipt(_ context.Context, txHash common.Hash) (*types.Receipt, error) { b.mu.Lock() defer b.mu.Unlock() @@ -207,7 +207,7 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common // blockchain. The isPending return value indicates whether the transaction has been // mined yet. Note that the transaction may not be part of the canonical chain even if // it's not pending. -func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { +func (b *SimulatedBackend) TransactionByHash(_ context.Context, txHash common.Hash) (*types.Transaction, bool, error) { b.mu.Lock() defer b.mu.Unlock() @@ -222,8 +222,8 @@ func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common. return nil, false, ethereum.NotFound } -// BlockByHash retrieves a block based on the block hash -func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { +// BlockByHash retrieves a block based on the block hash. +func (b *SimulatedBackend) BlockByHash(_ context.Context, hash common.Hash) (*types.Block, error) { b.mu.Lock() defer b.mu.Unlock() @@ -250,7 +250,7 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) ( // blockByNumberNoLock retrieves a block from the database by number, caching it // (associated with its hash) if found without Lock. -func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big.Int) (*types.Block, error) { +func (b *SimulatedBackend) blockByNumberNoLock(_ context.Context, number *big.Int) (*types.Block, error) { if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 { return b.blockchain.CurrentBlock(), nil } @@ -264,7 +264,7 @@ func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big. } // HeaderByHash returns a block header from the current canonical chain. -func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { +func (b *SimulatedBackend) HeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) { b.mu.Lock() defer b.mu.Unlock() @@ -282,7 +282,7 @@ func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) ( // HeaderByNumber returns a block header from the current canonical chain. If number is // nil, the latest known header is returned. -func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) { +func (b *SimulatedBackend) HeaderByNumber(_ context.Context, block *big.Int) (*types.Header, error) { b.mu.Lock() defer b.mu.Unlock() @@ -293,8 +293,8 @@ func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) ( return b.blockchain.GetHeaderByNumber(uint64(block.Int64())), nil } -// TransactionCount returns the number of transactions in a given block -func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { +// TransactionCount returns the number of transactions in a given block. +func (b *SimulatedBackend) TransactionCount(_ context.Context, blockHash common.Hash) (uint, error) { b.mu.Lock() defer b.mu.Unlock() @@ -310,8 +310,8 @@ func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash commo return uint(block.Transactions().Len()), nil } -// TransactionInBlock returns the transaction for a specific block at a specific index -func (b *SimulatedBackend) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { +// TransactionInBlock returns the transaction for a specific block at a specific index. +func (b *SimulatedBackend) TransactionInBlock(_ context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { b.mu.Lock() defer b.mu.Unlock() @@ -338,7 +338,7 @@ func (b *SimulatedBackend) TransactionInBlock(ctx context.Context, blockHash com } // PendingCodeAt returns the code associated with an account in the pending state. -func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { +func (b *SimulatedBackend) PendingCodeAt(_ context.Context, contract common.Address) ([]byte, error) { b.mu.Lock() defer b.mu.Unlock() @@ -357,14 +357,14 @@ func newRevertError(result *core.ExecutionResult) *revertError { } } -// revertError is an API error that encompassas an EVM revertal with JSON error +// revertError is an API error that encompasses an EVM revert with JSON error // code and a binary data blob. type revertError struct { error reason string // revert reason hex encoded } -// ErrorCode returns the JSON error code for a revertal. +// ErrorCode returns the JSON error code for a revert. // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal func (e *revertError) ErrorCode() int { return 3 @@ -383,11 +383,11 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { return nil, errBlockNumberUnsupported } - state, err := b.blockchain.State() + stateDB, err := b.blockchain.State() if err != nil { return nil, err } - res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state) + res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB) if err != nil { return nil, err } @@ -417,7 +417,7 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereu // PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving // the nonce currently pending for the account. -func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { +func (b *SimulatedBackend) PendingNonceAt(_ context.Context, account common.Address) (uint64, error) { b.mu.Lock() defer b.mu.Unlock() @@ -426,7 +426,7 @@ func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Ad // SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated // chain doesn't have miners, we just return a gas price of 1 for any call. -func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { +func (b *SimulatedBackend) SuggestGasPrice(_ context.Context) (*big.Int, error) { return big.NewInt(1), nil } @@ -525,7 +525,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs // callContract implements common code between normal and pending contract calls. // state is modified during execution, make sure to copy it if necessary. -func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) { +func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB) (*core.ExecutionResult, error) { // Ensure message is initialized properly. if call.GasPrice == nil { call.GasPrice = big.NewInt(1) @@ -537,23 +537,23 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM call.Value = new(big.Int) } // Set infinite balance to the fake caller account. - from := statedb.GetOrNewStateObject(call.From) + from := stateDB.GetOrNewStateObject(call.From) from.SetBalance(math.MaxBig256) // Execute the call. - msg := callmsg{call} + msg := callMsg{call} evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{}) - gaspool := new(core.GasPool).AddGas(math.MaxUint64) + vmEnv := vm.NewEVM(evmContext, stateDB, b.config, vm.Config{}) + gasPool := new(core.GasPool).AddGas(math.MaxUint64) - return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() + return core.NewStateTransition(vmEnv, msg, gasPool).TransitionDb() } // SendTransaction updates the pending block to include the given transaction. // It panics if the transaction is invalid. -func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { +func (b *SimulatedBackend) SendTransaction(_ context.Context, tx *types.Transaction) error { b.mu.Lock() defer b.mu.Unlock() @@ -572,10 +572,10 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa } block.AddTxWithChain(b.blockchain, tx) }) - statedb, _ := b.blockchain.State() + stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] - b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database(), nil) + b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) return nil } @@ -589,7 +589,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.Filter // Block filter requested, construct a single-shot filter filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) } else { - // Initialize unset filter boundaried to run from genesis to chain head + // Initialize unset filter boundaries to run from genesis to chain head from := int64(0) if query.FromBlock != nil { from = query.FromBlock.Int64() @@ -607,15 +607,15 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.Filter return nil, err } res := make([]types.Log, len(logs)) - for i, log := range logs { - res[i] = *log + for i, nLog := range logs { + res[i] = *nLog } return res, nil } // SubscribeFilterLogs creates a background log filtering operation, returning a // subscription immediately, which can be used to stream the found events. -func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { +func (b *SimulatedBackend) SubscribeFilterLogs(_ context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { // Subscribe to contract events sink := make(chan []*types.Log) @@ -629,9 +629,9 @@ func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethere for { select { case logs := <-sink: - for _, log := range logs { + for _, nlog := range logs { select { - case ch <- *log: + case ch <- *nlog: case err := <-sub.Err(): return err case <-quit: @@ -647,8 +647,8 @@ func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethere }), nil } -// SubscribeNewHead returns an event subscription for a new header -func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { +// SubscribeNewHead returns an event subscription for a new header. +func (b *SimulatedBackend) SubscribeNewHead(_ context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { // subscribe to a new head sink := make(chan *types.Header) sub := b.events.SubscribeNewHeads(sink) @@ -687,10 +687,10 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { block.OffsetTime(int64(adjustment.Seconds())) }) - statedb, _ := b.blockchain.State() + stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] - b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database(), nil) + b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) return nil } @@ -700,19 +700,19 @@ func (b *SimulatedBackend) Blockchain() *core.BlockChain { return b.blockchain } -// callmsg implements core.Message to allow passing it as a transaction simulator. -type callmsg struct { +// callMsg implements core.Message to allow passing it as a transaction simulator. +type callMsg struct { ethereum.CallMsg } -func (m callmsg) From() common.Address { return m.CallMsg.From } -func (m callmsg) Nonce() uint64 { return 0 } -func (m callmsg) CheckNonce() bool { return false } -func (m callmsg) To() *common.Address { return m.CallMsg.To } -func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } -func (m callmsg) Gas() uint64 { return m.CallMsg.Gas } -func (m callmsg) Value() *big.Int { return m.CallMsg.Value } -func (m callmsg) Data() []byte { return m.CallMsg.Data } +func (m callMsg) From() common.Address { return m.CallMsg.From } +func (m callMsg) Nonce() uint64 { return 0 } +func (m callMsg) CheckNonce() bool { return false } +func (m callMsg) To() *common.Address { return m.CallMsg.To } +func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice } +func (m callMsg) Gas() uint64 { return m.CallMsg.Gas } +func (m callMsg) Value() *big.Int { return m.CallMsg.Value } +func (m callMsg) Data() []byte { return m.CallMsg.Data } // filterBackend implements filters.Backend to support filtering for logs without // taking bloom-bits acceleration structures into account. @@ -724,18 +724,18 @@ type filterBackend struct { func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } -func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { +func (fb *filterBackend) HeaderByNumber(_ context.Context, block rpc.BlockNumber) (*types.Header, error) { if block == rpc.LatestBlockNumber { return fb.bc.CurrentHeader(), nil } return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } -func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { +func (fb *filterBackend) HeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) { return fb.bc.GetHeaderByHash(hash), nil } -func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { +func (fb *filterBackend) GetReceipts(_ context.Context, hash common.Hash) (types.Receipts, error) { number := rawdb.ReadHeaderNumber(fb.db, hash) if number == nil { return nil, nil @@ -743,7 +743,7 @@ func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (typ return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil } -func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { +func (fb *filterBackend) GetLogs(_ context.Context, hash common.Hash) ([][]*types.Log, error) { number := rawdb.ReadHeaderNumber(fb.db, hash) if number == nil { return nil, nil @@ -759,7 +759,7 @@ func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*ty return logs, nil } -func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { +func (fb *filterBackend) SubscribeNewTxsEvent(_ chan<- core.NewTxsEvent) event.Subscription { return nullSubscription() } @@ -775,13 +775,13 @@ func (fb *filterBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscr return fb.bc.SubscribeLogsEvent(ch) } -func (fb *filterBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { +func (fb *filterBackend) SubscribePendingLogsEvent(_ chan<- []*types.Log) event.Subscription { return nullSubscription() } func (fb *filterBackend) BloomStatus() (uint64, uint64) { return 4096, 0 } -func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.MatcherSession) { +func (fb *filterBackend) ServiceFilter(_ context.Context, _ *bloombits.MatcherSession) { panic("not supported") } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 9087d74bc6..2dffe26f6e 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -129,8 +129,8 @@ func TestNewSimulatedBackend(t *testing.T) { t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config) } - statedb, _ := sim.blockchain.State() - bal := statedb.GetBalance(testAddr) + stateDB, _ := sim.blockchain.State() + bal := stateDB.GetBalance(testAddr) if bal.Cmp(expectedBal) != 0 { t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) } @@ -521,7 +521,7 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) { sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000) defer sim.Close() - receipant := common.HexToAddress("deadbeef") + recipient := common.HexToAddress("deadbeef") var cases = []struct { name string message ethereum.CallMsg @@ -530,7 +530,7 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) { }{ {"EstimateWithoutPrice", ethereum.CallMsg{ From: addr, - To: &receipant, + To: &recipient, Gas: 0, GasPrice: big.NewInt(0), Value: big.NewInt(1000), @@ -539,7 +539,7 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) { {"EstimateWithPrice", ethereum.CallMsg{ From: addr, - To: &receipant, + To: &recipient, Gas: 0, GasPrice: big.NewInt(1000), Value: big.NewInt(1000), @@ -548,7 +548,7 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) { {"EstimateWithVeryHighPrice", ethereum.CallMsg{ From: addr, - To: &receipant, + To: &recipient, Gas: 0, GasPrice: big.NewInt(1e14), // gascost = 2.1ether Value: big.NewInt(1e17), // the remaining balance for fee is 2.1ether @@ -557,7 +557,7 @@ func TestSimulatedBackend_EstimateGasWithPrice(t *testing.T) { {"EstimateWithSuperhighPrice", ethereum.CallMsg{ From: addr, - To: &receipant, + To: &recipient, Gas: 0, GasPrice: big.NewInt(2e14), // gascost = 4.2ether Value: big.NewInt(1000), @@ -1086,12 +1086,12 @@ func TestSimulatedBackend_CallContractRevert(t *testing.T) { t.Errorf("result from %v was not nil: %v", key, res) } if val != nil { - rerr, ok := err.(*revertError) + rErr, ok := err.(*revertError) if !ok { t.Errorf("expect revert error") } - if rerr.Error() != "execution reverted: "+val.(string) { - t.Errorf("error was malformed: got %v want %v", rerr.Error(), val) + if rErr.Error() != "execution reverted: "+val.(string) { + t.Errorf("error was malformed: got %v want %v", rErr.Error(), val) } } else { // revert(0x0,0x0) From d54f2f2e5e393741ff887a364877c0fddd5571a5 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 8 Sep 2020 08:47:48 +0000 Subject: [PATCH 16/24] whisper: remove whisper (#21487) * whisper: remove whisper * Update cmd/geth/config.go Co-authored-by: Marius van der Wijden * cmd/geth: warn on enabling whisper + remove more whisper deps * mobile: remove all whisper references Co-authored-by: Marius van der Wijden Co-authored-by: Martin Holst Swende --- cmd/geth/config.go | 27 +- cmd/geth/consolecmd_test.go | 8 +- cmd/geth/usage.go | 2 +- cmd/utils/flags.go | 27 +- cmd/wnode/main.go | 773 ----------- mobile/geth.go | 10 - mobile/shhclient.go | 195 --- mobile/types.go | 93 -- .../009c5adfa4fd685caef58e1ce932fa7fb209730a | Bin 61 -> 0 bytes tests/fuzzers/whisperv6/whisper-fuzzer.go | 90 -- whisper/mailserver/mailserver.go | 209 --- whisper/mailserver/server_test.go | 235 ---- whisper/shhclient/client.go | 193 --- whisper/whisperv6/api.go | 593 --------- whisper/whisperv6/api_test.go | 64 - whisper/whisperv6/benchmarks_test.go | 208 --- whisper/whisperv6/config.go | 31 - whisper/whisperv6/doc.go | 92 -- whisper/whisperv6/envelope.go | 280 ---- whisper/whisperv6/envelope_test.go | 91 -- whisper/whisperv6/filter.go | 262 ---- whisper/whisperv6/filter_test.go | 836 ------------ whisper/whisperv6/gen_criteria_json.go | 66 - whisper/whisperv6/gen_message_json.go | 84 -- whisper/whisperv6/gen_newmessage_json.go | 90 -- whisper/whisperv6/message.go | 355 ----- whisper/whisperv6/message_test.go | 471 ------- whisper/whisperv6/peer.go | 268 ---- whisper/whisperv6/topic.go | 56 - whisper/whisperv6/topic_test.go | 134 -- whisper/whisperv6/whisper.go | 1140 ----------------- whisper/whisperv6/whisper_test.go | 928 -------------- 32 files changed, 17 insertions(+), 7894 deletions(-) delete mode 100644 cmd/wnode/main.go delete mode 100644 mobile/shhclient.go delete mode 100644 tests/fuzzers/whisperv6/corpus/009c5adfa4fd685caef58e1ce932fa7fb209730a delete mode 100644 tests/fuzzers/whisperv6/whisper-fuzzer.go delete mode 100644 whisper/mailserver/mailserver.go delete mode 100644 whisper/mailserver/server_test.go delete mode 100644 whisper/shhclient/client.go delete mode 100644 whisper/whisperv6/api.go delete mode 100644 whisper/whisperv6/api_test.go delete mode 100644 whisper/whisperv6/benchmarks_test.go delete mode 100644 whisper/whisperv6/config.go delete mode 100644 whisper/whisperv6/doc.go delete mode 100644 whisper/whisperv6/envelope.go delete mode 100644 whisper/whisperv6/envelope_test.go delete mode 100644 whisper/whisperv6/filter.go delete mode 100644 whisper/whisperv6/filter_test.go delete mode 100644 whisper/whisperv6/gen_criteria_json.go delete mode 100644 whisper/whisperv6/gen_message_json.go delete mode 100644 whisper/whisperv6/gen_newmessage_json.go delete mode 100644 whisper/whisperv6/message.go delete mode 100644 whisper/whisperv6/message_test.go delete mode 100644 whisper/whisperv6/peer.go delete mode 100644 whisper/whisperv6/topic.go delete mode 100644 whisper/whisperv6/topic_test.go delete mode 100644 whisper/whisperv6/whisper.go delete mode 100644 whisper/whisperv6/whisper_test.go diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 5fa64abe36..2c15a4c832 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -29,9 +29,9 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" "github.com/naoina/toml" ) @@ -75,7 +75,6 @@ type ethstatsConfig struct { type gethConfig struct { Eth eth.Config - Shh whisper.Config Node node.Config Ethstats ethstatsConfig } @@ -110,7 +109,6 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { // Load defaults. cfg := gethConfig{ Eth: eth.DefaultConfig, - Shh: whisper.DefaultConfig, Node: defaultNodeConfig(), } @@ -131,19 +129,18 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) { cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name) } - utils.SetShhConfig(ctx, stack, &cfg.Shh) + utils.SetShhConfig(ctx, stack) return stack, cfg } // enableWhisper returns true in case one of the whisper flags is set. -func enableWhisper(ctx *cli.Context) bool { +func checkWhisper(ctx *cli.Context) { for _, flag := range whisperFlags { if ctx.GlobalIsSet(flag.GetName()) { - return true + log.Warn("deprecated whisper flag detected. Whisper has been moved to github.com/ethereum/whisper") } } - return false } // makeFullNode loads geth configuration and creates the Ethereum backend. @@ -152,21 +149,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { backend := utils.RegisterEthService(stack, &cfg.Eth) - // Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode - shhEnabled := enableWhisper(ctx) - shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name) - if shhEnabled || shhAutoEnabled { - if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) { - cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name)) - } - if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) { - cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name) - } - if ctx.GlobalIsSet(utils.WhisperRestrictConnectionBetweenLightClientsFlag.Name) { - cfg.Shh.RestrictConnectionBetweenLightClients = true - } - utils.RegisterShhService(stack, &cfg.Shh) - } + checkWhisper(ctx) // Configure GraphQL if requested if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) { utils.RegisterGraphQLService(stack, backend, cfg.Node) diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index a2489892e4..6c100e18d9 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -31,7 +31,7 @@ import ( ) const ( - ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0" + ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0" httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" ) @@ -43,7 +43,7 @@ func TestConsoleWelcome(t *testing.T) { // Start a geth console, make sure it's cleaned up and terminate the console geth := runGeth(t, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--etherbase", coinbase, "--shh", + "--etherbase", coinbase, "console") // Gather all the infos the welcome message needs to contain @@ -83,11 +83,9 @@ func TestIPCAttachWelcome(t *testing.T) { defer os.RemoveAll(ws) ipc = filepath.Join(ws, "geth.ipc") } - // Note: we need --shh because testAttachWelcome checks for default - // list of ipc modules and shh is included there. geth := runGeth(t, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--etherbase", coinbase, "--shh", "--ipcpath", ipc) + "--etherbase", coinbase, "--ipcpath", ipc) defer func() { geth.Interrupt() diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 44f5750fee..5e004c42be 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -211,7 +211,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ Flags: metricsFlags, }, { - Name: "WHISPER (EXPERIMENTAL)", + Name: "WHISPER (deprecated)", Flags: whisperFlags, }, { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 403888c12f..e6382c1634 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -63,7 +63,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/params" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" pcsclite "github.com/gballet/go-libpcsclite" cli "gopkg.in/urfave/cli.v1" ) @@ -639,12 +638,12 @@ var ( WhisperMaxMessageSizeFlag = cli.IntFlag{ Name: "shh.maxmessagesize", Usage: "Max message size accepted", - Value: int(whisper.DefaultMaxMessageSize), + Value: 1024 * 1024, } WhisperMinPOWFlag = cli.Float64Flag{ Name: "shh.pow", Usage: "Minimum POW accepted", - Value: whisper.DefaultMinimumPoW, + Value: 0.2, } WhisperRestrictConnectionBetweenLightClientsFlag = cli.BoolFlag{ Name: "shh.restrict-light", @@ -1465,15 +1464,12 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) { } // SetShhConfig applies shh-related command line flags to the config. -func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) { - if ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) { - cfg.MaxMessageSize = uint32(ctx.GlobalUint(WhisperMaxMessageSizeFlag.Name)) - } - if ctx.GlobalIsSet(WhisperMinPOWFlag.Name) { - cfg.MinimumAcceptedPOW = ctx.GlobalFloat64(WhisperMinPOWFlag.Name) - } - if ctx.GlobalIsSet(WhisperRestrictConnectionBetweenLightClientsFlag.Name) { - cfg.RestrictConnectionBetweenLightClients = true +func SetShhConfig(ctx *cli.Context, stack *node.Node) { + if ctx.GlobalIsSet(WhisperEnabledFlag.Name) || + ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) || + ctx.GlobalIsSet(WhisperMinPOWFlag.Name) || + ctx.GlobalIsSet(WhisperRestrictConnectionBetweenLightClientsFlag.Name) { + log.Warn("Whisper support has been deprecated and the code has been moved to github.com/ethereum/whisper") } } @@ -1697,13 +1693,6 @@ func RegisterEthService(stack *node.Node, cfg *eth.Config) ethapi.Backend { } } -// RegisterShhService configures Whisper and adds it to the given node. -func RegisterShhService(stack *node.Node, cfg *whisper.Config) { - if _, err := whisper.New(stack, cfg); err != nil { - Fatalf("Failed to register the Whisper service: %v", err) - } -} - // RegisterEthStatsService configures the Ethereum Stats daemon and adds it to // the given node. func RegisterEthStatsService(stack *node.Node, backend ethapi.Backend, url string) { diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go deleted file mode 100644 index bdb0d306b7..0000000000 --- a/cmd/wnode/main.go +++ /dev/null @@ -1,773 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -// This is a simple Whisper node. It could be used as a stand-alone bootstrap node. -// Also, could be used for different test and diagnostics purposes. - -package main - -import ( - "bufio" - "crypto/ecdsa" - crand "crypto/rand" - "crypto/sha512" - "encoding/binary" - "encoding/hex" - "flag" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/console/prompt" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/p2p/nat" - "github.com/ethereum/go-ethereum/whisper/mailserver" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" - "golang.org/x/crypto/pbkdf2" -) - -const quitCommand = "~Q" -const entropySize = 32 - -// singletons -var ( - server *p2p.Server - shh *whisper.Whisper - done chan struct{} - mailServer mailserver.WMailServer - entropy [entropySize]byte - - input = bufio.NewReader(os.Stdin) -) - -// encryption -var ( - symKey []byte - pub *ecdsa.PublicKey - asymKey *ecdsa.PrivateKey - nodeid *ecdsa.PrivateKey - topic whisper.TopicType - - asymKeyID string - asymFilterID string - symFilterID string - symPass string - msPassword string -) - -// cmd arguments -var ( - bootstrapMode = flag.Bool("standalone", false, "boostrap node: don't initiate connection to peers, just wait for incoming connections") - forwarderMode = flag.Bool("forwarder", false, "forwarder mode: only forward messages, neither encrypt nor decrypt messages") - mailServerMode = flag.Bool("mailserver", false, "mail server mode: delivers expired messages on demand") - requestMail = flag.Bool("mailclient", false, "request expired messages from the bootstrap server") - asymmetricMode = flag.Bool("asym", false, "use asymmetric encryption") - generateKey = flag.Bool("generatekey", false, "generate and show the private key") - fileExMode = flag.Bool("fileexchange", false, "file exchange mode") - fileReader = flag.Bool("filereader", false, "load and decrypt messages saved as files, display as plain text") - testMode = flag.Bool("test", false, "use of predefined parameters for diagnostics (password, etc.)") - echoMode = flag.Bool("echo", false, "echo mode: prints some arguments for diagnostics") - - argVerbosity = flag.Int("verbosity", int(log.LvlError), "log verbosity level") - argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds") - argWorkTime = flag.Uint("work", 5, "work time in seconds") - argMaxSize = flag.Uint("maxsize", uint(whisper.DefaultMaxMessageSize), "max size of message") - argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)") - argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request") - - argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)") - argPub = flag.String("pub", "", "public key for asymmetric encryption") - argDBPath = flag.String("dbpath", "", "path to the server's DB directory") - argIDFile = flag.String("idfile", "", "file name with node id (private key)") - argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://e454......08d50@52.176.211.200:16428)") - argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)") - argSaveDir = flag.String("savedir", "", "directory where all incoming messages will be saved as files") -) - -func main() { - processArgs() - initialize() - run() - shutdown() -} - -func processArgs() { - flag.Parse() - - if len(*argIDFile) > 0 { - var err error - nodeid, err = crypto.LoadECDSA(*argIDFile) - if err != nil { - utils.Fatalf("Failed to load file [%s]: %s.", *argIDFile, err) - } - } - - const enodePrefix = "enode://" - if len(*argEnode) > 0 { - if (*argEnode)[:len(enodePrefix)] != enodePrefix { - *argEnode = enodePrefix + *argEnode - } - } - - if len(*argTopic) > 0 { - x, err := hex.DecodeString(*argTopic) - if err != nil { - utils.Fatalf("Failed to parse the topic: %s", err) - } - topic = whisper.BytesToTopic(x) - } - - if *asymmetricMode && len(*argPub) > 0 { - var err error - if pub, err = crypto.UnmarshalPubkey(common.FromHex(*argPub)); err != nil { - utils.Fatalf("invalid public key") - } - } - - if len(*argSaveDir) > 0 { - if _, err := os.Stat(*argSaveDir); os.IsNotExist(err) { - utils.Fatalf("Download directory '%s' does not exist", *argSaveDir) - } - } else if *fileExMode { - utils.Fatalf("Parameter 'savedir' is mandatory for file exchange mode") - } - - if *echoMode { - echo() - } -} - -func echo() { - fmt.Printf("ttl = %d \n", *argTTL) - fmt.Printf("workTime = %d \n", *argWorkTime) - fmt.Printf("pow = %f \n", *argPoW) - fmt.Printf("mspow = %f \n", *argServerPoW) - fmt.Printf("ip = %s \n", *argIP) - fmt.Printf("pub = %s \n", hexutil.Encode(crypto.FromECDSAPub(pub))) - fmt.Printf("idfile = %s \n", *argIDFile) - fmt.Printf("dbpath = %s \n", *argDBPath) - fmt.Printf("boot = %s \n", *argEnode) -} - -func initialize() { - log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*argVerbosity), log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) - - done = make(chan struct{}) - var peers []*enode.Node - var err error - - if *generateKey { - key, err := crypto.GenerateKey() - if err != nil { - utils.Fatalf("Failed to generate private key: %s", err) - } - k := hex.EncodeToString(crypto.FromECDSA(key)) - fmt.Printf("Random private key: %s \n", k) - os.Exit(0) - } - - if *testMode { - symPass = "wwww" // ascii code: 0x77777777 - msPassword = "wwww" - } - - if *bootstrapMode { - if len(*argIP) == 0 { - argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30348): ") - } - } else if *fileReader { - *bootstrapMode = true - } else { - if len(*argEnode) == 0 { - argEnode = scanLineA("Please enter the peer's enode: ") - } - peer := enode.MustParse(*argEnode) - peers = append(peers, peer) - } - - if *mailServerMode { - if len(msPassword) == 0 { - msPassword, err = prompt.Stdin.PromptPassword("Please enter the Mail Server password: ") - if err != nil { - utils.Fatalf("Failed to read Mail Server password: %s", err) - } - } - } - - cfg := &whisper.Config{ - MaxMessageSize: uint32(*argMaxSize), - MinimumAcceptedPOW: *argPoW, - } - shh = whisper.StandaloneWhisperService(cfg) - - if *argPoW != whisper.DefaultMinimumPoW { - err := shh.SetMinimumPoW(*argPoW) - if err != nil { - utils.Fatalf("Failed to set PoW: %s", err) - } - } - - if uint32(*argMaxSize) != whisper.DefaultMaxMessageSize { - err := shh.SetMaxMessageSize(uint32(*argMaxSize)) - if err != nil { - utils.Fatalf("Failed to set max message size: %s", err) - } - } - - asymKeyID, err = shh.NewKeyPair() - if err != nil { - utils.Fatalf("Failed to generate a new key pair: %s", err) - } - - asymKey, err = shh.GetPrivateKey(asymKeyID) - if err != nil { - utils.Fatalf("Failed to retrieve a new key pair: %s", err) - } - - if nodeid == nil { - tmpID, err := shh.NewKeyPair() - if err != nil { - utils.Fatalf("Failed to generate a new key pair: %s", err) - } - - nodeid, err = shh.GetPrivateKey(tmpID) - if err != nil { - utils.Fatalf("Failed to retrieve a new key pair: %s", err) - } - } - - maxPeers := 80 - if *bootstrapMode { - maxPeers = 800 - } - - _, err = crand.Read(entropy[:]) - if err != nil { - utils.Fatalf("crypto/rand failed: %s", err) - } - - if *mailServerMode { - shh.RegisterServer(&mailServer) - if err := mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW); err != nil { - utils.Fatalf("Failed to init MailServer: %s", err) - } - } - - server = &p2p.Server{ - Config: p2p.Config{ - PrivateKey: nodeid, - MaxPeers: maxPeers, - Name: common.MakeName("wnode", "6.0"), - Protocols: shh.Protocols(), - ListenAddr: *argIP, - NAT: nat.Any(), - BootstrapNodes: peers, - StaticNodes: peers, - TrustedNodes: peers, - }, - } -} - -func startServer() error { - err := server.Start() - if err != nil { - fmt.Printf("Failed to start Whisper peer: %s.", err) - return err - } - - fmt.Printf("my public key: %s \n", hexutil.Encode(crypto.FromECDSAPub(&asymKey.PublicKey))) - fmt.Println(server.NodeInfo().Enode) - - if *bootstrapMode { - configureNode() - fmt.Println("Bootstrap Whisper node started") - } else { - fmt.Println("Whisper node started") - // first see if we can establish connection, then ask for user input - waitForConnection(true) - configureNode() - } - - if *fileExMode { - fmt.Printf("Please type the file name to be send. To quit type: '%s'\n", quitCommand) - } else if *fileReader { - fmt.Printf("Please type the file name to be decrypted. To quit type: '%s'\n", quitCommand) - } else if !*forwarderMode { - fmt.Printf("Please type the message. To quit type: '%s'\n", quitCommand) - } - return nil -} - -func configureNode() { - var err error - var p2pAccept bool - - if *forwarderMode { - return - } - - if *asymmetricMode { - if len(*argPub) == 0 { - s := scanLine("Please enter the peer's public key: ") - b := common.FromHex(s) - if b == nil { - utils.Fatalf("Error: can not convert hexadecimal string") - } - if pub, err = crypto.UnmarshalPubkey(b); err != nil { - utils.Fatalf("Error: invalid peer public key") - } - } - } - - if *requestMail { - p2pAccept = true - if len(msPassword) == 0 { - msPassword, err = prompt.Stdin.PromptPassword("Please enter the Mail Server password: ") - if err != nil { - utils.Fatalf("Failed to read Mail Server password: %s", err) - } - } - } - - if !*asymmetricMode && !*forwarderMode { - if len(symPass) == 0 { - symPass, err = prompt.Stdin.PromptPassword("Please enter the password for symmetric encryption: ") - if err != nil { - utils.Fatalf("Failed to read password: %v", err) - } - } - - symKeyID, err := shh.AddSymKeyFromPassword(symPass) - if err != nil { - utils.Fatalf("Failed to create symmetric key: %s", err) - } - symKey, err = shh.GetSymKey(symKeyID) - if err != nil { - utils.Fatalf("Failed to save symmetric key: %s", err) - } - if len(*argTopic) == 0 { - generateTopic([]byte(symPass)) - } - - fmt.Printf("Filter is configured for the topic: %x \n", topic) - } - - if *mailServerMode { - if len(*argDBPath) == 0 { - argDBPath = scanLineA("Please enter the path to DB file: ") - } - } - - symFilter := whisper.Filter{ - KeySym: symKey, - Topics: [][]byte{topic[:]}, - AllowP2P: p2pAccept, - } - symFilterID, err = shh.Subscribe(&symFilter) - if err != nil { - utils.Fatalf("Failed to install filter: %s", err) - } - - asymFilter := whisper.Filter{ - KeyAsym: asymKey, - Topics: [][]byte{topic[:]}, - AllowP2P: p2pAccept, - } - asymFilterID, err = shh.Subscribe(&asymFilter) - if err != nil { - utils.Fatalf("Failed to install filter: %s", err) - } -} - -func generateTopic(password []byte) { - x := pbkdf2.Key(password, password, 4096, 128, sha512.New) - for i := 0; i < len(x); i++ { - topic[i%whisper.TopicLength] ^= x[i] - } -} - -func waitForConnection(timeout bool) { - var cnt int - var connected bool - for !connected { - time.Sleep(time.Millisecond * 50) - connected = server.PeerCount() > 0 - if timeout { - cnt++ - if cnt > 1000 { - utils.Fatalf("Timeout expired, failed to connect") - } - } - } - - fmt.Println("Connected to peer.") -} - -func run() { - err := startServer() - if err != nil { - return - } - defer server.Stop() - shh.Start() - defer shh.Stop() - - if !*forwarderMode { - go messageLoop() - } - - if *requestMail { - requestExpiredMessagesLoop() - } else if *fileExMode { - sendFilesLoop() - } else if *fileReader { - fileReaderLoop() - } else { - sendLoop() - } -} - -func shutdown() { - close(done) - mailServer.Close() -} - -func sendLoop() { - for { - s := scanLine("") - if s == quitCommand { - fmt.Println("Quit command received") - return - } - sendMsg([]byte(s)) - if *asymmetricMode { - // print your own message for convenience, - // because in asymmetric mode it is impossible to decrypt it - timestamp := time.Now().Unix() - from := crypto.PubkeyToAddress(asymKey.PublicKey) - fmt.Printf("\n%d <%x>: %s\n", timestamp, from, s) - } - } -} - -func sendFilesLoop() { - for { - s := scanLine("") - if s == quitCommand { - fmt.Println("Quit command received") - return - } - b, err := ioutil.ReadFile(s) - if err != nil { - fmt.Printf(">>> Error: %s \n", err) - } else { - h := sendMsg(b) - if (h == common.Hash{}) { - fmt.Printf(">>> Error: message was not sent \n") - } else { - timestamp := time.Now().Unix() - from := crypto.PubkeyToAddress(asymKey.PublicKey) - fmt.Printf("\n%d <%x>: sent message with hash %x\n", timestamp, from, h) - } - } - } -} - -func fileReaderLoop() { - watcher1 := shh.GetFilter(symFilterID) - watcher2 := shh.GetFilter(asymFilterID) - if watcher1 == nil && watcher2 == nil { - fmt.Println("Error: neither symmetric nor asymmetric filter is installed") - return - } - - for { - s := scanLine("") - if s == quitCommand { - fmt.Println("Quit command received") - return - } - raw, err := ioutil.ReadFile(s) - if err != nil { - fmt.Printf(">>> Error: %s \n", err) - } else { - env := whisper.Envelope{Data: raw} // the topic is zero - msg := env.Open(watcher1) // force-open envelope regardless of the topic - if msg == nil { - msg = env.Open(watcher2) - } - if msg == nil { - fmt.Printf(">>> Error: failed to decrypt the message \n") - } else { - printMessageInfo(msg) - } - } - } -} - -func scanLine(prompt string) string { - if len(prompt) > 0 { - fmt.Print(prompt) - } - txt, err := input.ReadString('\n') - if err != nil { - utils.Fatalf("input error: %s", err) - } - txt = strings.TrimRight(txt, "\n\r") - return txt -} - -func scanLineA(prompt string) *string { - s := scanLine(prompt) - return &s -} - -func scanUint(prompt string) uint32 { - s := scanLine(prompt) - i, err := strconv.Atoi(s) - if err != nil { - utils.Fatalf("Fail to parse the lower time limit: %s", err) - } - return uint32(i) -} - -func sendMsg(payload []byte) common.Hash { - params := whisper.MessageParams{ - Src: asymKey, - Dst: pub, - KeySym: symKey, - Payload: payload, - Topic: topic, - TTL: uint32(*argTTL), - PoW: *argPoW, - WorkTime: uint32(*argWorkTime), - } - - msg, err := whisper.NewSentMessage(¶ms) - if err != nil { - utils.Fatalf("failed to create new message: %s", err) - } - - envelope, err := msg.Wrap(¶ms) - if err != nil { - fmt.Printf("failed to seal message: %v \n", err) - return common.Hash{} - } - - err = shh.Send(envelope) - if err != nil { - fmt.Printf("failed to send message: %v \n", err) - return common.Hash{} - } - - return envelope.Hash() -} - -func messageLoop() { - sf := shh.GetFilter(symFilterID) - if sf == nil { - utils.Fatalf("symmetric filter is not installed") - } - - af := shh.GetFilter(asymFilterID) - if af == nil { - utils.Fatalf("asymmetric filter is not installed") - } - - ticker := time.NewTicker(time.Millisecond * 50) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - m1 := sf.Retrieve() - m2 := af.Retrieve() - messages := append(m1, m2...) - for _, msg := range messages { - reportedOnce := false - if !*fileExMode && len(msg.Payload) <= 2048 { - printMessageInfo(msg) - reportedOnce = true - } - - // All messages are saved upon specifying argSaveDir. - // fileExMode only specifies how messages are displayed on the console after they are saved. - // if fileExMode == true, only the hashes are displayed, since messages might be too big. - if len(*argSaveDir) > 0 { - writeMessageToFile(*argSaveDir, msg, !reportedOnce) - } - } - case <-done: - return - } - } -} - -func printMessageInfo(msg *whisper.ReceivedMessage) { - timestamp := fmt.Sprintf("%d", msg.Sent) // unix timestamp for diagnostics - text := string(msg.Payload) - - var address common.Address - if msg.Src != nil { - address = crypto.PubkeyToAddress(*msg.Src) - } - - if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) { - fmt.Printf("\n%s <%x>: %s\n", timestamp, address, text) // message from myself - } else { - fmt.Printf("\n%s [%x]: %s\n", timestamp, address, text) // message from a peer - } -} - -func writeMessageToFile(dir string, msg *whisper.ReceivedMessage, show bool) { - if len(dir) == 0 { - return - } - - timestamp := fmt.Sprintf("%d", msg.Sent) - name := fmt.Sprintf("%x", msg.EnvelopeHash) - - var address common.Address - if msg.Src != nil { - address = crypto.PubkeyToAddress(*msg.Src) - } - - env := shh.GetEnvelope(msg.EnvelopeHash) - if env == nil { - fmt.Printf("\nUnexpected error: envelope not found: %x\n", msg.EnvelopeHash) - return - } - - // this is a sample code; uncomment if you don't want to save your own messages. - //if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) { - // fmt.Printf("\n%s <%x>: message from myself received, not saved: '%s'\n", timestamp, address, name) - // return - //} - - fullpath := filepath.Join(dir, name) - err := ioutil.WriteFile(fullpath, env.Data, 0644) - if err != nil { - fmt.Printf("\n%s {%x}: message received but not saved: %s\n", timestamp, address, err) - } else if show { - fmt.Printf("\n%s {%x}: message received and saved as '%s' (%d bytes)\n", timestamp, address, name, len(env.Data)) - } -} - -func requestExpiredMessagesLoop() { - var key, peerID, bloom []byte - var timeLow, timeUpp uint32 - var t string - var xt whisper.TopicType - - keyID, err := shh.AddSymKeyFromPassword(msPassword) - if err != nil { - utils.Fatalf("Failed to create symmetric key for mail request: %s", err) - } - key, err = shh.GetSymKey(keyID) - if err != nil { - utils.Fatalf("Failed to save symmetric key for mail request: %s", err) - } - peerID = extractIDFromEnode(*argEnode) - shh.AllowP2PMessagesFromPeer(peerID) - - for { - timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ") - timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ") - t = scanLine("Enter the topic (hex). Press enter to request all messages, regardless of the topic: ") - if len(t) == whisper.TopicLength*2 { - x, err := hex.DecodeString(t) - if err != nil { - fmt.Printf("Failed to parse the topic: %s \n", err) - continue - } - xt = whisper.BytesToTopic(x) - bloom = whisper.TopicToBloom(xt) - obfuscateBloom(bloom) - } else if len(t) == 0 { - bloom = whisper.MakeFullNodeBloom() - } else { - fmt.Println("Error: topic is invalid, request aborted") - continue - } - - if timeUpp == 0 { - timeUpp = 0xFFFFFFFF - } - - data := make([]byte, 8, 8+whisper.BloomFilterSize) - binary.BigEndian.PutUint32(data, timeLow) - binary.BigEndian.PutUint32(data[4:], timeUpp) - data = append(data, bloom...) - - var params whisper.MessageParams - params.PoW = *argServerPoW - params.Payload = data - params.KeySym = key - params.Src = asymKey - params.WorkTime = 5 - - msg, err := whisper.NewSentMessage(¶ms) - if err != nil { - utils.Fatalf("failed to create new message: %s", err) - } - env, err := msg.Wrap(¶ms) - if err != nil { - utils.Fatalf("Wrap failed: %s", err) - } - - err = shh.RequestHistoricMessages(peerID, env) - if err != nil { - utils.Fatalf("Failed to send P2P message: %s", err) - } - - time.Sleep(time.Second * 5) - } -} - -func extractIDFromEnode(s string) []byte { - n, err := enode.Parse(enode.ValidSchemes, s) - if err != nil { - utils.Fatalf("Failed to parse node: %s", err) - } - return n.ID().Bytes() -} - -// obfuscateBloom adds 16 random bits to the bloom -// filter, in order to obfuscate the containing topics. -// it does so deterministically within every session. -// despite additional bits, it will match on average -// 32000 times less messages than full node's bloom filter. -func obfuscateBloom(bloom []byte) { - const half = entropySize / 2 - for i := 0; i < half; i++ { - x := int(entropy[i]) - if entropy[half+i] < 128 { - x += 256 - } - - bloom[x/8] = 1 << uint(x%8) // set the bit number X - } -} diff --git a/mobile/geth.go b/mobile/geth.go index d614f8eb36..ba58507d63 100644 --- a/mobile/geth.go +++ b/mobile/geth.go @@ -35,7 +35,6 @@ import ( "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/params" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" ) // NodeConfig represents the collection of configuration values to fine tune the Geth @@ -71,9 +70,6 @@ type NodeConfig struct { // It has the form "nodename:secret@host:port" EthereumNetStats string - // WhisperEnabled specifies whether the node should run the Whisper protocol. - WhisperEnabled bool - // Listening address of pprof server. PprofAddress string } @@ -186,12 +182,6 @@ func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) { } } } - // Register the Whisper protocol if requested - if config.WhisperEnabled { - if _, err := whisper.New(rawStack, &whisper.DefaultConfig); err != nil { - return nil, fmt.Errorf("whisper init: %v", err) - } - } return &Node{rawStack}, nil } diff --git a/mobile/shhclient.go b/mobile/shhclient.go deleted file mode 100644 index 90a8b83c39..0000000000 --- a/mobile/shhclient.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Contains a wrapper for the Whisper client. - -package geth - -import ( - "github.com/ethereum/go-ethereum/whisper/shhclient" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" -) - -// WhisperClient provides access to the Ethereum APIs. -type WhisperClient struct { - client *shhclient.Client -} - -// NewWhisperClient connects a client to the given URL. -func NewWhisperClient(rawurl string) (client *WhisperClient, _ error) { - rawClient, err := shhclient.Dial(rawurl) - return &WhisperClient{rawClient}, err -} - -// GetVersion returns the Whisper sub-protocol version. -func (wc *WhisperClient) GetVersion(ctx *Context) (version string, _ error) { - return wc.client.Version(ctx.context) -} - -// Info returns diagnostic information about the whisper node. -func (wc *WhisperClient) GetInfo(ctx *Context) (info *Info, _ error) { - rawInfo, err := wc.client.Info(ctx.context) - return &Info{&rawInfo}, err -} - -// SetMaxMessageSize sets the maximal message size allowed by this node. Incoming -// and outgoing messages with a larger size will be rejected. Whisper message size -// can never exceed the limit imposed by the underlying P2P protocol (10 Mb). -func (wc *WhisperClient) SetMaxMessageSize(ctx *Context, size int32) error { - return wc.client.SetMaxMessageSize(ctx.context, uint32(size)) -} - -// SetMinimumPoW (experimental) sets the minimal PoW required by this node. -// This experimental function was introduced for the future dynamic adjustment of -// PoW requirement. If the node is overwhelmed with messages, it should raise the -// PoW requirement and notify the peers. The new value should be set relative to -// the old value (e.g. double). The old value could be obtained via shh_info call. -func (wc *WhisperClient) SetMinimumPoW(ctx *Context, pow float64) error { - return wc.client.SetMinimumPoW(ctx.context, pow) -} - -// Marks specific peer trusted, which will allow it to send historic (expired) messages. -// Note This function is not adding new nodes, the node needs to exists as a peer. -func (wc *WhisperClient) MarkTrustedPeer(ctx *Context, enode string) error { - return wc.client.MarkTrustedPeer(ctx.context, enode) -} - -// NewKeyPair generates a new public and private key pair for message decryption and encryption. -// It returns an identifier that can be used to refer to the key. -func (wc *WhisperClient) NewKeyPair(ctx *Context) (string, error) { - return wc.client.NewKeyPair(ctx.context) -} - -// AddPrivateKey stored the key pair, and returns its ID. -func (wc *WhisperClient) AddPrivateKey(ctx *Context, key []byte) (string, error) { - return wc.client.AddPrivateKey(ctx.context, key) -} - -// DeleteKeyPair delete the specifies key. -func (wc *WhisperClient) DeleteKeyPair(ctx *Context, id string) (string, error) { - return wc.client.DeleteKeyPair(ctx.context, id) -} - -// HasKeyPair returns an indication if the node has a private key or -// key pair matching the given ID. -func (wc *WhisperClient) HasKeyPair(ctx *Context, id string) (bool, error) { - return wc.client.HasKeyPair(ctx.context, id) -} - -// GetPublicKey return the public key for a key ID. -func (wc *WhisperClient) GetPublicKey(ctx *Context, id string) ([]byte, error) { - return wc.client.PublicKey(ctx.context, id) -} - -// GetPrivateKey return the private key for a key ID. -func (wc *WhisperClient) GetPrivateKey(ctx *Context, id string) ([]byte, error) { - return wc.client.PrivateKey(ctx.context, id) -} - -// NewSymmetricKey generates a random symmetric key and returns its identifier. -// Can be used encrypting and decrypting messages where the key is known to both parties. -func (wc *WhisperClient) NewSymmetricKey(ctx *Context) (string, error) { - return wc.client.NewSymmetricKey(ctx.context) -} - -// AddSymmetricKey stores the key, and returns its identifier. -func (wc *WhisperClient) AddSymmetricKey(ctx *Context, key []byte) (string, error) { - return wc.client.AddSymmetricKey(ctx.context, key) -} - -// GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier. -func (wc *WhisperClient) GenerateSymmetricKeyFromPassword(ctx *Context, passwd string) (string, error) { - return wc.client.GenerateSymmetricKeyFromPassword(ctx.context, passwd) -} - -// HasSymmetricKey returns an indication if the key associated with the given id is stored in the node. -func (wc *WhisperClient) HasSymmetricKey(ctx *Context, id string) (bool, error) { - return wc.client.HasSymmetricKey(ctx.context, id) -} - -// GetSymmetricKey returns the symmetric key associated with the given identifier. -func (wc *WhisperClient) GetSymmetricKey(ctx *Context, id string) ([]byte, error) { - return wc.client.GetSymmetricKey(ctx.context, id) -} - -// DeleteSymmetricKey deletes the symmetric key associated with the given identifier. -func (wc *WhisperClient) DeleteSymmetricKey(ctx *Context, id string) error { - return wc.client.DeleteSymmetricKey(ctx.context, id) -} - -// Post a message onto the network. -func (wc *WhisperClient) Post(ctx *Context, message *NewMessage) (string, error) { - return wc.client.Post(ctx.context, *message.newMessage) -} - -// NewHeadHandler is a client-side subscription callback to invoke on events and -// subscription failure. -type NewMessageHandler interface { - OnNewMessage(message *Message) - OnError(failure string) -} - -// SubscribeMessages subscribes to messages that match the given criteria. This method -// is only supported on bi-directional connections such as websockets and IPC. -// NewMessageFilter uses polling and is supported over HTTP. -func (wc *WhisperClient) SubscribeMessages(ctx *Context, criteria *Criteria, handler NewMessageHandler, buffer int) (*Subscription, error) { - // Subscribe to the event internally - ch := make(chan *whisper.Message, buffer) - rawSub, err := wc.client.SubscribeMessages(ctx.context, *criteria.criteria, ch) - if err != nil { - return nil, err - } - // Start up a dispatcher to feed into the callback - go func() { - for { - select { - case message := <-ch: - handler.OnNewMessage(&Message{message}) - - case err := <-rawSub.Err(): - if err != nil { - handler.OnError(err.Error()) - } - return - } - } - }() - return &Subscription{rawSub}, nil -} - -// NewMessageFilter creates a filter within the node. This filter can be used to poll -// for new messages (see FilterMessages) that satisfy the given criteria. A filter can -// timeout when it was polled for in whisper.filterTimeout. -func (wc *WhisperClient) NewMessageFilter(ctx *Context, criteria *Criteria) (string, error) { - return wc.client.NewMessageFilter(ctx.context, *criteria.criteria) -} - -// DeleteMessageFilter removes the filter associated with the given id. -func (wc *WhisperClient) DeleteMessageFilter(ctx *Context, id string) error { - return wc.client.DeleteMessageFilter(ctx.context, id) -} - -// GetFilterMessages retrieves all messages that are received between the last call to -// this function and match the criteria that where given when the filter was created. -func (wc *WhisperClient) GetFilterMessages(ctx *Context, id string) (*Messages, error) { - rawFilterMessages, err := wc.client.FilterMessages(ctx.context, id) - if err != nil { - return nil, err - } - res := make([]*whisper.Message, len(rawFilterMessages)) - copy(res, rawFilterMessages) - return &Messages{res}, nil -} diff --git a/mobile/types.go b/mobile/types.go index b9c44c25d7..9d75520282 100644 --- a/mobile/types.go +++ b/mobile/types.go @@ -26,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" ) // A Nonce is a 64-bit hash which proves (combined with the mix-hash) that @@ -345,95 +344,3 @@ func (r *Receipt) GetLogs() *Logs { return &Logs{r.receipt.Logs} } func (r *Receipt) GetTxHash() *Hash { return &Hash{r.receipt.TxHash} } func (r *Receipt) GetContractAddress() *Address { return &Address{r.receipt.ContractAddress} } func (r *Receipt) GetGasUsed() int64 { return int64(r.receipt.GasUsed) } - -// Info represents a diagnostic information about the whisper node. -type Info struct { - info *whisper.Info -} - -// NewMessage represents a new whisper message that is posted through the RPC. -type NewMessage struct { - newMessage *whisper.NewMessage -} - -func NewNewMessage() *NewMessage { - nm := &NewMessage{ - newMessage: new(whisper.NewMessage), - } - return nm -} - -func (nm *NewMessage) GetSymKeyID() string { return nm.newMessage.SymKeyID } -func (nm *NewMessage) SetSymKeyID(symKeyID string) { nm.newMessage.SymKeyID = symKeyID } -func (nm *NewMessage) GetPublicKey() []byte { return nm.newMessage.PublicKey } -func (nm *NewMessage) SetPublicKey(publicKey []byte) { - nm.newMessage.PublicKey = common.CopyBytes(publicKey) -} -func (nm *NewMessage) GetSig() string { return nm.newMessage.Sig } -func (nm *NewMessage) SetSig(sig string) { nm.newMessage.Sig = sig } -func (nm *NewMessage) GetTTL() int64 { return int64(nm.newMessage.TTL) } -func (nm *NewMessage) SetTTL(ttl int64) { nm.newMessage.TTL = uint32(ttl) } -func (nm *NewMessage) GetPayload() []byte { return nm.newMessage.Payload } -func (nm *NewMessage) SetPayload(payload []byte) { nm.newMessage.Payload = common.CopyBytes(payload) } -func (nm *NewMessage) GetPowTime() int64 { return int64(nm.newMessage.PowTime) } -func (nm *NewMessage) SetPowTime(powTime int64) { nm.newMessage.PowTime = uint32(powTime) } -func (nm *NewMessage) GetPowTarget() float64 { return nm.newMessage.PowTarget } -func (nm *NewMessage) SetPowTarget(powTarget float64) { nm.newMessage.PowTarget = powTarget } -func (nm *NewMessage) GetTargetPeer() string { return nm.newMessage.TargetPeer } -func (nm *NewMessage) SetTargetPeer(targetPeer string) { nm.newMessage.TargetPeer = targetPeer } -func (nm *NewMessage) GetTopic() []byte { return nm.newMessage.Topic[:] } -func (nm *NewMessage) SetTopic(topic []byte) { nm.newMessage.Topic = whisper.BytesToTopic(topic) } - -// Message represents a whisper message. -type Message struct { - message *whisper.Message -} - -func (m *Message) GetSig() []byte { return m.message.Sig } -func (m *Message) GetTTL() int64 { return int64(m.message.TTL) } -func (m *Message) GetTimestamp() int64 { return int64(m.message.Timestamp) } -func (m *Message) GetPayload() []byte { return m.message.Payload } -func (m *Message) GetPoW() float64 { return m.message.PoW } -func (m *Message) GetHash() []byte { return m.message.Hash } -func (m *Message) GetDst() []byte { return m.message.Dst } - -// Messages represents an array of messages. -type Messages struct { - messages []*whisper.Message -} - -// Size returns the number of messages in the slice. -func (m *Messages) Size() int { - return len(m.messages) -} - -// Get returns the message at the given index from the slice. -func (m *Messages) Get(index int) (message *Message, _ error) { - if index < 0 || index >= len(m.messages) { - return nil, errors.New("index out of bounds") - } - return &Message{m.messages[index]}, nil -} - -// Criteria holds various filter options for inbound messages. -type Criteria struct { - criteria *whisper.Criteria -} - -func NewCriteria(topic []byte) *Criteria { - c := &Criteria{ - criteria: new(whisper.Criteria), - } - encodedTopic := whisper.BytesToTopic(topic) - c.criteria.Topics = []whisper.TopicType{encodedTopic} - return c -} - -func (c *Criteria) GetSymKeyID() string { return c.criteria.SymKeyID } -func (c *Criteria) SetSymKeyID(symKeyID string) { c.criteria.SymKeyID = symKeyID } -func (c *Criteria) GetPrivateKeyID() string { return c.criteria.PrivateKeyID } -func (c *Criteria) SetPrivateKeyID(privateKeyID string) { c.criteria.PrivateKeyID = privateKeyID } -func (c *Criteria) GetSig() []byte { return c.criteria.Sig } -func (c *Criteria) SetSig(sig []byte) { c.criteria.Sig = common.CopyBytes(sig) } -func (c *Criteria) GetMinPow() float64 { return c.criteria.MinPow } -func (c *Criteria) SetMinPow(pow float64) { c.criteria.MinPow = pow } diff --git a/tests/fuzzers/whisperv6/corpus/009c5adfa4fd685caef58e1ce932fa7fb209730a b/tests/fuzzers/whisperv6/corpus/009c5adfa4fd685caef58e1ce932fa7fb209730a deleted file mode 100644 index af2f0826730441cc5abb122074afd090fad2eb95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61 XcmaEK>c|9A!Hu2QZfJ0QyTbqgS<53t diff --git a/tests/fuzzers/whisperv6/whisper-fuzzer.go b/tests/fuzzers/whisperv6/whisper-fuzzer.go deleted file mode 100644 index 379e4224fd..0000000000 --- a/tests/fuzzers/whisperv6/whisper-fuzzer.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "bytes" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/whisper/whisperv6" -) - -type MessageParams struct { - Topic whisperv6.TopicType - WorkTime uint32 - TTL uint32 - KeySym []byte - Payload []byte -} - -//export fuzzer_entry -func Fuzz(input []byte) int { - - var paramsDecoded MessageParams - err := rlp.DecodeBytes(input, ¶msDecoded) - if err != nil { - return 0 - } - var params whisperv6.MessageParams - params.KeySym = make([]byte, 32) - if len(paramsDecoded.KeySym) <= 32 { - copy(params.KeySym, paramsDecoded.KeySym) - } - if input[0] == 255 { - params.PoW = 0.01 - params.WorkTime = 1 - } else { - params.PoW = 0 - params.WorkTime = 0 - } - params.TTL = paramsDecoded.TTL - params.Payload = paramsDecoded.Payload - text := make([]byte, 0, 512) - text = append(text, params.Payload...) - params.Topic = paramsDecoded.Topic - params.Src, err = crypto.GenerateKey() - if err != nil { - return 0 - } - msg, err := whisperv6.NewSentMessage(¶ms) - if err != nil { - panic(err) - //return - } - env, err := msg.Wrap(¶ms) - if err != nil { - panic(err) - } - decrypted, err := env.OpenSymmetric(params.KeySym) - if err != nil { - panic(err) - } - if !decrypted.ValidateAndParse() { - panic("ValidateAndParse failed") - } - if !bytes.Equal(text, decrypted.Payload) { - panic("text != decrypted.Payload") - } - if len(decrypted.Signature) != 65 { - panic("Unexpected signature length") - } - if !whisperv6.IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { - panic("Unexpected public key") - } - return 0 -} diff --git a/whisper/mailserver/mailserver.go b/whisper/mailserver/mailserver.go deleted file mode 100644 index 7312bbe23d..0000000000 --- a/whisper/mailserver/mailserver.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package mailserver provides a naive, example mailserver implementation -package mailserver - -import ( - "encoding/binary" - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" -) - -// WMailServer represents the state data of the mailserver. -type WMailServer struct { - db *leveldb.DB - w *whisper.Whisper - pow float64 - key []byte -} - -type DBKey struct { - timestamp uint32 - hash common.Hash - raw []byte -} - -// NewDbKey is a helper function that creates a levelDB -// key from a hash and an integer. -func NewDbKey(t uint32, h common.Hash) *DBKey { - const sz = common.HashLength + 4 - var k DBKey - k.timestamp = t - k.hash = h - k.raw = make([]byte, sz) - binary.BigEndian.PutUint32(k.raw, k.timestamp) - copy(k.raw[4:], k.hash[:]) - return &k -} - -// Init initializes the mail server. -func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) error { - var err error - if len(path) == 0 { - return fmt.Errorf("DB file is not specified") - } - - if len(password) == 0 { - return fmt.Errorf("password is not specified") - } - - s.db, err = leveldb.OpenFile(path, &opt.Options{OpenFilesCacheCapacity: 32}) - if _, iscorrupted := err.(*errors.ErrCorrupted); iscorrupted { - s.db, err = leveldb.RecoverFile(path, nil) - } - if err != nil { - return fmt.Errorf("open DB file: %s", err) - } - - s.w = shh - s.pow = pow - - MailServerKeyID, err := s.w.AddSymKeyFromPassword(password) - if err != nil { - return fmt.Errorf("create symmetric key: %s", err) - } - s.key, err = s.w.GetSymKey(MailServerKeyID) - if err != nil { - return fmt.Errorf("save symmetric key: %s", err) - } - return nil -} - -// Close cleans up before shutdown. -func (s *WMailServer) Close() { - if s.db != nil { - s.db.Close() - } -} - -// Archive stores the -func (s *WMailServer) Archive(env *whisper.Envelope) { - key := NewDbKey(env.Expiry-env.TTL, env.Hash()) - rawEnvelope, err := rlp.EncodeToBytes(env) - if err != nil { - log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err)) - } else { - err = s.db.Put(key.raw, rawEnvelope, nil) - if err != nil { - log.Error(fmt.Sprintf("Writing to DB failed: %s", err)) - } - } -} - -// DeliverMail responds with saved messages upon request by the -// messages' owner. -func (s *WMailServer) DeliverMail(peer *whisper.Peer, request *whisper.Envelope) { - if peer == nil { - log.Error("Whisper peer is nil") - return - } - - ok, lower, upper, bloom := s.validateRequest(peer.ID(), request) - if ok { - s.processRequest(peer, lower, upper, bloom) - } -} - -func (s *WMailServer) processRequest(peer *whisper.Peer, lower, upper uint32, bloom []byte) []*whisper.Envelope { - ret := make([]*whisper.Envelope, 0) - var err error - var zero common.Hash - kl := NewDbKey(lower, zero) - ku := NewDbKey(upper+1, zero) // LevelDB is exclusive, while the Whisper API is inclusive - i := s.db.NewIterator(&util.Range{Start: kl.raw, Limit: ku.raw}, nil) - defer i.Release() - - for i.Next() { - var envelope whisper.Envelope - err = rlp.DecodeBytes(i.Value(), &envelope) - if err != nil { - log.Error(fmt.Sprintf("RLP decoding failed: %s", err)) - } - - if whisper.BloomFilterMatch(bloom, envelope.Bloom()) { - if peer == nil { - // used for test purposes - ret = append(ret, &envelope) - } else { - err = s.w.SendP2PDirect(peer, &envelope) - if err != nil { - log.Error(fmt.Sprintf("Failed to send direct message to peer: %s", err)) - return nil - } - } - } - } - - err = i.Error() - if err != nil { - log.Error(fmt.Sprintf("Level DB iterator error: %s", err)) - } - - return ret -} - -func (s *WMailServer) validateRequest(peerID []byte, request *whisper.Envelope) (bool, uint32, uint32, []byte) { - if s.pow > 0.0 && request.PoW() < s.pow { - return false, 0, 0, nil - } - - f := whisper.Filter{KeySym: s.key} - decrypted := request.Open(&f) - if decrypted == nil { - log.Warn("Failed to decrypt p2p request") - return false, 0, 0, nil - } - - src := crypto.FromECDSAPub(decrypted.Src) - if len(src)-len(peerID) == 1 { - src = src[1:] - } - - // if you want to check the signature, you can do it here. e.g.: - // if !bytes.Equal(peerID, src) { - if src == nil { - log.Warn("Wrong signature of p2p request") - return false, 0, 0, nil - } - - var bloom []byte - payloadSize := len(decrypted.Payload) - if payloadSize < 8 { - log.Warn("Undersized p2p request") - return false, 0, 0, nil - } else if payloadSize == 8 { - bloom = whisper.MakeFullNodeBloom() - } else if payloadSize < 8+whisper.BloomFilterSize { - log.Warn("Undersized bloom filter in p2p request") - return false, 0, 0, nil - } else { - bloom = decrypted.Payload[8 : 8+whisper.BloomFilterSize] - } - - lower := binary.BigEndian.Uint32(decrypted.Payload[:4]) - upper := binary.BigEndian.Uint32(decrypted.Payload[4:8]) - return true, lower, upper, bloom -} diff --git a/whisper/mailserver/server_test.go b/whisper/mailserver/server_test.go deleted file mode 100644 index 069ec97d09..0000000000 --- a/whisper/mailserver/server_test.go +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package mailserver - -import ( - "bytes" - "crypto/ecdsa" - "encoding/binary" - "io/ioutil" - "math/rand" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/node" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" -) - -const powRequirement = 0.00001 - -var keyID string -var shh *whisper.Whisper -var seed = time.Now().Unix() - -type ServerTestParams struct { - topic whisper.TopicType - low uint32 - upp uint32 - key *ecdsa.PrivateKey -} - -func assert(statement bool, text string, t *testing.T) { - if !statement { - t.Fatal(text) - } -} - -func TestDBKey(t *testing.T) { - var h common.Hash - i := uint32(time.Now().Unix()) - k := NewDbKey(i, h) - assert(len(k.raw) == common.HashLength+4, "wrong DB key length", t) - assert(byte(i%0x100) == k.raw[3], "raw representation should be big endian", t) - assert(byte(i/0x1000000) == k.raw[0], "big endian expected", t) -} - -func generateEnvelope(t *testing.T) *whisper.Envelope { - h := crypto.Keccak256Hash([]byte("test sample data")) - params := &whisper.MessageParams{ - KeySym: h[:], - Topic: whisper.TopicType{0x1F, 0x7E, 0xA1, 0x7F}, - Payload: []byte("test payload"), - PoW: powRequirement, - WorkTime: 2, - } - - msg, err := whisper.NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed to wrap with seed %d: %s.", seed, err) - } - return env -} - -func TestMailServer(t *testing.T) { - const password = "password_for_this_test" - const dbPath = "whisper-server-test" - - dir, err := ioutil.TempDir("", dbPath) - if err != nil { - t.Fatal(err) - } - - var server WMailServer - - stack, w := newNode(t) - defer stack.Close() - shh = w - - shh.RegisterServer(&server) - - err = server.Init(shh, dir, password, powRequirement) - if err != nil { - t.Fatal(err) - } - defer server.Close() - - keyID, err = shh.AddSymKeyFromPassword(password) - if err != nil { - t.Fatalf("Failed to create symmetric key for mail request: %s", err) - } - - rand.Seed(seed) - env := generateEnvelope(t) - server.Archive(env) - deliverTest(t, &server, env) -} - -func deliverTest(t *testing.T, server *WMailServer, env *whisper.Envelope) { - id, err := shh.NewKeyPair() - if err != nil { - t.Fatalf("failed to generate new key pair with seed %d: %s.", seed, err) - } - testPeerID, err := shh.GetPrivateKey(id) - if err != nil { - t.Fatalf("failed to retrieve new key pair with seed %d: %s.", seed, err) - } - birth := env.Expiry - env.TTL - p := &ServerTestParams{ - topic: env.Topic, - low: birth - 1, - upp: birth + 1, - key: testPeerID, - } - - singleRequest(t, server, env, p, true) - - p.low, p.upp = birth+1, 0xffffffff - singleRequest(t, server, env, p, false) - - p.low, p.upp = 0, birth-1 - singleRequest(t, server, env, p, false) - - p.low = birth - 1 - p.upp = birth + 1 - p.topic[0] = 0xFF - singleRequest(t, server, env, p, false) -} - -func singleRequest(t *testing.T, server *WMailServer, env *whisper.Envelope, p *ServerTestParams, expect bool) { - request := createRequest(t, p) - src := crypto.FromECDSAPub(&p.key.PublicKey) - ok, lower, upper, bloom := server.validateRequest(src, request) - if !ok { - t.Fatalf("request validation failed, seed: %d.", seed) - } - if lower != p.low { - t.Fatalf("request validation failed (lower bound), seed: %d.", seed) - } - if upper != p.upp { - t.Fatalf("request validation failed (upper bound), seed: %d.", seed) - } - expectedBloom := whisper.TopicToBloom(p.topic) - if !bytes.Equal(bloom, expectedBloom) { - t.Fatalf("request validation failed (topic), seed: %d.", seed) - } - - var exist bool - mail := server.processRequest(nil, p.low, p.upp, bloom) - for _, msg := range mail { - if msg.Hash() == env.Hash() { - exist = true - break - } - } - - if exist != expect { - t.Fatalf("error: exist = %v, seed: %d.", exist, seed) - } - - src[0]++ - ok, lower, upper, _ = server.validateRequest(src, request) - if !ok { - // request should be valid regardless of signature - t.Fatalf("request validation false negative, seed: %d (lower: %d, upper: %d).", seed, lower, upper) - } -} - -func createRequest(t *testing.T, p *ServerTestParams) *whisper.Envelope { - bloom := whisper.TopicToBloom(p.topic) - data := make([]byte, 8) - binary.BigEndian.PutUint32(data, p.low) - binary.BigEndian.PutUint32(data[4:], p.upp) - data = append(data, bloom...) - - key, err := shh.GetSymKey(keyID) - if err != nil { - t.Fatalf("failed to retrieve sym key with seed %d: %s.", seed, err) - } - - params := &whisper.MessageParams{ - KeySym: key, - Topic: p.topic, - Payload: data, - PoW: powRequirement * 2, - WorkTime: 2, - Src: p.key, - } - - msg, err := whisper.NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed to wrap with seed %d: %s.", seed, err) - } - return env -} - -// newNode creates a new node using a default config and -// creates and registers a new Whisper service on it. -func newNode(t *testing.T) (*node.Node, *whisper.Whisper) { - stack, err := node.New(&node.DefaultConfig) - if err != nil { - t.Fatalf("could not create new node: %v", err) - } - w, err := whisper.New(stack, &whisper.DefaultConfig) - if err != nil { - t.Fatalf("could not create new whisper service: %v", err) - } - err = stack.Start() - if err != nil { - t.Fatalf("could not start node: %v", err) - } - return stack, w -} diff --git a/whisper/shhclient/client.go b/whisper/shhclient/client.go deleted file mode 100644 index 4973113674..0000000000 --- a/whisper/shhclient/client.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package shhclient - -import ( - "context" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rpc" - whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" -) - -// Client defines typed wrappers for the Whisper v6 RPC API. -type Client struct { - c *rpc.Client -} - -// Dial connects a client to the given URL. -func Dial(rawurl string) (*Client, error) { - c, err := rpc.Dial(rawurl) - if err != nil { - return nil, err - } - return NewClient(c), nil -} - -// NewClient creates a client that uses the given RPC client. -func NewClient(c *rpc.Client) *Client { - return &Client{c} -} - -// Version returns the Whisper sub-protocol version. -func (sc *Client) Version(ctx context.Context) (string, error) { - var result string - err := sc.c.CallContext(ctx, &result, "shh_version") - return result, err -} - -// Info returns diagnostic information about the whisper node. -func (sc *Client) Info(ctx context.Context) (whisper.Info, error) { - var info whisper.Info - err := sc.c.CallContext(ctx, &info, "shh_info") - return info, err -} - -// SetMaxMessageSize sets the maximal message size allowed by this node. Incoming -// and outgoing messages with a larger size will be rejected. Whisper message size -// can never exceed the limit imposed by the underlying P2P protocol (10 Mb). -func (sc *Client) SetMaxMessageSize(ctx context.Context, size uint32) error { - var ignored bool - return sc.c.CallContext(ctx, &ignored, "shh_setMaxMessageSize", size) -} - -// SetMinimumPoW (experimental) sets the minimal PoW required by this node. -// This experimental function was introduced for the future dynamic adjustment of -// PoW requirement. If the node is overwhelmed with messages, it should raise the -// PoW requirement and notify the peers. The new value should be set relative to -// the old value (e.g. double). The old value could be obtained via shh_info call. -func (sc *Client) SetMinimumPoW(ctx context.Context, pow float64) error { - var ignored bool - return sc.c.CallContext(ctx, &ignored, "shh_setMinPoW", pow) -} - -// MarkTrustedPeer marks specific peer trusted, which will allow it to send historic (expired) messages. -// Note This function is not adding new nodes, the node needs to exists as a peer. -func (sc *Client) MarkTrustedPeer(ctx context.Context, enode string) error { - var ignored bool - return sc.c.CallContext(ctx, &ignored, "shh_markTrustedPeer", enode) -} - -// NewKeyPair generates a new public and private key pair for message decryption and encryption. -// It returns an identifier that can be used to refer to the key. -func (sc *Client) NewKeyPair(ctx context.Context) (string, error) { - var id string - return id, sc.c.CallContext(ctx, &id, "shh_newKeyPair") -} - -// AddPrivateKey stored the key pair, and returns its ID. -func (sc *Client) AddPrivateKey(ctx context.Context, key []byte) (string, error) { - var id string - return id, sc.c.CallContext(ctx, &id, "shh_addPrivateKey", hexutil.Bytes(key)) -} - -// DeleteKeyPair delete the specifies key. -func (sc *Client) DeleteKeyPair(ctx context.Context, id string) (string, error) { - var ignored bool - return id, sc.c.CallContext(ctx, &ignored, "shh_deleteKeyPair", id) -} - -// HasKeyPair returns an indication if the node has a private key or -// key pair matching the given ID. -func (sc *Client) HasKeyPair(ctx context.Context, id string) (bool, error) { - var has bool - return has, sc.c.CallContext(ctx, &has, "shh_hasKeyPair", id) -} - -// PublicKey return the public key for a key ID. -func (sc *Client) PublicKey(ctx context.Context, id string) ([]byte, error) { - var key hexutil.Bytes - return []byte(key), sc.c.CallContext(ctx, &key, "shh_getPublicKey", id) -} - -// PrivateKey return the private key for a key ID. -func (sc *Client) PrivateKey(ctx context.Context, id string) ([]byte, error) { - var key hexutil.Bytes - return []byte(key), sc.c.CallContext(ctx, &key, "shh_getPrivateKey", id) -} - -// NewSymmetricKey generates a random symmetric key and returns its identifier. -// Can be used encrypting and decrypting messages where the key is known to both parties. -func (sc *Client) NewSymmetricKey(ctx context.Context) (string, error) { - var id string - return id, sc.c.CallContext(ctx, &id, "shh_newSymKey") -} - -// AddSymmetricKey stores the key, and returns its identifier. -func (sc *Client) AddSymmetricKey(ctx context.Context, key []byte) (string, error) { - var id string - return id, sc.c.CallContext(ctx, &id, "shh_addSymKey", hexutil.Bytes(key)) -} - -// GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier. -func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd string) (string, error) { - var id string - return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", passwd) -} - -// HasSymmetricKey returns an indication if the key associated with the given id is stored in the node. -func (sc *Client) HasSymmetricKey(ctx context.Context, id string) (bool, error) { - var found bool - return found, sc.c.CallContext(ctx, &found, "shh_hasSymKey", id) -} - -// GetSymmetricKey returns the symmetric key associated with the given identifier. -func (sc *Client) GetSymmetricKey(ctx context.Context, id string) ([]byte, error) { - var key hexutil.Bytes - return []byte(key), sc.c.CallContext(ctx, &key, "shh_getSymKey", id) -} - -// DeleteSymmetricKey deletes the symmetric key associated with the given identifier. -func (sc *Client) DeleteSymmetricKey(ctx context.Context, id string) error { - var ignored bool - return sc.c.CallContext(ctx, &ignored, "shh_deleteSymKey", id) -} - -// Post a message onto the network. -func (sc *Client) Post(ctx context.Context, message whisper.NewMessage) (string, error) { - var hash string - return hash, sc.c.CallContext(ctx, &hash, "shh_post", message) -} - -// SubscribeMessages subscribes to messages that match the given criteria. This method -// is only supported on bi-directional connections such as websockets and IPC. -// NewMessageFilter uses polling and is supported over HTTP. -func (sc *Client) SubscribeMessages(ctx context.Context, criteria whisper.Criteria, ch chan<- *whisper.Message) (ethereum.Subscription, error) { - return sc.c.ShhSubscribe(ctx, ch, "messages", criteria) -} - -// NewMessageFilter creates a filter within the node. This filter can be used to poll -// for new messages (see FilterMessages) that satisfy the given criteria. A filter can -// timeout when it was polled for in whisper.filterTimeout. -func (sc *Client) NewMessageFilter(ctx context.Context, criteria whisper.Criteria) (string, error) { - var id string - return id, sc.c.CallContext(ctx, &id, "shh_newMessageFilter", criteria) -} - -// DeleteMessageFilter removes the filter associated with the given id. -func (sc *Client) DeleteMessageFilter(ctx context.Context, id string) error { - var ignored bool - return sc.c.CallContext(ctx, &ignored, "shh_deleteMessageFilter", id) -} - -// FilterMessages retrieves all messages that are received between the last call to -// this function and match the criteria that where given when the filter was created. -func (sc *Client) FilterMessages(ctx context.Context, id string) ([]*whisper.Message, error) { - var messages []*whisper.Message - return messages, sc.c.CallContext(ctx, &messages, "shh_getFilterMessages", id) -} diff --git a/whisper/whisperv6/api.go b/whisper/whisperv6/api.go deleted file mode 100644 index d6d4c8d3de..0000000000 --- a/whisper/whisperv6/api.go +++ /dev/null @@ -1,593 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "context" - "crypto/ecdsa" - "errors" - "fmt" - "sync" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/rpc" -) - -// List of errors -var ( - ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key") - ErrInvalidSymmetricKey = errors.New("invalid symmetric key") - ErrInvalidPublicKey = errors.New("invalid public key") - ErrInvalidSigningPubKey = errors.New("invalid signing public key") - ErrTooLowPoW = errors.New("message rejected, PoW too low") - ErrNoTopics = errors.New("missing topic(s)") -) - -// PublicWhisperAPI provides the whisper RPC service that can be -// use publicly without security implications. -type PublicWhisperAPI struct { - w *Whisper - - mu sync.Mutex - lastUsed map[string]time.Time // keeps track when a filter was polled for the last time. -} - -// NewPublicWhisperAPI create a new RPC whisper service. -func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI { - api := &PublicWhisperAPI{ - w: w, - lastUsed: make(map[string]time.Time), - } - return api -} - -// Version returns the Whisper sub-protocol version. -func (api *PublicWhisperAPI) Version(ctx context.Context) string { - return ProtocolVersionStr -} - -// Info contains diagnostic information. -type Info struct { - Memory int `json:"memory"` // Memory size of the floating messages in bytes. - Messages int `json:"messages"` // Number of floating messages. - MinPow float64 `json:"minPow"` // Minimal accepted PoW - MaxMessageSize uint32 `json:"maxMessageSize"` // Maximum accepted message size -} - -// Info returns diagnostic information about the whisper node. -func (api *PublicWhisperAPI) Info(ctx context.Context) Info { - stats := api.w.Stats() - return Info{ - Memory: stats.memoryUsed, - Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue), - MinPow: api.w.MinPow(), - MaxMessageSize: api.w.MaxMessageSize(), - } -} - -// SetMaxMessageSize sets the maximum message size that is accepted. -// Upper limit is defined by MaxMessageSize. -func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32) (bool, error) { - return true, api.w.SetMaxMessageSize(size) -} - -// SetMinPoW sets the minimum PoW, and notifies the peers. -func (api *PublicWhisperAPI) SetMinPoW(ctx context.Context, pow float64) (bool, error) { - return true, api.w.SetMinimumPoW(pow) -} - -// SetBloomFilter sets the new value of bloom filter, and notifies the peers. -func (api *PublicWhisperAPI) SetBloomFilter(ctx context.Context, bloom hexutil.Bytes) (bool, error) { - return true, api.w.SetBloomFilter(bloom) -} - -// MarkTrustedPeer marks a peer trusted, which will allow it to send historic (expired) messages. -// Note: This function is not adding new nodes, the node needs to exists as a peer. -func (api *PublicWhisperAPI) MarkTrustedPeer(ctx context.Context, url string) (bool, error) { - n, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - return false, err - } - return true, api.w.AllowP2PMessagesFromPeer(n.ID().Bytes()) -} - -// NewKeyPair generates a new public and private key pair for message decryption and encryption. -// It returns an ID that can be used to refer to the keypair. -func (api *PublicWhisperAPI) NewKeyPair(ctx context.Context) (string, error) { - return api.w.NewKeyPair() -} - -// AddPrivateKey imports the given private key. -func (api *PublicWhisperAPI) AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error) { - key, err := crypto.ToECDSA(privateKey) - if err != nil { - return "", err - } - return api.w.AddKeyPair(key) -} - -// DeleteKeyPair removes the key with the given key if it exists. -func (api *PublicWhisperAPI) DeleteKeyPair(ctx context.Context, key string) (bool, error) { - if ok := api.w.DeleteKeyPair(key); ok { - return true, nil - } - return false, fmt.Errorf("key pair %s not found", key) -} - -// HasKeyPair returns an indication if the node has a key pair that is associated with the given id. -func (api *PublicWhisperAPI) HasKeyPair(ctx context.Context, id string) bool { - return api.w.HasKeyPair(id) -} - -// GetPublicKey returns the public key associated with the given key. The key is the hex -// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62. -func (api *PublicWhisperAPI) GetPublicKey(ctx context.Context, id string) (hexutil.Bytes, error) { - key, err := api.w.GetPrivateKey(id) - if err != nil { - return hexutil.Bytes{}, err - } - return crypto.FromECDSAPub(&key.PublicKey), nil -} - -// GetPrivateKey returns the private key associated with the given key. The key is the hex -// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62. -func (api *PublicWhisperAPI) GetPrivateKey(ctx context.Context, id string) (hexutil.Bytes, error) { - key, err := api.w.GetPrivateKey(id) - if err != nil { - return hexutil.Bytes{}, err - } - return crypto.FromECDSA(key), nil -} - -// NewSymKey generate a random symmetric key. -// It returns an ID that can be used to refer to the key. -// Can be used encrypting and decrypting messages where the key is known to both parties. -func (api *PublicWhisperAPI) NewSymKey(ctx context.Context) (string, error) { - return api.w.GenerateSymKey() -} - -// AddSymKey import a symmetric key. -// It returns an ID that can be used to refer to the key. -// Can be used encrypting and decrypting messages where the key is known to both parties. -func (api *PublicWhisperAPI) AddSymKey(ctx context.Context, key hexutil.Bytes) (string, error) { - return api.w.AddSymKeyDirect([]byte(key)) -} - -// GenerateSymKeyFromPassword derive a key from the given password, stores it, and returns its ID. -func (api *PublicWhisperAPI) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) { - return api.w.AddSymKeyFromPassword(passwd) -} - -// HasSymKey returns an indication if the node has a symmetric key associated with the given key. -func (api *PublicWhisperAPI) HasSymKey(ctx context.Context, id string) bool { - return api.w.HasSymKey(id) -} - -// GetSymKey returns the symmetric key associated with the given id. -func (api *PublicWhisperAPI) GetSymKey(ctx context.Context, id string) (hexutil.Bytes, error) { - return api.w.GetSymKey(id) -} - -// DeleteSymKey deletes the symmetric key that is associated with the given id. -func (api *PublicWhisperAPI) DeleteSymKey(ctx context.Context, id string) bool { - return api.w.DeleteSymKey(id) -} - -// MakeLightClient turns the node into light client, which does not forward -// any incoming messages, and sends only messages originated in this node. -func (api *PublicWhisperAPI) MakeLightClient(ctx context.Context) bool { - api.w.SetLightClientMode(true) - return api.w.LightClientMode() -} - -// CancelLightClient cancels light client mode. -func (api *PublicWhisperAPI) CancelLightClient(ctx context.Context) bool { - api.w.SetLightClientMode(false) - return !api.w.LightClientMode() -} - -//go:generate gencodec -type NewMessage -field-override newMessageOverride -out gen_newmessage_json.go - -// NewMessage represents a new whisper message that is posted through the RPC. -type NewMessage struct { - SymKeyID string `json:"symKeyID"` - PublicKey []byte `json:"pubKey"` - Sig string `json:"sig"` - TTL uint32 `json:"ttl"` - Topic TopicType `json:"topic"` - Payload []byte `json:"payload"` - Padding []byte `json:"padding"` - PowTime uint32 `json:"powTime"` - PowTarget float64 `json:"powTarget"` - TargetPeer string `json:"targetPeer"` -} - -type newMessageOverride struct { - PublicKey hexutil.Bytes - Payload hexutil.Bytes - Padding hexutil.Bytes -} - -// Post posts a message on the Whisper network. -// returns the hash of the message in case of success. -func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (hexutil.Bytes, error) { - var ( - symKeyGiven = len(req.SymKeyID) > 0 - pubKeyGiven = len(req.PublicKey) > 0 - err error - ) - - // user must specify either a symmetric or an asymmetric key - if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) { - return nil, ErrSymAsym - } - - params := &MessageParams{ - TTL: req.TTL, - Payload: req.Payload, - Padding: req.Padding, - WorkTime: req.PowTime, - PoW: req.PowTarget, - Topic: req.Topic, - } - - // Set key that is used to sign the message - if len(req.Sig) > 0 { - if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil { - return nil, err - } - } - - // Set symmetric key that is used to encrypt the message - if symKeyGiven { - if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption - return nil, ErrNoTopics - } - if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil { - return nil, err - } - if !validateDataIntegrity(params.KeySym, aesKeyLength) { - return nil, ErrInvalidSymmetricKey - } - } - - // Set asymmetric key that is used to encrypt the message - if pubKeyGiven { - if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil { - return nil, ErrInvalidPublicKey - } - } - - // encrypt and sent message - whisperMsg, err := NewSentMessage(params) - if err != nil { - return nil, err - } - - var result []byte - env, err := whisperMsg.Wrap(params) - if err != nil { - return nil, err - } - - // send to specific node (skip PoW check) - if len(req.TargetPeer) > 0 { - n, err := enode.Parse(enode.ValidSchemes, req.TargetPeer) - if err != nil { - return nil, fmt.Errorf("failed to parse target peer: %s", err) - } - err = api.w.SendP2PMessage(n.ID().Bytes(), env) - if err == nil { - hash := env.Hash() - result = hash[:] - } - return result, err - } - - // ensure that the message PoW meets the node's minimum accepted PoW - if req.PowTarget < api.w.MinPow() { - return nil, ErrTooLowPoW - } - - err = api.w.Send(env) - if err == nil { - hash := env.Hash() - result = hash[:] - } - return result, err -} - -//go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go - -// Criteria holds various filter options for inbound messages. -type Criteria struct { - SymKeyID string `json:"symKeyID"` - PrivateKeyID string `json:"privateKeyID"` - Sig []byte `json:"sig"` - MinPow float64 `json:"minPow"` - Topics []TopicType `json:"topics"` - AllowP2P bool `json:"allowP2P"` -} - -type criteriaOverride struct { - Sig hexutil.Bytes -} - -// Messages set up a subscription that fires events when messages arrive that match -// the given set of criteria. -func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.Subscription, error) { - var ( - symKeyGiven = len(crit.SymKeyID) > 0 - pubKeyGiven = len(crit.PrivateKeyID) > 0 - err error - ) - - // ensure that the RPC connection supports subscriptions - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return nil, rpc.ErrNotificationsUnsupported - } - - // user must specify either a symmetric or an asymmetric key - if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) { - return nil, ErrSymAsym - } - - filter := Filter{ - PoW: crit.MinPow, - Messages: make(map[common.Hash]*ReceivedMessage), - AllowP2P: crit.AllowP2P, - } - - if len(crit.Sig) > 0 { - if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil { - return nil, ErrInvalidSigningPubKey - } - } - - for i, bt := range crit.Topics { - if len(bt) == 0 || len(bt) > 4 { - return nil, fmt.Errorf("subscribe: topic %d has wrong size: %d", i, len(bt)) - } - filter.Topics = append(filter.Topics, bt[:]) - } - - // listen for message that are encrypted with the given symmetric key - if symKeyGiven { - if len(filter.Topics) == 0 { - return nil, ErrNoTopics - } - key, err := api.w.GetSymKey(crit.SymKeyID) - if err != nil { - return nil, err - } - if !validateDataIntegrity(key, aesKeyLength) { - return nil, ErrInvalidSymmetricKey - } - filter.KeySym = key - filter.SymKeyHash = crypto.Keccak256Hash(filter.KeySym) - } - - // listen for messages that are encrypted with the given public key - if pubKeyGiven { - filter.KeyAsym, err = api.w.GetPrivateKey(crit.PrivateKeyID) - if err != nil || filter.KeyAsym == nil { - return nil, ErrInvalidPublicKey - } - } - - id, err := api.w.Subscribe(&filter) - if err != nil { - return nil, err - } - - // create subscription and start waiting for message events - rpcSub := notifier.CreateSubscription() - go func() { - // for now poll internally, refactor whisper internal for channel support - ticker := time.NewTicker(250 * time.Millisecond) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - if filter := api.w.GetFilter(id); filter != nil { - for _, rpcMessage := range toMessage(filter.Retrieve()) { - if err := notifier.Notify(rpcSub.ID, rpcMessage); err != nil { - log.Error("Failed to send notification", "err", err) - } - } - } - case <-rpcSub.Err(): - api.w.Unsubscribe(id) - return - case <-notifier.Closed(): - api.w.Unsubscribe(id) - return - } - } - }() - - return rpcSub, nil -} - -//go:generate gencodec -type Message -field-override messageOverride -out gen_message_json.go - -// Message is the RPC representation of a whisper message. -type Message struct { - Sig []byte `json:"sig,omitempty"` - TTL uint32 `json:"ttl"` - Timestamp uint32 `json:"timestamp"` - Topic TopicType `json:"topic"` - Payload []byte `json:"payload"` - Padding []byte `json:"padding"` - PoW float64 `json:"pow"` - Hash []byte `json:"hash"` - Dst []byte `json:"recipientPublicKey,omitempty"` -} - -type messageOverride struct { - Sig hexutil.Bytes - Payload hexutil.Bytes - Padding hexutil.Bytes - Hash hexutil.Bytes - Dst hexutil.Bytes -} - -// ToWhisperMessage converts an internal message into an API version. -func ToWhisperMessage(message *ReceivedMessage) *Message { - msg := Message{ - Payload: message.Payload, - Padding: message.Padding, - Timestamp: message.Sent, - TTL: message.TTL, - PoW: message.PoW, - Hash: message.EnvelopeHash.Bytes(), - Topic: message.Topic, - } - - if message.Dst != nil { - b := crypto.FromECDSAPub(message.Dst) - if b != nil { - msg.Dst = b - } - } - - if isMessageSigned(message.Raw[0]) { - b := crypto.FromECDSAPub(message.SigToPubKey()) - if b != nil { - msg.Sig = b - } - } - - return &msg -} - -// toMessage converts a set of messages to its RPC representation. -func toMessage(messages []*ReceivedMessage) []*Message { - msgs := make([]*Message, len(messages)) - for i, msg := range messages { - msgs[i] = ToWhisperMessage(msg) - } - return msgs -} - -// GetFilterMessages returns the messages that match the filter criteria and -// are received between the last poll and now. -func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) { - api.mu.Lock() - f := api.w.GetFilter(id) - if f == nil { - api.mu.Unlock() - return nil, fmt.Errorf("filter not found") - } - api.lastUsed[id] = time.Now() - api.mu.Unlock() - - receivedMessages := f.Retrieve() - messages := make([]*Message, 0, len(receivedMessages)) - for _, msg := range receivedMessages { - messages = append(messages, ToWhisperMessage(msg)) - } - - return messages, nil -} - -// DeleteMessageFilter deletes a filter. -func (api *PublicWhisperAPI) DeleteMessageFilter(id string) (bool, error) { - api.mu.Lock() - defer api.mu.Unlock() - - delete(api.lastUsed, id) - return true, api.w.Unsubscribe(id) -} - -// NewMessageFilter creates a new filter that can be used to poll for -// (new) messages that satisfy the given criteria. -func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) { - var ( - src *ecdsa.PublicKey - keySym []byte - keyAsym *ecdsa.PrivateKey - topics [][]byte - - symKeyGiven = len(req.SymKeyID) > 0 - asymKeyGiven = len(req.PrivateKeyID) > 0 - - err error - ) - - // user must specify either a symmetric or an asymmetric key - if (symKeyGiven && asymKeyGiven) || (!symKeyGiven && !asymKeyGiven) { - return "", ErrSymAsym - } - - if len(req.Sig) > 0 { - if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil { - return "", ErrInvalidSigningPubKey - } - } - - if symKeyGiven { - if keySym, err = api.w.GetSymKey(req.SymKeyID); err != nil { - return "", err - } - if !validateDataIntegrity(keySym, aesKeyLength) { - return "", ErrInvalidSymmetricKey - } - } - - if asymKeyGiven { - if keyAsym, err = api.w.GetPrivateKey(req.PrivateKeyID); err != nil { - return "", err - } - } - - if len(req.Topics) > 0 { - topics = make([][]byte, len(req.Topics)) - for i, topic := range req.Topics { - topics[i] = make([]byte, TopicLength) - copy(topics[i], topic[:]) - } - } - - f := &Filter{ - Src: src, - KeySym: keySym, - KeyAsym: keyAsym, - PoW: req.MinPow, - AllowP2P: req.AllowP2P, - Topics: topics, - Messages: make(map[common.Hash]*ReceivedMessage), - } - - id, err := api.w.Subscribe(f) - if err != nil { - return "", err - } - - api.mu.Lock() - api.lastUsed[id] = time.Now() - api.mu.Unlock() - - return id, nil -} diff --git a/whisper/whisperv6/api_test.go b/whisper/whisperv6/api_test.go deleted file mode 100644 index 759ef221ed..0000000000 --- a/whisper/whisperv6/api_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "bytes" - "testing" - "time" -) - -func TestMultipleTopicCopyInNewMessageFilter(t *testing.T) { - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - keyID, err := w.GenerateSymKey() - if err != nil { - t.Fatalf("Error generating symmetric key: %v", err) - } - api := PublicWhisperAPI{ - w: w, - lastUsed: make(map[string]time.Time), - } - - t1 := [4]byte{0xde, 0xea, 0xbe, 0xef} - t2 := [4]byte{0xca, 0xfe, 0xde, 0xca} - - crit := Criteria{ - SymKeyID: keyID, - Topics: []TopicType{TopicType(t1), TopicType(t2)}, - } - - _, err = api.NewMessageFilter(crit) - if err != nil { - t.Fatalf("Error creating the filter: %v", err) - } - - found := false - candidates := w.filters.getWatchersByTopic(TopicType(t1)) - for _, f := range candidates { - if len(f.Topics) == 2 { - if bytes.Equal(f.Topics[0], t1[:]) && bytes.Equal(f.Topics[1], t2[:]) { - found = true - } - } - } - - if !found { - t.Fatalf("Could not find filter with both topics") - } -} diff --git a/whisper/whisperv6/benchmarks_test.go b/whisper/whisperv6/benchmarks_test.go deleted file mode 100644 index 0473179da5..0000000000 --- a/whisper/whisperv6/benchmarks_test.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "crypto/sha256" - "testing" - - "github.com/ethereum/go-ethereum/crypto" - "golang.org/x/crypto/pbkdf2" -) - -func BenchmarkDeriveKeyMaterial(b *testing.B) { - for i := 0; i < b.N; i++ { - pbkdf2.Key([]byte("test"), nil, 65356, aesKeyLength, sha256.New) - } -} - -func BenchmarkEncryptionSym(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - for i := 0; i < b.N; i++ { - msg, _ := NewSentMessage(params) - _, err := msg.Wrap(params) - if err != nil { - b.Errorf("failed Wrap with seed %d: %s.", seed, err) - b.Errorf("i = %d, len(msg.Raw) = %d, params.Payload = %d.", i, len(msg.Raw), len(params.Payload)) - return - } - } -} - -func BenchmarkEncryptionAsym(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - key, err := crypto.GenerateKey() - if err != nil { - b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - params.KeySym = nil - params.Dst = &key.PublicKey - - for i := 0; i < b.N; i++ { - msg, _ := NewSentMessage(params) - _, err := msg.Wrap(params) - if err != nil { - b.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - } -} - -func BenchmarkDecryptionSymValid(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, _ := NewSentMessage(params) - env, err := msg.Wrap(params) - if err != nil { - b.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - f := Filter{KeySym: params.KeySym} - - for i := 0; i < b.N; i++ { - msg := env.Open(&f) - if msg == nil { - b.Fatalf("failed to open with seed %d.", seed) - } - } -} - -func BenchmarkDecryptionSymInvalid(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, _ := NewSentMessage(params) - env, err := msg.Wrap(params) - if err != nil { - b.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - f := Filter{KeySym: []byte("arbitrary stuff here")} - - for i := 0; i < b.N; i++ { - msg := env.Open(&f) - if msg != nil { - b.Fatalf("opened envelope with invalid key, seed: %d.", seed) - } - } -} - -func BenchmarkDecryptionAsymValid(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - key, err := crypto.GenerateKey() - if err != nil { - b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - f := Filter{KeyAsym: key} - params.KeySym = nil - params.Dst = &key.PublicKey - msg, _ := NewSentMessage(params) - env, err := msg.Wrap(params) - if err != nil { - b.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - for i := 0; i < b.N; i++ { - msg := env.Open(&f) - if msg == nil { - b.Fatalf("fail to open, seed: %d.", seed) - } - } -} - -func BenchmarkDecryptionAsymInvalid(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - key, err := crypto.GenerateKey() - if err != nil { - b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - params.KeySym = nil - params.Dst = &key.PublicKey - msg, _ := NewSentMessage(params) - env, err := msg.Wrap(params) - if err != nil { - b.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - key, err = crypto.GenerateKey() - if err != nil { - b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - f := Filter{KeyAsym: key} - - for i := 0; i < b.N; i++ { - msg := env.Open(&f) - if msg != nil { - b.Fatalf("opened envelope with invalid key, seed: %d.", seed) - } - } -} - -func increment(x []byte) { - for i := 0; i < len(x); i++ { - x[i]++ - if x[i] != 0 { - break - } - } -} - -func BenchmarkPoW(b *testing.B) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - params.Payload = make([]byte, 32) - params.PoW = 10.0 - params.TTL = 1 - - for i := 0; i < b.N; i++ { - increment(params.Payload) - msg, _ := NewSentMessage(params) - _, err := msg.Wrap(params) - if err != nil { - b.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - } -} diff --git a/whisper/whisperv6/config.go b/whisper/whisperv6/config.go deleted file mode 100644 index 38eb9551cc..0000000000 --- a/whisper/whisperv6/config.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -// Config represents the configuration state of a whisper node. -type Config struct { - MaxMessageSize uint32 `toml:",omitempty"` - MinimumAcceptedPOW float64 `toml:",omitempty"` - RestrictConnectionBetweenLightClients bool `toml:",omitempty"` -} - -// DefaultConfig represents (shocker!) the default configuration. -var DefaultConfig = Config{ - MaxMessageSize: DefaultMaxMessageSize, - MinimumAcceptedPOW: DefaultMinimumPoW, - RestrictConnectionBetweenLightClients: true, -} diff --git a/whisper/whisperv6/doc.go b/whisper/whisperv6/doc.go deleted file mode 100644 index 44c0c3271c..0000000000 --- a/whisper/whisperv6/doc.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -/* -Package whisper implements the Whisper protocol (version 6). - -Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP). -As such it may be likened and compared to both, not dissimilar to the -matter/energy duality (apologies to physicists for the blatant abuse of a -fundamental and beautiful natural principle). - -Whisper is a pure identity-based messaging system. Whisper provides a low-level -(non-application-specific) but easily-accessible API without being based upon -or prejudiced by the low-level hardware attributes and characteristics, -particularly the notion of singular endpoints. -*/ - -// Contains the Whisper protocol constant definitions - -package whisperv6 - -import ( - "time" - - "github.com/ethereum/go-ethereum/crypto" -) - -// Whisper protocol parameters -const ( - ProtocolVersion = uint64(6) // Protocol version number - ProtocolVersionStr = "6.0" // The same, as a string - ProtocolName = "shh" // Nickname of the protocol in geth - - // whisper protocol message codes, according to EIP-627 - statusCode = 0 // used by whisper protocol - messagesCode = 1 // normal whisper message - powRequirementCode = 2 // PoW requirement - bloomFilterExCode = 3 // bloom filter exchange - p2pRequestCode = 126 // peer-to-peer message, used by Dapp protocol - p2pMessageCode = 127 // peer-to-peer message (to be consumed by the peer, but not forwarded any further) - NumberOfMessageCodes = 128 - - SizeMask = byte(3) // mask used to extract the size of payload size field from the flags - signatureFlag = byte(4) - - TopicLength = 4 // in bytes - signatureLength = crypto.SignatureLength // in bytes - aesKeyLength = 32 // in bytes - aesNonceLength = 12 // in bytes; for more info please see cipher.gcmStandardNonceSize & aesgcm.NonceSize() - keyIDSize = 32 // in bytes - BloomFilterSize = 64 // in bytes - flagsLength = 1 - - EnvelopeHeaderLength = 20 - - MaxMessageSize = uint32(10 * 1024 * 1024) // maximum accepted size of a message. - DefaultMaxMessageSize = uint32(1024 * 1024) - DefaultMinimumPoW = 0.2 - - padSizeLimit = 256 // just an arbitrary number, could be changed without breaking the protocol - messageQueueLimit = 1024 - - expirationCycle = time.Second - transmissionCycle = 300 * time.Millisecond - - DefaultTTL = 50 // seconds - DefaultSyncAllowance = 10 // seconds -) - -// MailServer represents a mail server, capable of -// archiving the old messages for subsequent delivery -// to the peers. Any implementation must ensure that both -// functions are thread-safe. Also, they must return ASAP. -// DeliverMail should use directMessagesCode for delivery, -// in order to bypass the expiry checks. -type MailServer interface { - Archive(env *Envelope) - DeliverMail(whisperPeer *Peer, request *Envelope) -} diff --git a/whisper/whisperv6/envelope.go b/whisper/whisperv6/envelope.go deleted file mode 100644 index 5b6925edb3..0000000000 --- a/whisper/whisperv6/envelope.go +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Contains the Whisper protocol Envelope element. - -package whisperv6 - -import ( - "crypto/ecdsa" - "encoding/binary" - "fmt" - gmath "math" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/ecies" - "github.com/ethereum/go-ethereum/rlp" -) - -// Envelope represents a clear-text data packet to transmit through the Whisper -// network. Its contents may or may not be encrypted and signed. -type Envelope struct { - Expiry uint32 - TTL uint32 - Topic TopicType - Data []byte - Nonce uint64 - - pow float64 // Message-specific PoW as described in the Whisper specification. - - // the following variables should not be accessed directly, use the corresponding function instead: Hash(), Bloom() - hash common.Hash // Cached hash of the envelope to avoid rehashing every time. - bloom []byte -} - -// size returns the size of envelope as it is sent (i.e. public fields only) -func (e *Envelope) size() int { - return EnvelopeHeaderLength + len(e.Data) -} - -// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce. -func (e *Envelope) rlpWithoutNonce() []byte { - res, _ := rlp.EncodeToBytes([]interface{}{e.Expiry, e.TTL, e.Topic, e.Data}) - return res -} - -// NewEnvelope wraps a Whisper message with expiration and destination data -// included into an envelope for network forwarding. -func NewEnvelope(ttl uint32, topic TopicType, msg *sentMessage) *Envelope { - env := Envelope{ - Expiry: uint32(time.Now().Add(time.Second * time.Duration(ttl)).Unix()), - TTL: ttl, - Topic: topic, - Data: msg.Raw, - Nonce: 0, - } - - return &env -} - -// Seal closes the envelope by spending the requested amount of time as a proof -// of work on hashing the data. -func (e *Envelope) Seal(options *MessageParams) error { - if options.PoW == 0 { - // PoW is not required - return nil - } - - var target, bestLeadingZeros int - if options.PoW < 0 { - // target is not set - the function should run for a period - // of time specified in WorkTime param. Since we can predict - // the execution time, we can also adjust Expiry. - e.Expiry += options.WorkTime - } else { - target = e.powToFirstBit(options.PoW) - } - - rlp := e.rlpWithoutNonce() - buf := make([]byte, len(rlp)+8) - copy(buf, rlp) - asAnInt := new(big.Int) - - finish := time.Now().Add(time.Duration(options.WorkTime) * time.Second).UnixNano() - for nonce := uint64(0); time.Now().UnixNano() < finish; { - for i := 0; i < 1024; i++ { - binary.BigEndian.PutUint64(buf[len(rlp):], nonce) - h := crypto.Keccak256(buf) - asAnInt.SetBytes(h) - leadingZeros := 256 - asAnInt.BitLen() - if leadingZeros > bestLeadingZeros { - e.Nonce, bestLeadingZeros = nonce, leadingZeros - if target > 0 && bestLeadingZeros >= target { - return nil - } - } - nonce++ - } - } - - if target > 0 && bestLeadingZeros < target { - return fmt.Errorf("failed to reach the PoW target, specified pow time (%d seconds) was insufficient", options.WorkTime) - } - - return nil -} - -// PoW computes (if necessary) and returns the proof of work target -// of the envelope. -func (e *Envelope) PoW() float64 { - if e.pow == 0 { - e.calculatePoW(0) - } - return e.pow -} - -func (e *Envelope) calculatePoW(diff uint32) { - rlp := e.rlpWithoutNonce() - buf := make([]byte, len(rlp)+8) - copy(buf, rlp) - binary.BigEndian.PutUint64(buf[len(rlp):], e.Nonce) - powHash := new(big.Int).SetBytes(crypto.Keccak256(buf)) - leadingZeroes := 256 - powHash.BitLen() - x := gmath.Pow(2, float64(leadingZeroes)) - x /= float64(len(rlp)) - x /= float64(e.TTL + diff) - e.pow = x -} - -func (e *Envelope) powToFirstBit(pow float64) int { - x := pow - x *= float64(e.size()) - x *= float64(e.TTL) - bits := gmath.Log2(x) - bits = gmath.Ceil(bits) - res := int(bits) - if res < 1 { - res = 1 - } - return res -} - -// Hash returns the SHA3 hash of the envelope, calculating it if not yet done. -func (e *Envelope) Hash() common.Hash { - if (e.hash == common.Hash{}) { - encoded, _ := rlp.EncodeToBytes(e) - e.hash = crypto.Keccak256Hash(encoded) - } - return e.hash -} - -// DecodeRLP decodes an Envelope from an RLP data stream. -func (e *Envelope) DecodeRLP(s *rlp.Stream) error { - raw, err := s.Raw() - if err != nil { - return err - } - // The decoding of Envelope uses the struct fields but also needs - // to compute the hash of the whole RLP-encoded envelope. This - // type has the same structure as Envelope but is not an - // rlp.Decoder (does not implement DecodeRLP function). - // Only public members will be encoded. - type rlpenv Envelope - if err := rlp.DecodeBytes(raw, (*rlpenv)(e)); err != nil { - return err - } - e.hash = crypto.Keccak256Hash(raw) - return nil -} - -// OpenAsymmetric tries to decrypt an envelope, potentially encrypted with a particular key. -func (e *Envelope) OpenAsymmetric(key *ecdsa.PrivateKey) (*ReceivedMessage, error) { - message := &ReceivedMessage{Raw: e.Data} - err := message.decryptAsymmetric(key) - switch err { - case nil: - return message, nil - case ecies.ErrInvalidPublicKey: // addressed to somebody else - return nil, err - default: - return nil, fmt.Errorf("unable to open envelope, decrypt failed: %v", err) - } -} - -// OpenSymmetric tries to decrypt an envelope, potentially encrypted with a particular key. -func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error) { - msg = &ReceivedMessage{Raw: e.Data} - err = msg.decryptSymmetric(key) - if err != nil { - msg = nil - } - return msg, err -} - -// Open tries to decrypt an envelope, and populates the message fields in case of success. -func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) { - if watcher == nil { - return nil - } - - // The API interface forbids filters doing both symmetric and asymmetric encryption. - if watcher.expectsAsymmetricEncryption() && watcher.expectsSymmetricEncryption() { - return nil - } - - if watcher.expectsAsymmetricEncryption() { - msg, _ = e.OpenAsymmetric(watcher.KeyAsym) - if msg != nil { - msg.Dst = &watcher.KeyAsym.PublicKey - } - } else if watcher.expectsSymmetricEncryption() { - msg, _ = e.OpenSymmetric(watcher.KeySym) - if msg != nil { - msg.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym) - } - } - - if msg != nil { - ok := msg.ValidateAndParse() - if !ok { - return nil - } - msg.Topic = e.Topic - msg.PoW = e.PoW() - msg.TTL = e.TTL - msg.Sent = e.Expiry - e.TTL - msg.EnvelopeHash = e.Hash() - } - return msg -} - -// Bloom maps 4-bytes Topic into 64-byte bloom filter with 3 bits set (at most). -func (e *Envelope) Bloom() []byte { - if e.bloom == nil { - e.bloom = TopicToBloom(e.Topic) - } - return e.bloom -} - -// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes) -func TopicToBloom(topic TopicType) []byte { - b := make([]byte, BloomFilterSize) - var index [3]int - for j := 0; j < 3; j++ { - index[j] = int(topic[j]) - if (topic[3] & (1 << uint(j))) != 0 { - index[j] += 256 - } - } - - for j := 0; j < 3; j++ { - byteIndex := index[j] / 8 - bitIndex := index[j] % 8 - b[byteIndex] = (1 << uint(bitIndex)) - } - return b -} - -// GetEnvelope retrieves an envelope from the message queue by its hash. -// It returns nil if the envelope can not be found. -func (w *Whisper) GetEnvelope(hash common.Hash) *Envelope { - w.poolMu.RLock() - defer w.poolMu.RUnlock() - return w.envelopes[hash] -} diff --git a/whisper/whisperv6/envelope_test.go b/whisper/whisperv6/envelope_test.go deleted file mode 100644 index c0bb4373b8..0000000000 --- a/whisper/whisperv6/envelope_test.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Contains the tests associated with the Whisper protocol Envelope object. - -package whisperv6 - -import ( - mrand "math/rand" - "testing" - - "github.com/ethereum/go-ethereum/crypto" -) - -func TestPoWCalculationsWithNoLeadingZeros(t *testing.T) { - e := Envelope{ - TTL: 1, - Data: []byte{0xde, 0xad, 0xbe, 0xef}, - Nonce: 100000, - } - - e.calculatePoW(0) - - if e.pow != 0.07692307692307693 { - t.Fatalf("invalid PoW calculation. Expected 0.07692307692307693, got %v", e.pow) - } -} - -func TestPoWCalculationsWith8LeadingZeros(t *testing.T) { - e := Envelope{ - TTL: 1, - Data: []byte{0xde, 0xad, 0xbe, 0xef}, - Nonce: 276, - } - e.calculatePoW(0) - - if e.pow != 19.692307692307693 { - t.Fatalf("invalid PoW calculation. Expected 19.692307692307693, got %v", e.pow) - } -} - -func TestEnvelopeOpenAcceptsOnlyOneKeyTypeInFilter(t *testing.T) { - symKey := make([]byte, aesKeyLength) - mrand.Read(symKey) - - asymKey, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - - params := MessageParams{ - PoW: 0.01, - WorkTime: 1, - TTL: uint32(mrand.Intn(1024)), - Payload: make([]byte, 50), - KeySym: symKey, - Dst: nil, - } - - mrand.Read(params.Payload) - - msg, err := NewSentMessage(¶ms) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - - e, err := msg.Wrap(¶ms) - if err != nil { - t.Fatalf("Failed to Wrap the message in an envelope with seed %d: %s", seed, err) - } - - f := Filter{KeySym: symKey, KeyAsym: asymKey} - - decrypted := e.Open(&f) - if decrypted != nil { - t.Fatalf("Managed to decrypt a message with an invalid filter, seed %d", seed) - } -} diff --git a/whisper/whisperv6/filter.go b/whisper/whisperv6/filter.go deleted file mode 100644 index 6a5b79674b..0000000000 --- a/whisper/whisperv6/filter.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "crypto/ecdsa" - "fmt" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" -) - -// Filter represents a Whisper message filter -type Filter struct { - Src *ecdsa.PublicKey // Sender of the message - KeyAsym *ecdsa.PrivateKey // Private Key of recipient - KeySym []byte // Key associated with the Topic - Topics [][]byte // Topics to filter messages with - PoW float64 // Proof of work as described in the Whisper spec - AllowP2P bool // Indicates whether this filter is interested in direct peer-to-peer messages - SymKeyHash common.Hash // The Keccak256Hash of the symmetric key, needed for optimization - id string // unique identifier - - Messages map[common.Hash]*ReceivedMessage - mutex sync.RWMutex -} - -// Filters represents a collection of filters -type Filters struct { - watchers map[string]*Filter - - topicMatcher map[TopicType]map[*Filter]struct{} // map a topic to the filters that are interested in being notified when a message matches that topic - allTopicsMatcher map[*Filter]struct{} // list all the filters that will be notified of a new message, no matter what its topic is - - whisper *Whisper - mutex sync.RWMutex -} - -// NewFilters returns a newly created filter collection -func NewFilters(w *Whisper) *Filters { - return &Filters{ - watchers: make(map[string]*Filter), - topicMatcher: make(map[TopicType]map[*Filter]struct{}), - allTopicsMatcher: make(map[*Filter]struct{}), - whisper: w, - } -} - -// Install will add a new filter to the filter collection -func (fs *Filters) Install(watcher *Filter) (string, error) { - if watcher.KeySym != nil && watcher.KeyAsym != nil { - return "", fmt.Errorf("filters must choose between symmetric and asymmetric keys") - } - - if watcher.Messages == nil { - watcher.Messages = make(map[common.Hash]*ReceivedMessage) - } - - id, err := GenerateRandomID() - if err != nil { - return "", err - } - - fs.mutex.Lock() - defer fs.mutex.Unlock() - - if fs.watchers[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - - if watcher.expectsSymmetricEncryption() { - watcher.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym) - } - - watcher.id = id - fs.watchers[id] = watcher - fs.addTopicMatcher(watcher) - return id, err -} - -// Uninstall will remove a filter whose id has been specified from -// the filter collection -func (fs *Filters) Uninstall(id string) bool { - fs.mutex.Lock() - defer fs.mutex.Unlock() - if fs.watchers[id] != nil { - fs.removeFromTopicMatchers(fs.watchers[id]) - delete(fs.watchers, id) - return true - } - return false -} - -// addTopicMatcher adds a filter to the topic matchers. -// If the filter's Topics array is empty, it will be tried on every topic. -// Otherwise, it will be tried on the topics specified. -func (fs *Filters) addTopicMatcher(watcher *Filter) { - if len(watcher.Topics) == 0 { - fs.allTopicsMatcher[watcher] = struct{}{} - } else { - for _, t := range watcher.Topics { - topic := BytesToTopic(t) - if fs.topicMatcher[topic] == nil { - fs.topicMatcher[topic] = make(map[*Filter]struct{}) - } - fs.topicMatcher[topic][watcher] = struct{}{} - } - } -} - -// removeFromTopicMatchers removes a filter from the topic matchers -func (fs *Filters) removeFromTopicMatchers(watcher *Filter) { - delete(fs.allTopicsMatcher, watcher) - for _, topic := range watcher.Topics { - delete(fs.topicMatcher[BytesToTopic(topic)], watcher) - } -} - -// getWatchersByTopic returns a slice containing the filters that -// match a specific topic -func (fs *Filters) getWatchersByTopic(topic TopicType) []*Filter { - res := make([]*Filter, 0, len(fs.allTopicsMatcher)) - for watcher := range fs.allTopicsMatcher { - res = append(res, watcher) - } - for watcher := range fs.topicMatcher[topic] { - res = append(res, watcher) - } - return res -} - -// Get returns a filter from the collection with a specific ID -func (fs *Filters) Get(id string) *Filter { - fs.mutex.RLock() - defer fs.mutex.RUnlock() - return fs.watchers[id] -} - -// NotifyWatchers notifies any filter that has declared interest -// for the envelope's topic. -func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool) { - var msg *ReceivedMessage - - fs.mutex.RLock() - defer fs.mutex.RUnlock() - - candidates := fs.getWatchersByTopic(env.Topic) - for _, watcher := range candidates { - if p2pMessage && !watcher.AllowP2P { - log.Trace(fmt.Sprintf("msg [%x], filter [%s]: p2p messages are not allowed", env.Hash(), watcher.id)) - continue - } - - var match bool - if msg != nil { - match = watcher.MatchMessage(msg) - } else { - match = watcher.MatchEnvelope(env) - if match { - msg = env.Open(watcher) - if msg == nil { - log.Trace("processing message: failed to open", "message", env.Hash().Hex(), "filter", watcher.id) - } - } else { - log.Trace("processing message: does not match", "message", env.Hash().Hex(), "filter", watcher.id) - } - } - - if match && msg != nil { - log.Trace("processing message: decrypted", "hash", env.Hash().Hex()) - if watcher.Src == nil || IsPubKeyEqual(msg.Src, watcher.Src) { - watcher.Trigger(msg) - } - } - } -} - -func (f *Filter) expectsAsymmetricEncryption() bool { - return f.KeyAsym != nil -} - -func (f *Filter) expectsSymmetricEncryption() bool { - return f.KeySym != nil -} - -// Trigger adds a yet-unknown message to the filter's list of -// received messages. -func (f *Filter) Trigger(msg *ReceivedMessage) { - f.mutex.Lock() - defer f.mutex.Unlock() - - if _, exist := f.Messages[msg.EnvelopeHash]; !exist { - f.Messages[msg.EnvelopeHash] = msg - } -} - -// Retrieve will return the list of all received messages associated -// to a filter. -func (f *Filter) Retrieve() (all []*ReceivedMessage) { - f.mutex.Lock() - defer f.mutex.Unlock() - - all = make([]*ReceivedMessage, 0, len(f.Messages)) - for _, msg := range f.Messages { - all = append(all, msg) - } - - f.Messages = make(map[common.Hash]*ReceivedMessage) // delete old messages - return all -} - -// MatchMessage checks if the filter matches an already decrypted -// message (i.e. a Message that has already been handled by -// MatchEnvelope when checked by a previous filter). -// Topics are not checked here, since this is done by topic matchers. -func (f *Filter) MatchMessage(msg *ReceivedMessage) bool { - if f.PoW > 0 && msg.PoW < f.PoW { - return false - } - - if f.expectsAsymmetricEncryption() && msg.isAsymmetricEncryption() { - return IsPubKeyEqual(&f.KeyAsym.PublicKey, msg.Dst) - } else if f.expectsSymmetricEncryption() && msg.isSymmetricEncryption() { - return f.SymKeyHash == msg.SymKeyHash - } - return false -} - -// MatchEnvelope checks if it's worth decrypting the message. If -// it returns `true`, client code is expected to attempt decrypting -// the message and subsequently call MatchMessage. -// Topics are not checked here, since this is done by topic matchers. -func (f *Filter) MatchEnvelope(envelope *Envelope) bool { - return f.PoW <= 0 || envelope.pow >= f.PoW -} - -// IsPubKeyEqual checks that two public keys are equal -func IsPubKeyEqual(a, b *ecdsa.PublicKey) bool { - if !ValidatePublicKey(a) { - return false - } else if !ValidatePublicKey(b) { - return false - } - // the curve is always the same, just compare the points - return a.X.Cmp(b.X) == 0 && a.Y.Cmp(b.Y) == 0 -} diff --git a/whisper/whisperv6/filter_test.go b/whisper/whisperv6/filter_test.go deleted file mode 100644 index c95e506972..0000000000 --- a/whisper/whisperv6/filter_test.go +++ /dev/null @@ -1,836 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "math/big" - mrand "math/rand" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -var seed int64 - -// InitSingleTest should be called in the beginning of every -// test, which uses RNG, in order to make the tests -// reproduciblity independent of their sequence. -func InitSingleTest() { - seed = time.Now().Unix() - mrand.Seed(seed) -} - -type FilterTestCase struct { - f *Filter - id string - alive bool - msgCnt int -} - -func generateFilter(t *testing.T, symmetric bool) (*Filter, error) { - var f Filter - f.Messages = make(map[common.Hash]*ReceivedMessage) - - const topicNum = 8 - f.Topics = make([][]byte, topicNum) - for i := 0; i < topicNum; i++ { - f.Topics[i] = make([]byte, 4) - mrand.Read(f.Topics[i]) - f.Topics[i][0] = 0x01 - } - - key, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("generateFilter 1 failed with seed %d.", seed) - return nil, err - } - f.Src = &key.PublicKey - - if symmetric { - f.KeySym = make([]byte, aesKeyLength) - mrand.Read(f.KeySym) - f.SymKeyHash = crypto.Keccak256Hash(f.KeySym) - } else { - f.KeyAsym, err = crypto.GenerateKey() - if err != nil { - t.Fatalf("generateFilter 2 failed with seed %d.", seed) - return nil, err - } - } - - // AcceptP2P & PoW are not set - return &f, nil -} - -func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase { - cases := make([]FilterTestCase, SizeTestFilters) - for i := 0; i < SizeTestFilters; i++ { - f, _ := generateFilter(t, true) - cases[i].f = f - cases[i].alive = mrand.Int()&int(1) == 0 - } - return cases -} - -func TestInstallFilters(t *testing.T) { - InitSingleTest() - - const SizeTestFilters = 256 - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - filters := NewFilters(w) - tst := generateTestCases(t, SizeTestFilters) - - var err error - var j string - for i := 0; i < SizeTestFilters; i++ { - j, err = filters.Install(tst[i].f) - if err != nil { - t.Fatalf("seed %d: failed to install filter: %s", seed, err) - } - tst[i].id = j - if len(j) != keyIDSize*2 { - t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j)) - } - } - - for _, testCase := range tst { - if !testCase.alive { - filters.Uninstall(testCase.id) - } - } - - for i, testCase := range tst { - fil := filters.Get(testCase.id) - exist := fil != nil - if exist != testCase.alive { - t.Fatalf("seed %d: failed alive: %d, %v, %v", seed, i, exist, testCase.alive) - } - if exist && fil.PoW != testCase.f.PoW { - t.Fatalf("seed %d: failed Get: %d, %v, %v", seed, i, exist, testCase.alive) - } - } -} - -func TestInstallSymKeyGeneratesHash(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - filters := NewFilters(w) - filter, _ := generateFilter(t, true) - - // save the current SymKeyHash for comparison - initialSymKeyHash := filter.SymKeyHash - - // ensure the SymKeyHash is invalid, for Install to recreate it - var invalid common.Hash - filter.SymKeyHash = invalid - - _, err := filters.Install(filter) - - if err != nil { - t.Fatalf("Error installing the filter: %s", err) - } - - for i, b := range filter.SymKeyHash { - if b != initialSymKeyHash[i] { - t.Fatalf("The filter's symmetric key hash was not properly generated by Install") - } - } -} - -func TestInstallIdenticalFilters(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - filters := NewFilters(w) - filter1, _ := generateFilter(t, true) - - // Copy the first filter since some of its fields - // are randomly gnerated. - filter2 := &Filter{ - KeySym: filter1.KeySym, - Topics: filter1.Topics, - PoW: filter1.PoW, - AllowP2P: filter1.AllowP2P, - Messages: make(map[common.Hash]*ReceivedMessage), - } - - _, err := filters.Install(filter1) - - if err != nil { - t.Fatalf("Error installing the first filter with seed %d: %s", seed, err) - } - - _, err = filters.Install(filter2) - - if err != nil { - t.Fatalf("Error installing the second filter with seed %d: %s", seed, err) - } - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("Error generating message parameters with seed %d: %s", seed, err) - } - - params.KeySym = filter1.KeySym - params.Topic = BytesToTopic(filter1.Topics[0]) - - filter1.Src = ¶ms.Src.PublicKey - filter2.Src = ¶ms.Src.PublicKey - - sentMessage, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := sentMessage.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - msg := env.Open(filter1) - if msg == nil { - t.Fatalf("failed to Open with filter1") - } - - if !filter1.MatchEnvelope(env) { - t.Fatalf("failed matching with the first filter") - } - - if !filter2.MatchEnvelope(env) { - t.Fatalf("failed matching with the first filter") - } - - if !filter1.MatchMessage(msg) { - t.Fatalf("failed matching with the second filter") - } - - if !filter2.MatchMessage(msg) { - t.Fatalf("failed matching with the second filter") - } -} - -func TestInstallFilterWithSymAndAsymKeys(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - filters := NewFilters(w) - filter1, _ := generateFilter(t, true) - - asymKey, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("Unable to create asymetric keys: %v", err) - } - - // Copy the first filter since some of its fields - // are randomly gnerated. - filter := &Filter{ - KeySym: filter1.KeySym, - KeyAsym: asymKey, - Topics: filter1.Topics, - PoW: filter1.PoW, - AllowP2P: filter1.AllowP2P, - Messages: make(map[common.Hash]*ReceivedMessage), - } - - _, err = filters.Install(filter) - - if err == nil { - t.Fatalf("Error detecting that a filter had both an asymmetric and symmetric key, with seed %d", seed) - } -} - -func TestComparePubKey(t *testing.T) { - InitSingleTest() - - key1, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed to generate first key with seed %d: %s.", seed, err) - } - key2, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed to generate second key with seed %d: %s.", seed, err) - } - if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) { - t.Fatalf("public keys are equal, seed %d.", seed) - } - - // generate key3 == key1 - mrand.Seed(seed) - key3, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed to generate third key with seed %d: %s.", seed, err) - } - if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) { - t.Fatalf("key1 == key3, seed %d.", seed) - } -} - -func TestMatchEnvelope(t *testing.T) { - InitSingleTest() - - fsym, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) - } - - fasym, err := generateFilter(t, false) - if err != nil { - t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err) - } - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - params.Topic[0] = 0xFF // topic mismatch - - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - if _, err = msg.Wrap(params); err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - // encrypt symmetrically - i := mrand.Int() % 4 - fsym.Topics[i] = params.Topic[:] - fasym.Topics[i] = params.Topic[:] - msg, err = NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) - } - - // symmetric + matching topic: match - match := fsym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed) - } - - // symmetric + matching topic + insufficient PoW: mismatch - fsym.PoW = env.PoW() + 1.0 - match = fsym.MatchEnvelope(env) - if match { - t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed) - } - - // symmetric + matching topic + sufficient PoW: match - fsym.PoW = env.PoW() / 2 - match = fsym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed) - } - - // symmetric + topics are nil (wildcard): match - prevTopics := fsym.Topics - fsym.Topics = nil - match = fsym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed) - } - fsym.Topics = prevTopics - - // encrypt asymmetrically - key, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - params.KeySym = nil - params.Dst = &key.PublicKey - msg, err = NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err = msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap() with seed %d: %s.", seed, err) - } - - // encryption method mismatch - match = fsym.MatchEnvelope(env) - if match { - t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) - } - - // asymmetric + mismatching topic: mismatch - match = fasym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed) - } - - // asymmetric + matching topic: match - fasym.Topics[i] = fasym.Topics[i+1] - match = fasym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed) - } - - // asymmetric + filter without topic (wildcard): match - fasym.Topics = nil - match = fasym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed) - } - - // asymmetric + insufficient PoW: mismatch - fasym.PoW = env.PoW() + 1.0 - match = fasym.MatchEnvelope(env) - if match { - t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed) - } - - // asymmetric + sufficient PoW: match - fasym.PoW = env.PoW() / 2 - match = fasym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed) - } - - // filter without topic + envelope without topic: match - env.Topic = TopicType{} - match = fasym.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed) - } - - // filter with topic + envelope without topic: mismatch - fasym.Topics = fsym.Topics - match = fasym.MatchEnvelope(env) - if !match { - // topic mismatch should have no affect, as topics are handled by topic matchers - t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed) - } -} - -func TestMatchMessageSym(t *testing.T) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - f, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) - } - - const index = 1 - params.KeySym = f.KeySym - params.Topic = BytesToTopic(f.Topics[index]) - - sentMessage, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := sentMessage.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - msg := env.Open(f) - if msg == nil { - t.Fatalf("failed Open with seed %d.", seed) - } - - // Src: match - *f.Src.X = *params.Src.PublicKey.X - *f.Src.Y = *params.Src.PublicKey.Y - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed) - } - - // insufficient PoW: mismatch - f.PoW = msg.PoW + 1.0 - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed) - } - - // sufficient PoW: match - f.PoW = msg.PoW / 2 - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed) - } - - // topic mismatch - f.Topics[index][0]++ - if !f.MatchMessage(msg) { - // topic mismatch should have no affect, as topics are handled by topic matchers - t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed) - } - f.Topics[index][0]-- - - // key mismatch - f.SymKeyHash[0]++ - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed) - } - f.SymKeyHash[0]-- - - // Src absent: match - f.Src = nil - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed) - } - - // key hash mismatch - h := f.SymKeyHash - f.SymKeyHash = common.Hash{} - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed) - } - f.SymKeyHash = h - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed) - } - - // encryption method mismatch - f.KeySym = nil - f.KeyAsym, err = crypto.GenerateKey() - if err != nil { - t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) - } -} - -func TestMatchMessageAsym(t *testing.T) { - InitSingleTest() - - f, err := generateFilter(t, false) - if err != nil { - t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) - } - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - const index = 1 - params.Topic = BytesToTopic(f.Topics[index]) - params.Dst = &f.KeyAsym.PublicKey - keySymOrig := params.KeySym - params.KeySym = nil - - sentMessage, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := sentMessage.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - msg := env.Open(f) - if msg == nil { - t.Fatalf("failed to open with seed %d.", seed) - } - - // Src: match - *f.Src.X = *params.Src.PublicKey.X - *f.Src.Y = *params.Src.PublicKey.Y - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchMessage(src match) with seed %d.", seed) - } - - // insufficient PoW: mismatch - f.PoW = msg.PoW + 1.0 - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed) - } - - // sufficient PoW: match - f.PoW = msg.PoW / 2 - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed) - } - - // topic mismatch - f.Topics[index][0]++ - if !f.MatchMessage(msg) { - // topic mismatch should have no affect, as topics are handled by topic matchers - t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed) - } - f.Topics[index][0]-- - - // key mismatch - prev := *f.KeyAsym.PublicKey.X - zero := *big.NewInt(0) - *f.KeyAsym.PublicKey.X = zero - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed) - } - *f.KeyAsym.PublicKey.X = prev - - // Src absent: match - f.Src = nil - if !f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed) - } - - // encryption method mismatch - f.KeySym = keySymOrig - f.KeyAsym = nil - if f.MatchMessage(msg) { - t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed) - } -} - -func cloneFilter(orig *Filter) *Filter { - var clone Filter - clone.Messages = make(map[common.Hash]*ReceivedMessage) - clone.Src = orig.Src - clone.KeyAsym = orig.KeyAsym - clone.KeySym = orig.KeySym - clone.Topics = orig.Topics - clone.PoW = orig.PoW - clone.AllowP2P = orig.AllowP2P - clone.SymKeyHash = orig.SymKeyHash - return &clone -} - -func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope { - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - return nil - } - - params.KeySym = f.KeySym - params.Topic = BytesToTopic(f.Topics[2]) - sentMessage, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := sentMessage.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - return nil - } - return env -} - -func TestWatchers(t *testing.T) { - InitSingleTest() - - const NumFilters = 16 - const NumMessages = 256 - var i int - var j uint32 - var e *Envelope - var x, firstID string - var err error - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - filters := NewFilters(w) - tst := generateTestCases(t, NumFilters) - for i = 0; i < NumFilters; i++ { - tst[i].f.Src = nil - x, err = filters.Install(tst[i].f) - if err != nil { - t.Fatalf("failed to install filter with seed %d: %s.", seed, err) - } - tst[i].id = x - if len(firstID) == 0 { - firstID = x - } - } - - lastID := x - - var envelopes [NumMessages]*Envelope - for i = 0; i < NumMessages; i++ { - j = mrand.Uint32() % NumFilters - e = generateCompatibeEnvelope(t, tst[j].f) - envelopes[i] = e - tst[j].msgCnt++ - } - - for i = 0; i < NumMessages; i++ { - filters.NotifyWatchers(envelopes[i], false) - } - - var total int - var mail []*ReceivedMessage - var count [NumFilters]int - - for i = 0; i < NumFilters; i++ { - mail = tst[i].f.Retrieve() - count[i] = len(mail) - total += len(mail) - } - - if total != NumMessages { - t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages) - } - - for i = 0; i < NumFilters; i++ { - mail = tst[i].f.Retrieve() - if len(mail) != 0 { - t.Fatalf("failed with seed %d: i = %d.", seed, i) - } - - if tst[i].msgCnt != count[i] { - t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i]) - } - } - - // another round with a cloned filter - - clone := cloneFilter(tst[0].f) - filters.Uninstall(lastID) - total = 0 - last := NumFilters - 1 - tst[last].f = clone - filters.Install(clone) - for i = 0; i < NumFilters; i++ { - tst[i].msgCnt = 0 - count[i] = 0 - } - - // make sure that the first watcher receives at least one message - e = generateCompatibeEnvelope(t, tst[0].f) - envelopes[0] = e - tst[0].msgCnt++ - for i = 1; i < NumMessages; i++ { - j = mrand.Uint32() % NumFilters - e = generateCompatibeEnvelope(t, tst[j].f) - envelopes[i] = e - tst[j].msgCnt++ - } - - for i = 0; i < NumMessages; i++ { - filters.NotifyWatchers(envelopes[i], false) - } - - for i = 0; i < NumFilters; i++ { - mail = tst[i].f.Retrieve() - count[i] = len(mail) - total += len(mail) - } - - combined := tst[0].msgCnt + tst[last].msgCnt - if total != NumMessages+count[0] { - t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0]) - } - - if combined != count[0] { - t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0]) - } - - if combined != count[last] { - t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last]) - } - - for i = 1; i < NumFilters-1; i++ { - mail = tst[i].f.Retrieve() - if len(mail) != 0 { - t.Fatalf("failed with seed %d: i = %d.", seed, i) - } - - if tst[i].msgCnt != count[i] { - t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i]) - } - } - - // test AcceptP2P - - total = 0 - filters.NotifyWatchers(envelopes[0], true) - - for i = 0; i < NumFilters; i++ { - mail = tst[i].f.Retrieve() - total += len(mail) - } - - if total != 0 { - t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total) - } - - f := filters.Get(firstID) - if f == nil { - t.Fatalf("failed to get the filter with seed %d.", seed) - } - f.AllowP2P = true - total = 0 - filters.NotifyWatchers(envelopes[0], true) - - for i = 0; i < NumFilters; i++ { - mail = tst[i].f.Retrieve() - total += len(mail) - } - - if total != 1 { - t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total) - } -} - -func TestVariableTopics(t *testing.T) { - InitSingleTest() - - const lastTopicByte = 3 - var match bool - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - f, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateFilter with seed %d: %s.", seed, err) - } - - for i := 0; i < 4; i++ { - env.Topic = BytesToTopic(f.Topics[i]) - match = f.MatchEnvelope(env) - if !match { - t.Fatalf("failed MatchEnvelope symmetric with seed %d, step %d.", seed, i) - } - - f.Topics[i][lastTopicByte]++ - match = f.MatchEnvelope(env) - if !match { - // topic mismatch should have no affect, as topics are handled by topic matchers - t.Fatalf("MatchEnvelope symmetric with seed %d, step %d.", seed, i) - } - } -} diff --git a/whisper/whisperv6/gen_criteria_json.go b/whisper/whisperv6/gen_criteria_json.go deleted file mode 100644 index 1a428d6df7..0000000000 --- a/whisper/whisperv6/gen_criteria_json.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package whisperv6 - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*criteriaOverride)(nil) - -// MarshalJSON marshals type Criteria to a json string -func (c Criteria) MarshalJSON() ([]byte, error) { - type Criteria struct { - SymKeyID string `json:"symKeyID"` - PrivateKeyID string `json:"privateKeyID"` - Sig hexutil.Bytes `json:"sig"` - MinPow float64 `json:"minPow"` - Topics []TopicType `json:"topics"` - AllowP2P bool `json:"allowP2P"` - } - var enc Criteria - enc.SymKeyID = c.SymKeyID - enc.PrivateKeyID = c.PrivateKeyID - enc.Sig = c.Sig - enc.MinPow = c.MinPow - enc.Topics = c.Topics - enc.AllowP2P = c.AllowP2P - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals type Criteria to a json string -func (c *Criteria) UnmarshalJSON(input []byte) error { - type Criteria struct { - SymKeyID *string `json:"symKeyID"` - PrivateKeyID *string `json:"privateKeyID"` - Sig *hexutil.Bytes `json:"sig"` - MinPow *float64 `json:"minPow"` - Topics []TopicType `json:"topics"` - AllowP2P *bool `json:"allowP2P"` - } - var dec Criteria - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.SymKeyID != nil { - c.SymKeyID = *dec.SymKeyID - } - if dec.PrivateKeyID != nil { - c.PrivateKeyID = *dec.PrivateKeyID - } - if dec.Sig != nil { - c.Sig = *dec.Sig - } - if dec.MinPow != nil { - c.MinPow = *dec.MinPow - } - if dec.Topics != nil { - c.Topics = dec.Topics - } - if dec.AllowP2P != nil { - c.AllowP2P = *dec.AllowP2P - } - return nil -} diff --git a/whisper/whisperv6/gen_message_json.go b/whisper/whisperv6/gen_message_json.go deleted file mode 100644 index 6218f5df6e..0000000000 --- a/whisper/whisperv6/gen_message_json.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package whisperv6 - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*messageOverride)(nil) - -// MarshalJSON marshals type Message to a json string -func (m Message) MarshalJSON() ([]byte, error) { - type Message struct { - Sig hexutil.Bytes `json:"sig,omitempty"` - TTL uint32 `json:"ttl"` - Timestamp uint32 `json:"timestamp"` - Topic TopicType `json:"topic"` - Payload hexutil.Bytes `json:"payload"` - Padding hexutil.Bytes `json:"padding"` - PoW float64 `json:"pow"` - Hash hexutil.Bytes `json:"hash"` - Dst hexutil.Bytes `json:"recipientPublicKey,omitempty"` - } - var enc Message - enc.Sig = m.Sig - enc.TTL = m.TTL - enc.Timestamp = m.Timestamp - enc.Topic = m.Topic - enc.Payload = m.Payload - enc.Padding = m.Padding - enc.PoW = m.PoW - enc.Hash = m.Hash - enc.Dst = m.Dst - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals type Message to a json string -func (m *Message) UnmarshalJSON(input []byte) error { - type Message struct { - Sig *hexutil.Bytes `json:"sig,omitempty"` - TTL *uint32 `json:"ttl"` - Timestamp *uint32 `json:"timestamp"` - Topic *TopicType `json:"topic"` - Payload *hexutil.Bytes `json:"payload"` - Padding *hexutil.Bytes `json:"padding"` - PoW *float64 `json:"pow"` - Hash *hexutil.Bytes `json:"hash"` - Dst *hexutil.Bytes `json:"recipientPublicKey,omitempty"` - } - var dec Message - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Sig != nil { - m.Sig = *dec.Sig - } - if dec.TTL != nil { - m.TTL = *dec.TTL - } - if dec.Timestamp != nil { - m.Timestamp = *dec.Timestamp - } - if dec.Topic != nil { - m.Topic = *dec.Topic - } - if dec.Payload != nil { - m.Payload = *dec.Payload - } - if dec.Padding != nil { - m.Padding = *dec.Padding - } - if dec.PoW != nil { - m.PoW = *dec.PoW - } - if dec.Hash != nil { - m.Hash = *dec.Hash - } - if dec.Dst != nil { - m.Dst = *dec.Dst - } - return nil -} diff --git a/whisper/whisperv6/gen_newmessage_json.go b/whisper/whisperv6/gen_newmessage_json.go deleted file mode 100644 index 75a1279ae3..0000000000 --- a/whisper/whisperv6/gen_newmessage_json.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package whisperv6 - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*newMessageOverride)(nil) - -// MarshalJSON marshals type NewMessage to a json string -func (n NewMessage) MarshalJSON() ([]byte, error) { - type NewMessage struct { - SymKeyID string `json:"symKeyID"` - PublicKey hexutil.Bytes `json:"pubKey"` - Sig string `json:"sig"` - TTL uint32 `json:"ttl"` - Topic TopicType `json:"topic"` - Payload hexutil.Bytes `json:"payload"` - Padding hexutil.Bytes `json:"padding"` - PowTime uint32 `json:"powTime"` - PowTarget float64 `json:"powTarget"` - TargetPeer string `json:"targetPeer"` - } - var enc NewMessage - enc.SymKeyID = n.SymKeyID - enc.PublicKey = n.PublicKey - enc.Sig = n.Sig - enc.TTL = n.TTL - enc.Topic = n.Topic - enc.Payload = n.Payload - enc.Padding = n.Padding - enc.PowTime = n.PowTime - enc.PowTarget = n.PowTarget - enc.TargetPeer = n.TargetPeer - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals type NewMessage to a json string -func (n *NewMessage) UnmarshalJSON(input []byte) error { - type NewMessage struct { - SymKeyID *string `json:"symKeyID"` - PublicKey *hexutil.Bytes `json:"pubKey"` - Sig *string `json:"sig"` - TTL *uint32 `json:"ttl"` - Topic *TopicType `json:"topic"` - Payload *hexutil.Bytes `json:"payload"` - Padding *hexutil.Bytes `json:"padding"` - PowTime *uint32 `json:"powTime"` - PowTarget *float64 `json:"powTarget"` - TargetPeer *string `json:"targetPeer"` - } - var dec NewMessage - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.SymKeyID != nil { - n.SymKeyID = *dec.SymKeyID - } - if dec.PublicKey != nil { - n.PublicKey = *dec.PublicKey - } - if dec.Sig != nil { - n.Sig = *dec.Sig - } - if dec.TTL != nil { - n.TTL = *dec.TTL - } - if dec.Topic != nil { - n.Topic = *dec.Topic - } - if dec.Payload != nil { - n.Payload = *dec.Payload - } - if dec.Padding != nil { - n.Padding = *dec.Padding - } - if dec.PowTime != nil { - n.PowTime = *dec.PowTime - } - if dec.PowTarget != nil { - n.PowTarget = *dec.PowTarget - } - if dec.TargetPeer != nil { - n.TargetPeer = *dec.TargetPeer - } - return nil -} diff --git a/whisper/whisperv6/message.go b/whisper/whisperv6/message.go deleted file mode 100644 index 2d4e862441..0000000000 --- a/whisper/whisperv6/message.go +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Contains the Whisper protocol Message element. - -package whisperv6 - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/ecdsa" - crand "crypto/rand" - "encoding/binary" - "errors" - mrand "math/rand" - "strconv" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/ecies" - "github.com/ethereum/go-ethereum/log" -) - -// MessageParams specifies the exact way a message should be wrapped -// into an Envelope. -type MessageParams struct { - TTL uint32 - Src *ecdsa.PrivateKey - Dst *ecdsa.PublicKey - KeySym []byte - Topic TopicType - WorkTime uint32 - PoW float64 - Payload []byte - Padding []byte -} - -// SentMessage represents an end-user data packet to transmit through the -// Whisper protocol. These are wrapped into Envelopes that need not be -// understood by intermediate nodes, just forwarded. -type sentMessage struct { - Raw []byte -} - -// ReceivedMessage represents a data packet to be received through the -// Whisper protocol and successfully decrypted. -type ReceivedMessage struct { - Raw []byte - - Payload []byte - Padding []byte - Signature []byte - Salt []byte - - PoW float64 // Proof of work as described in the Whisper spec - Sent uint32 // Time when the message was posted into the network - TTL uint32 // Maximum time to live allowed for the message - Src *ecdsa.PublicKey // Message recipient (identity used to decode the message) - Dst *ecdsa.PublicKey // Message recipient (identity used to decode the message) - Topic TopicType - - SymKeyHash common.Hash // The Keccak256Hash of the key - EnvelopeHash common.Hash // Message envelope hash to act as a unique id -} - -func isMessageSigned(flags byte) bool { - return (flags & signatureFlag) != 0 -} - -func (msg *ReceivedMessage) isSymmetricEncryption() bool { - return msg.SymKeyHash != common.Hash{} -} - -func (msg *ReceivedMessage) isAsymmetricEncryption() bool { - return msg.Dst != nil -} - -// NewSentMessage creates and initializes a non-signed, non-encrypted Whisper message. -func NewSentMessage(params *MessageParams) (*sentMessage, error) { - const payloadSizeFieldMaxSize = 4 - msg := sentMessage{} - msg.Raw = make([]byte, 1, - flagsLength+payloadSizeFieldMaxSize+len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit) - msg.Raw[0] = 0 // set all the flags to zero - msg.addPayloadSizeField(params.Payload) - msg.Raw = append(msg.Raw, params.Payload...) - err := msg.appendPadding(params) - return &msg, err -} - -// addPayloadSizeField appends the auxiliary field containing the size of payload -func (msg *sentMessage) addPayloadSizeField(payload []byte) { - fieldSize := getSizeOfPayloadSizeField(payload) - field := make([]byte, 4) - binary.LittleEndian.PutUint32(field, uint32(len(payload))) - field = field[:fieldSize] - msg.Raw = append(msg.Raw, field...) - msg.Raw[0] |= byte(fieldSize) -} - -// getSizeOfPayloadSizeField returns the number of bytes necessary to encode the size of payload -func getSizeOfPayloadSizeField(payload []byte) int { - s := 1 - for i := len(payload); i >= 256; i /= 256 { - s++ - } - return s -} - -// appendPadding appends the padding specified in params. -// If no padding is provided in params, then random padding is generated. -func (msg *sentMessage) appendPadding(params *MessageParams) error { - if len(params.Padding) != 0 { - // padding data was provided by the Dapp, just use it as is - msg.Raw = append(msg.Raw, params.Padding...) - return nil - } - - rawSize := flagsLength + getSizeOfPayloadSizeField(params.Payload) + len(params.Payload) - if params.Src != nil { - rawSize += signatureLength - } - odd := rawSize % padSizeLimit - paddingSize := padSizeLimit - odd - pad := make([]byte, paddingSize) - _, err := crand.Read(pad) - if err != nil { - return err - } - if !validateDataIntegrity(pad, paddingSize) { - return errors.New("failed to generate random padding of size " + strconv.Itoa(paddingSize)) - } - msg.Raw = append(msg.Raw, pad...) - return nil -} - -// sign calculates and sets the cryptographic signature for the message, -// also setting the sign flag. -func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error { - if isMessageSigned(msg.Raw[0]) { - // this should not happen, but no reason to panic - log.Error("failed to sign the message: already signed") - return nil - } - - msg.Raw[0] |= signatureFlag // it is important to set this flag before signing - hash := crypto.Keccak256(msg.Raw) - signature, err := crypto.Sign(hash, key) - if err != nil { - msg.Raw[0] &= (0xFF ^ signatureFlag) // clear the flag - return err - } - msg.Raw = append(msg.Raw, signature...) - return nil -} - -// encryptAsymmetric encrypts a message with a public key. -func (msg *sentMessage) encryptAsymmetric(key *ecdsa.PublicKey) error { - if !ValidatePublicKey(key) { - return errors.New("invalid public key provided for asymmetric encryption") - } - encrypted, err := ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), msg.Raw, nil, nil) - if err == nil { - msg.Raw = encrypted - } - return err -} - -// encryptSymmetric encrypts a message with a topic key, using AES-GCM-256. -// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize). -func (msg *sentMessage) encryptSymmetric(key []byte) (err error) { - if !validateDataIntegrity(key, aesKeyLength) { - return errors.New("invalid key provided for symmetric encryption, size: " + strconv.Itoa(len(key))) - } - block, err := aes.NewCipher(key) - if err != nil { - return err - } - aesgcm, err := cipher.NewGCM(block) - if err != nil { - return err - } - salt, err := generateSecureRandomData(aesNonceLength) // never use more than 2^32 random nonces with a given key - if err != nil { - return err - } - encrypted := aesgcm.Seal(nil, salt, msg.Raw, nil) - msg.Raw = append(encrypted, salt...) - return nil -} - -// generateSecureRandomData generates random data where extra security is required. -// The purpose of this function is to prevent some bugs in software or in hardware -// from delivering not-very-random data. This is especially useful for AES nonce, -// where true randomness does not really matter, but it is very important to have -// a unique nonce for every message. -func generateSecureRandomData(length int) ([]byte, error) { - x := make([]byte, length) - y := make([]byte, length) - res := make([]byte, length) - - _, err := crand.Read(x) - if err != nil { - return nil, err - } else if !validateDataIntegrity(x, length) { - return nil, errors.New("crypto/rand failed to generate secure random data") - } - _, err = mrand.Read(y) - if err != nil { - return nil, err - } else if !validateDataIntegrity(y, length) { - return nil, errors.New("math/rand failed to generate secure random data") - } - for i := 0; i < length; i++ { - res[i] = x[i] ^ y[i] - } - if !validateDataIntegrity(res, length) { - return nil, errors.New("failed to generate secure random data") - } - return res, nil -} - -// Wrap bundles the message into an Envelope to transmit over the network. -func (msg *sentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) { - if options.TTL == 0 { - options.TTL = DefaultTTL - } - if options.Src != nil { - if err = msg.sign(options.Src); err != nil { - return nil, err - } - } - if options.Dst != nil { - err = msg.encryptAsymmetric(options.Dst) - } else if options.KeySym != nil { - err = msg.encryptSymmetric(options.KeySym) - } else { - err = errors.New("unable to encrypt the message: neither symmetric nor assymmetric key provided") - } - if err != nil { - return nil, err - } - - envelope = NewEnvelope(options.TTL, options.Topic, msg) - if err = envelope.Seal(options); err != nil { - return nil, err - } - return envelope, nil -} - -// decryptSymmetric decrypts a message with a topic key, using AES-GCM-256. -// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize). -func (msg *ReceivedMessage) decryptSymmetric(key []byte) error { - // symmetric messages are expected to contain the 12-byte nonce at the end of the payload - if len(msg.Raw) < aesNonceLength { - return errors.New("missing salt or invalid payload in symmetric message") - } - salt := msg.Raw[len(msg.Raw)-aesNonceLength:] - - block, err := aes.NewCipher(key) - if err != nil { - return err - } - aesgcm, err := cipher.NewGCM(block) - if err != nil { - return err - } - decrypted, err := aesgcm.Open(nil, salt, msg.Raw[:len(msg.Raw)-aesNonceLength], nil) - if err != nil { - return err - } - msg.Raw = decrypted - msg.Salt = salt - return nil -} - -// decryptAsymmetric decrypts an encrypted payload with a private key. -func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error { - decrypted, err := ecies.ImportECDSA(key).Decrypt(msg.Raw, nil, nil) - if err == nil { - msg.Raw = decrypted - } - return err -} - -// ValidateAndParse checks the message validity and extracts the fields in case of success. -func (msg *ReceivedMessage) ValidateAndParse() bool { - end := len(msg.Raw) - if end < 1 { - return false - } - - if isMessageSigned(msg.Raw[0]) { - end -= signatureLength - if end <= 1 { - return false - } - msg.Signature = msg.Raw[end : end+signatureLength] - msg.Src = msg.SigToPubKey() - if msg.Src == nil { - return false - } - } - - beg := 1 - payloadSize := 0 - sizeOfPayloadSizeField := int(msg.Raw[0] & SizeMask) // number of bytes indicating the size of payload - if sizeOfPayloadSizeField != 0 { - payloadSize = int(bytesToUintLittleEndian(msg.Raw[beg : beg+sizeOfPayloadSizeField])) - if payloadSize+1 > end { - return false - } - beg += sizeOfPayloadSizeField - msg.Payload = msg.Raw[beg : beg+payloadSize] - } - - beg += payloadSize - msg.Padding = msg.Raw[beg:end] - return true -} - -// SigToPubKey returns the public key associated to the message's -// signature. -func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey { - defer func() { recover() }() // in case of invalid signature - - pub, err := crypto.SigToPub(msg.hash(), msg.Signature) - if err != nil { - log.Error("failed to recover public key from signature", "err", err) - return nil - } - return pub -} - -// hash calculates the SHA3 checksum of the message flags, payload size field, payload and padding. -func (msg *ReceivedMessage) hash() []byte { - if isMessageSigned(msg.Raw[0]) { - sz := len(msg.Raw) - signatureLength - return crypto.Keccak256(msg.Raw[:sz]) - } - return crypto.Keccak256(msg.Raw) -} diff --git a/whisper/whisperv6/message_test.go b/whisper/whisperv6/message_test.go deleted file mode 100644 index ece6d732cc..0000000000 --- a/whisper/whisperv6/message_test.go +++ /dev/null @@ -1,471 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - mrand "math/rand" - "testing" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -func generateMessageParams() (*MessageParams, error) { - // set all the parameters except p.Dst and p.Padding - - buf := make([]byte, 4) - mrand.Read(buf) - sz := mrand.Intn(400) - - var p MessageParams - p.PoW = 0.001 - p.WorkTime = 1 - p.TTL = uint32(mrand.Intn(1024)) - p.Payload = make([]byte, sz) - p.KeySym = make([]byte, aesKeyLength) - mrand.Read(p.Payload) - mrand.Read(p.KeySym) - p.Topic = BytesToTopic(buf) - - var err error - p.Src, err = crypto.GenerateKey() - if err != nil { - return nil, err - } - - return &p, nil -} - -func singleMessageTest(t *testing.T, symmetric bool) { - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - key, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - - if !symmetric { - params.KeySym = nil - params.Dst = &key.PublicKey - } - - text := make([]byte, 0, 512) - text = append(text, params.Payload...) - - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - var decrypted *ReceivedMessage - if symmetric { - decrypted, err = env.OpenSymmetric(params.KeySym) - } else { - decrypted, err = env.OpenAsymmetric(key) - } - - if err != nil { - t.Fatalf("failed to encrypt with seed %d: %s.", seed, err) - } - - if !decrypted.ValidateAndParse() { - t.Fatalf("failed to validate with seed %d, symmetric = %v.", seed, symmetric) - } - - if !bytes.Equal(text, decrypted.Payload) { - t.Fatalf("failed with seed %d: compare payload.", seed) - } - if !isMessageSigned(decrypted.Raw[0]) { - t.Fatalf("failed with seed %d: unsigned.", seed) - } - if len(decrypted.Signature) != signatureLength { - t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) - } - if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { - t.Fatalf("failed with seed %d: signature mismatch.", seed) - } -} - -func TestMessageEncryption(t *testing.T) { - InitSingleTest() - - var symmetric bool - for i := 0; i < 256; i++ { - singleMessageTest(t, symmetric) - symmetric = !symmetric - } -} - -func TestMessageWrap(t *testing.T) { - seed = int64(1777444222) - mrand.Seed(seed) - target := 128.0 - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - params.TTL = 1 - params.WorkTime = 12 - params.PoW = target - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - pow := env.PoW() - if pow < target { - t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) - } - - // set PoW target too high, expect error - msg2, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - params.TTL = 1000000 - params.WorkTime = 1 - params.PoW = 10000000.0 - _, err = msg2.Wrap(params) - if err == nil { - t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed) - } -} - -func TestMessageSeal(t *testing.T) { - // this test depends on deterministic choice of seed (1976726903) - seed = int64(1976726903) - mrand.Seed(seed) - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - params.TTL = 1 - - env := NewEnvelope(params.TTL, params.Topic, msg) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - env.Expiry = uint32(seed) // make it deterministic - target := 32.0 - params.WorkTime = 4 - params.PoW = target - env.Seal(params) - - env.calculatePoW(0) - pow := env.PoW() - if pow < target { - t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target) - } - - params.WorkTime = 1 - params.PoW = 1000000000.0 - env.Seal(params) - env.calculatePoW(0) - pow = env.PoW() - if pow < 2*target { - t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow) - } -} - -func TestEnvelopeOpen(t *testing.T) { - InitSingleTest() - - var symmetric bool - for i := 0; i < 32; i++ { - singleEnvelopeOpenTest(t, symmetric) - symmetric = !symmetric - } -} - -func singleEnvelopeOpenTest(t *testing.T, symmetric bool) { - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - key, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err) - } - - if !symmetric { - params.KeySym = nil - params.Dst = &key.PublicKey - } - - text := make([]byte, 0, 512) - text = append(text, params.Payload...) - - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - var f Filter - if symmetric { - f = Filter{KeySym: params.KeySym} - } else { - f = Filter{KeyAsym: key} - } - decrypted := env.Open(&f) - if decrypted == nil { - t.Fatalf("failed to open with seed %d.", seed) - } - - if !bytes.Equal(text, decrypted.Payload) { - t.Fatalf("failed with seed %d: compare payload.", seed) - } - if !isMessageSigned(decrypted.Raw[0]) { - t.Fatalf("failed with seed %d: unsigned.", seed) - } - if len(decrypted.Signature) != signatureLength { - t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature)) - } - if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) { - t.Fatalf("failed with seed %d: signature mismatch.", seed) - } - if decrypted.isAsymmetricEncryption() == symmetric { - t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric) - } - if decrypted.isSymmetricEncryption() != symmetric { - t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric) - } - if !symmetric { - if decrypted.Dst == nil { - t.Fatalf("failed with seed %d: dst is nil.", seed) - } - if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) { - t.Fatalf("failed with seed %d: Dst.", seed) - } - } -} - -func TestEncryptWithZeroKey(t *testing.T) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - params.KeySym = make([]byte, aesKeyLength) - _, err = msg.Wrap(params) - if err == nil { - t.Fatalf("wrapped with zero key, seed: %d.", seed) - } - - params, err = generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, err = NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - params.KeySym = make([]byte, 0) - _, err = msg.Wrap(params) - if err == nil { - t.Fatalf("wrapped with empty key, seed: %d.", seed) - } - - params, err = generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, err = NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - params.KeySym = nil - _, err = msg.Wrap(params) - if err == nil { - t.Fatalf("wrapped with nil key, seed: %d.", seed) - } -} - -func TestRlpEncode(t *testing.T) { - InitSingleTest() - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("wrapped with zero key, seed: %d.", seed) - } - - raw, err := rlp.EncodeToBytes(env) - if err != nil { - t.Fatalf("RLP encode failed: %s.", err) - } - - var decoded Envelope - rlp.DecodeBytes(raw, &decoded) - if err != nil { - t.Fatalf("RLP decode failed: %s.", err) - } - - he := env.Hash() - hd := decoded.Hash() - - if he != hd { - t.Fatalf("Hashes are not equal: %x vs. %x", he, hd) - } -} - -func singlePaddingTest(t *testing.T, padSize int) { - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err) - } - params.Padding = make([]byte, padSize) - params.PoW = 0.0000000001 - pad := make([]byte, padSize) - _, err = mrand.Read(pad) - if err != nil { - t.Fatalf("padding is not generated (seed %d): %s", seed, err) - } - n := copy(params.Padding, pad) - if n != padSize { - t.Fatalf("padding is not copied (seed %d): %s", seed, err) - } - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize) - } - f := Filter{KeySym: params.KeySym} - decrypted := env.Open(&f) - if decrypted == nil { - t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize) - } - if !bytes.Equal(pad, decrypted.Padding) { - t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding) - } -} - -func TestPadding(t *testing.T) { - InitSingleTest() - - for i := 1; i < 260; i++ { - singlePaddingTest(t, i) - } - - lim := 256 * 256 - for i := lim - 5; i < lim+2; i++ { - singlePaddingTest(t, i) - } - - for i := 0; i < 256; i++ { - n := mrand.Intn(256*254) + 256 - singlePaddingTest(t, n) - } - - for i := 0; i < 256; i++ { - n := mrand.Intn(256*1024) + 256*256 - singlePaddingTest(t, n) - } -} - -func TestPaddingAppendedToSymMessagesWithSignature(t *testing.T) { - params := &MessageParams{ - Payload: make([]byte, 246), - KeySym: make([]byte, aesKeyLength), - } - - pSrc, err := crypto.GenerateKey() - - if err != nil { - t.Fatalf("Error creating the signature key %v", err) - return - } - params.Src = pSrc - - // Simulate a message with a payload just under 256 so that - // payload + flag + signature > 256. Check that the result - // is padded on the next 256 boundary. - msg := sentMessage{} - const payloadSizeFieldMinSize = 1 - msg.Raw = make([]byte, flagsLength+payloadSizeFieldMinSize+len(params.Payload)) - - err = msg.appendPadding(params) - - if err != nil { - t.Fatalf("Error appending padding to message %v", err) - return - } - - if len(msg.Raw) != 512-signatureLength { - t.Errorf("Invalid size %d != 512", len(msg.Raw)) - } -} - -func TestAesNonce(t *testing.T) { - key := hexutil.MustDecode("0x03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31") - block, err := aes.NewCipher(key) - if err != nil { - t.Fatalf("NewCipher failed: %s", err) - } - aesgcm, err := cipher.NewGCM(block) - if err != nil { - t.Fatalf("NewGCM failed: %s", err) - } - // This is the most important single test in this package. - // If it fails, whisper will not be working. - if aesgcm.NonceSize() != aesNonceLength { - t.Fatalf("Nonce size is wrong. This is a critical error. Apparently AES nonce size have changed in the new version of AES GCM package. Whisper will not be working until this problem is resolved.") - } -} diff --git a/whisper/whisperv6/peer.go b/whisper/whisperv6/peer.go deleted file mode 100644 index 68fa7c8cba..0000000000 --- a/whisper/whisperv6/peer.go +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "fmt" - "math" - "sync" - "time" - - mapset "github.com/deckarep/golang-set" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/rlp" -) - -// Peer represents a whisper protocol peer connection. -type Peer struct { - host *Whisper - peer *p2p.Peer - ws p2p.MsgReadWriter - - trusted bool - powRequirement float64 - bloomMu sync.Mutex - bloomFilter []byte - fullNode bool - - known mapset.Set // Messages already known by the peer to avoid wasting bandwidth - - quit chan struct{} - - wg sync.WaitGroup -} - -// newPeer creates a new whisper peer object, but does not run the handshake itself. -func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer { - return &Peer{ - host: host, - peer: remote, - ws: rw, - trusted: false, - powRequirement: 0.0, - known: mapset.NewSet(), - quit: make(chan struct{}), - bloomFilter: MakeFullNodeBloom(), - fullNode: true, - } -} - -// start initiates the peer updater, periodically broadcasting the whisper packets -// into the network. -func (peer *Peer) start() { - peer.wg.Add(1) - go peer.update() - log.Trace("start", "peer", peer.ID()) -} - -// stop terminates the peer updater, stopping message forwarding to it. -func (peer *Peer) stop() { - close(peer.quit) - peer.wg.Wait() - log.Trace("stop", "peer", peer.ID()) -} - -// handshake sends the protocol initiation status message to the remote peer and -// verifies the remote status too. -func (peer *Peer) handshake() error { - // Send the handshake status message asynchronously - errc := make(chan error, 1) - isLightNode := peer.host.LightClientMode() - isRestrictedLightNodeConnection := peer.host.LightClientModeConnectionRestricted() - peer.wg.Add(1) - go func() { - defer peer.wg.Done() - pow := peer.host.MinPow() - powConverted := math.Float64bits(pow) - bloom := peer.host.BloomFilter() - - errc <- p2p.SendItems(peer.ws, statusCode, ProtocolVersion, powConverted, bloom, isLightNode) - }() - - // Fetch the remote status packet and verify protocol match - packet, err := peer.ws.ReadMsg() - if err != nil { - return err - } - if packet.Code != statusCode { - return fmt.Errorf("peer [%x] sent packet %x before status packet", peer.ID(), packet.Code) - } - s := rlp.NewStream(packet.Payload, uint64(packet.Size)) - _, err = s.List() - if err != nil { - return fmt.Errorf("peer [%x] sent bad status message: %v", peer.ID(), err) - } - peerVersion, err := s.Uint() - if err != nil { - return fmt.Errorf("peer [%x] sent bad status message (unable to decode version): %v", peer.ID(), err) - } - if peerVersion != ProtocolVersion { - return fmt.Errorf("peer [%x]: protocol version mismatch %d != %d", peer.ID(), peerVersion, ProtocolVersion) - } - - // only version is mandatory, subsequent parameters are optional - powRaw, err := s.Uint() - if err == nil { - pow := math.Float64frombits(powRaw) - if math.IsInf(pow, 0) || math.IsNaN(pow) || pow < 0.0 { - return fmt.Errorf("peer [%x] sent bad status message: invalid pow", peer.ID()) - } - peer.powRequirement = pow - - var bloom []byte - err = s.Decode(&bloom) - if err == nil { - sz := len(bloom) - if sz != BloomFilterSize && sz != 0 { - return fmt.Errorf("peer [%x] sent bad status message: wrong bloom filter size %d", peer.ID(), sz) - } - peer.setBloomFilter(bloom) - } - } - - isRemotePeerLightNode, _ := s.Bool() - if isRemotePeerLightNode && isLightNode && isRestrictedLightNodeConnection { - return fmt.Errorf("peer [%x] is useless: two light client communication restricted", peer.ID()) - } - - if err := <-errc; err != nil { - return fmt.Errorf("peer [%x] failed to send status packet: %v", peer.ID(), err) - } - return nil -} - -// update executes periodic operations on the peer, including message transmission -// and expiration. -func (peer *Peer) update() { - defer peer.wg.Done() - // Start the tickers for the updates - expire := time.NewTicker(expirationCycle) - defer expire.Stop() - transmit := time.NewTicker(transmissionCycle) - defer transmit.Stop() - - // Loop and transmit until termination is requested - for { - select { - case <-expire.C: - peer.expire() - - case <-transmit.C: - if err := peer.broadcast(); err != nil { - log.Trace("broadcast failed", "reason", err, "peer", peer.ID()) - return - } - - case <-peer.quit: - return - } - } -} - -// mark marks an envelope known to the peer so that it won't be sent back. -func (peer *Peer) mark(envelope *Envelope) { - peer.known.Add(envelope.Hash()) -} - -// marked checks if an envelope is already known to the remote peer. -func (peer *Peer) marked(envelope *Envelope) bool { - return peer.known.Contains(envelope.Hash()) -} - -// expire iterates over all the known envelopes in the host and removes all -// expired (unknown) ones from the known list. -func (peer *Peer) expire() { - unmark := make(map[common.Hash]struct{}) - peer.known.Each(func(v interface{}) bool { - if !peer.host.isEnvelopeCached(v.(common.Hash)) { - unmark[v.(common.Hash)] = struct{}{} - } - return true - }) - // Dump all known but no longer cached - for hash := range unmark { - peer.known.Remove(hash) - } -} - -// broadcast iterates over the collection of envelopes and transmits yet unknown -// ones over the network. -func (peer *Peer) broadcast() error { - envelopes := peer.host.Envelopes() - bundle := make([]*Envelope, 0, len(envelopes)) - for _, envelope := range envelopes { - if !peer.marked(envelope) && envelope.PoW() >= peer.powRequirement && peer.bloomMatch(envelope) { - bundle = append(bundle, envelope) - } - } - - if len(bundle) > 0 { - // transmit the batch of envelopes - if err := p2p.Send(peer.ws, messagesCode, bundle); err != nil { - return err - } - - // mark envelopes only if they were successfully sent - for _, e := range bundle { - peer.mark(e) - } - - log.Trace("broadcast", "num. messages", len(bundle)) - } - return nil -} - -// ID returns a peer's id -func (peer *Peer) ID() []byte { - id := peer.peer.ID() - return id[:] -} - -func (peer *Peer) notifyAboutPowRequirementChange(pow float64) error { - i := math.Float64bits(pow) - return p2p.Send(peer.ws, powRequirementCode, i) -} - -func (peer *Peer) notifyAboutBloomFilterChange(bloom []byte) error { - return p2p.Send(peer.ws, bloomFilterExCode, bloom) -} - -func (peer *Peer) bloomMatch(env *Envelope) bool { - peer.bloomMu.Lock() - defer peer.bloomMu.Unlock() - return peer.fullNode || BloomFilterMatch(peer.bloomFilter, env.Bloom()) -} - -func (peer *Peer) setBloomFilter(bloom []byte) { - peer.bloomMu.Lock() - defer peer.bloomMu.Unlock() - peer.bloomFilter = bloom - peer.fullNode = isFullNode(bloom) - if peer.fullNode && peer.bloomFilter == nil { - peer.bloomFilter = MakeFullNodeBloom() - } -} - -func MakeFullNodeBloom() []byte { - bloom := make([]byte, BloomFilterSize) - for i := 0; i < BloomFilterSize; i++ { - bloom[i] = 0xFF - } - return bloom -} diff --git a/whisper/whisperv6/topic.go b/whisper/whisperv6/topic.go deleted file mode 100644 index ee255f785d..0000000000 --- a/whisper/whisperv6/topic.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Contains the Whisper protocol Topic element. - -package whisperv6 - -import ( - "github.com/ethereum/go-ethereum/common/hexutil" -) - -// TopicType represents a cryptographically secure, probabilistic partial -// classifications of a message, determined as the first (left) 4 bytes of the -// SHA3 hash of some arbitrary data given by the original author of the message. -type TopicType [TopicLength]byte - -// BytesToTopic converts from the byte array representation of a topic -// into the TopicType type. -func BytesToTopic(b []byte) (t TopicType) { - sz := TopicLength - if x := len(b); x < TopicLength { - sz = x - } - for i := 0; i < sz; i++ { - t[i] = b[i] - } - return t -} - -// String converts a topic byte array to a string representation. -func (t *TopicType) String() string { - return hexutil.Encode(t[:]) -} - -// MarshalText returns the hex representation of t. -func (t TopicType) MarshalText() ([]byte, error) { - return hexutil.Bytes(t[:]).MarshalText() -} - -// UnmarshalText parses a hex representation to a topic. -func (t *TopicType) UnmarshalText(input []byte) error { - return hexutil.UnmarshalFixedText("Topic", input, t[:]) -} diff --git a/whisper/whisperv6/topic_test.go b/whisper/whisperv6/topic_test.go deleted file mode 100644 index 454afe0de1..0000000000 --- a/whisper/whisperv6/topic_test.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "encoding/json" - "testing" -) - -var topicStringTests = []struct { - topic TopicType - str string -}{ - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, str: "0x00000000"}, - {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, str: "0x007f80ff"}, - {topic: TopicType{0xff, 0x80, 0x7f, 0x00}, str: "0xff807f00"}, - {topic: TopicType{0xf2, 0x6e, 0x77, 0x79}, str: "0xf26e7779"}, -} - -func TestTopicString(t *testing.T) { - for i, tst := range topicStringTests { - s := tst.topic.String() - if s != tst.str { - t.Fatalf("failed test %d: have %s, want %s.", i, s, tst.str) - } - } -} - -var bytesToTopicTests = []struct { - data []byte - topic TopicType -}{ - {topic: TopicType{0x8f, 0x9a, 0x2b, 0x7d}, data: []byte{0x8f, 0x9a, 0x2b, 0x7d}}, - {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, data: []byte{0x00, 0x7f, 0x80, 0xff}}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{0x00, 0x00, 0x00, 0x00}}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{0x00, 0x00, 0x00}}, - {topic: TopicType{0x01, 0x00, 0x00, 0x00}, data: []byte{0x01}}, - {topic: TopicType{0x00, 0xfe, 0x00, 0x00}, data: []byte{0x00, 0xfe}}, - {topic: TopicType{0xea, 0x1d, 0x43, 0x00}, data: []byte{0xea, 0x1d, 0x43}}, - {topic: TopicType{0x6f, 0x3c, 0xb0, 0xdd}, data: []byte{0x6f, 0x3c, 0xb0, 0xdd, 0x0f, 0x00, 0x90}}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{}}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: nil}, -} - -var unmarshalTestsGood = []struct { - topic TopicType - data []byte -}{ - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x00000000"`)}, - {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, data: []byte(`"0x007f80ff"`)}, - {topic: TopicType{0xff, 0x80, 0x7f, 0x00}, data: []byte(`"0xff807f00"`)}, - {topic: TopicType{0xf2, 0x6e, 0x77, 0x79}, data: []byte(`"0xf26e7779"`)}, -} - -var unmarshalTestsBad = []struct { - topic TopicType - data []byte -}{ - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x0000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x000000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x0000000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"000000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0000000000"`)}, - {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"abcdefg0"`)}, -} - -var unmarshalTestsUgly = []struct { - topic TopicType - data []byte -}{ - {topic: TopicType{0x01, 0x00, 0x00, 0x00}, data: []byte(`"0x00000001"`)}, -} - -func TestBytesToTopic(t *testing.T) { - for i, tst := range bytesToTopicTests { - top := BytesToTopic(tst.data) - if top != tst.topic { - t.Fatalf("failed test %d: have %v, want %v.", i, t, tst.topic) - } - } -} - -func TestUnmarshalTestsGood(t *testing.T) { - for i, tst := range unmarshalTestsGood { - var top TopicType - err := json.Unmarshal(tst.data, &top) - if err != nil { - t.Errorf("failed test %d. input: %v. err: %v", i, tst.data, err) - } else if top != tst.topic { - t.Errorf("failed test %d: have %v, want %v.", i, t, tst.topic) - } - } -} - -func TestUnmarshalTestsBad(t *testing.T) { - // in this test UnmarshalJSON() is supposed to fail - for i, tst := range unmarshalTestsBad { - var top TopicType - err := json.Unmarshal(tst.data, &top) - if err == nil { - t.Fatalf("failed test %d. input: %v.", i, tst.data) - } - } -} - -func TestUnmarshalTestsUgly(t *testing.T) { - // in this test UnmarshalJSON() is NOT supposed to fail, but result should be wrong - for i, tst := range unmarshalTestsUgly { - var top TopicType - err := json.Unmarshal(tst.data, &top) - if err != nil { - t.Errorf("failed test %d. input: %v.", i, tst.data) - } else if top == tst.topic { - t.Errorf("failed test %d: have %v, want %v.", i, top, tst.topic) - } - } -} diff --git a/whisper/whisperv6/whisper.go b/whisper/whisperv6/whisper.go deleted file mode 100644 index ac61036705..0000000000 --- a/whisper/whisperv6/whisper.go +++ /dev/null @@ -1,1140 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "bytes" - "crypto/ecdsa" - "crypto/sha256" - "fmt" - "math" - "runtime" - "sync" - "time" - - mapset "github.com/deckarep/golang-set" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/rpc" - "github.com/syndtr/goleveldb/leveldb/errors" - "golang.org/x/crypto/pbkdf2" - "golang.org/x/sync/syncmap" -) - -// Statistics holds several message-related counter for analytics -// purposes. -type Statistics struct { - messagesCleared int - memoryCleared int - memoryUsed int - cycles int - totalMessagesCleared int -} - -const ( - maxMsgSizeIdx = iota // Maximal message length allowed by the whisper node - overflowIdx // Indicator of message queue overflow - minPowIdx // Minimal PoW required by the whisper node - minPowToleranceIdx // Minimal PoW tolerated by the whisper node for a limited time - bloomFilterIdx // Bloom filter for topics of interest for this node - bloomFilterToleranceIdx // Bloom filter tolerated by the whisper node for a limited time - lightClientModeIdx // Light client mode. (does not forward any messages) - restrictConnectionBetweenLightClientsIdx // Restrict connection between two light clients -) - -// Whisper represents a dark communication interface through the Ethereum -// network, using its very own P2P communication layer. -type Whisper struct { - protocol p2p.Protocol // Protocol description and parameters - filters *Filters // Message filters installed with Subscribe function - - privateKeys map[string]*ecdsa.PrivateKey // Private key storage - symKeys map[string][]byte // Symmetric key storage - keyMu sync.RWMutex // Mutex associated with key storages - - poolMu sync.RWMutex // Mutex to sync the message and expiration pools - envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node - expirations map[uint32]mapset.Set // Message expiration pool - - peerMu sync.RWMutex // Mutex to sync the active peer set - peers map[*Peer]struct{} // Set of currently active peers - - messageQueue chan *Envelope // Message queue for normal whisper messages - p2pMsgQueue chan *Envelope // Message queue for peer-to-peer messages (not to be forwarded any further) - quit chan struct{} // Channel used for graceful exit - - settings syncmap.Map // holds configuration settings that can be dynamically changed - - syncAllowance int // maximum time in seconds allowed to process the whisper-related messages - - statsMu sync.Mutex // guard stats - stats Statistics // Statistics of whisper node - - mailServer MailServer // MailServer interface - - wg sync.WaitGroup -} - -// New creates a Whisper client ready to communicate through the Ethereum P2P network. -func New(stack *node.Node, cfg *Config) (*Whisper, error) { - if cfg == nil { - cfg = &DefaultConfig - } - - whisper := &Whisper{ - privateKeys: make(map[string]*ecdsa.PrivateKey), - symKeys: make(map[string][]byte), - envelopes: make(map[common.Hash]*Envelope), - expirations: make(map[uint32]mapset.Set), - peers: make(map[*Peer]struct{}), - messageQueue: make(chan *Envelope, messageQueueLimit), - p2pMsgQueue: make(chan *Envelope, messageQueueLimit), - quit: make(chan struct{}), - syncAllowance: DefaultSyncAllowance, - } - - whisper.filters = NewFilters(whisper) - - whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW) - whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize) - whisper.settings.Store(overflowIdx, false) - whisper.settings.Store(restrictConnectionBetweenLightClientsIdx, cfg.RestrictConnectionBetweenLightClients) - - // p2p whisper sub protocol handler - whisper.protocol = p2p.Protocol{ - Name: ProtocolName, - Version: uint(ProtocolVersion), - Length: NumberOfMessageCodes, - Run: whisper.HandlePeer, - NodeInfo: func() interface{} { - return map[string]interface{}{ - "version": ProtocolVersionStr, - "maxMessageSize": whisper.MaxMessageSize(), - "minimumPoW": whisper.MinPow(), - } - }, - } - - stack.RegisterAPIs(whisper.APIs()) - stack.RegisterProtocols(whisper.Protocols()) - stack.RegisterLifecycle(whisper) - return whisper, nil -} - -// MinPow returns the PoW value required by this node. -func (whisper *Whisper) MinPow() float64 { - val, exist := whisper.settings.Load(minPowIdx) - if !exist || val == nil { - return DefaultMinimumPoW - } - v, ok := val.(float64) - if !ok { - log.Error("Error loading minPowIdx, using default") - return DefaultMinimumPoW - } - return v -} - -// MinPowTolerance returns the value of minimum PoW which is tolerated for a limited -// time after PoW was changed. If sufficient time have elapsed or no change of PoW -// have ever occurred, the return value will be the same as return value of MinPow(). -func (whisper *Whisper) MinPowTolerance() float64 { - val, exist := whisper.settings.Load(minPowToleranceIdx) - if !exist || val == nil { - return DefaultMinimumPoW - } - return val.(float64) -} - -// BloomFilter returns the aggregated bloom filter for all the topics of interest. -// The nodes are required to send only messages that match the advertised bloom filter. -// If a message does not match the bloom, it will tantamount to spam, and the peer will -// be disconnected. -func (whisper *Whisper) BloomFilter() []byte { - val, exist := whisper.settings.Load(bloomFilterIdx) - if !exist || val == nil { - return nil - } - return val.([]byte) -} - -// BloomFilterTolerance returns the bloom filter which is tolerated for a limited -// time after new bloom was advertised to the peers. If sufficient time have elapsed -// or no change of bloom filter have ever occurred, the return value will be the same -// as return value of BloomFilter(). -func (whisper *Whisper) BloomFilterTolerance() []byte { - val, exist := whisper.settings.Load(bloomFilterToleranceIdx) - if !exist || val == nil { - return nil - } - return val.([]byte) -} - -// MaxMessageSize returns the maximum accepted message size. -func (whisper *Whisper) MaxMessageSize() uint32 { - val, _ := whisper.settings.Load(maxMsgSizeIdx) - return val.(uint32) -} - -// Overflow returns an indication if the message queue is full. -func (whisper *Whisper) Overflow() bool { - val, _ := whisper.settings.Load(overflowIdx) - return val.(bool) -} - -// APIs returns the RPC descriptors the Whisper implementation offers -func (whisper *Whisper) APIs() []rpc.API { - return []rpc.API{ - { - Namespace: ProtocolName, - Version: ProtocolVersionStr, - Service: NewPublicWhisperAPI(whisper), - Public: true, - }, - } -} - -// RegisterServer registers MailServer interface. -// MailServer will process all the incoming messages with p2pRequestCode. -func (whisper *Whisper) RegisterServer(server MailServer) { - whisper.mailServer = server -} - -// Protocols returns the whisper sub-protocols ran by this particular client. -func (whisper *Whisper) Protocols() []p2p.Protocol { - return []p2p.Protocol{whisper.protocol} -} - -// Version returns the whisper sub-protocols version number. -func (whisper *Whisper) Version() uint { - return whisper.protocol.Version -} - -// SetMaxMessageSize sets the maximal message size allowed by this node -func (whisper *Whisper) SetMaxMessageSize(size uint32) error { - if size > MaxMessageSize { - return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize) - } - whisper.settings.Store(maxMsgSizeIdx, size) - return nil -} - -// SetBloomFilter sets the new bloom filter -func (whisper *Whisper) SetBloomFilter(bloom []byte) error { - if len(bloom) != BloomFilterSize { - return fmt.Errorf("invalid bloom filter size: %d", len(bloom)) - } - - b := make([]byte, BloomFilterSize) - copy(b, bloom) - - whisper.settings.Store(bloomFilterIdx, b) - whisper.notifyPeersAboutBloomFilterChange(b) - - whisper.wg.Add(1) - go func() { - // allow some time before all the peers have processed the notification - defer whisper.wg.Done() - ticker := time.NewTicker(time.Duration(whisper.syncAllowance) * time.Second) - defer ticker.Stop() - - <-ticker.C - whisper.settings.Store(bloomFilterToleranceIdx, b) - }() - - return nil -} - -// SetMinimumPoW sets the minimal PoW required by this node -func (whisper *Whisper) SetMinimumPoW(val float64) error { - if val < 0.0 { - return fmt.Errorf("invalid PoW: %f", val) - } - - whisper.settings.Store(minPowIdx, val) - whisper.notifyPeersAboutPowRequirementChange(val) - - whisper.wg.Add(1) - go func() { - defer whisper.wg.Done() - // allow some time before all the peers have processed the notification - ticker := time.NewTicker(time.Duration(whisper.syncAllowance) * time.Second) - defer ticker.Stop() - - <-ticker.C - whisper.settings.Store(minPowToleranceIdx, val) - }() - - return nil -} - -// SetMinimumPowTest sets the minimal PoW in test environment -func (whisper *Whisper) SetMinimumPowTest(val float64) { - whisper.settings.Store(minPowIdx, val) - whisper.notifyPeersAboutPowRequirementChange(val) - whisper.settings.Store(minPowToleranceIdx, val) -} - -//SetLightClientMode makes node light client (does not forward any messages) -func (whisper *Whisper) SetLightClientMode(v bool) { - whisper.settings.Store(lightClientModeIdx, v) -} - -//LightClientMode indicates is this node is light client (does not forward any messages) -func (whisper *Whisper) LightClientMode() bool { - val, exist := whisper.settings.Load(lightClientModeIdx) - if !exist || val == nil { - return false - } - v, ok := val.(bool) - return v && ok -} - -//LightClientModeConnectionRestricted indicates that connection to light client in light client mode not allowed -func (whisper *Whisper) LightClientModeConnectionRestricted() bool { - val, exist := whisper.settings.Load(restrictConnectionBetweenLightClientsIdx) - if !exist || val == nil { - return false - } - v, ok := val.(bool) - return v && ok -} - -func (whisper *Whisper) notifyPeersAboutPowRequirementChange(pow float64) { - arr := whisper.getPeers() - for _, p := range arr { - err := p.notifyAboutPowRequirementChange(pow) - if err != nil { - // allow one retry - err = p.notifyAboutPowRequirementChange(pow) - } - if err != nil { - log.Warn("failed to notify peer about new pow requirement", "peer", p.ID(), "error", err) - } - } -} - -func (whisper *Whisper) notifyPeersAboutBloomFilterChange(bloom []byte) { - arr := whisper.getPeers() - for _, p := range arr { - err := p.notifyAboutBloomFilterChange(bloom) - if err != nil { - // allow one retry - err = p.notifyAboutBloomFilterChange(bloom) - } - if err != nil { - log.Warn("failed to notify peer about new bloom filter", "peer", p.ID(), "error", err) - } - } -} - -func (whisper *Whisper) getPeers() []*Peer { - arr := make([]*Peer, len(whisper.peers)) - i := 0 - whisper.peerMu.Lock() - defer whisper.peerMu.Unlock() - for p := range whisper.peers { - arr[i] = p - i++ - } - return arr -} - -// getPeer retrieves peer by ID -func (whisper *Whisper) getPeer(peerID []byte) (*Peer, error) { - whisper.peerMu.Lock() - defer whisper.peerMu.Unlock() - for p := range whisper.peers { - id := p.peer.ID() - if bytes.Equal(peerID, id[:]) { - return p, nil - } - } - return nil, fmt.Errorf("could not find peer with ID: %x", peerID) -} - -// AllowP2PMessagesFromPeer marks specific peer trusted, -// which will allow it to send historic (expired) messages. -func (whisper *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error { - p, err := whisper.getPeer(peerID) - if err != nil { - return err - } - p.trusted = true - return nil -} - -// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer, -// which is known to implement MailServer interface, and is supposed to process this -// request and respond with a number of peer-to-peer messages (possibly expired), -// which are not supposed to be forwarded any further. -// The whisper protocol is agnostic of the format and contents of envelope. -func (whisper *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error { - p, err := whisper.getPeer(peerID) - if err != nil { - return err - } - p.trusted = true - return p2p.Send(p.ws, p2pRequestCode, envelope) -} - -// SendP2PMessage sends a peer-to-peer message to a specific peer. -func (whisper *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error { - p, err := whisper.getPeer(peerID) - if err != nil { - return err - } - return whisper.SendP2PDirect(p, envelope) -} - -// SendP2PDirect sends a peer-to-peer message to a specific peer. -func (whisper *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error { - return p2p.Send(peer.ws, p2pMessageCode, envelope) -} - -// NewKeyPair generates a new cryptographic identity for the client, and injects -// it into the known identities for message decryption. Returns ID of the new key pair. -func (whisper *Whisper) NewKeyPair() (string, error) { - key, err := crypto.GenerateKey() - if err != nil || !validatePrivateKey(key) { - key, err = crypto.GenerateKey() // retry once - } - if err != nil { - return "", err - } - if !validatePrivateKey(key) { - return "", fmt.Errorf("failed to generate valid key") - } - - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - - whisper.keyMu.Lock() - defer whisper.keyMu.Unlock() - - if whisper.privateKeys[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - whisper.privateKeys[id] = key - return id, nil -} - -// DeleteKeyPair deletes the specified key if it exists. -func (whisper *Whisper) DeleteKeyPair(key string) bool { - whisper.keyMu.Lock() - defer whisper.keyMu.Unlock() - - if whisper.privateKeys[key] != nil { - delete(whisper.privateKeys, key) - return true - } - return false -} - -// AddKeyPair imports a asymmetric private key and returns it identifier. -func (whisper *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - - whisper.keyMu.Lock() - whisper.privateKeys[id] = key - whisper.keyMu.Unlock() - - return id, nil -} - -// HasKeyPair checks if the whisper node is configured with the private key -// of the specified public pair. -func (whisper *Whisper) HasKeyPair(id string) bool { - whisper.keyMu.RLock() - defer whisper.keyMu.RUnlock() - return whisper.privateKeys[id] != nil -} - -// GetPrivateKey retrieves the private key of the specified identity. -func (whisper *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { - whisper.keyMu.RLock() - defer whisper.keyMu.RUnlock() - key := whisper.privateKeys[id] - if key == nil { - return nil, fmt.Errorf("invalid id") - } - return key, nil -} - -// GenerateSymKey generates a random symmetric key and stores it under id, -// which is then returned. Will be used in the future for session key exchange. -func (whisper *Whisper) GenerateSymKey() (string, error) { - key, err := generateSecureRandomData(aesKeyLength) - if err != nil { - return "", err - } else if !validateDataIntegrity(key, aesKeyLength) { - return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") - } - - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - - whisper.keyMu.Lock() - defer whisper.keyMu.Unlock() - - if whisper.symKeys[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - whisper.symKeys[id] = key - return id, nil -} - -// AddSymKeyDirect stores the key, and returns its id. -func (whisper *Whisper) AddSymKeyDirect(key []byte) (string, error) { - if len(key) != aesKeyLength { - return "", fmt.Errorf("wrong key size: %d", len(key)) - } - - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - - whisper.keyMu.Lock() - defer whisper.keyMu.Unlock() - - if whisper.symKeys[id] != nil { - return "", fmt.Errorf("failed to generate unique ID") - } - whisper.symKeys[id] = key - return id, nil -} - -// AddSymKeyFromPassword generates the key from password, stores it, and returns its id. -func (whisper *Whisper) AddSymKeyFromPassword(password string) (string, error) { - id, err := GenerateRandomID() - if err != nil { - return "", fmt.Errorf("failed to generate ID: %s", err) - } - if whisper.HasSymKey(id) { - return "", fmt.Errorf("failed to generate unique ID") - } - - // kdf should run no less than 0.1 seconds on an average computer, - // because it's an once in a session experience - derived := pbkdf2.Key([]byte(password), nil, 65356, aesKeyLength, sha256.New) - if err != nil { - return "", err - } - - whisper.keyMu.Lock() - defer whisper.keyMu.Unlock() - - // double check is necessary, because deriveKeyMaterial() is very slow - if whisper.symKeys[id] != nil { - return "", fmt.Errorf("critical error: failed to generate unique ID") - } - whisper.symKeys[id] = derived - return id, nil -} - -// HasSymKey returns true if there is a key associated with the given id. -// Otherwise returns false. -func (whisper *Whisper) HasSymKey(id string) bool { - whisper.keyMu.RLock() - defer whisper.keyMu.RUnlock() - return whisper.symKeys[id] != nil -} - -// DeleteSymKey deletes the key associated with the name string if it exists. -func (whisper *Whisper) DeleteSymKey(id string) bool { - whisper.keyMu.Lock() - defer whisper.keyMu.Unlock() - if whisper.symKeys[id] != nil { - delete(whisper.symKeys, id) - return true - } - return false -} - -// GetSymKey returns the symmetric key associated with the given id. -func (whisper *Whisper) GetSymKey(id string) ([]byte, error) { - whisper.keyMu.RLock() - defer whisper.keyMu.RUnlock() - if whisper.symKeys[id] != nil { - return whisper.symKeys[id], nil - } - return nil, fmt.Errorf("non-existent key ID") -} - -// Subscribe installs a new message handler used for filtering, decrypting -// and subsequent storing of incoming messages. -func (whisper *Whisper) Subscribe(f *Filter) (string, error) { - s, err := whisper.filters.Install(f) - if err == nil { - whisper.updateBloomFilter(f) - } - return s, err -} - -// updateBloomFilter recalculates the new value of bloom filter, -// and informs the peers if necessary. -func (whisper *Whisper) updateBloomFilter(f *Filter) { - aggregate := make([]byte, BloomFilterSize) - for _, t := range f.Topics { - top := BytesToTopic(t) - b := TopicToBloom(top) - aggregate = addBloom(aggregate, b) - } - - if !BloomFilterMatch(whisper.BloomFilter(), aggregate) { - // existing bloom filter must be updated - aggregate = addBloom(whisper.BloomFilter(), aggregate) - whisper.SetBloomFilter(aggregate) - } -} - -// GetFilter returns the filter by id. -func (whisper *Whisper) GetFilter(id string) *Filter { - return whisper.filters.Get(id) -} - -// Unsubscribe removes an installed message handler. -func (whisper *Whisper) Unsubscribe(id string) error { - ok := whisper.filters.Uninstall(id) - if !ok { - return fmt.Errorf("Unsubscribe: Invalid ID") - } - return nil -} - -// Send injects a message into the whisper send queue, to be distributed in the -// network in the coming cycles. -func (whisper *Whisper) Send(envelope *Envelope) error { - ok, err := whisper.add(envelope, false) - if err == nil && !ok { - return fmt.Errorf("failed to add envelope") - } - return err -} - -// Start implements node.Lifecycle, starting the background data propagation thread -// of the Whisper protocol. -func (whisper *Whisper) Start() error { - log.Info("started whisper v." + ProtocolVersionStr) - whisper.wg.Add(1) - go whisper.update() - - numCPU := runtime.NumCPU() - for i := 0; i < numCPU; i++ { - whisper.wg.Add(1) - go whisper.processQueue() - } - - return nil -} - -// Stop implements node.Lifecycle, stopping the background data propagation thread -// of the Whisper protocol. -func (whisper *Whisper) Stop() error { - close(whisper.quit) - whisper.wg.Wait() - log.Info("whisper stopped") - return nil -} - -// HandlePeer is called by the underlying P2P layer when the whisper sub-protocol -// connection is negotiated. -func (whisper *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { - // Create the new peer and start tracking it - whisperPeer := newPeer(whisper, peer, rw) - - whisper.peerMu.Lock() - whisper.peers[whisperPeer] = struct{}{} - whisper.peerMu.Unlock() - - defer func() { - whisper.peerMu.Lock() - delete(whisper.peers, whisperPeer) - whisper.peerMu.Unlock() - }() - - // Run the peer handshake and state updates - if err := whisperPeer.handshake(); err != nil { - return err - } - whisperPeer.start() - defer whisperPeer.stop() - - return whisper.runMessageLoop(whisperPeer, rw) -} - -// runMessageLoop reads and processes inbound messages directly to merge into client-global state. -func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { - for { - // fetch the next packet - packet, err := rw.ReadMsg() - if err != nil { - log.Info("message loop", "peer", p.peer.ID(), "err", err) - return err - } - if packet.Size > whisper.MaxMessageSize() { - log.Warn("oversized message received", "peer", p.peer.ID()) - return errors.New("oversized message received") - } - - switch packet.Code { - case statusCode: - // this should not happen, but no need to panic; just ignore this message. - log.Warn("unxepected status message received", "peer", p.peer.ID()) - case messagesCode: - // decode the contained envelopes - var envelopes []*Envelope - if err := packet.Decode(&envelopes); err != nil { - log.Warn("failed to decode envelopes, peer will be disconnected", "peer", p.peer.ID(), "err", err) - return errors.New("invalid envelopes") - } - - trouble := false - for _, env := range envelopes { - cached, err := whisper.add(env, whisper.LightClientMode()) - if err != nil { - trouble = true - log.Error("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err) - } - if cached { - p.mark(env) - } - } - - if trouble { - return errors.New("invalid envelope") - } - case powRequirementCode: - s := rlp.NewStream(packet.Payload, uint64(packet.Size)) - i, err := s.Uint() - if err != nil { - log.Warn("failed to decode powRequirementCode message, peer will be disconnected", "peer", p.peer.ID(), "err", err) - return errors.New("invalid powRequirementCode message") - } - f := math.Float64frombits(i) - if math.IsInf(f, 0) || math.IsNaN(f) || f < 0.0 { - log.Warn("invalid value in powRequirementCode message, peer will be disconnected", "peer", p.peer.ID(), "err", err) - return errors.New("invalid value in powRequirementCode message") - } - p.powRequirement = f - case bloomFilterExCode: - var bloom []byte - err := packet.Decode(&bloom) - if err == nil && len(bloom) != BloomFilterSize { - err = fmt.Errorf("wrong bloom filter size %d", len(bloom)) - } - - if err != nil { - log.Warn("failed to decode bloom filter exchange message, peer will be disconnected", "peer", p.peer.ID(), "err", err) - return errors.New("invalid bloom filter exchange message") - } - p.setBloomFilter(bloom) - case p2pMessageCode: - // peer-to-peer message, sent directly to peer bypassing PoW checks, etc. - // this message is not supposed to be forwarded to other peers, and - // therefore might not satisfy the PoW, expiry and other requirements. - // these messages are only accepted from the trusted peer. - if p.trusted { - var envelope Envelope - if err := packet.Decode(&envelope); err != nil { - log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) - return errors.New("invalid direct message") - } - whisper.postEvent(&envelope, true) - } - case p2pRequestCode: - // Must be processed if mail server is implemented. Otherwise ignore. - if whisper.mailServer != nil { - var request Envelope - if err := packet.Decode(&request); err != nil { - log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) - return errors.New("invalid p2p request") - } - whisper.mailServer.DeliverMail(p, &request) - } - default: - // New message types might be implemented in the future versions of Whisper. - // For forward compatibility, just ignore. - } - - packet.Discard() - } -} - -// add inserts a new envelope into the message pool to be distributed within the -// whisper network. It also inserts the envelope into the expiration pool at the -// appropriate time-stamp. In case of error, connection should be dropped. -// param isP2P indicates whether the message is peer-to-peer (should not be forwarded). -func (whisper *Whisper) add(envelope *Envelope, isP2P bool) (bool, error) { - now := uint32(time.Now().Unix()) - sent := envelope.Expiry - envelope.TTL - - if sent > now { - if sent-DefaultSyncAllowance > now { - return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) - } - // recalculate PoW, adjusted for the time difference, plus one second for latency - envelope.calculatePoW(sent - now + 1) - } - - if envelope.Expiry < now { - if envelope.Expiry+DefaultSyncAllowance*2 < now { - return false, fmt.Errorf("very old message") - } - log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) - return false, nil // drop envelope without error - } - - if uint32(envelope.size()) > whisper.MaxMessageSize() { - return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) - } - - if envelope.PoW() < whisper.MinPow() { - // maybe the value was recently changed, and the peers did not adjust yet. - // in this case the previous value is retrieved by MinPowTolerance() - // for a short period of peer synchronization. - if envelope.PoW() < whisper.MinPowTolerance() { - return false, fmt.Errorf("envelope with low PoW received: PoW=%f, hash=[%v]", envelope.PoW(), envelope.Hash().Hex()) - } - } - - if !BloomFilterMatch(whisper.BloomFilter(), envelope.Bloom()) { - // maybe the value was recently changed, and the peers did not adjust yet. - // in this case the previous value is retrieved by BloomFilterTolerance() - // for a short period of peer synchronization. - if !BloomFilterMatch(whisper.BloomFilterTolerance(), envelope.Bloom()) { - return false, fmt.Errorf("envelope does not match bloom filter, hash=[%v], bloom: \n%x \n%x \n%x", - envelope.Hash().Hex(), whisper.BloomFilter(), envelope.Bloom(), envelope.Topic) - } - } - - hash := envelope.Hash() - - whisper.poolMu.Lock() - _, alreadyCached := whisper.envelopes[hash] - if !alreadyCached { - whisper.envelopes[hash] = envelope - if whisper.expirations[envelope.Expiry] == nil { - whisper.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() - } - if !whisper.expirations[envelope.Expiry].Contains(hash) { - whisper.expirations[envelope.Expiry].Add(hash) - } - } - whisper.poolMu.Unlock() - - if alreadyCached { - log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) - } else { - log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) - whisper.statsMu.Lock() - whisper.stats.memoryUsed += envelope.size() - whisper.statsMu.Unlock() - whisper.postEvent(envelope, isP2P) // notify the local node about the new message - if whisper.mailServer != nil { - whisper.mailServer.Archive(envelope) - } - } - return true, nil -} - -// postEvent queues the message for further processing. -func (whisper *Whisper) postEvent(envelope *Envelope, isP2P bool) { - if isP2P { - whisper.p2pMsgQueue <- envelope - } else { - whisper.checkOverflow() - whisper.messageQueue <- envelope - } -} - -// checkOverflow checks if message queue overflow occurs and reports it if necessary. -func (whisper *Whisper) checkOverflow() { - queueSize := len(whisper.messageQueue) - - if queueSize == messageQueueLimit { - if !whisper.Overflow() { - whisper.settings.Store(overflowIdx, true) - log.Warn("message queue overflow") - } - } else if queueSize <= messageQueueLimit/2 { - if whisper.Overflow() { - whisper.settings.Store(overflowIdx, false) - log.Warn("message queue overflow fixed (back to normal)") - } - } -} - -// processQueue delivers the messages to the watchers during the lifetime of the whisper node. -func (whisper *Whisper) processQueue() { - defer whisper.wg.Done() - var e *Envelope - for { - select { - case <-whisper.quit: - return - - case e = <-whisper.messageQueue: - whisper.filters.NotifyWatchers(e, false) - - case e = <-whisper.p2pMsgQueue: - whisper.filters.NotifyWatchers(e, true) - } - } -} - -// update loops until the lifetime of the whisper node, updating its internal -// state by expiring stale messages from the pool. -func (whisper *Whisper) update() { - defer whisper.wg.Done() - // Start a ticker to check for expirations - expire := time.NewTicker(expirationCycle) - defer expire.Stop() - - // Repeat updates until termination is requested - for { - select { - case <-expire.C: - whisper.expire() - - case <-whisper.quit: - return - } - } -} - -// expire iterates over all the expiration timestamps, removing all stale -// messages from the pools. -func (whisper *Whisper) expire() { - whisper.poolMu.Lock() - defer whisper.poolMu.Unlock() - - whisper.statsMu.Lock() - defer whisper.statsMu.Unlock() - whisper.stats.reset() - now := uint32(time.Now().Unix()) - for expiry, hashSet := range whisper.expirations { - if expiry < now { - // Dump all expired messages and remove timestamp - hashSet.Each(func(v interface{}) bool { - sz := whisper.envelopes[v.(common.Hash)].size() - delete(whisper.envelopes, v.(common.Hash)) - whisper.stats.messagesCleared++ - whisper.stats.memoryCleared += sz - whisper.stats.memoryUsed -= sz - return false - }) - whisper.expirations[expiry].Clear() - delete(whisper.expirations, expiry) - } - } -} - -// Stats returns the whisper node statistics. -func (whisper *Whisper) Stats() Statistics { - whisper.statsMu.Lock() - defer whisper.statsMu.Unlock() - - return whisper.stats -} - -// Envelopes retrieves all the messages currently pooled by the node. -func (whisper *Whisper) Envelopes() []*Envelope { - whisper.poolMu.RLock() - defer whisper.poolMu.RUnlock() - - all := make([]*Envelope, 0, len(whisper.envelopes)) - for _, envelope := range whisper.envelopes { - all = append(all, envelope) - } - return all -} - -// isEnvelopeCached checks if envelope with specific hash has already been received and cached. -func (whisper *Whisper) isEnvelopeCached(hash common.Hash) bool { - whisper.poolMu.Lock() - defer whisper.poolMu.Unlock() - - _, exist := whisper.envelopes[hash] - return exist -} - -// reset resets the node's statistics after each expiry cycle. -func (s *Statistics) reset() { - s.cycles++ - s.totalMessagesCleared += s.messagesCleared - - s.memoryCleared = 0 - s.messagesCleared = 0 -} - -// ValidatePublicKey checks the format of the given public key. -func ValidatePublicKey(k *ecdsa.PublicKey) bool { - return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0 -} - -// validatePrivateKey checks the format of the given private key. -func validatePrivateKey(k *ecdsa.PrivateKey) bool { - if k == nil || k.D == nil || k.D.Sign() == 0 { - return false - } - return ValidatePublicKey(&k.PublicKey) -} - -// validateDataIntegrity returns false if the data have the wrong or contains all zeros, -// which is the simplest and the most common bug. -func validateDataIntegrity(k []byte, expectedSize int) bool { - if len(k) != expectedSize { - return false - } - if expectedSize > 3 && containsOnlyZeros(k) { - return false - } - return true -} - -// containsOnlyZeros checks if the data contain only zeros. -func containsOnlyZeros(data []byte) bool { - for _, b := range data { - if b != 0 { - return false - } - } - return true -} - -// bytesToUintLittleEndian converts the slice to 64-bit unsigned integer. -func bytesToUintLittleEndian(b []byte) (res uint64) { - mul := uint64(1) - for i := 0; i < len(b); i++ { - res += uint64(b[i]) * mul - mul *= 256 - } - return res -} - -// BytesToUintBigEndian converts the slice to 64-bit unsigned integer. -func BytesToUintBigEndian(b []byte) (res uint64) { - for i := 0; i < len(b); i++ { - res *= 256 - res += uint64(b[i]) - } - return res -} - -// GenerateRandomID generates a random string, which is then returned to be used as a key id -func GenerateRandomID() (id string, err error) { - buf, err := generateSecureRandomData(keyIDSize) - if err != nil { - return "", err - } - if !validateDataIntegrity(buf, keyIDSize) { - return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") - } - id = common.Bytes2Hex(buf) - return id, err -} - -func isFullNode(bloom []byte) bool { - if bloom == nil { - return true - } - for _, b := range bloom { - if b != 255 { - return false - } - } - return true -} - -func BloomFilterMatch(filter, sample []byte) bool { - if filter == nil { - return true - } - - for i := 0; i < BloomFilterSize; i++ { - f := filter[i] - s := sample[i] - if (f | s) != f { - return false - } - } - - return true -} - -func addBloom(a, b []byte) []byte { - c := make([]byte, BloomFilterSize) - for i := 0; i < BloomFilterSize; i++ { - c[i] = a[i] | b[i] - } - return c -} - -func StandaloneWhisperService(cfg *Config) *Whisper { - if cfg == nil { - cfg = &DefaultConfig - } - - whisper := &Whisper{ - privateKeys: make(map[string]*ecdsa.PrivateKey), - symKeys: make(map[string][]byte), - envelopes: make(map[common.Hash]*Envelope), - expirations: make(map[uint32]mapset.Set), - peers: make(map[*Peer]struct{}), - messageQueue: make(chan *Envelope, messageQueueLimit), - p2pMsgQueue: make(chan *Envelope, messageQueueLimit), - quit: make(chan struct{}), - syncAllowance: DefaultSyncAllowance, - } - - whisper.filters = NewFilters(whisper) - - whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW) - whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize) - whisper.settings.Store(overflowIdx, false) - whisper.settings.Store(restrictConnectionBetweenLightClientsIdx, cfg.RestrictConnectionBetweenLightClients) - - // p2p whisper sub protocol handler - whisper.protocol = p2p.Protocol{ - Name: ProtocolName, - Version: uint(ProtocolVersion), - Length: NumberOfMessageCodes, - Run: whisper.HandlePeer, - NodeInfo: func() interface{} { - return map[string]interface{}{ - "version": ProtocolVersionStr, - "maxMessageSize": whisper.MaxMessageSize(), - "minimumPoW": whisper.MinPow(), - } - }, - } - - return whisper -} diff --git a/whisper/whisperv6/whisper_test.go b/whisper/whisperv6/whisper_test.go deleted file mode 100644 index 7fb8f7c1cd..0000000000 --- a/whisper/whisperv6/whisper_test.go +++ /dev/null @@ -1,928 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package whisperv6 - -import ( - "bytes" - "crypto/ecdsa" - "crypto/sha256" - mrand "math/rand" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/node" - "golang.org/x/crypto/pbkdf2" -) - -func TestWhisperBasic(t *testing.T) { - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - shh := w.Protocols()[0] - if shh.Name != ProtocolName { - t.Fatalf("failed Protocol Name: %v.", shh.Name) - } - if uint64(shh.Version) != ProtocolVersion { - t.Fatalf("failed Protocol Version: %v.", shh.Version) - } - if shh.Length != NumberOfMessageCodes { - t.Fatalf("failed Protocol Length: %v.", shh.Length) - } - if shh.Run == nil { - t.Fatal("failed shh.Run.") - } - if uint64(w.Version()) != ProtocolVersion { - t.Fatalf("failed whisper Version: %v.", shh.Version) - } - if w.GetFilter("non-existent") != nil { - t.Fatal("failed GetFilter.") - } - - peerID := make([]byte, 64) - mrand.Read(peerID) - peer, _ := w.getPeer(peerID) - if peer != nil { - t.Fatal("found peer for random key.") - } - if err := w.AllowP2PMessagesFromPeer(peerID); err == nil { - t.Fatal("failed MarkPeerTrusted.") - } - exist := w.HasSymKey("non-existing") - if exist { - t.Fatal("failed HasSymKey.") - } - key, err := w.GetSymKey("non-existing") - if err == nil { - t.Fatalf("failed GetSymKey(non-existing): false positive. key=%v", key) - } - if key != nil { - t.Fatalf("failed GetSymKey: false positive. key=%v", key) - } - mail := w.Envelopes() - if len(mail) != 0 { - t.Fatalf("failed w.Envelopes(). length=%d", len(mail)) - } - - derived := pbkdf2.Key(peerID, nil, 65356, aesKeyLength, sha256.New) - if !validateDataIntegrity(derived, aesKeyLength) { - t.Fatalf("failed validateSymmetricKey with param = %v.", derived) - } - if containsOnlyZeros(derived) { - t.Fatalf("failed containsOnlyZeros with param = %v.", derived) - } - - buf := []byte{0xFF, 0xE5, 0x80, 0x2, 0} - le := bytesToUintLittleEndian(buf) - be := BytesToUintBigEndian(buf) - if le != uint64(0x280e5ff) { - t.Fatalf("failed bytesToIntLittleEndian: %d.", le) - } - if be != uint64(0xffe5800200) { - t.Fatalf("failed BytesToIntBigEndian: %d.", be) - } - - id, err := w.NewKeyPair() - if err != nil { - t.Fatalf("failed to generate new key pair: %v.", err) - } - pk, err := w.GetPrivateKey(id) - if err != nil { - t.Fatalf("failed to retrieve new key pair: %v.", err) - } - if !validatePrivateKey(pk) { - t.Fatalf("failed validatePrivateKey: %v.", pk) - } - if !ValidatePublicKey(&pk.PublicKey) { - t.Fatalf("failed ValidatePublicKey: %v.", pk) - } -} - -func TestWhisperAsymmetricKeyImport(t *testing.T) { - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - var privateKeys []*ecdsa.PrivateKey - for i := 0; i < 50; i++ { - id, err := w.NewKeyPair() - if err != nil { - t.Fatalf("could not generate key: %v", err) - } - - pk, err := w.GetPrivateKey(id) - if err != nil { - t.Fatalf("could not export private key: %v", err) - } - - privateKeys = append(privateKeys, pk) - - if !w.DeleteKeyPair(id) { - t.Fatal("could not delete private key") - } - } - - for _, pk := range privateKeys { - if _, err := w.AddKeyPair(pk); err != nil { - t.Fatalf("could not import private key: %v", err) - } - } -} - -func TestWhisperIdentityManagement(t *testing.T) { - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - id1, err := w.NewKeyPair() - if err != nil { - t.Fatalf("failed to generate new key pair: %s.", err) - } - id2, err := w.NewKeyPair() - if err != nil { - t.Fatalf("failed to generate new key pair: %s.", err) - } - pk1, err := w.GetPrivateKey(id1) - if err != nil { - t.Fatalf("failed to retrieve the key pair: %s.", err) - } - pk2, err := w.GetPrivateKey(id2) - if err != nil { - t.Fatalf("failed to retrieve the key pair: %s.", err) - } - - if !w.HasKeyPair(id1) { - t.Fatal("failed HasIdentity(pk1).") - } - if !w.HasKeyPair(id2) { - t.Fatal("failed HasIdentity(pk2).") - } - if pk1 == nil { - t.Fatal("failed GetIdentity(pk1).") - } - if pk2 == nil { - t.Fatal("failed GetIdentity(pk2).") - } - - if !validatePrivateKey(pk1) { - t.Fatal("pk1 is invalid.") - } - if !validatePrivateKey(pk2) { - t.Fatal("pk2 is invalid.") - } - - // Delete one identity - done := w.DeleteKeyPair(id1) - if !done { - t.Fatal("failed to delete id1.") - } - pk1, err = w.GetPrivateKey(id1) - if err == nil { - t.Fatalf("retrieve the key pair: false positive. key=%v", pk1) - } - pk2, err = w.GetPrivateKey(id2) - if err != nil { - t.Fatalf("failed to retrieve the key pair: %s.", err) - } - if w.HasKeyPair(id1) { - t.Fatal("failed DeleteIdentity(pub1): still exist.") - } - if !w.HasKeyPair(id2) { - t.Fatal("failed DeleteIdentity(pub1): pub2 does not exist.") - } - if pk1 != nil { - t.Fatal("failed DeleteIdentity(pub1): first key still exist.") - } - if pk2 == nil { - t.Fatal("failed DeleteIdentity(pub1): second key does not exist.") - } - - // Delete again non-existing identity - done = w.DeleteKeyPair(id1) - if done { - t.Fatal("delete id1: false positive.") - } - pk1, err = w.GetPrivateKey(id1) - if err == nil { - t.Fatalf("retrieve the key pair: false positive. key=%v", pk1) - } - pk2, err = w.GetPrivateKey(id2) - if err != nil { - t.Fatalf("failed to retrieve the key pair: %s.", err) - } - if w.HasKeyPair(id1) { - t.Fatal("failed delete non-existing identity: exist.") - } - if !w.HasKeyPair(id2) { - t.Fatal("failed delete non-existing identity: pub2 does not exist.") - } - if pk1 != nil { - t.Fatalf("failed delete non-existing identity: first key exist. key=%v", pk1) - } - if pk2 == nil { - t.Fatal("failed delete non-existing identity: second key does not exist.") - } - - // Delete second identity - done = w.DeleteKeyPair(id2) - if !done { - t.Fatal("failed to delete id2.") - } - pk1, err = w.GetPrivateKey(id1) - if err == nil { - t.Fatalf("retrieve the key pair: false positive. key=%v", pk1) - } - pk2, err = w.GetPrivateKey(id2) - if err == nil { - t.Fatalf("retrieve the key pair: false positive. key=%v", pk2) - } - if w.HasKeyPair(id1) { - t.Fatal("failed delete second identity: first identity exist.") - } - if w.HasKeyPair(id2) { - t.Fatal("failed delete second identity: still exist.") - } - if pk1 != nil { - t.Fatalf("failed delete second identity: first key exist. key=%v", pk1) - } - if pk2 != nil { - t.Fatalf("failed delete second identity: second key exist. key=%v", pk2) - } -} - -func TestWhisperSymKeyManagement(t *testing.T) { - InitSingleTest() - var ( - k1, k2 []byte - id2 = string("arbitrary-string-2") - ) - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - id1, err := w.GenerateSymKey() - if err != nil { - t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err) - } - - k1, err = w.GetSymKey(id1) - if err != nil { - t.Fatalf("failed GetSymKey(id1). err=%v", err) - } - k2, err = w.GetSymKey(id2) - if err == nil { - t.Fatalf("failed GetSymKey(id2): false positive. key=%v", k2) - } - if !w.HasSymKey(id1) { - t.Fatal("failed HasSymKey(id1).") - } - if w.HasSymKey(id2) { - t.Fatal("failed HasSymKey(id2): false positive.") - } - if k1 == nil { - t.Fatal("first key does not exist.") - } - if k2 != nil { - t.Fatalf("second key still exist. key=%v", k2) - } - - // add existing id, nothing should change - randomKey := make([]byte, aesKeyLength) - mrand.Read(randomKey) - id1, err = w.AddSymKeyDirect(randomKey) - if err != nil { - t.Fatalf("failed AddSymKey with seed %d: %s.", seed, err) - } - - k1, err = w.GetSymKey(id1) - if err != nil { - t.Fatalf("failed w.GetSymKey(id1). err=%v", err) - } - k2, err = w.GetSymKey(id2) - if err == nil { - t.Fatalf("failed w.GetSymKey(id2): false positive. key=%v", k2) - } - if !w.HasSymKey(id1) { - t.Fatal("failed w.HasSymKey(id1).") - } - if w.HasSymKey(id2) { - t.Fatal("failed w.HasSymKey(id2): false positive.") - } - if k1 == nil { - t.Fatal("first key does not exist.") - } - if !bytes.Equal(k1, randomKey) { - t.Fatal("k1 != randomKey.") - } - if k2 != nil { - t.Fatalf("second key already exist. key=%v", k2) - } - - id2, err = w.AddSymKeyDirect(randomKey) - if err != nil { - t.Fatalf("failed AddSymKey(id2) with seed %d: %s.", seed, err) - } - k1, err = w.GetSymKey(id1) - if err != nil { - t.Fatalf("failed w.GetSymKey(id1). err=%v", err) - } - k2, err = w.GetSymKey(id2) - if err != nil { - t.Fatalf("failed w.GetSymKey(id2). err=%v", err) - } - if !w.HasSymKey(id1) { - t.Fatal("HasSymKey(id1) failed.") - } - if !w.HasSymKey(id2) { - t.Fatal("HasSymKey(id2) failed.") - } - if k1 == nil { - t.Fatal("k1 does not exist.") - } - if k2 == nil { - t.Fatal("k2 does not exist.") - } - if !bytes.Equal(k1, k2) { - t.Fatal("k1 != k2.") - } - if !bytes.Equal(k1, randomKey) { - t.Fatal("k1 != randomKey.") - } - if len(k1) != aesKeyLength { - t.Fatalf("wrong length of k1. length=%d", len(k1)) - } - if len(k2) != aesKeyLength { - t.Fatalf("wrong length of k2. length=%d", len(k2)) - } - - w.DeleteSymKey(id1) - k1, err = w.GetSymKey(id1) - if err == nil { - t.Fatal("failed w.GetSymKey(id1): false positive.") - } - if k1 != nil { - t.Fatalf("failed GetSymKey(id1): false positive. key=%v", k1) - } - k2, err = w.GetSymKey(id2) - if err != nil { - t.Fatalf("failed w.GetSymKey(id2). err=%v", err) - } - if w.HasSymKey(id1) { - t.Fatal("failed to delete first key: still exist.") - } - if !w.HasSymKey(id2) { - t.Fatal("failed to delete first key: second key does not exist.") - } - if k2 == nil { - t.Fatal("failed to delete first key: second key is nil.") - } - - w.DeleteSymKey(id1) - w.DeleteSymKey(id2) - k1, err = w.GetSymKey(id1) - if err == nil { - t.Fatalf("failed w.GetSymKey(id1): false positive. key=%v", k1) - } - k2, err = w.GetSymKey(id2) - if err == nil { - t.Fatalf("failed w.GetSymKey(id2): false positive. key=%v", k2) - } - if k1 != nil || k2 != nil { - t.Fatal("k1 or k2 is not nil") - } - if w.HasSymKey(id1) { - t.Fatal("failed to delete second key: first key exist.") - } - if w.HasSymKey(id2) { - t.Fatal("failed to delete second key: still exist.") - } - if k1 != nil { - t.Fatal("failed to delete second key: first key is not nil.") - } - if k2 != nil { - t.Fatal("failed to delete second key: second key is not nil.") - } - - randomKey = make([]byte, aesKeyLength+1) - mrand.Read(randomKey) - _, err = w.AddSymKeyDirect(randomKey) - if err == nil { - t.Fatalf("added the key with wrong size, seed %d.", seed) - } - - const password = "arbitrary data here" - id1, err = w.AddSymKeyFromPassword(password) - if err != nil { - t.Fatalf("failed AddSymKeyFromPassword(id1) with seed %d: %s.", seed, err) - } - id2, err = w.AddSymKeyFromPassword(password) - if err != nil { - t.Fatalf("failed AddSymKeyFromPassword(id2) with seed %d: %s.", seed, err) - } - k1, err = w.GetSymKey(id1) - if err != nil { - t.Fatalf("failed w.GetSymKey(id1). err=%v", err) - } - k2, err = w.GetSymKey(id2) - if err != nil { - t.Fatalf("failed w.GetSymKey(id2). err=%v", err) - } - if !w.HasSymKey(id1) { - t.Fatal("HasSymKey(id1) failed.") - } - if !w.HasSymKey(id2) { - t.Fatal("HasSymKey(id2) failed.") - } - if !validateDataIntegrity(k2, aesKeyLength) { - t.Fatal("key validation failed.") - } - if !bytes.Equal(k1, k2) { - t.Fatal("k1 != k2.") - } -} - -func TestExpiry(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - w.SetMinimumPowTest(0.0000001) - defer w.SetMinimumPowTest(DefaultMinimumPoW) - w.Start() - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - params.TTL = 1 - - messagesCount := 5 - - // Send a few messages one after another. Due to low PoW and expiration buckets - // with one second resolution, it covers a case when there are multiple items - // in a single expiration bucket. - for i := 0; i < messagesCount; i++ { - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - err = w.Send(env) - if err != nil { - t.Fatalf("failed to send envelope with seed %d: %s.", seed, err) - } - } - - // wait till received or timeout - var received, expired bool - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - for j := 0; j < 20; j++ { - <-ticker.C - if len(w.Envelopes()) == messagesCount { - received = true - break - } - } - - if !received { - t.Fatalf("did not receive the sent envelope, seed: %d.", seed) - } - - // wait till expired or timeout - for j := 0; j < 20; j++ { - <-ticker.C - if len(w.Envelopes()) == 0 { - expired = true - break - } - } - - if !expired { - t.Fatalf("expire failed, seed: %d.", seed) - } -} - -func TestCustomization(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - defer w.SetMinimumPowTest(DefaultMinimumPoW) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start() - - const smallPoW = 0.00001 - - f, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - params.KeySym = f.KeySym - params.Topic = BytesToTopic(f.Topics[2]) - params.PoW = smallPoW - params.TTL = 3600 * 24 // one day - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - err = w.Send(env) - if err == nil { - t.Fatalf("successfully sent envelope with PoW %.06f, false positive (seed %d).", env.PoW(), seed) - } - - w.SetMinimumPowTest(smallPoW / 2) - err = w.Send(env) - if err != nil { - t.Fatalf("failed to send envelope with seed %d: %s.", seed, err) - } - - params.TTL++ - msg, err = NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err = msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - w.SetMaxMessageSize(uint32(env.size() - 1)) - err = w.Send(env) - if err == nil { - t.Fatalf("successfully sent oversized envelope (seed %d): false positive.", seed) - } - - w.SetMaxMessageSize(DefaultMaxMessageSize) - err = w.Send(env) - if err != nil { - t.Fatalf("failed to send second envelope with seed %d: %s.", seed, err) - } - - // wait till received or timeout - var received bool - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - for j := 0; j < 20; j++ { - <-ticker.C - if len(w.Envelopes()) > 1 { - received = true - break - } - } - - if !received { - t.Fatalf("did not receive the sent envelope, seed: %d.", seed) - } - - // check w.messages() - _, err = w.Subscribe(f) - if err != nil { - t.Fatalf("failed subscribe with seed %d: %s.", seed, err) - } - <-ticker.C - mail := f.Retrieve() - if len(mail) > 0 { - t.Fatalf("received premature mail. mail=%v", mail) - } -} - -func TestSymmetricSendCycle(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - defer w.SetMinimumPowTest(DefaultMinimumPoW) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start() - - filter1, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - filter1.PoW = DefaultMinimumPoW - - // Copy the first filter since some of its fields - // are randomly gnerated. - filter2 := &Filter{ - KeySym: filter1.KeySym, - Topics: filter1.Topics, - PoW: filter1.PoW, - AllowP2P: filter1.AllowP2P, - Messages: make(map[common.Hash]*ReceivedMessage), - } - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - filter1.Src = ¶ms.Src.PublicKey - filter2.Src = ¶ms.Src.PublicKey - - params.KeySym = filter1.KeySym - params.Topic = BytesToTopic(filter1.Topics[2]) - params.PoW = filter1.PoW - params.WorkTime = 10 - params.TTL = 50 - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - _, err = w.Subscribe(filter1) - if err != nil { - t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err) - } - - _, err = w.Subscribe(filter2) - if err != nil { - t.Fatalf("failed subscribe 2 with seed %d: %s.", seed, err) - } - - err = w.Send(env) - if err != nil { - t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err) - } - - // wait till received or timeout - var received bool - ticker := time.NewTicker(10 * time.Millisecond) - defer ticker.Stop() - for j := 0; j < 200; j++ { - <-ticker.C - if len(w.Envelopes()) > 0 { - received = true - break - } - } - - if !received { - t.Fatalf("did not receive the sent envelope, seed: %d.", seed) - } - - // check w.messages() - <-ticker.C - mail1 := filter1.Retrieve() - mail2 := filter2.Retrieve() - if len(mail2) == 0 { - t.Fatal("did not receive any email for filter 2.") - } - if len(mail1) == 0 { - t.Fatal("did not receive any email for filter 1.") - } - -} - -func TestSymmetricSendWithoutAKey(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - defer w.SetMinimumPowTest(DefaultMinimumPoW) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start() - - filter, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - filter.PoW = DefaultMinimumPoW - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - filter.Src = nil - - params.KeySym = filter.KeySym - params.Topic = BytesToTopic(filter.Topics[2]) - params.PoW = filter.PoW - params.WorkTime = 10 - params.TTL = 50 - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - _, err = w.Subscribe(filter) - if err != nil { - t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err) - } - - err = w.Send(env) - if err != nil { - t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err) - } - - // wait till received or timeout - var received bool - ticker := time.NewTicker(10 * time.Millisecond) - defer ticker.Stop() - for j := 0; j < 200; j++ { - <-ticker.C - if len(w.Envelopes()) > 0 { - received = true - break - } - } - - if !received { - t.Fatalf("did not receive the sent envelope, seed: %d.", seed) - } - - // check w.messages() - <-ticker.C - mail := filter.Retrieve() - if len(mail) == 0 { - t.Fatal("did not receive message in spite of not setting a public key") - } -} - -func TestSymmetricSendKeyMismatch(t *testing.T) { - InitSingleTest() - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - defer w.SetMinimumPowTest(DefaultMinimumPoW) - defer w.SetMaxMessageSize(DefaultMaxMessageSize) - w.Start() - - filter, err := generateFilter(t, true) - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - filter.PoW = DefaultMinimumPoW - - params, err := generateMessageParams() - if err != nil { - t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err) - } - - params.KeySym = filter.KeySym - params.Topic = BytesToTopic(filter.Topics[2]) - params.PoW = filter.PoW - params.WorkTime = 10 - params.TTL = 50 - msg, err := NewSentMessage(params) - if err != nil { - t.Fatalf("failed to create new message with seed %d: %s.", seed, err) - } - env, err := msg.Wrap(params) - if err != nil { - t.Fatalf("failed Wrap with seed %d: %s.", seed, err) - } - - _, err = w.Subscribe(filter) - if err != nil { - t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err) - } - - err = w.Send(env) - if err != nil { - t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err) - } - - // wait till received or timeout - var received bool - ticker := time.NewTicker(10 * time.Millisecond) - defer ticker.Stop() - for j := 0; j < 200; j++ { - <-ticker.C - if len(w.Envelopes()) > 0 { - received = true - break - } - } - - if !received { - t.Fatalf("did not receive the sent envelope, seed: %d.", seed) - } - - // check w.messages() - <-ticker.C - mail := filter.Retrieve() - if len(mail) > 0 { - t.Fatalf("received a message when keys weren't matching. message=%v", mail) - } -} - -func TestBloom(t *testing.T) { - topic := TopicType{0, 0, 255, 6} - b := TopicToBloom(topic) - x := make([]byte, BloomFilterSize) - x[0] = byte(1) - x[32] = byte(1) - x[BloomFilterSize-1] = byte(128) - if !BloomFilterMatch(x, b) || !BloomFilterMatch(b, x) { - t.Fatal("bloom filter does not match the mask") - } - - _, err := mrand.Read(b) - if err != nil { - t.Fatalf("math rand error. err=%v", err) - } - _, err = mrand.Read(x) - if err != nil { - t.Fatalf("math rand error. err=%v", err) - } - if !BloomFilterMatch(b, b) { - t.Fatal("bloom filter does not match self") - } - x = addBloom(x, b) - if !BloomFilterMatch(x, b) { - t.Fatal("bloom filter does not match combined bloom") - } - if !isFullNode(nil) { - t.Fatal("isFullNode did not recognize nil as full node") - } - x[17] = 254 - if isFullNode(x) { - t.Fatal("isFullNode false positive") - } - for i := 0; i < BloomFilterSize; i++ { - b[i] = byte(255) - } - if !isFullNode(b) { - t.Fatal("isFullNode false negative") - } - if BloomFilterMatch(x, b) { - t.Fatal("bloomFilterMatch false positive") - } - if !BloomFilterMatch(b, x) { - t.Fatal("bloomFilterMatch false negative") - } - - stack, w := newNodeWithWhisper(t) - defer stack.Close() - - f := w.BloomFilter() - if f != nil { - t.Fatal("wrong bloom on creation") - } - err = w.SetBloomFilter(x) - if err != nil { - t.Fatalf("failed to set bloom filter: %v", err) - } - f = w.BloomFilter() - if !BloomFilterMatch(f, x) || !BloomFilterMatch(x, f) { - t.Fatal("retireved wrong bloom filter") - } -} - -// newNodeWithWhisper creates a new node using a default config and -// creates and registers a new Whisper service on it. -func newNodeWithWhisper(t *testing.T) (*node.Node, *Whisper) { - stack, err := node.New(&node.DefaultConfig) - if err != nil { - t.Fatalf("could not create new node: %v", err) - } - w, err := New(stack, &DefaultConfig) - if err != nil { - t.Fatalf("could not create new whisper service: %v", err) - } - err = stack.Start() - if err != nil { - t.Fatalf("could not start node: %v", err) - } - return stack, w -} From 8327d1fdfc42b0d73520fe1af1e875b960f03ee1 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 8 Sep 2020 13:07:55 +0200 Subject: [PATCH 17/24] accounts/usbwallet, signer/core: show accounts from ledger legacy derivation paths (#21517) * accounts/usbwallet, signer/core: un-hide accounts from ledger legacy derivation paths * Update accounts/usbwallet/wallet.go * Update signer/core/api.go * Update signer/core/api.go --- accounts/usbwallet/wallet.go | 14 +++++++++----- signer/core/api.go | 33 +++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index ee539d9653..993c599346 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -368,18 +368,22 @@ func (w *wallet) selfDerive() { w.log.Warn("USB wallet nonce retrieval failed", "err", err) break } - // If the next account is empty, stop self-derivation, but add for the last base path + // We've just self-derived a new account, start tracking it locally + // unless the account was empty. + path := make(accounts.DerivationPath, len(nextPaths[i])) + copy(path[:], nextPaths[i][:]) if balance.Sign() == 0 && nonce == 0 { empty = true + // If it indeed was empty, make a log output for it anyway. In the case + // of legacy-ledger, the first account on the legacy-path will + // be shown to the user, even if we don't actively track it if i < len(nextAddrs)-1 { + w.log.Info("Skipping trakcking first account on legacy path, use personal.deriveAccount(,, false) to track", + "path", path, "address", nextAddrs[i]) break } } - // We've just self-derived a new account, start tracking it locally - path := make(accounts.DerivationPath, len(nextPaths[i])) - copy(path[:], nextPaths[i][:]) paths = append(paths, path) - account := accounts.Account{ Address: nextAddrs[i], URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)}, diff --git a/signer/core/api.go b/signer/core/api.go index 7e6ece997f..3817345c8f 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -346,19 +346,28 @@ func (api *SignerAPI) startUSBListener() { case accounts.WalletOpened: status, _ := event.Wallet.Status() log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) - - // Derive first N accounts, hardcoded for now - var nextPath = make(accounts.DerivationPath, len(accounts.DefaultBaseDerivationPath)) - copy(nextPath[:], accounts.DefaultBaseDerivationPath[:]) - - for i := 0; i < numberOfAccountsToDerive; i++ { - acc, err := event.Wallet.Derive(nextPath, true) - if err != nil { - log.Warn("account derivation failed", "error", err) - } else { - log.Info("derived account", "address", acc.Address) + var derive = func(numToDerive int, base accounts.DerivationPath) { + // Derive first N accounts, hardcoded for now + var nextPath = make(accounts.DerivationPath, len(base)) + copy(nextPath[:], base[:]) + + for i := 0; i < numToDerive; i++ { + acc, err := event.Wallet.Derive(nextPath, true) + if err != nil { + log.Warn("Account derivation failed", "error", err) + } else { + log.Info("Derived account", "address", acc.Address, "path", nextPath) + } + nextPath[len(nextPath)-1]++ } - nextPath[len(nextPath)-1]++ + } + if event.Wallet.URL().Scheme == "ledger" { + log.Info("Deriving ledger default paths") + derive(numberOfAccountsToDerive/2, accounts.DefaultBaseDerivationPath) + log.Info("Deriving ledger legacy paths") + derive(numberOfAccountsToDerive/2, accounts.LegacyLedgerBaseDerivationPath) + } else { + derive(numberOfAccountsToDerive, accounts.DefaultBaseDerivationPath) } case accounts.WalletDropped: log.Info("Old wallet dropped", "url", event.Wallet.URL()) From 066c75531d5668366dc0cf9a8a2d9cb2addbc487 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 8 Sep 2020 14:13:48 +0000 Subject: [PATCH 18/24] build: remove wnode from the list of packages binaries (#21526) --- build/ci.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build/ci.go b/build/ci.go index ae5aaf5ac8..ea708d5e7b 100644 --- a/build/ci.go +++ b/build/ci.go @@ -79,7 +79,6 @@ var ( executablePath("geth"), executablePath("puppeth"), executablePath("rlpdump"), - executablePath("wnode"), executablePath("clef"), } @@ -109,10 +108,6 @@ var ( BinaryName: "rlpdump", Description: "Developer utility tool that prints RLP structures.", }, - { - BinaryName: "wnode", - Description: "Ethereum Whisper diagnostic tool", - }, { BinaryName: "clef", Description: "Ethereum account management tool.", From 86bcbb0d79859266d4ce69ee99408aaff6018830 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet Date: Tue, 8 Sep 2020 20:02:14 +0000 Subject: [PATCH 19/24] .github: remove whisper from CODEOWNERS (#21527) --- .github/CODEOWNERS | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 59e73396a6..58c1a4a62e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -20,4 +20,3 @@ p2p/simulations @fjl p2p/protocols @fjl p2p/testing @fjl signer/ @holiman -whisper/ @gballet From dc681fc1f6a183a476446167695e5e6fa0e5d4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 9 Sep 2020 10:33:20 +0300 Subject: [PATCH 20/24] params: update CHTs for v1.9.21 release --- params/config.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/params/config.go b/params/config.go index c935405e7f..e5ec64b2bf 100644 --- a/params/config.go +++ b/params/config.go @@ -73,10 +73,10 @@ var ( // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. MainnetTrustedCheckpoint = &TrustedCheckpoint{ - SectionIndex: 326, - SectionHead: common.HexToHash("0xbdec9f7056159360d64d6488ee11a0db574a67757cddd6fffd6719121d5733a5"), - CHTRoot: common.HexToHash("0xf9d2617f8e038b824a256025f01af3b3da681987df29dbfe718ad4c6c8a0875d"), - BloomRoot: common.HexToHash("0x712016984cfb66c165fdaf05c6a4aa89f08e4bb66fa77b199f2878fff4232d78"), + SectionIndex: 329, + SectionHead: common.HexToHash("0x96bb6d286ded20a18480dd98d537ab503bd81110c6b9c3f8ad1f9338f3b9852d"), + CHTRoot: common.HexToHash("0x10627ff648077adeaab9dbd4e5bbed8671c86005b2aef5f5d4857acca19a49d8"), + BloomRoot: common.HexToHash("0xf499b0cfaf426a490b7b5ddca58d3031b008f0c15338f8f25c20f3df050bf785"), } // MainnetCheckpointOracle contains a set of configs for the main network oracle. @@ -112,10 +112,10 @@ var ( // RopstenTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network. RopstenTrustedCheckpoint = &TrustedCheckpoint{ - SectionIndex: 260, - SectionHead: common.HexToHash("0xdcf714d033b8be3f0786515649d76e526157f811e5ae89c59dbfd53029d0d165"), - CHTRoot: common.HexToHash("0x987759454d404cd393a6a7743da64610076f167e989ec2cf9e0c0be6578d1304"), - BloomRoot: common.HexToHash("0xb8ee6d34cc30d61410717e2dc1af3294bc056f4b32a5eed5f6f386a8c1daa2b1"), + SectionIndex: 262, + SectionHead: common.HexToHash("0x12b068f285789b966a983b632266484f1bc93803df6c78773538a5777f57a236"), + CHTRoot: common.HexToHash("0x14000a1407e866f174f3a20fe9f271acd704bcf929b5205d83b70a1bba8c82c2"), + BloomRoot: common.HexToHash("0x2f4f4a34a55e35d0691c79a79e39b6f661259345080fb880da5195c11c2413be"), } // RopstenCheckpointOracle contains a set of configs for the Ropsten test network oracle. @@ -154,10 +154,10 @@ var ( // RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network. RinkebyTrustedCheckpoint = &TrustedCheckpoint{ - SectionIndex: 214, - SectionHead: common.HexToHash("0x297b4daf21db636e76555c9d3e302d79a8efe3a3434143b9bcf61187ce8abcb1"), - CHTRoot: common.HexToHash("0x602044234a4ba8534286240200cde6e5797ae40151cbdd2dbf8eb8c0486a2c63"), - BloomRoot: common.HexToHash("0x9ccf6840ecc541b290c7b9f19edcba3e5f39206b05cd4ae5a7754040783d47d9"), + SectionIndex: 217, + SectionHead: common.HexToHash("0x9afa4900a60cb44b102eb2eb5e5ef1d7f4cc1911c1c0588518995fb778ffe894"), + CHTRoot: common.HexToHash("0xcc963e5085622c7cb6b3bf747fbfdfe71887e0d5bc9e4b3fb0474d44fc97942a"), + BloomRoot: common.HexToHash("0x1064ca3a36b6f129783cff51bb18fb038bade47d2b776d1cccb9c74925106703"), } // RinkebyCheckpointOracle contains a set of configs for the Rinkeby test network oracle. @@ -194,10 +194,10 @@ var ( // GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network. GoerliTrustedCheckpoint = &TrustedCheckpoint{ - SectionIndex: 99, - SectionHead: common.HexToHash("0xc9f09369acd657d5f77e6a389a68f673bf909ad98c269800c08229d75c1a90e3"), - CHTRoot: common.HexToHash("0x523218630348e98fa9f4e7fc3054aff717982d79c700cbecf5730c1479f21c6e"), - BloomRoot: common.HexToHash("0x75219ad4a3ec4682b89dd248ee56b52ef26fe577a426f4813297550deb5c4cb2"), + SectionIndex: 101, + SectionHead: common.HexToHash("0x396f5dd8e526edfb550873bcfe0e93dc00d70be4b881ab256980833b97a18c3e"), + CHTRoot: common.HexToHash("0x0d145657a6595508ef878c9bbf8eca045631986f664bfab0d898fc64804a4e64"), + BloomRoot: common.HexToHash("0x12df34d07cf1268abe22d40ee6deb199b8918e3d57d52f9e70f9b2883f57d74f"), } // GoerliCheckpointOracle contains a set of configs for the Goerli test network oracle. From 0287d54847d3297f3ced62cd83a4c95ccbe0045b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 9 Sep 2020 11:22:11 +0300 Subject: [PATCH 21/24] params: release Geth v1.9.21 --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index f827bcd62e..4a0e2f0c9b 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 1 // Major version component of the current release - VersionMinor = 9 // Minor version component of the current release - VersionPatch = 21 // Patch version component of the current release - VersionMeta = "unstable" // Version metadata to append to the version string + VersionMajor = 1 // Major version component of the current release + VersionMinor = 9 // Minor version component of the current release + VersionPatch = 21 // Patch version component of the current release + VersionMeta = "stable" // Version metadata to append to the version string ) // Version holds the textual version string. From 4f4546566438312add2a28b3d9a0f3d192613d3b Mon Sep 17 00:00:00 2001 From: Baptiste Boussemart Date: Wed, 9 Jun 2021 05:10:25 -0700 Subject: [PATCH 22/24] Merge branch 'public_master' into upgrade/go-ethereum/v1.9.21-2021607125909 --- .bintray.json | 37 + .github/CONTRIBUTING.md | 28 +- .github/ISSUE_TEMPLATE.md | 4 +- .github/workflows/build.yml | 273 +++ .github/workflows/pr.yml | 120 ++ .github/workflows/release.yml | 383 ++++ .github/workflows/upgradebot.yml | 27 + .gitignore | 5 + .golangci.yml | 2 +- BUILDING.md | 33 + Dockerfile | 5 +- Makefile | 5 + NOTES.md | 112 ++ README.md | 397 +---- accounts/abi/bind/auth.go | 16 + accounts/abi/bind/backend.go | 4 +- accounts/abi/bind/backends/simulated.go | 67 +- accounts/abi/bind/backends/simulated_test.go | 32 +- accounts/abi/bind/base.go | 50 +- accounts/abi/bind/bind_test.go | 7 + accounts/abi/bind/template.go | 3 + accounts/abi/bind/util_test.go | 6 +- accounts/external/backend.go | 15 +- accounts/keystore/account_cache_test.go | 2 +- accounts/keystore/keystore.go | 11 + accounts/manager.go | 16 + accounts/pluggable/backend.go | 74 + accounts/pluggable/backend_test.go | 131 ++ .../pluggable/internal/testutils/matchers.go | 19 + .../testutils/mock_plugin/mock_plugin.go | 196 +++ accounts/pluggable/wallet.go | 129 ++ accounts/pluggable/wallet_test.go | 397 +++++ accounts/usbwallet/wallet.go | 5 + build/ci.go | 6 +- build/install-constellation-linux.sh | 7 + build/install-constellation-mac.sh | 15 + build/travis-install-linux.sh | 42 + build/travis-run-acceptance-tests-linux.sh | 20 + cmd/clef/README.md | 5 +- cmd/clef/main.go | 135 +- cmd/evm/internal/t8ntool/execution.go | 21 +- cmd/faucet/faucet.go | 4 +- cmd/geth/accountcmd.go | 1 + cmd/geth/accountcmd_plugin.go | 323 ++++ cmd/geth/accountcmd_plugin_test.go | 299 ++++ cmd/geth/accountcmd_test.go | 52 +- cmd/geth/chaincmd.go | 44 +- cmd/geth/config.go | 137 +- cmd/geth/consolecmd.go | 146 +- cmd/geth/consolecmd_test.go | 180 +- cmd/geth/dao_test.go | 1 + cmd/geth/genesis_test.go | 105 +- cmd/geth/les_test.go | 4 + cmd/geth/main.go | 77 +- cmd/geth/misccmd.go | 2 + cmd/geth/retesteth.go | 33 +- cmd/geth/testdata/clique.json | 3 +- cmd/geth/testdata/geth/nodekey | 1 + cmd/geth/testdata/geth/static-nodes.json | 3 + cmd/geth/usage.go | 75 + cmd/puppeth/genesis_test.go | 8 + cmd/utils/flags.go | 399 ++++- cmd/utils/flags_test.go | 93 + common/http/certificate.go | 61 + common/http/client.go | 49 + common/http/config.go | 206 +++ common/http/config_test.go | 342 ++++ common/http/transport.go | 55 + common/slice.go | 55 + common/slice_test.go | 94 + common/types.go | 141 ++ common/types_test.go | 77 + consensus/clique/api.go | 46 +- consensus/clique/clique.go | 12 +- consensus/consensus.go | 27 + consensus/ethash/consensus.go | 17 +- consensus/ethash/ethash.go | 8 + consensus/istanbul/backend.go | 75 + consensus/istanbul/backend/api.go | 272 +++ consensus/istanbul/backend/backend.go | 318 ++++ consensus/istanbul/backend/backend_test.go | 239 +++ consensus/istanbul/backend/engine.go | 759 ++++++++ consensus/istanbul/backend/engine_test.go | 579 ++++++ consensus/istanbul/backend/handler.go | 138 ++ consensus/istanbul/backend/handler_test.go | 182 ++ consensus/istanbul/backend/snapshot.go | 321 ++++ consensus/istanbul/backend/snapshot_test.go | 457 +++++ consensus/istanbul/config.go | 44 + consensus/istanbul/core/backlog.go | 188 ++ consensus/istanbul/core/backlog_test.go | 364 ++++ consensus/istanbul/core/commit.go | 107 ++ consensus/istanbul/core/commit_test.go | 325 ++++ consensus/istanbul/core/core.go | 359 ++++ consensus/istanbul/core/core_test.go | 97 + consensus/istanbul/core/errors.go | 48 + consensus/istanbul/core/events.go | 28 + consensus/istanbul/core/final_committed.go | 26 + consensus/istanbul/core/handler.go | 201 +++ consensus/istanbul/core/handler_test.go | 127 ++ consensus/istanbul/core/message_set.go | 115 ++ consensus/istanbul/core/message_set_test.go | 106 ++ consensus/istanbul/core/prepare.go | 95 + consensus/istanbul/core/prepare_test.go | 359 ++++ consensus/istanbul/core/preprepare.go | 129 ++ consensus/istanbul/core/preprepare_test.go | 298 ++++ consensus/istanbul/core/request.go | 99 ++ consensus/istanbul/core/request_test.go | 138 ++ consensus/istanbul/core/roundchange.go | 172 ++ consensus/istanbul/core/roundchange_test.go | 92 + consensus/istanbul/core/roundstate.go | 221 +++ consensus/istanbul/core/roundstate_test.go | 76 + consensus/istanbul/core/testbackend_test.go | 291 +++ consensus/istanbul/core/types.go | 180 ++ consensus/istanbul/core/types_test.go | 180 ++ consensus/istanbul/errors.go | 29 + consensus/istanbul/events.go | 31 + consensus/istanbul/types.go | 147 ++ consensus/istanbul/types_test.go | 71 + consensus/istanbul/utils.go | 60 + consensus/istanbul/validator.go | 80 + consensus/istanbul/validator/default.go | 201 +++ consensus/istanbul/validator/default_test.go | 209 +++ consensus/istanbul/validator/validator.go | 47 + consensus/protocol.go | 77 + console/console.go | 54 +- .../develop-alpine/Dockerfile_BASE_30347 | 14 + .../develop-alpine/Dockerfile_LOCAL_30347 | 14 + containers/vagrant/.gitignore | 1 + .../vagrant/provisioners/shell/centos.sh | 11 + .../vagrant/provisioners/shell/debian.sh | 11 + .../vagrant/provisioners/shell/ubuntu.sh | 11 + core/bench_test.go | 1 + core/block_validator.go | 6 +- core/blockchain.go | 219 ++- core/blockchain_test.go | 30 +- core/call_helper.go | 100 ++ core/chain_makers.go | 2 +- core/chain_makers_test.go | 2 +- core/constellation-test-keys/tm1.key | 1 + core/constellation-test-keys/tm1.pub | 1 + core/constellation-test-keys/tm1a.key | 1 + core/constellation-test-keys/tm1a.pub | 1 + core/default_psm.go | 58 + core/default_psm_test.go | 106 ++ core/dual_state_test.go | 213 +++ core/error.go | 17 + core/events.go | 3 + core/forkid/forkid.go | 5 + core/genesis.go | 37 +- core/genesis_test.go | 61 +- core/mps/default_psr.go | 110 ++ core/mps/default_psr_test.go | 171 ++ core/mps/interface.go | 44 + core/mps/mock_interface.go | 367 ++++ core/mps/multiple_psr.go | 225 +++ core/mps/multiple_psr_test.go | 430 +++++ core/mps/types.go | 78 + core/mps/types_test.go | 48 + core/multiple_psm.go | 74 + core/multiple_psm_test.go | 331 ++++ core/private_state_manager.go | 83 + core/private_state_test.go | 146 ++ core/rawdb/accessors_chain.go | 57 +- core/rawdb/database_quorum.go | 134 ++ core/rawdb/database_quorum_test.go | 184 ++ core/rawdb/freezer.go | 10 +- core/rawdb/freezer_test.go | 73 + core/state/account_extra_data.go | 160 ++ core/state/account_extra_data_test.go | 193 ++ core/state/database.go | 23 +- core/state/dump.go | 30 + core/state/journal.go | 17 +- core/state/state_object.go | 151 ++ core/state/state_test.go | 58 + core/state/statedb.go | 175 +- core/state/statedb_test.go | 205 +++ core/state_prefetcher.go | 6 +- core/state_processor.go | 202 ++- core/state_transition.go | 175 +- core/state_transition_pmh.go | 136 ++ core/state_transition_pmh_test.go | 53 + core/state_transition_test.go | 1363 ++++++++++++++ core/tx_pool.go | 90 +- core/tx_pool_test.go | 233 ++- core/types.go | 3 +- core/types/block.go | 12 + core/types/bloom9.go | 9 + core/types/istanbul.go | 107 ++ core/types/istanbul_test.go | 88 + core/types/log.go | 3 + core/types/mps.go | 23 + core/types/receipt.go | 187 ++ core/types/receipt_test.go | 324 +++- core/types/transaction.go | 162 +- core/types/transaction_signing.go | 13 +- core/types/transaction_signing_private.go | 61 + ...transaction_signing_quorum_private_test.go | 62 + core/types/transaction_signing_quorum_test.go | 354 ++++ core/types/transaction_signing_test.go | 33 +- core/types/transaction_test.go | 24 + core/vm/errors.go | 3 + core/vm/evm.go | 294 +++- core/vm/gas_table.go | 7 +- core/vm/gas_table_test.go | 2 +- core/vm/instructions.go | 33 +- core/vm/instructions_test.go | 14 +- core/vm/interface.go | 58 +- core/vm/interpreter.go | 5 + core/vm/logger_test.go | 3 +- core/vm/mock_interface.go | 957 ++++++++++ core/vm/runtime/env.go | 2 +- core/vm/runtime/evm_privacy_test.go | 448 +++++ core/vm/runtime/runtime_test.go | 7 + crypto/bn256/cloudflare/gfp_decl.go | 1 - crypto/crypto.go | 2 +- crypto/secp256k1/go.mod | 3 + docs/Quorum Design.png | Bin 0 -> 76981 bytes docs/Quorum Whitepaper v0.2.pdf | Bin 0 -> 1887682 bytes docs/conf.py | 2 + docs/images/ContractDesign.png | Bin 0 -> 816382 bytes docs/images/PermissionsModel.png | Bin 0 -> 348517 bytes docs/images/logo-48x48.png | Bin 0 -> 1717 bytes docs/images/logo.png | Bin 0 -> 206848 bytes docs/images/qubernetes/k8s-logo.png | Bin 0 -> 286328 bytes docs/theme/404.html | 4 + .../javascripts/application.81068b3a.js | 6 + .../stylesheets/application.668e8dde.css | 1 + docs/theme/assets/stylesheets/extra.css | 15 + docs/theme/base.html | 220 +++ docs/theme/partials/footer.html | 80 + docs/theme/partials/header.html | 87 + docs/theme/partials/nav.html | 46 + eth/api.go | 111 +- eth/api_backend.go | 265 ++- eth/api_backend_test.go | 63 + eth/api_tracer.go | 205 ++- eth/backend.go | 172 +- eth/bloombits.go | 10 +- eth/config.go | 23 +- eth/config_test.go | 21 + eth/downloader/downloader.go | 244 ++- eth/downloader/downloader_test.go | 4 + eth/downloader/modes.go | 2 + eth/downloader/peer.go | 3 +- eth/filters/api.go | 39 +- eth/filters/bench_test.go | 4 +- eth/filters/filter.go | 35 +- eth/filters/filter_system.go | 10 +- eth/filters/filter_system_test.go | 50 +- eth/filters/filter_test.go | 185 +- eth/gen_config.go | 7 + eth/handler.go | 153 +- eth/handler_test.go | 48 +- eth/helper_test.go | 61 +- eth/peer.go | 58 +- eth/protocol.go | 2 +- eth/protocol_test.go | 20 +- eth/quorum_protocol.go | 209 +++ eth/sync.go | 16 +- eth/sync_test.go | 4 +- eth/tracers/tracer_test.go | 7 +- eth/tracers/tracers_test.go | 4 +- ethclient/ethclient.go | 44 +- ethclient/ethclient_test.go | 29 + ethclient/privateTransactionManagerClient.go | 73 + .../privateTransactionManagerClient_test.go | 56 + ethstats/ethstats.go | 4 +- extension/api.go | 395 +++++ extension/backend.go | 429 +++++ extension/backend_test.go | 211 +++ extension/client.go | 51 + extension/contract_facade.go | 66 + extension/data_handler.go | 107 ++ extension/data_handler_test.go | 80 + .../extensionContracts/contract_extender.go | 1559 +++++++++++++++++ .../extensionContracts/contract_extender.sol | 168 ++ .../extensionContracts/extensionHandler.go | 18 + extension/extensionContracts/types.go | 9 + extension/extension_utilities.go | 38 + .../privacyExtension/state_set_utilities.go | 98 ++ .../state_set_utilities_test.go | 368 ++++ extension/privacyExtension/state_setter.go | 178 ++ .../privacyExtension/state_setter_test.go | 218 +++ extension/services_factory.go | 58 + extension/state_fetcher.go | 122 ++ extension/state_fetcher_test.go | 49 + extension/subscriptions.go | 58 + extension/types.go | 40 + go.mod | 41 +- go.sum | 132 +- graphql/graphiql.go | 106 +- graphql/graphiql_test.go | 80 + graphql/graphql.go | 67 +- graphql/graphql_test.go | 308 ++++ graphql/schema.go | 4 + graphql/service.go | 83 +- interfaces.go | 1 + internal/build/gosrc.go | 81 + internal/build/util.go | 50 + internal/build/util_test.go | 40 + internal/ethapi/api.go | 797 ++++++++- internal/ethapi/api_test.go | 853 +++++++++ internal/ethapi/backend.go | 21 +- internal/plugin/protocol.go | 21 + internal/web3ext/web3ext.go | 455 ++++- les/api_backend.go | 37 +- les/client.go | 8 +- les/odr_test.go | 4 +- les/server_handler.go | 5 +- les/test_helper.go | 16 +- light/lightchain.go | 18 + light/odr_test.go | 2 +- light/trie.go | 19 + log/emit_checkpoint.go | 22 + logo.png | Bin 0 -> 14735 bytes miner/miner.go | 23 +- miner/worker.go | 243 ++- miner/worker_test.go | 239 ++- mkdocs.yml | 187 ++ mobile/ethclient.go | 4 +- multitenancy/authorization.go | 138 ++ multitenancy/authorization_test.go | 253 +++ multitenancy/docs.go | 15 + multitenancy/types.go | 61 + node/api.go | 31 +- node/config.go | 47 + node/config_test.go | 92 + node/endpoints.go | 49 +- node/node.go | 138 +- node/node_test.go | 3 +- node/rpcstack.go | 47 +- node/rpcstack_test.go | 6 +- p2p/enode/node.go | 95 +- p2p/enode/node_test.go | 124 ++ p2p/enode/urlv4.go | 108 +- p2p/enode/urlv4_test.go | 15 + p2p/enr/entries.go | 10 + p2p/peer.go | 15 + p2p/peer_error.go | 13 + p2p/server.go | 67 + p2p/server_test.go | 73 + params/config.go | 255 ++- params/config_test.go | 210 ++- params/network_params.go | 29 + params/network_params_test.go | 17 + params/protocol_params.go | 23 +- params/protocol_params_test.go | 25 + params/quorum.go | 12 + params/version.go | 12 + permission/api.go | 1095 ++++++++++++ permission/backend.go | 284 +++ permission/connection.go | 65 + permission/core/cache.go | 634 +++++++ permission/core/cache_test.go | 433 +++++ permission/core/permissions.go | 127 ++ permission/core/permissions_test.go | 132 ++ permission/core/types/backend.go | 350 ++++ permission/core/types/contract.go | 130 ++ permission/permission.go | 416 +++++ permission/permission_test.go | 1001 +++++++++++ permission/v1/backend.go | 368 ++++ permission/v1/bind/accounts.go | 935 ++++++++++ permission/v1/bind/nodes.go | 1356 ++++++++++++++ permission/v1/bind/org.go | 1075 ++++++++++++ permission/v1/bind/permission_impl.go | 983 +++++++++++ permission/v1/bind/permission_interface.go | 840 +++++++++ permission/v1/bind/permission_upgr.go | 313 ++++ permission/v1/bind/roles.go | 718 ++++++++ permission/v1/bind/voter.go | 853 +++++++++ permission/v1/contract.go | 372 ++++ permission/v1/contract/AccountManager.sol | 362 ++++ permission/v1/contract/NodeManager.sol | 257 +++ permission/v1/contract/OrgManager.sol | 371 ++++ .../v1/contract/PermissionsImplementation.sol | 662 +++++++ .../v1/contract/PermissionsInterface.sol | 302 ++++ .../v1/contract/PermissionsUpgradable.sol | 103 ++ permission/v1/contract/RoleManager.sol | 199 +++ permission/v1/contract/VoterManager.sol | 250 +++ permission/v1/contract/gen/AccountManager.abi | 1 + permission/v1/contract/gen/AccountManager.bin | 1 + permission/v1/contract/gen/NodeManager.abi | 1 + permission/v1/contract/gen/NodeManager.bin | 1 + permission/v1/contract/gen/OrgManager.abi | 1 + permission/v1/contract/gen/OrgManager.bin | 1 + .../gen/PermissionsImplementation.abi | 1 + .../gen/PermissionsImplementation.bin | 1 + .../v1/contract/gen/PermissionsInterface.abi | 1 + .../v1/contract/gen/PermissionsInterface.bin | 1 + .../v1/contract/gen/PermissionsUpgradable.abi | 1 + .../v1/contract/gen/PermissionsUpgradable.bin | 1 + permission/v1/contract/gen/RoleManager.abi | 1 + permission/v1/contract/gen/RoleManager.bin | 1 + permission/v1/contract/gen/VoterManager.abi | 1 + permission/v1/contract/gen/VoterManager.bin | 1 + permission/v1/contract/gen/gen.go | 27 + permission/v2/backend.go | 348 ++++ permission/v2/bind/accounts.go | 991 +++++++++++ permission/v2/bind/nodes.go | 1427 +++++++++++++++ permission/v2/bind/org.go | 1101 ++++++++++++ permission/v2/bind/permission_impl.go | 1035 +++++++++++ permission/v2/bind/permission_interface.go | 892 ++++++++++ permission/v2/bind/permission_upgr.go | 313 ++++ permission/v2/bind/roles.go | 770 ++++++++ permission/v2/bind/voter.go | 853 +++++++++ permission/v2/contract.go | 408 +++++ permission/v2/contract/AccountManager.sol | 377 ++++ permission/v2/contract/NodeManager.sol | 310 ++++ permission/v2/contract/OrgManager.sol | 390 +++++ .../v2/contract/PermissionsImplementation.sol | 760 ++++++++ .../v2/contract/PermissionsInterface.sol | 351 ++++ .../v2/contract/PermissionsUpgradable.sol | 103 ++ permission/v2/contract/RoleManager.sol | 236 +++ permission/v2/contract/VoterManager.sol | 250 +++ permission/v2/contract/gen/AccountManager.abi | 1 + permission/v2/contract/gen/AccountManager.bin | 1 + permission/v2/contract/gen/NodeManager.abi | 1 + permission/v2/contract/gen/NodeManager.bin | 1 + permission/v2/contract/gen/OrgManager.abi | 1 + permission/v2/contract/gen/OrgManager.bin | 1 + .../gen/PermissionsImplementation.abi | 1 + .../gen/PermissionsImplementation.bin | 1 + .../v2/contract/gen/PermissionsInterface.abi | 1 + .../v2/contract/gen/PermissionsInterface.bin | 1 + .../v2/contract/gen/PermissionsUpgradable.abi | 1 + .../v2/contract/gen/PermissionsUpgradable.bin | 1 + permission/v2/contract/gen/RoleManager.abi | 1 + permission/v2/contract/gen/RoleManager.bin | 1 + permission/v2/contract/gen/VoterManager.abi | 1 + permission/v2/contract/gen/VoterManager.bin | 1 + permission/v2/contract/gen/gen.go | 27 + plugin/account/connector.go | 26 + plugin/account/creator.go | 25 + plugin/account/gateway.go | 213 +++ plugin/account/gateway_test.go | 338 ++++ plugin/account/internal/testutils/matchers.go | 184 ++ plugin/account/reloadableimpl.go | 105 ++ plugin/account/service.go | 26 + plugin/api.go | 15 + plugin/base.go | 291 +++ plugin/central.go | 197 +++ plugin/central_test.go | 138 ++ plugin/downloader.go | 34 + plugin/downloader_test.go | 38 + plugin/gen/docs.markdown.tmpl | 76 + plugin/gen/gen.go | 27 + plugin/gen/proto_common/init.pb.go | 247 +++ plugin/gen/proto_common/mock_init.go | 94 + plugin/helloworld/connector.go | 26 + plugin/helloworld/gateway.go | 21 + plugin/helloworld/gateway_test.go | 32 + plugin/helloworld/service.go | 21 + plugin/initializer/connector.go | 26 + plugin/initializer/gateway.go | 19 + plugin/initializer/gateway_test.go | 32 + plugin/initializer/service.go | 7 + plugin/local_verifier.go | 54 + plugin/local_verifier_test.go | 39 + plugin/online_verifier.go | 23 + plugin/plugin_templates.go | 98 ++ plugin/security/connector.go | 43 + plugin/security/gateway.go | 88 + plugin/security/gateway_test.go | 157 ++ plugin/security/service.go | 61 + plugin/security/utils.go | 57 + plugin/service.go | 254 +++ plugin/service_test.go | 146 ++ plugin/settings.go | 310 ++++ plugin/settings_test.go | 276 +++ plugin/utils.go | 173 ++ plugin/utils_test.go | 342 ++++ plugin/verifier.go | 45 + plugin/verifier_test.go | 40 + private/cache/cache.go | 22 + private/engine/common.go | 123 ++ private/engine/common_test.go | 71 + private/engine/constellation/constellation.go | 119 ++ private/engine/constellation/node.go | 77 + .../notinuse/notInUsePrivateTxManager.go | 63 + .../notinuse/notInUsePrivateTxManager_test.go | 58 + private/engine/tessera/model.go | 94 + private/engine/tessera/tessera.go | 461 +++++ private/engine/tessera/tessera_test.go | 510 ++++++ .../engine/tessera/tessera_version_checker.go | 78 + .../tessera/tessera_version_checker_test.go | 82 + .../engine/tessera/tessera_version_reader.go | 55 + .../tessera/tessera_version_reader_test.go | 121 ++ private/mock_private.go | 224 +++ private/private.go | 124 ++ private/private_test.go | 106 ++ raft/api.go | 134 ++ raft/backend.go | 113 ++ raft/backend_test.go | 42 + raft/constants.go | 35 + raft/events.go | 13 + raft/handler.go | 1098 ++++++++++++ raft/handler_test.go | 182 ++ raft/listener.go | 59 + raft/minter.go | 451 +++++ raft/minter_test.go | 208 +++ raft/peer.go | 116 ++ raft/persistence.go | 57 + raft/snapshot.go | 393 +++++ raft/speculative_chain.go | 187 ++ raft/util.go | 30 + raft/wal.go | 54 + rpc/client.go | 61 +- rpc/client_test.go | 186 +- rpc/context.go | 101 ++ rpc/handler.go | 29 +- rpc/http.go | 46 +- rpc/inproc.go | 3 + rpc/ipc.go | 13 +- rpc/json.go | 13 + rpc/security.go | 248 +++ rpc/security_test.go | 310 ++++ rpc/server.go | 36 +- rpc/server_test.go | 169 ++ rpc/testservice_test.go | 19 + rpc/types.go | 6 + rpc/types_test.go | 2 +- rpc/websocket.go | 50 +- rpc/websocket_test.go | 2 +- signer/core/api.go | 24 +- signer/core/api_test.go | 2 +- signer/core/plugin_api.go | 39 + signer/core/types.go | 14 +- tests/block_test.go | 6 + tests/block_test_util.go | 2 +- tests/fuzzers/trie/trie-fuzzer.go | 18 +- tests/state_test_util.go | 2 +- tests/transaction_test.go | 17 + tests/vm_test_util.go | 2 +- trie/database.go | 3 + 533 files changed, 73944 insertions(+), 1380 deletions(-) create mode 100644 .bintray.json create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/upgradebot.yml create mode 100644 BUILDING.md create mode 100644 NOTES.md create mode 100644 accounts/pluggable/backend.go create mode 100644 accounts/pluggable/backend_test.go create mode 100644 accounts/pluggable/internal/testutils/matchers.go create mode 100644 accounts/pluggable/internal/testutils/mock_plugin/mock_plugin.go create mode 100644 accounts/pluggable/wallet.go create mode 100644 accounts/pluggable/wallet_test.go create mode 100755 build/install-constellation-linux.sh create mode 100755 build/install-constellation-mac.sh create mode 100755 build/travis-install-linux.sh create mode 100755 build/travis-run-acceptance-tests-linux.sh create mode 100644 cmd/geth/accountcmd_plugin.go create mode 100644 cmd/geth/accountcmd_plugin_test.go create mode 100644 cmd/geth/testdata/geth/nodekey create mode 100644 cmd/geth/testdata/geth/static-nodes.json create mode 100644 common/http/certificate.go create mode 100644 common/http/client.go create mode 100644 common/http/config.go create mode 100644 common/http/config_test.go create mode 100644 common/http/transport.go create mode 100644 common/slice.go create mode 100644 common/slice_test.go create mode 100644 consensus/istanbul/backend.go create mode 100644 consensus/istanbul/backend/api.go create mode 100644 consensus/istanbul/backend/backend.go create mode 100644 consensus/istanbul/backend/backend_test.go create mode 100644 consensus/istanbul/backend/engine.go create mode 100644 consensus/istanbul/backend/engine_test.go create mode 100644 consensus/istanbul/backend/handler.go create mode 100644 consensus/istanbul/backend/handler_test.go create mode 100644 consensus/istanbul/backend/snapshot.go create mode 100644 consensus/istanbul/backend/snapshot_test.go create mode 100644 consensus/istanbul/config.go create mode 100644 consensus/istanbul/core/backlog.go create mode 100644 consensus/istanbul/core/backlog_test.go create mode 100644 consensus/istanbul/core/commit.go create mode 100644 consensus/istanbul/core/commit_test.go create mode 100644 consensus/istanbul/core/core.go create mode 100644 consensus/istanbul/core/core_test.go create mode 100644 consensus/istanbul/core/errors.go create mode 100644 consensus/istanbul/core/events.go create mode 100644 consensus/istanbul/core/final_committed.go create mode 100644 consensus/istanbul/core/handler.go create mode 100644 consensus/istanbul/core/handler_test.go create mode 100644 consensus/istanbul/core/message_set.go create mode 100644 consensus/istanbul/core/message_set_test.go create mode 100644 consensus/istanbul/core/prepare.go create mode 100644 consensus/istanbul/core/prepare_test.go create mode 100644 consensus/istanbul/core/preprepare.go create mode 100644 consensus/istanbul/core/preprepare_test.go create mode 100644 consensus/istanbul/core/request.go create mode 100644 consensus/istanbul/core/request_test.go create mode 100644 consensus/istanbul/core/roundchange.go create mode 100644 consensus/istanbul/core/roundchange_test.go create mode 100644 consensus/istanbul/core/roundstate.go create mode 100644 consensus/istanbul/core/roundstate_test.go create mode 100644 consensus/istanbul/core/testbackend_test.go create mode 100644 consensus/istanbul/core/types.go create mode 100644 consensus/istanbul/core/types_test.go create mode 100644 consensus/istanbul/errors.go create mode 100644 consensus/istanbul/events.go create mode 100644 consensus/istanbul/types.go create mode 100644 consensus/istanbul/types_test.go create mode 100644 consensus/istanbul/utils.go create mode 100644 consensus/istanbul/validator.go create mode 100644 consensus/istanbul/validator/default.go create mode 100644 consensus/istanbul/validator/default_test.go create mode 100644 consensus/istanbul/validator/validator.go create mode 100644 consensus/protocol.go create mode 100644 containers/docker/develop-alpine/Dockerfile_BASE_30347 create mode 100644 containers/docker/develop-alpine/Dockerfile_LOCAL_30347 create mode 100644 containers/vagrant/.gitignore create mode 100755 containers/vagrant/provisioners/shell/centos.sh create mode 100755 containers/vagrant/provisioners/shell/debian.sh create mode 100755 containers/vagrant/provisioners/shell/ubuntu.sh create mode 100644 core/call_helper.go create mode 100644 core/constellation-test-keys/tm1.key create mode 100644 core/constellation-test-keys/tm1.pub create mode 100644 core/constellation-test-keys/tm1a.key create mode 100644 core/constellation-test-keys/tm1a.pub create mode 100644 core/default_psm.go create mode 100644 core/default_psm_test.go create mode 100644 core/dual_state_test.go create mode 100644 core/mps/default_psr.go create mode 100644 core/mps/default_psr_test.go create mode 100644 core/mps/interface.go create mode 100644 core/mps/mock_interface.go create mode 100644 core/mps/multiple_psr.go create mode 100644 core/mps/multiple_psr_test.go create mode 100644 core/mps/types.go create mode 100644 core/mps/types_test.go create mode 100644 core/multiple_psm.go create mode 100644 core/multiple_psm_test.go create mode 100644 core/private_state_manager.go create mode 100644 core/private_state_test.go create mode 100644 core/rawdb/database_quorum.go create mode 100644 core/rawdb/database_quorum_test.go create mode 100644 core/rawdb/freezer_test.go create mode 100644 core/state/account_extra_data.go create mode 100644 core/state/account_extra_data_test.go create mode 100644 core/state_transition_pmh.go create mode 100644 core/state_transition_pmh_test.go create mode 100644 core/state_transition_test.go create mode 100644 core/types/istanbul.go create mode 100644 core/types/istanbul_test.go create mode 100644 core/types/mps.go create mode 100644 core/types/transaction_signing_private.go create mode 100644 core/types/transaction_signing_quorum_private_test.go create mode 100644 core/types/transaction_signing_quorum_test.go create mode 100644 core/vm/mock_interface.go create mode 100644 core/vm/runtime/evm_privacy_test.go create mode 100644 crypto/secp256k1/go.mod create mode 100644 docs/Quorum Design.png create mode 100644 docs/Quorum Whitepaper v0.2.pdf create mode 100644 docs/conf.py create mode 100644 docs/images/ContractDesign.png create mode 100644 docs/images/PermissionsModel.png create mode 100644 docs/images/logo-48x48.png create mode 100644 docs/images/logo.png create mode 100644 docs/images/qubernetes/k8s-logo.png create mode 100644 docs/theme/404.html create mode 100644 docs/theme/assets/javascripts/application.81068b3a.js create mode 100644 docs/theme/assets/stylesheets/application.668e8dde.css create mode 100644 docs/theme/assets/stylesheets/extra.css create mode 100644 docs/theme/base.html create mode 100644 docs/theme/partials/footer.html create mode 100644 docs/theme/partials/header.html create mode 100644 docs/theme/partials/nav.html create mode 100644 eth/api_backend_test.go create mode 100644 eth/config_test.go create mode 100644 eth/quorum_protocol.go create mode 100644 ethclient/privateTransactionManagerClient.go create mode 100644 ethclient/privateTransactionManagerClient_test.go create mode 100644 extension/api.go create mode 100644 extension/backend.go create mode 100644 extension/backend_test.go create mode 100644 extension/client.go create mode 100644 extension/contract_facade.go create mode 100644 extension/data_handler.go create mode 100644 extension/data_handler_test.go create mode 100644 extension/extensionContracts/contract_extender.go create mode 100644 extension/extensionContracts/contract_extender.sol create mode 100644 extension/extensionContracts/extensionHandler.go create mode 100644 extension/extensionContracts/types.go create mode 100644 extension/extension_utilities.go create mode 100644 extension/privacyExtension/state_set_utilities.go create mode 100644 extension/privacyExtension/state_set_utilities_test.go create mode 100644 extension/privacyExtension/state_setter.go create mode 100644 extension/privacyExtension/state_setter_test.go create mode 100644 extension/services_factory.go create mode 100644 extension/state_fetcher.go create mode 100644 extension/state_fetcher_test.go create mode 100644 extension/subscriptions.go create mode 100644 extension/types.go create mode 100644 graphql/graphiql_test.go create mode 100644 internal/build/gosrc.go create mode 100644 internal/build/util_test.go create mode 100644 internal/ethapi/api_test.go create mode 100644 internal/plugin/protocol.go create mode 100644 log/emit_checkpoint.go create mode 100644 logo.png create mode 100644 mkdocs.yml create mode 100644 multitenancy/authorization.go create mode 100644 multitenancy/authorization_test.go create mode 100644 multitenancy/docs.go create mode 100644 multitenancy/types.go create mode 100644 params/network_params_test.go create mode 100644 params/protocol_params_test.go create mode 100644 params/quorum.go create mode 100644 permission/api.go create mode 100644 permission/backend.go create mode 100644 permission/connection.go create mode 100644 permission/core/cache.go create mode 100644 permission/core/cache_test.go create mode 100644 permission/core/permissions.go create mode 100644 permission/core/permissions_test.go create mode 100644 permission/core/types/backend.go create mode 100644 permission/core/types/contract.go create mode 100644 permission/permission.go create mode 100644 permission/permission_test.go create mode 100644 permission/v1/backend.go create mode 100644 permission/v1/bind/accounts.go create mode 100644 permission/v1/bind/nodes.go create mode 100644 permission/v1/bind/org.go create mode 100644 permission/v1/bind/permission_impl.go create mode 100644 permission/v1/bind/permission_interface.go create mode 100644 permission/v1/bind/permission_upgr.go create mode 100644 permission/v1/bind/roles.go create mode 100644 permission/v1/bind/voter.go create mode 100644 permission/v1/contract.go create mode 100644 permission/v1/contract/AccountManager.sol create mode 100644 permission/v1/contract/NodeManager.sol create mode 100644 permission/v1/contract/OrgManager.sol create mode 100644 permission/v1/contract/PermissionsImplementation.sol create mode 100644 permission/v1/contract/PermissionsInterface.sol create mode 100644 permission/v1/contract/PermissionsUpgradable.sol create mode 100644 permission/v1/contract/RoleManager.sol create mode 100644 permission/v1/contract/VoterManager.sol create mode 100644 permission/v1/contract/gen/AccountManager.abi create mode 100644 permission/v1/contract/gen/AccountManager.bin create mode 100644 permission/v1/contract/gen/NodeManager.abi create mode 100644 permission/v1/contract/gen/NodeManager.bin create mode 100644 permission/v1/contract/gen/OrgManager.abi create mode 100644 permission/v1/contract/gen/OrgManager.bin create mode 100644 permission/v1/contract/gen/PermissionsImplementation.abi create mode 100644 permission/v1/contract/gen/PermissionsImplementation.bin create mode 100644 permission/v1/contract/gen/PermissionsInterface.abi create mode 100644 permission/v1/contract/gen/PermissionsInterface.bin create mode 100644 permission/v1/contract/gen/PermissionsUpgradable.abi create mode 100644 permission/v1/contract/gen/PermissionsUpgradable.bin create mode 100644 permission/v1/contract/gen/RoleManager.abi create mode 100644 permission/v1/contract/gen/RoleManager.bin create mode 100644 permission/v1/contract/gen/VoterManager.abi create mode 100644 permission/v1/contract/gen/VoterManager.bin create mode 100644 permission/v1/contract/gen/gen.go create mode 100644 permission/v2/backend.go create mode 100644 permission/v2/bind/accounts.go create mode 100644 permission/v2/bind/nodes.go create mode 100644 permission/v2/bind/org.go create mode 100644 permission/v2/bind/permission_impl.go create mode 100644 permission/v2/bind/permission_interface.go create mode 100644 permission/v2/bind/permission_upgr.go create mode 100644 permission/v2/bind/roles.go create mode 100644 permission/v2/bind/voter.go create mode 100644 permission/v2/contract.go create mode 100644 permission/v2/contract/AccountManager.sol create mode 100644 permission/v2/contract/NodeManager.sol create mode 100644 permission/v2/contract/OrgManager.sol create mode 100644 permission/v2/contract/PermissionsImplementation.sol create mode 100644 permission/v2/contract/PermissionsInterface.sol create mode 100644 permission/v2/contract/PermissionsUpgradable.sol create mode 100644 permission/v2/contract/RoleManager.sol create mode 100644 permission/v2/contract/VoterManager.sol create mode 100644 permission/v2/contract/gen/AccountManager.abi create mode 100644 permission/v2/contract/gen/AccountManager.bin create mode 100644 permission/v2/contract/gen/NodeManager.abi create mode 100644 permission/v2/contract/gen/NodeManager.bin create mode 100644 permission/v2/contract/gen/OrgManager.abi create mode 100644 permission/v2/contract/gen/OrgManager.bin create mode 100644 permission/v2/contract/gen/PermissionsImplementation.abi create mode 100644 permission/v2/contract/gen/PermissionsImplementation.bin create mode 100644 permission/v2/contract/gen/PermissionsInterface.abi create mode 100644 permission/v2/contract/gen/PermissionsInterface.bin create mode 100644 permission/v2/contract/gen/PermissionsUpgradable.abi create mode 100644 permission/v2/contract/gen/PermissionsUpgradable.bin create mode 100644 permission/v2/contract/gen/RoleManager.abi create mode 100644 permission/v2/contract/gen/RoleManager.bin create mode 100644 permission/v2/contract/gen/VoterManager.abi create mode 100644 permission/v2/contract/gen/VoterManager.bin create mode 100644 permission/v2/contract/gen/gen.go create mode 100644 plugin/account/connector.go create mode 100644 plugin/account/creator.go create mode 100644 plugin/account/gateway.go create mode 100644 plugin/account/gateway_test.go create mode 100644 plugin/account/internal/testutils/matchers.go create mode 100644 plugin/account/reloadableimpl.go create mode 100644 plugin/account/service.go create mode 100644 plugin/api.go create mode 100644 plugin/base.go create mode 100644 plugin/central.go create mode 100644 plugin/central_test.go create mode 100644 plugin/downloader.go create mode 100644 plugin/downloader_test.go create mode 100644 plugin/gen/docs.markdown.tmpl create mode 100644 plugin/gen/gen.go create mode 100644 plugin/gen/proto_common/init.pb.go create mode 100644 plugin/gen/proto_common/mock_init.go create mode 100644 plugin/helloworld/connector.go create mode 100644 plugin/helloworld/gateway.go create mode 100644 plugin/helloworld/gateway_test.go create mode 100644 plugin/helloworld/service.go create mode 100644 plugin/initializer/connector.go create mode 100644 plugin/initializer/gateway.go create mode 100644 plugin/initializer/gateway_test.go create mode 100644 plugin/initializer/service.go create mode 100644 plugin/local_verifier.go create mode 100644 plugin/local_verifier_test.go create mode 100644 plugin/online_verifier.go create mode 100644 plugin/plugin_templates.go create mode 100644 plugin/security/connector.go create mode 100644 plugin/security/gateway.go create mode 100644 plugin/security/gateway_test.go create mode 100644 plugin/security/service.go create mode 100644 plugin/security/utils.go create mode 100644 plugin/service.go create mode 100644 plugin/service_test.go create mode 100644 plugin/settings.go create mode 100644 plugin/settings_test.go create mode 100644 plugin/utils.go create mode 100644 plugin/utils_test.go create mode 100644 plugin/verifier.go create mode 100644 plugin/verifier_test.go create mode 100644 private/cache/cache.go create mode 100644 private/engine/common.go create mode 100644 private/engine/common_test.go create mode 100644 private/engine/constellation/constellation.go create mode 100644 private/engine/constellation/node.go create mode 100644 private/engine/notinuse/notInUsePrivateTxManager.go create mode 100644 private/engine/notinuse/notInUsePrivateTxManager_test.go create mode 100644 private/engine/tessera/model.go create mode 100644 private/engine/tessera/tessera.go create mode 100644 private/engine/tessera/tessera_test.go create mode 100644 private/engine/tessera/tessera_version_checker.go create mode 100644 private/engine/tessera/tessera_version_checker_test.go create mode 100644 private/engine/tessera/tessera_version_reader.go create mode 100644 private/engine/tessera/tessera_version_reader_test.go create mode 100644 private/mock_private.go create mode 100644 private/private.go create mode 100644 private/private_test.go create mode 100755 raft/api.go create mode 100644 raft/backend.go create mode 100644 raft/backend_test.go create mode 100644 raft/constants.go create mode 100644 raft/events.go create mode 100644 raft/handler.go create mode 100644 raft/handler_test.go create mode 100644 raft/listener.go create mode 100644 raft/minter.go create mode 100644 raft/minter_test.go create mode 100644 raft/peer.go create mode 100644 raft/persistence.go create mode 100644 raft/snapshot.go create mode 100644 raft/speculative_chain.go create mode 100644 raft/util.go create mode 100644 raft/wal.go create mode 100644 rpc/context.go create mode 100644 rpc/security.go create mode 100644 rpc/security_test.go create mode 100644 signer/core/plugin_api.go diff --git a/.bintray.json b/.bintray.json new file mode 100644 index 0000000000..953647582c --- /dev/null +++ b/.bintray.json @@ -0,0 +1,37 @@ +{ + "package": { + "name": "geth", + "repo": "quorum", + "subject": "_ORGANIZATION_", + "vcs_url": "https://github.com/jpmorganchase/quorum", + "licenses": [ + "LGPL-3.0" + ] + }, + "version": { + "name": "_TRAVIS_TAG_", + "desc": "Quorum: _TRAVIS_TAG_, Geth: _GETH_VERSION_, Commit: _TRAVIS_COMMIT_, Build Number: _TRAVIS_BUILD_NUMBER_", + "released": "_RELEASED_DATE_", + "vcs_tag": "_TRAVIS_TAG_", + "gpgSign": true, + "attributes": [ + { + "name": "Travis", + "values": [ + "_TRAVIS_JOB_WEB_URL_" + ], + "type": "string" + } + ] + }, + "files": [ + { + "includePattern": "/dist/(.*.tar.gz)", + "uploadPattern": "_TRAVIS_TAG_/$1", + "matrixParams": { + "override": 1 + } + } + ], + "publish": true +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index f87996cdcb..ab2def41c7 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,25 +1,21 @@ # Contributing -Thank you for considering to help out with the source code! We welcome -contributions from anyone on the internet, and are grateful for even the +Thank you for your interest in contributing to Quorum! +We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! -If you'd like to contribute to go-ethereum, please fork, fix, commit and send a -pull request for the maintainers to review and merge into the main code base. If -you wish to submit more complex changes though, please check up with the core -devs first on [our gitter channel](https://gitter.im/ethereum/go-ethereum) to -ensure those changes are in line with the general philosophy of the project -and/or get some early feedback which can make both your efforts much lighter as -well as our review and merge procedures quick and simple. +If you'd like to contribute to quorum please fork, fix, commit and +send a pull request. Commits which do not comply with the coding standards +are ignored. ## Coding guidelines Please make sure your contributions adhere to our coding guidelines: - * Code must adhere to the official Go -[formatting](https://golang.org/doc/effective_go.html#formatting) guidelines + * Code must adhere to the official Go +[formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). - * Code must be documented adhering to the official Go + * Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. * Pull requests need to be based on and opened against the `master` branch. * Commit messages should be prefixed with the package(s) they modify. @@ -27,10 +23,10 @@ Please make sure your contributions adhere to our coding guidelines: ## Can I have feature X -Before you submit a feature request, please check and make sure that it isn't -possible through some other means. The JavaScript-enabled console is a powerful -feature in the right hands. Please check our -[Wiki page](https://github.com/ethereum/go-ethereum/wiki) for more info +Before you submit a feature request, please check and make sure that it isn't +possible through some other means. The JavaScript-enabled console is a powerful +feature in the right hands. Please check our +[developer documentation](https://docs.goquorum.consensys.net/en/latest/) for more info and help. ## Configuration, dependencies, and tests diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 59285e456d..70903dee4f 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -7,8 +7,10 @@ For general questions please use [discord](https://discord.gg/nthXNEv) or the Et #### System information Geth version: `geth version` + OS & Version: Windows/Linux/OSX -Commit hash : (if `develop`) + +Branch, Commit Hash or Release: `git status` #### Expected behaviour diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..0ccd0ba462 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,273 @@ +name: Build Check +on: + push: + paths-ignore: + - 'docs/**' + - '**.md' + - 'mkdocs.yml' + - '.gitignore' + branches: + - master +env: + GO_VERSION: 1.15.5 + GOPATH: ${{ github.workspace }}/go + WORKING_DIR: ${{ github.workspace }}/go/src/github.com/ethereum/go-ethereum +jobs: + build: + name: 'Run tests and build on ${{ matrix.os }}' + strategy: + fail-fast: false + matrix: + # Not enable for macos as there's a consistent failure: + # --- FAIL: TestUPNP_DDWRT (2.20s) + # ###[error] natupnp_test.go:165: not discovered + # must be sommething with Github Actions VM networking setup. + # Event Ubuntu requires a workaround + os: [ "ubuntu-18.04" ] + env: + QUORUM_IGNORE_TEST_PACKAGES: github.com/ethereum/go-ethereum/les,github.com/ethereum/go-ethereum/les/flowcontrol,github.com/ethereum/go-ethereum/mobile + runs-on: ${{ matrix.os }} + steps: + - name: 'Setup Go ${{ env.GO_VERSION }}' + uses: actions/setup-go@v1 + with: + go-version: ${{ env.GO_VERSION }} + - name: 'Check out project files' + uses: actions/checkout@v2 + with: + submodules: recursive + path: ${{ env.WORKING_DIR }} + - name: 'Apply workaround to fix networking in Linux' + if: runner.os == 'Linux' + run: | + # https://github.com/actions/virtual-environments/issues/798 + sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf + - name: 'Prepare environment' + run: | + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + - name: 'Run tests and build all' + working-directory: ${{ env.WORKING_DIR }} + run: | + make test all + publish-docker: + name: Publish Docker Image + needs: + - build + runs-on: ubuntu-18.04 + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + - name: 'Build and publish to Docker Hub' + uses: docker/build-push-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_ACCESS_TOKEN }} + repository: ${{ secrets.DOCKER_REPO }} + tags: develop + add_git_labels: true + notify: + if: always() + name: Notify + needs: + - build + - publish-docker + runs-on: ubuntu-18.04 + steps: + - name: 'Setup metadata' + id: setup + run: | + gitref_path="${{ github.ref }}" + gitref_path=${gitref_path/refs\/heads/tree} # for refs/heads/my-branch + gitref_path=${gitref_path/refs\/tags/tree} # for refs/tags/v1.0.0 + gitref_path=${gitref_path#refs\/} # for refs/pull/123/merge + gitref_path=${gitref_path%/merge} # for refs/pull/123/merge + echo "::set-output name=gitref-path::$gitref_path" + - name: 'Prepare Slack message with full info' + id: status + uses: actions/github-script@0.8.0 + with: + script: | + var gitref_path = "${{ steps.setup.outputs.gitref-path }}" + //////////////////////////////////// + // retrieve workflow run data + //////////////////////////////////// + console.log("get workflow run") + const wf_run = await github.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.run_id }} + }) + console.log(wf_run.data) + console.log("get jobs for workflow run:", wf_run.data.jobs_url) + const jobs_response = await github.request(wf_run.data.jobs_url) + //////////////////////////////////// + // build slack notification message + //////////////////////////////////// + // some utility functions + var date_diff_func = function(start, end) { + var duration = end - start + // format the duration + var delta = duration / 1000 + var days = Math.floor(delta / 86400) + delta -= days * 86400 + var hours = Math.floor(delta / 3600) % 24 + delta -= hours * 3600 + var minutes = Math.floor(delta / 60) % 60 + delta -= minutes * 60 + var seconds = Math.floor(delta % 60) + var format_func = function(v, text, check) { + if (v <= 0 && check) { + return "" + } else { + return v + text + } + } + return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false) + } + var status_icon_func = function(s) { + switch (s) { + case "w_success": + return ":white_check_mark:" + case "w_failure": + return ":no_entry:" + case "w_cancelled": + return ":warning:" + case "success": + return "\u2713" + case "failure": + return "\u2717" + default: + return "\u20e0" + } + } + // build the message + var job_blocks = [] + var is_wf_success = true + var is_wf_failure = false + for (j of jobs_response.data.jobs) { + console.log(j.name, ":", j.status, j.conclusion, j.started_at, j.completed_at) + // ignore the current job running this script + if (j.status != "completed") { + continue + } + if (j.conclusion != "success") { + is_wf_success = false + } + if (j.conclusion == "failure") { + is_wf_failure = true + } + job_blocks.push({ + type: "section", + text: { + type: "mrkdwn", + text: `${status_icon_func(j.conclusion)} <${j.html_url}|${j.name}> took ${date_diff_func(new Date(j.started_at), new Date(j.completed_at))}` + } + }) + } + var workflow_status = "w_cancelled" + if (is_wf_success) { + workflow_status = "w_success" + } else if (is_wf_failure) { + workflow_status = "w_failure" + } + var context_elements = [ + { + "type": "mrkdwn", + "text": "*Repo:* " + }, + { + "type": "mrkdwn", + "text": `*Branch:* ` + }, + { + "type": "mrkdwn", + "text": `*Event:* ${wf_run.data.event}` + }, + { + "type": "mrkdwn", + "text": `*Commit:* ` + }, + { + "type": "mrkdwn", + "text": `*Author:* ${wf_run.data.head_commit.author.name}` + } + ] + var header_blocks = [ + { + type: "section", + text: { + type: "mrkdwn", + text: `${status_icon_func(workflow_status)} *${{ github.workflow }}* <${wf_run.data.html_url}|#${{ github.run_number }}> took ${date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at))}` + } + }, + { + type: "context", + elements: context_elements, + }, + { + type: "divider" + } + ] + var slack_msg = { + blocks: [].concat(header_blocks, job_blocks) + } + return slack_msg + - name: 'Prepare Slack message with partial info' + id: short_status + if: failure() + uses: actions/github-script@0.8.0 + with: + script: | + //////////////////////////////////// + // retrieve workflow run data + //////////////////////////////////// + const wf_run = await github.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.run_id }} + }) + var date_diff_func = function(start, end) { + var duration = end - start + // format the duration + var delta = duration / 1000 + var days = Math.floor(delta / 86400) + delta -= days * 86400 + var hours = Math.floor(delta / 3600) % 24 + delta -= hours * 3600 + var minutes = Math.floor(delta / 60) % 60 + delta -= minutes * 60 + var seconds = Math.floor(delta % 60) + var format_func = function(v, text, check) { + if (v <= 0 && check) { + return "" + } else { + return v + text + } + } + return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false) + } + var slack_msg = { + blocks: [ + { + type: "section", + text: { + type: "mrkdwn", + text: `:skull_and_crossbones: *${{ github.workflow }}* <${wf_run.data.html_url}|#${{ github.run_number }}> (took ${date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at))})` + } + } + ] + } + return slack_msg + - name: 'Send to Slack' + if: always() + run: | + cat < long_message.json + ${{ steps.status.outputs.result }} + JSON + cat < short_message.json + ${{ steps.short_status.outputs.result }} + JSON + _post() { + curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} -H "Content-type: application/json" --data "@${1}" + } + _post "long_message.json" || _post "short_message.json" \ No newline at end of file diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000000..f18d3a4f95 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,120 @@ +name: Pull Request Check +on: + pull_request: + paths-ignore: + - 'docs/**' + - '**.md' + - .gitignore +env: + GO_VERSION: 1.15.5 +jobs: + lint: + name: 'Code linters' + runs-on: ubuntu-18.04 + steps: + - name: 'Setup Go ${{ env.GO_VERSION }}' + uses: actions/setup-go@v1 + with: + go-version: ${{ env.GO_VERSION }} + - name: 'Check out project files' + uses: actions/checkout@v2 + with: + submodules: false + - name: 'Prepare environment' + run: | + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + - name: 'Run code linters' + run: | + GO111MODULE=on make lint + unit-tests: + name: 'Unit tests in ${{ matrix.os }}' + strategy: + fail-fast: false + matrix: + os: ["ubuntu-18.04"] + env: + QUORUM_IGNORE_TEST_PACKAGES: github.com/ethereum/go-ethereum/les,github.com/ethereum/go-ethereum/les/flowcontrol,github.com/ethereum/go-ethereum/mobile + runs-on: ${{ matrix.os }} + steps: + - name: 'Setup Go ${{ env.GO_VERSION }}' + uses: actions/setup-go@v1 + with: + go-version: ${{ env.GO_VERSION }} + - name: 'Check out project files' + uses: actions/checkout@v2 + with: + submodules: recursive + - name: 'Prepare environment' + run: | + # https://github.com/actions/virtual-environments/issues/798 + sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf + + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + - name: 'Run unit tests' + run: | + make test + docker-build: + name: 'Build Docker image' + runs-on: ubuntu-18.04 + steps: + - name: 'Check out project files' + uses: actions/checkout@v2 + - name: 'Build docker image' + id: build + run: | + output_dir=${{ runner.temp }}/docker + mkdir -p $output_dir + docker build -t quorumengineering/quorum:pr . + docker save quorumengineering/quorum:pr > quorum-pr.tar + tar cfvz $output_dir/quorum-pr.tar.gz quorum-pr.tar + echo "::set-output name=output_dir::$output_dir" + - name: 'Upload workflow artifact - Docker image' + uses: actions/upload-artifact@v1 + with: + name: docker-image + path: ${{ steps.build.outputs.output_dir }} + acceptance-tests: + name: Acceptance tests (${{ matrix.tag }}) + needs: + - docker-build + if: success() + strategy: + fail-fast: false + matrix: + # list of tag expression being executed in parallel + # for PR, only selective tests are run. + # More comprehensive suites are scheduled to run in master + tag: + - 'basic || basic-raft || (advanced && raft) || networks/typical::raft' + - 'basic || basic-istanbul || (advanced && istanbul && !block-heights) || networks/typical::istanbul' + runs-on: ubuntu-18.04 + steps: + - name: 'Download workflow artifact - Docker image' + uses: actions/download-artifact@v1 + with: + name: docker-image + - name: 'Load Docker image' + id: setup + run: | + tar xfvz docker-image/quorum-pr.tar.gz + docker load --input quorum-pr.tar + docker_env_file="${{ runner.temp }}/env.list" + echo "TF_VAR_quorum_docker_image={ name = \"quorumengineering/quorum:pr\", local = true }" >> $docker_env_file + echo "::set-output name=outputDir::${{ runner.temp }}" + echo "::set-output name=dockerEnvFile::$docker_env_file" + - name: 'Run acceptance tests' + run: | + cat ${{ steps.setup.outputs.dockerEnvFile }} + docker run --rm \ + --network host \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v ${{ steps.setup.outputs.outputDir }}:${{ steps.setup.outputs.outputDir }} \ + --env-file ${{ steps.setup.outputs.dockerEnvFile }} \ + quorumengineering/acctests:latest test \ + -Pauto \ + -Dauto.outputDir=${{ steps.setup.outputs.outputDir }} \ + -Dtags="${{ matrix.tag }}" + - name: 'Debug' + run: | + docker images + docker ps -a \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..e2a6d364e2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,383 @@ +name: Release +on: + push: + tags: + - 'v*' +env: + GO_VERSION: 1.15.5 + GOPATH: ${{ github.workspace }}/go + WORKING_DIR: ${{ github.workspace }}/go/src/github.com/ethereum/go-ethereum +jobs: + publish-docker: + name: Publish Docker Image + runs-on: ubuntu-18.04 + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + - name: 'Extract Docker Image Tag' + id: extract + run: | + REF=${{ github.ref }} + echo ::set-output name=image_tag::$(echo $REF | sed 's/refs\/tags\/v//g') + echo ::set-output name=image_tag_minor_latest::$(echo $REF | sed -e 's/refs\/tags\/v//g' -e 's/^\([[:digit:]]*\.[[:digit:]]*\).*/\1/') + - name: 'Build and publish to Docker Hub' + uses: docker/build-push-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_ACCESS_TOKEN }} + repository: ${{ secrets.DOCKER_REPO }} + tags: ${{ steps.extract.outputs.image_tag }}, ${{ steps.extract.outputs.image_tag_minor_latest }}, latest + add_git_labels: true + build-binary: + name: 'Build binary for ${{ matrix.os }}' + strategy: + fail-fast: false + matrix: + os: [ "ubuntu-18.04", "macos-latest" ] + runs-on: ${{ matrix.os }} + steps: + - name: 'Setup Go ${{ env.GO_VERSION }}' + uses: actions/setup-go@v1 + with: + go-version: ${{ env.GO_VERSION }} + - name: 'Prepare environment' + id: env + run: | + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + echo "::set-output name=key::$(go env GOOS)_$(go env GOARCH)" + echo "::set-output name=version::${GITHUB_REF##*/}" + - name: 'Check out project files' + uses: actions/checkout@v2 + with: + path: ${{ env.WORKING_DIR }} + - name: 'Build geth' + # For MacOS, We use gtar and run purge command to workaround issue + # https://github.com/actions/virtual-environments/issues/2619 + id: build + working-directory: ${{ env.WORKING_DIR }} + run: |- + make geth + mkdir -p build/artifact + tar_file=build/artifact/geth_${{ steps.env.outputs.version }}_${{ steps.env.outputs.key }}.tar.gz + + if [ "${{ matrix.os }}" == "macos-latest" ]; then + sudo /usr/sbin/purge + gtar cfvz ${tar_file} -C build/bin geth + else + tar cfvz ${tar_file} -C build/bin geth + fi + + echo "::set-output name=tar_file::${tar_file}" + echo "::set-output name=checksum::$(shasum -a 256 build/bin/geth | awk '{print $1}')" + - name: 'Verify tarball' + working-directory: ${{ env.WORKING_DIR }} + run: |- + cp ${{ steps.build.outputs.tar_file }} ${{ runner.temp }} + pushd ${{ runner.temp}} + tar xfvz *.tar.gz + actual_checksum=$(shasum -a 256 geth | awk '{print $1}') + echo "Checksum: ${actual_checksum}" + popd + if [ "${{ steps.build.outputs.checksum }}" != "${actual_checksum}" ]; then + echo "::error::geth checksum validation fails" + exit 1 + fi + - name: 'Upload artifact' + uses: actions/upload-artifact@v2 + with: + path: ${{ env.WORKING_DIR }}/build/artifact + name: ${{ steps.env.outputs.key }} + if-no-files-found: error + deploy-cloudsmith: + name: 'Deploy binary to Cloudsmith for ${{ matrix.goarch }}' + needs: + - build-binary + strategy: + fail-fast: false + matrix: + goarch: [ "linux_amd64", "darwin_amd64" ] + runs-on: ubuntu-latest + steps: + - name: 'Prepare environment' + id: env + run: | + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + echo "::set-output name=version::${GITHUB_REF##*/}" + - name: 'Download artifacts' + uses: actions/download-artifact@v2 + with: + path: artifact + - name: 'Upload artifacts to Cloudsmith' + id: push + uses: cloudsmith-io/action@master + with: + api-key: ${{ secrets.CLOUDSMITH_API_KEY }} + command: "push" + format: "raw" + owner: "consensys" + repo: "go-quorum" + file: "artifact/${{ matrix.goarch }}/geth_${{ steps.env.outputs.version }}_${{ matrix.goarch }}.tar.gz" + name: "geth_${{ steps.env.outputs.version }}_${{ matrix.goarch }}.tar.gz" + summary: "GoQuorum ${{ steps.env.outputs.version }} - binary distribution for ${{ matrix.goarch }}" + description: "See https://github.com/ConsenSys/quorum/" + version: "${{ steps.env.outputs.version }}" + draft-release: + name: 'Draft Github release' + needs: + - deploy-cloudsmith + - publish-docker + runs-on: ubuntu-18.04 + steps: + - name: 'Check out project files' + uses: actions/checkout@v2 + - name: 'Generate release notes' + id: release_notes + run: | + git fetch --depth=1 origin +refs/tags/*:refs/tags/* + file="generated-release-notes.md" + current_version="${GITHUB_REF##*/}" + last_version=$(git describe --abbrev=0 --tags `git rev-list --tags --skip=1 --max-count=1`) + last_release_date=$(git log -1 --format=%cd --date=short $last_version) + echo "Last version: $last_version on $last_release_date" + # pulling from git logs + curl -q -s -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/search/issues?q=repo:ConsenSys/quorum+is:pr+is:merged+merged%3A>=$last_release_date+sort%3Aupdated-desc" | jq -r '"* " + (.items[]|.title + " #" + (.number|tostring))' \ + >> $file + # pulling file hashes from Cloudsmith + echo "" >> $file + echo "| Filename | SHA256 Hash |" >> $file + echo "|:---------|:------------|" >> $file + curl --request GET \ + --url "https://api.cloudsmith.io/v1/packages/consensys/go-quorum/?query=version:$current_version" \ + --header 'Accept: application/json' \ + --header 'X-Api-Key: ${{ secrets.CLOUDSMITH_API_KEY }}' \ + | jq '.[] | select(.name | endswith(".asc") | not) | "|[\(.name)](\(.cdn_url))|`\(.checksum_sha256)`|"' -r \ + >> $file + content=$(cat $file) + # escape newline + content="${content//'%'/'%25'}" + content="${content//$'\n'/'%0A'}" + content="${content//$'\r'/'%0D'}" + echo "::set-output name=content::$content" + - name: 'Create Github draft release' + uses: actions/create-release@v1 + env: + # This token is provided by Actions, you do not need to create your own token + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + body: | + ${{ steps.release_notes.outputs.content }} + draft: true + prerelease: false + notify: + if: always() + name: 'Notify' + needs: + - build-binary + - deploy-cloudsmith + - publish-docker + - draft-release + runs-on: ubuntu-18.04 + steps: + - name: 'Setup metadata' + id: setup + run: | + gitref_path="${{ github.ref }}" + gitref_path=${gitref_path/refs\/heads/tree} # for refs/heads/my-branch + gitref_path=${gitref_path/refs\/tags/tree} # for refs/tags/v1.0.0 + gitref_path=${gitref_path#refs\/} # for refs/pull/123/merge + gitref_path=${gitref_path%/merge} # for refs/pull/123/merge + echo "::set-output name=gitref-path::$gitref_path" + echo "::set-output name=version::${GITHUB_REF##*/}" + - name: 'Prepare Slack message with full info' + id: status + uses: actions/github-script@0.8.0 + with: + script: | + var gitref_path = "${{ steps.setup.outputs.gitref-path }}" + //////////////////////////////////// + // retrieve workflow run data + //////////////////////////////////// + console.log("get workflow run") + const wf_run = await github.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.run_id }} + }) + console.log(wf_run.data) + console.log("get jobs for workflow run:", wf_run.data.jobs_url) + const jobs_response = await github.request(wf_run.data.jobs_url) + //////////////////////////////////// + // build slack notification message + //////////////////////////////////// + // some utility functions + var date_diff_func = function(start, end) { + var duration = end - start + // format the duration + var delta = duration / 1000 + var days = Math.floor(delta / 86400) + delta -= days * 86400 + var hours = Math.floor(delta / 3600) % 24 + delta -= hours * 3600 + var minutes = Math.floor(delta / 60) % 60 + delta -= minutes * 60 + var seconds = Math.floor(delta % 60) + var format_func = function(v, text, check) { + if (v <= 0 && check) { + return "" + } else { + return v + text + } + } + return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false) + } + var status_icon_func = function(s) { + switch (s) { + case "w_success": + return ":white_check_mark:" + case "w_failure": + return ":no_entry:" + case "w_cancelled": + return ":warning:" + case "success": + return "\u2713" + case "failure": + return "\u2717" + default: + return "\u20e0" + } + } + // build the message + var job_blocks = [] + var is_wf_success = true + var is_wf_failure = false + for (j of jobs_response.data.jobs) { + console.log(j.name, ":", j.status, j.conclusion, j.started_at, j.completed_at) + // ignore the current job running this script + if (j.status != "completed") { + continue + } + if (j.conclusion != "success") { + is_wf_success = false + } + if (j.conclusion == "failure") { + is_wf_failure = true + } + job_blocks.push({ + type: "section", + text: { + type: "mrkdwn", + text: `${status_icon_func(j.conclusion)} <${j.html_url}|${j.name}> took ${date_diff_func(new Date(j.started_at), new Date(j.completed_at))}` + } + }) + } + var workflow_status = "w_cancelled" + if (is_wf_success) { + workflow_status = "w_success" + } else if (is_wf_failure) { + workflow_status = "w_failure" + } + var context_elements = [ + { + "type": "mrkdwn", + "text": "*Repo:* " + }, + { + "type": "mrkdwn", + "text": `*Branch:* ` + }, + { + "type": "mrkdwn", + "text": `*Event:* ${wf_run.data.event}` + }, + { + "type": "mrkdwn", + "text": `*Commit:* ` + }, + { + "type": "mrkdwn", + "text": `*Author:* ${wf_run.data.head_commit.author.name}` + } + ] + var header_blocks = [ + { + type: "section", + text: { + type: "mrkdwn", + text: `${status_icon_func(workflow_status)} *${{ github.workflow }} ${{ steps.setup.outputs.version }}* <${wf_run.data.html_url}|#${{ github.run_number }}> took ${date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at))}` + } + }, + { + type: "context", + elements: context_elements, + }, + { + type: "divider" + } + ] + var slack_msg = { + blocks: [].concat(header_blocks, job_blocks) + } + return slack_msg + - name: 'Prepare Slack message with partial info' + id: short_status + if: failure() + uses: actions/github-script@0.8.0 + with: + script: | + //////////////////////////////////// + // retrieve workflow run data + //////////////////////////////////// + const wf_run = await github.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.run_id }} + }) + var date_diff_func = function(start, end) { + var duration = end - start + // format the duration + var delta = duration / 1000 + var days = Math.floor(delta / 86400) + delta -= days * 86400 + var hours = Math.floor(delta / 3600) % 24 + delta -= hours * 3600 + var minutes = Math.floor(delta / 60) % 60 + delta -= minutes * 60 + var seconds = Math.floor(delta % 60) + var format_func = function(v, text, check) { + if (v <= 0 && check) { + return "" + } else { + return v + text + } + } + return format_func(days, "d", true) + format_func(hours, "h", true) + format_func(minutes, "m", true) + format_func(seconds, "s", false) + } + var slack_msg = { + blocks: [ + { + type: "section", + text: { + type: "mrkdwn", + text: `:skull_and_crossbones: *${{ github.workflow }}* <${wf_run.data.html_url}|#${{ github.run_number }}> (took ${date_diff_func(new Date(wf_run.data.created_at), new Date(wf_run.data.updated_at))})` + } + } + ] + } + return slack_msg + - name: 'Send to Slack' + if: always() + run: | + cat < long_message.json + ${{ steps.status.outputs.result }} + JSON + cat < short_message.json + ${{ steps.short_status.outputs.result }} + JSON + _post() { + curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} -H "Content-type: application/json" --data "@${1}" + } + _post "long_message.json" || _post "short_message.json" + diff --git a/.github/workflows/upgradebot.yml b/.github/workflows/upgradebot.yml new file mode 100644 index 0000000000..0d0403143b --- /dev/null +++ b/.github/workflows/upgradebot.yml @@ -0,0 +1,27 @@ +name: Run Geth Upgrade +on: + workflow_dispatch: + schedule: + # * is a special character in YAML so you have to quote this string + - cron: '0 4 * * *' + +env: + GITHUB_USERNAME: ${{ secrets.QUORUM_BOT_GITHUB_USERNAME }} + GITHUB_USER_TOKEN: ${{ secrets.QUORUM_BOT_GITHUB_USER_TOKEN }} + GOPATH: /tmp + +jobs: + check_geth: + runs-on: ubuntu-latest + steps: + - name: Set up Go 1.15 + uses: actions/setup-go@v1 + with: + go-version: 1.15 + id: go + - name: Clone upgrade geth bot + run: | + git clone https://github.com/Consensys/quorum-bots.git $GOPATH/src/upgradebot + - name: Execute upgrade geth bot + run: | + go run upgradebot/cmd diff --git a/.gitignore b/.gitignore index 1ee8b83022..f1fcc40fa5 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ */**/*tx_database* */**/*dapps* build/_vendor/pkg +.idea +*.iml #* .#* @@ -47,3 +49,6 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log + +# QUORUM +generated-release-notes.md \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 18b325e206..395a91fe1b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,7 +1,7 @@ # This file configures github.com/golangci/golangci-lint. run: - timeout: 3m + timeout: 5m tests: true # default is true. Enables skipping of directories: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 0000000000..56c6ae7526 --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,33 @@ + +# Building Quorum + +Note: Building Quorum requires both a Go (version 1.9 or later) and a C compiler. You can install them using your favourite package manager. + +Clone the repository and build the source: + +``` +git clone https://github.com/jpmorganchase/quorum.git +cd quorum +make all +make test +``` + +Binaries are placed within `./build/bin`, most notably `geth` and `bootnode`. Either add this directory to your `$PATH` or copy those two bins into your PATH: + +```sh +# assumes that /usr/local/bin is in your PATH +cp ./build/bin/geth ./build/bin/bootnode /usr/local/bin/ +``` + +# Building on Windows +It is possible to build and run Quorum on Windows. Below are the steps required, please use Slack for any questions or support. Keep in mind that original Go-Ethereum provides a number of helper scripts for environment configuration and build execution. We're not planning ot provide this ourselves, but steps below explain what you may need to set up on your system to create such scripts. + +1. Install Go version 1.10 or 1.11 for Windows +2. Create a folder that you will bind to be GOPATH + * Set this folder as GOPATH in your environment: `set GOPATH=your_new_folder` + * Go will build binaries to a sub-path of GOPATH, so add it into PATH: `set "PATH=%PATH%;%GOPATH%\bin\"` +3. In GOPATH folder, create `src\github.com\ethereum` set of sub paths +4. Checkout Quorum into newly created GOPATH structure like so: `git clone https://github.com/jpmorganchase/quorum.git GOPATH\src\github.com\ethereum\go-ethereum`. Note: **go-ethereum** added at the end is required since Quorum occupies the same namespace as go-ethereum project. For this reason, on windows, a separate GOPATH is recommended if you need to build both projects +5. Change directory into checked out project and build it with `go install -v ./cmd/geth` + +The steps mimic the documentation from [go-ethereum project](https://github.com/ethereum/go-ethereum/wiki/Installation-instructions-for-Windows), please reference as needed diff --git a/Dockerfile b/Dockerfile index 0705361f5b..da99963d00 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,17 @@ # Build Geth in a stock Go builder container -FROM golang:1.15-alpine as builder +FROM golang:1.15.5-alpine as builder RUN apk add --no-cache make gcc musl-dev linux-headers git ADD . /go-ethereum -RUN cd /go-ethereum && make geth +RUN cd /go-ethereum && make geth bootnode # Pull Geth into a second stage deploy alpine container FROM alpine:latest RUN apk add --no-cache ca-certificates COPY --from=builder /go-ethereum/build/bin/geth /usr/local/bin/ +COPY --from=builder /go-ethereum/build/bin/bootnode /usr/local/bin/ EXPOSE 8545 8546 8547 30303 30303/udp ENTRYPOINT ["geth"] diff --git a/Makefile b/Makefile index 67095f4d00..0cac496449 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,11 @@ geth: @echo "Done building." @echo "Run \"$(GOBIN)/geth\" to launch geth." +bootnode: + $(GORUN) build/ci.go install ./cmd/bootnode + @echo "Done building." + @echo "Run \"$(GOBIN)/bootnode\" to launch bootnode." + all: $(GORUN) build/ci.go install diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 0000000000..e38ff02969 --- /dev/null +++ b/NOTES.md @@ -0,0 +1,112 @@ +# Hacking on Quorum / various notes + +## How does private state work? + +Original commit from Jeff explains the dual public and private state with INITIAL restrictions: +``` +commit 763f939f4725daa136161868d3b01fa7a84eb71e +Author: Jeffrey Wilcke +Date: Mon Oct 31 12:46:40 2016 +0100 + + core, core/vm: dual state & read only EVM + + This commit implements a dual state approach. The dual state approach + separates public and private state by making the core vm environment + context aware. + + Although not currently implemented it will need to prohibit value + transfers and it must initialise all transactions from accounts on the + public state. This means that sending transactions increments the + account nonce on the public state and contract addresses are derived + from the public state when initialised by a transaction. For obvious + reasons, contract created by private contracts are still derived from + public state. + + This is required in order to have consensus over the public state at all + times as non-private participants would still process the transaction on + the public state even though private payload can not be decrypted. This + means that participants of a private group must do the same in order to + have public consensus. However the creation of the contract and + interaction still occurs on the private state. + + It implements support for the following calling model: + + S: sender, (X): private, X: public, ->: direction, [ ]: read only mode + + 1. S -> A -> B + 2. S -> (A) -> (B) + 3. S -> (A) -> [ B -> C ] + + It does not support + + 1. (S) -> A + 2. (S) -> (A) + 3. S -> (A) -> B + + Implemented "read only" mode for the EVM. Read only mode is checked + during any opcode that could potentially modify the state. If such an + opcode is encountered during "read only", it throws an exception. + + The EVM is flagged "read only" when a private contract calls in to + public state. +``` + + +Some things have changed since, let's look at the EVM structure in some more detail: + +```go +type EVM struct { + ... + // StateDB gives access to the underlying state + StateDB StateDB + // Depth is the current call stack + depth int + ... + + publicState PublicState + privateState PrivateState + states [1027]*state.StateDB + currentStateDepth uint + readOnly bool + readOnlyDepth uint +} +``` + +The vanilla EVM has a call depth limit of 1024. Our `states` parallel the EVM call stack, recording as contracts in the public and private state call back and forth to each other. Note it doesn't have to be a "public -> private -> public -> private" back-and-forth chain. It can be any sequence of { public, private }. + +The interface for calling is this `Push` / `Pop` sequence: + +```go +evm.Push(getDualState(evm, addr)) +defer func() { evm.Pop() }() +// ... do work in the pushed state +``` + +The definitions of `Push` and `Pop` are simple and important enough to duplicate here: + +```go +func (env *EVM) Push(statedb StateDB) { + if env.privateState != statedb { + env.readOnly = true + env.readOnlyDepth = env.currentStateDepth + } + + if castedStateDb, ok := statedb.(*state.StateDB); ok { + env.states[env.currentStateDepth] = castedStateDb + env.currentStateDepth++ + } + + env.StateDB = statedb +} +func (env *EVM) Pop() { + env.currentStateDepth-- + if env.readOnly && env.currentStateDepth == env.readOnlyDepth { + env.readOnly = false + } + env.StateDB = env.states[env.currentStateDepth-1] +} +``` + +Note the invariant that `StateDB` always points to the current state db. + +The other interesting note is read only mode. Any time we call from the private state into the public state (`env.privateState != statedb`), we require anything deeper to be *read only*. Private state transactions can't affect public state, so we throw an EVM exception on any mutating operation (`SELFDESTRUCT, CREATE, SSTORE, LOG0, LOG1, LOG2, LOG3, LOG4`). Question: have any more mutating operations been added? Question: could we not mutate deeper private state? diff --git a/README.md b/README.md index ddb885dfdc..2de1c24af1 100644 --- a/README.md +++ b/README.md @@ -1,359 +1,104 @@ -## Go Ethereum +# -Official Golang implementation of the Ethereum protocol. +Quorum Slack +![Build Check](https://github.com/jpmorganchase/quorum/workflows/Build%20Check/badge.svg?branch=master) +[![Download](https://api.bintray.com/packages/quorumengineering/quorum/geth/images/download.svg)](https://bintray.com/quorumengineering/quorum/geth/_latestVersion) +[![Docker Pulls](https://img.shields.io/docker/pulls/quorumengineering/quorum)](https://hub.docker.com/r/quorumengineering/quorum) -[![API Reference]( -https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667 -)](https://pkg.go.dev/github.com/ethereum/go-ethereum?tab=doc) -[![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum) -[![Travis](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) -[![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) +GoQuorum is an Ethereum-based distributed ledger protocol with transaction/contract privacy and new consensus mechanisms. -Automated builds are available for stable releases and the unstable master branch. Binary -archives are published at https://geth.ethereum.org/downloads/. +GoQuorum is a fork of [go-ethereum](https://github.com/ethereum/go-ethereum) and is updated in line with go-ethereum releases. -## Building the source +Key enhancements over go-ethereum: -For prerequisites and detailed build instructions please read the [Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum) on the wiki. +* [__Privacy__](https://docs.goquorum.consensys.net/en/stable/Concepts/Privacy/Privacy/) - GoQuorum supports private transactions and private contracts through public/private state separation, and utilises peer-to-peer encrypted message exchanges (see [Constellation](https://github.com/consensys/constellation) and [Tessera](https://github.com/consensys/tessera)) for directed transfer of private data to network participants +* [__Alternative Consensus Mechanisms__](https://docs.goquorum.consensys.net/en/stable/Concepts/Consensus/Overview/) - with no need for POW/POS in a permissioned network, GoQuorum instead offers multiple consensus mechanisms that are more appropriate for consortium chains: + * [__Raft-based Consensus__](https://docs.goquorum.consensys.net/en/stable/Concepts/Consensus/Raft/) - a consensus model for faster blocktimes, transaction finality, and on-demand block creation + * [__Istanbul BFT__](https://docs.goquorum.consensys.net/en/stable/Concepts/Consensus/IBFT/) - a PBFT-inspired consensus algorithm with transaction finality, by AMIS. + * [__Clique POA Consensus__](https://github.com/ethereum/EIPs/issues/225) - a default POA consensus algorithm bundled with Go Ethereum. +* [__Peer Permissioning__](https://docs.goquorum.consensys.net/en/stable/Concepts/Permissioning/PermissionsOverview/) - node/peer permissioning, ensuring only known parties can join the network +* [__Account Management__](https://docs.goquorum.consensys.net/en/stable/Concepts/AccountManagement/) - GoQuorum introduced account plugins, which allows GoQuorum or clef to be extended with alternative methods of managing accounts including external vaults. +* [__Pluggable Architecture__](https://docs.goquorum.consensys.net/en/stable/Concepts/Plugins/Plugins/) - allows adding additional features as plugins to the core `geth`, providing extensibility, flexibility, and distinct isolation of GoQuorum features. +* __Higher Performance__ - GoQuorum offers significantly higher performance throughput than public geth -Building `geth` requires both a Go (version 1.13 or later) and a C compiler. You can install -them using your favourite package manager. Once the dependencies are installed, run +## Architecture -```shell -make geth -``` +![GoQuorum Tessera Privacy Flow](https://github.com/consensys/quorum/blob/master/docs/Quorum%20Design.png) -or, to build the full suite of utilities: +The above diagram is very high-level overview of component architecture used by GoQuorum. For more in-depth discussion of the components and how they interact, please refer to [lifecycle of a private transaction](https://docs.goquorum.consensys.net/en/stable/Concepts/Privacy/PrivateTransactionLifecycle/). -```shell -make all -``` +## Quickstart +There are [several ways](https://docs.goquorum.consensys.net/en/stable/HowTo/GetStarted/GettingStartedOverview/) to quickly get up and running with GoQuorum. One of the easiest is to use [GoQuorum Wizard](https://docs.goquorum.consensys.net/en/stable/HowTo/GetStarted/GettingStartedOverview/#goquorum-wizard) - a command line tool that allows users to set up a development GoQuorum network on their local machine in less than *2 minutes*. -## Executables +## GoQuorum Projects -The go-ethereum project comes with several wrappers/executables found in the `cmd` -directory. +Check out some of the interesting projects we are actively working on: -| Command | Description | -| :-----------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default), archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) for command line options. | -| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However, it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. | -| `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. | -| `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug run`). | -| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. | -| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user-friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). | -| `puppeth` | a CLI wizard that aids in creating a new Ethereum network. | +* [quorum-wizard](https://docs.goquorum.consensys.net/en/stable/HowTo/GetStarted/Wizard/GettingStarted/): Setup a GoQuorum network in 2 minutes! +* [quorum-remix-plugin](https://docs.goquorum.consensys.net/en/stable/Reference/RemixPlugin/Overview/): The GoQuorum plugin for Ethereum's Remix IDE adds support for creating and interacting with private contracts on a GoQuorum network. +* [Cakeshop](https://docs.goquorum.consensys.net/en/stable/HowTo/GetStarted/Cakeshop/): An integrated development environment and SDK for GoQuorum +* [quorum-profiling](https://docs.goquorum.consensys.net/en/stable/Concepts/Profiling/): Toolset for stress testing & benchmarking GoQuorum networks. +* [quorum-examples](https://docs.goquorum.consensys.net/en/stable/Reference/GoQuorum-Projects/): GoQuorum demonstration examples +* [qubernetes](https://docs.goquorum.consensys.net/en/stable/HowTo/GetStarted/GettingStartedOverview/#goquorum-on-kubernetes-qubernetes): Deploy GoQuorum on Kubernetes +* [quorum-cloud](https://docs.goquorum.consensys.net/en/stable/HowTo/GetStarted/GettingStartedOverview/#creating-a-network-deployed-in-the-cloud): Tools to help deploy GoQuorum network in a cloud provider of choice +* [quorum.js](https://docs.goquorum.consensys.net/en/stable/Reference/quorum.js/Overview/): Extends web3.js to support GoQuorum-specific APIs +* Zero Knowledge on GoQuorum + * [ZSL](https://docs.goquorum.consensys.net/en/stable/Reference/GoQuorum-Projects/#zsl-proof-of-concept) POC and [ZSL on GoQuorum](https://github.com/ConsenSys/zsl-q/blob/master/README.md) + * [Anonymous Zether](https://github.com/ConsenSys/anonymous-zether) implementation -## Running `geth` -Going through all the possible command line flags is out of scope here (please consult our -[CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)), -but we've enumerated a few common parameter combos to get you up to speed quickly -on how you can run your own `geth` instance. -### Full node on the main Ethereum network +## Official Docker Containers +The official docker containers can be found under https://hub.docker.com/u/quorumengineering/ -By far the most common scenario is people wanting to simply interact with the Ethereum -network: create accounts; transfer funds; deploy and interact with contracts. For this -particular use-case the user doesn't care about years-old historical data, so we can -fast-sync quickly to the current state of the network. To do so: +## Third Party Tools/Libraries -```shell -$ geth console -``` +The following GoQuorum-related libraries/applications have been created by Third Parties and as such are not specifically endorsed by J.P. Morgan. A big thanks to the developers for improving the tooling around GoQuorum! -This command will: - * Start `geth` in fast sync mode (default, can be changed with the `--syncmode` flag), - causing it to download more data in exchange for avoiding processing the entire history - of the Ethereum network, which is very CPU intensive. - * Start up `geth`'s built-in interactive [JavaScript console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console), - (via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/ethereum/wiki/wiki/JavaScript-API) - as well as `geth`'s own [management APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs). - This tool is optional and if you leave it out you can always attach to an already running - `geth` instance with `geth attach`. +* [Quorum Blockchain Explorer](https://github.com/web3labs/epirus-free) - a Blockchain Explorer for GoQuorum which supports viewing private transactions +* [Quorum-Genesis](https://github.com/davebryson/quorum-genesis) - A simple CL utility for GoQuorum to help populate the genesis file with voters and makers +* [Quorum Maker](https://github.com/synechron-finlabs/quorum-maker/) - a utility to create GoQuorum nodes +* [QuorumNetworkManager](https://github.com/ConsenSys/QuorumNetworkManager) - makes creating & managing GoQuorum networks easy +* [ERC20 REST service](https://github.com/web3labs/erc20-rest-service) - a GoQuorum-supported RESTful service for creating and managing ERC-20 tokens +* [Nethereum Quorum](https://github.com/Nethereum/Nethereum/tree/master/src/Nethereum.Quorum) - a .NET GoQuorum adapter +* [web3j-quorum](https://github.com/web3j/web3j-quorum) - an extension to the web3j Java library providing support for the GoQuorum API +* [Apache Camel](http://github.com/apache/camel) - an Apache Camel component providing support for the GoQuorum API using web3j library. Here is the artcile describing how to use Apache Camel with Ethereum and GoQuorum https://medium.com/@bibryam/enterprise-integration-for-ethereum-fa67a1577d43 -### A Full node on the Görli test network +## Contributing +GoQuorum is built on open source and we invite you to contribute enhancements. Upon review you will be required to complete a Contributor License Agreement (CLA) before we are able to merge. If you have any questions about the contribution process, please feel free to send an email to [info@goquorum.com](mailto:info@goquorum.com). Please see the [Contributors guide](.github/CONTRIBUTING.md) for more information about the process. -Transitioning towards developers, if you'd like to play around with creating Ethereum -contracts, you almost certainly would like to do that without any real money involved until -you get the hang of the entire system. In other words, instead of attaching to the main -network, you want to join the **test** network with your node, which is fully equivalent to -the main network, but with play-Ether only. +## Reporting Security Bugs +Security is part of our commitment to our users. At GoQuorum we have a close relationship with the security community, we understand the realm, and encourage security researchers to become part of our mission of building secure reliable software. This section explains how to submit security bugs, and what to expect in return. -```shell -$ geth --goerli console -``` +All security bugs in [GoQuorum](https://github.com/consensys/quorum) and its ecosystem ([Tessera](https://github.com/consensys/tessera), [Constellation](https://github.com/consensys/constellation), [Cakeshop](https://github.com/consensys/cakeshop), ..etc) should be reported by email to [security-quorum@consensys.net](mailto:security-quorum@consensys.net). Please use the prefix **[security]** in your subject. This email is delivered to GoQuorum security team. Your email will be acknowledged, and you'll receive a more detailed response to your email as soon as possible indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement. -The `console` subcommand has the exact same meaning as above and they are equally -useful on the testnet too. Please, see above for their explanations if you've skipped here. +If you have not received a reply to your email or you have not heard from the security team please contact any team member through GoQuorum slack security channel. **Please note that GoQuorum slack channels are public discussion forum**. When escalating to this medium, please do not disclose the details of the issue. Simply state that you're trying to reach a member of the security team. -Specifying the `--goerli` flag, however, will reconfigure your `geth` instance a bit: +#### Responsible Disclosure Process +GoQuorum project uses the following responsible disclosure process: - * Instead of connecting the main Ethereum network, the client will connect to the Görli - test network, which uses different P2P bootnodes, different network IDs and genesis - states. - * Instead of using the default data directory (`~/.ethereum` on Linux for example), `geth` - will nest itself one level deeper into a `goerli` subfolder (`~/.ethereum/goerli` on - Linux). Note, on OSX and Linux this also means that attaching to a running testnet node - requires the use of a custom endpoint since `geth attach` will try to attach to a - production node endpoint by default, e.g., - `geth attach /goerli/geth.ipc`. Windows users are not affected by - this. +- Once the security report is received it is assigned a primary handler. This person coordinates the fix and release process. +- The issue is confirmed and a list of affected software is determined. +- Code is audited to find any potential similar problems. +- If it is determined, in consultation with the submitter, that a CVE-ID is required, the primary handler will trigger the process. +- Fixes are applied to the public repository and a new release is issued. +- On the date that the fixes are applied, announcements are sent to Quorum-announce. +- At this point you would be able to disclose publicly your finding. -*Note: Although there are some internal protective measures to prevent transactions from -crossing over between the main network and test network, you should make sure to always -use separate accounts for play-money and real-money. Unless you manually move -accounts, `geth` will by default correctly separate the two networks and will not make any -accounts available between them.* +**Note:** This process can take some time. Every effort will be made to handle the security bug in as timely a manner as possible, however it's important that we follow the process described above to ensure that disclosures are handled consistently. -### Full node on the Rinkeby test network +#### Receiving Security Updates +The best way to receive security announcements is to subscribe to the Quorum-announce mailing list/channel. Any messages pertaining to a security issue will be prefixed with **[security]**. -Go Ethereum also supports connecting to the older proof-of-authority based test network -called [*Rinkeby*](https://www.rinkeby.io) which is operated by members of the community. - -```shell -$ geth --rinkeby console -``` - -### Full node on the Ropsten test network - -In addition to Görli and Rinkeby, Geth also supports the ancient Ropsten testnet. The -Ropsten test network is based on the Ethash proof-of-work consensus algorithm. As such, -it has certain extra overhead and is more susceptible to reorganization attacks due to the -network's low difficulty/security. - -```shell -$ geth --ropsten console -``` - -*Note: Older Geth configurations store the Ropsten database in the `testnet` subdirectory.* - -### Configuration - -As an alternative to passing the numerous flags to the `geth` binary, you can also pass a -configuration file via: - -```shell -$ geth --config /path/to/your_config.toml -``` - -To get an idea how the file should look like you can use the `dumpconfig` subcommand to -export your existing configuration: - -```shell -$ geth --your-favourite-flags dumpconfig -``` - -*Note: This works only with `geth` v1.6.0 and above.* - -#### Docker quick start - -One of the quickest ways to get Ethereum up and running on your machine is by using -Docker: - -```shell -docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \ - -p 8545:8545 -p 30303:30303 \ - ethereum/client-go -``` - -This will start `geth` in fast-sync mode with a DB memory allowance of 1GB just as the -above command does. It will also create a persistent volume in your home directory for -saving your blockchain as well as map the default ports. There is also an `alpine` tag -available for a slim version of the image. - -Do not forget `--http.addr 0.0.0.0`, if you want to access RPC from other containers -and/or hosts. By default, `geth` binds to the local interface and RPC endpoints is not -accessible from the outside. - -### Programmatically interfacing `geth` nodes - -As a developer, sooner rather than later you'll want to start interacting with `geth` and the -Ethereum network via your own programs and not manually through the console. To aid -this, `geth` has built-in support for a JSON-RPC based APIs ([standard APIs](https://github.com/ethereum/wiki/wiki/JSON-RPC) -and [`geth` specific APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs)). -These can be exposed via HTTP, WebSockets and IPC (UNIX sockets on UNIX based -platforms, and named pipes on Windows). - -The IPC interface is enabled by default and exposes all the APIs supported by `geth`, -whereas the HTTP and WS interfaces need to manually be enabled and only expose a -subset of APIs due to security reasons. These can be turned on/off and configured as -you'd expect. - -HTTP based JSON-RPC API options: - - * `--http` Enable the HTTP-RPC server - * `--http.addr` HTTP-RPC server listening interface (default: `localhost`) - * `--http.port` HTTP-RPC server listening port (default: `8545`) - * `--http.api` API's offered over the HTTP-RPC interface (default: `eth,net,web3`) - * `--http.corsdomain` Comma separated list of domains from which to accept cross origin requests (browser enforced) - * `--ws` Enable the WS-RPC server - * `--ws.addr` WS-RPC server listening interface (default: `localhost`) - * `--ws.port` WS-RPC server listening port (default: `8546`) - * `--ws.api` API's offered over the WS-RPC interface (default: `eth,net,web3`) - * `--ws.origins` Origins from which to accept websockets requests - * `--ipcdisable` Disable the IPC-RPC server - * `--ipcapi` API's offered over the IPC-RPC interface (default: `admin,debug,eth,miner,net,personal,shh,txpool,web3`) - * `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it) - -You'll need to use your own programming environments' capabilities (libraries, tools, etc) to -connect via HTTP, WS or IPC to a `geth` node configured with the above flags and you'll -need to speak [JSON-RPC](https://www.jsonrpc.org/specification) on all transports. You -can reuse the same connection for multiple requests! - -**Note: Please understand the security implications of opening up an HTTP/WS based -transport before doing so! Hackers on the internet are actively trying to subvert -Ethereum nodes with exposed APIs! Further, all browser tabs can access locally -running web servers, so malicious web pages could try to subvert locally available -APIs!** - -### Operating a private network - -Maintaining your own private network is more involved as a lot of configurations taken for -granted in the official networks need to be manually set up. - -#### Defining the private genesis state - -First, you'll need to create the genesis state of your networks, which all nodes need to be -aware of and agree upon. This consists of a small JSON file (e.g. call it `genesis.json`): - -```json -{ - "config": { - "chainId": , - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0 - }, - "alloc": {}, - "coinbase": "0x0000000000000000000000000000000000000000", - "difficulty": "0x20000", - "extraData": "", - "gasLimit": "0x2fefd8", - "nonce": "0x0000000000000042", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x00" -} -``` - -The above fields should be fine for most purposes, although we'd recommend changing -the `nonce` to some random value so you prevent unknown remote nodes from being able -to connect to you. If you'd like to pre-fund some accounts for easier testing, create -the accounts and populate the `alloc` field with their addresses. - -```json -"alloc": { - "0x0000000000000000000000000000000000000001": { - "balance": "111111111" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "222222222" - } -} -``` - -With the genesis state defined in the above JSON file, you'll need to initialize **every** -`geth` node with it prior to starting it up to ensure all blockchain parameters are correctly -set: - -```shell -$ geth init path/to/genesis.json -``` - -#### Creating the rendezvous point - -With all nodes that you want to run initialized to the desired genesis state, you'll need to -start a bootstrap node that others can use to find each other in your network and/or over -the internet. The clean way is to configure and run a dedicated bootnode: - -```shell -$ bootnode --genkey=boot.key -$ bootnode --nodekey=boot.key -``` - -With the bootnode online, it will display an [`enode` URL](https://github.com/ethereum/wiki/wiki/enode-url-format) -that other nodes can use to connect to it and exchange peer information. Make sure to -replace the displayed IP address information (most probably `[::]`) with your externally -accessible IP to get the actual `enode` URL. - -*Note: You could also use a full-fledged `geth` node as a bootnode, but it's the less -recommended way.* - -#### Starting up your member nodes - -With the bootnode operational and externally reachable (you can try -`telnet ` to ensure it's indeed reachable), start every subsequent `geth` -node pointed to the bootnode for peer discovery via the `--bootnodes` flag. It will -probably also be desirable to keep the data directory of your private network separated, so -do also specify a custom `--datadir` flag. - -```shell -$ geth --datadir=path/to/custom/data/folder --bootnodes= -``` - -*Note: Since your network will be completely cut off from the main and test networks, you'll -also need to configure a miner to process transactions and create new blocks for you.* - -#### Running a private miner - -Mining on the public Ethereum network is a complex task as it's only feasible using GPUs, -requiring an OpenCL or CUDA enabled `ethminer` instance. For information on such a -setup, please consult the [EtherMining subreddit](https://www.reddit.com/r/EtherMining/) -and the [ethminer](https://github.com/ethereum-mining/ethminer) repository. - -In a private network setting, however a single CPU miner instance is more than enough for -practical purposes as it can produce a stable stream of blocks at the correct intervals -without needing heavy resources (consider running on a single thread, no need for multiple -ones either). To start a `geth` instance for mining, run it with all your usual flags, extended -by: - -```shell -$ geth --mine --miner.threads=1 --etherbase=0x0000000000000000000000000000000000000000 -``` - -Which will start mining blocks and transactions on a single CPU thread, crediting all -proceedings to the account specified by `--etherbase`. You can further tune the mining -by changing the default gas limit blocks converge to (`--targetgaslimit`) and the price -transactions are accepted at (`--gasprice`). - -## Contribution - -Thank you for considering to help out with the source code! We welcome contributions -from anyone on the internet, and are grateful for even the smallest of fixes! - -If you'd like to contribute to go-ethereum, please fork, fix, commit and send a pull request -for the maintainers to review and merge into the main code base. If you wish to submit -more complex changes though, please check up with the core devs first on [our gitter channel](https://gitter.im/ethereum/go-ethereum) -to ensure those changes are in line with the general philosophy of the project and/or get -some early feedback which can make both your efforts much lighter as well as our review -and merge procedures quick and simple. - -Please make sure your contributions adhere to our coding guidelines: - - * Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) - guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). - * Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) - guidelines. - * Pull requests need to be based on and opened against the `master` branch. - * Commit messages should be prefixed with the package(s) they modify. - * E.g. "eth, rpc: make trace configs optional" - -Please see the [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide) -for more details on configuring your environment, managing project dependencies, and -testing procedures. +Comments on This Policy +If you have any suggestions to improve this policy, please send an email to info@goquorum.com for discussion. ## License The go-ethereum library (i.e. all code outside of the `cmd` directory) is licensed under the -[GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html), -also included in our repository in the `COPYING.LESSER` file. +[GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html), also +included in our repository in the `COPYING.LESSER` file. The go-ethereum binaries (i.e. all code inside of the `cmd` directory) is licensed under the -[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), also -included in our repository in the `COPYING` file. +[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), also included +in our repository in the `COPYING` file. diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index e51f0bd8ea..4865eb7bdd 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -94,3 +94,19 @@ func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) }, } } + +// Quorum +// +// NewWalletTransactor is a utility method to easily create a transaction signer +// from a wallet account +func NewWalletTransactor(w accounts.Wallet, account accounts.Account) *TransactOpts { + return &TransactOpts{ + From: account.Address, + Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, errors.New("not authorized to sign this account") + } + return w.SignTx(account, tx, nil) // homestead signer without chainID is backward compatible + }, + } +} diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index ca60cc1b43..ca456e6f0e 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -81,7 +81,9 @@ type ContractTransactor interface { // for setting a reasonable default. EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) // SendTransaction injects the transaction into the pending pool for execution. - SendTransaction(ctx context.Context, tx *types.Transaction) error + SendTransaction(ctx context.Context, tx *types.Transaction, args PrivateTxArgs) error + // PreparePrivateTransaction send the private transaction to Tessera/Constellation's /storeraw API using HTTP + PreparePrivateTransaction(data []byte, privateFrom string) (common.EncryptedPayloadHash, error) } // ContractFilterer defines the methods needed to access log events using one-off diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index a43cb94678..d0e44645cd 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -33,10 +33,12 @@ import ( "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" @@ -89,6 +91,20 @@ func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.Genesis return backend } +// Quorum +// +// Create a simulated backend based on existing Ethereum service +func NewSimulatedBackendFrom(ethereum *eth.Ethereum) *SimulatedBackend { + backend := &SimulatedBackend{ + database: ethereum.ChainDb(), + blockchain: ethereum.BlockChain(), + config: ethereum.BlockChain().Config(), + events: filters.NewEventSystem(&filterBackend{ethereum.ChainDb(), ethereum.BlockChain()}, false), + } + backend.rollback() + return backend +} + // NewSimulatedBackend creates a new binding backend using a simulated blockchain // for testing purposes. func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { @@ -123,7 +139,7 @@ func (b *SimulatedBackend) Rollback() { func (b *SimulatedBackend) rollback() { blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {}) - stateDB, _ := b.blockchain.State() + stateDB, _, _ := b.blockchain.State() b.pendingBlock = blocks[0] b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) @@ -132,13 +148,15 @@ func (b *SimulatedBackend) rollback() { // stateByBlockNumber retrieves a state by a given blocknumber. func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) { if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 { - return b.blockchain.State() + statedb, _, err := b.blockchain.State() + return statedb, err } block, err := b.blockByNumberNoLock(ctx, blockNumber) if err != nil { return nil, err } - return b.blockchain.StateAt(block.Root()) + statedb, _, err := b.blockchain.StateAt(block.Root()) + return statedb, err } // CodeAt returns the code associated with a certain account in the blockchain. @@ -150,7 +168,7 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, if err != nil { return nil, err } - + stateDB, _, _ = b.blockchain.State() return stateDB.GetCode(contract), nil } @@ -163,7 +181,7 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres if err != nil { return nil, err } - + stateDB, _, _ = b.blockchain.State() return stateDB.GetBalance(contract), nil } @@ -176,7 +194,7 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, if err != nil { return 0, err } - + stateDB, _, _ = b.blockchain.State() return stateDB.GetNonce(contract), nil } @@ -189,7 +207,7 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres if err != nil { return nil, err } - + stateDB, _, _ = b.blockchain.State() val := stateDB.GetState(contract, key) return val[:], nil } @@ -383,11 +401,11 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { return nil, errBlockNumberUnsupported } - stateDB, err := b.blockchain.State() + stateDB, _, err := b.blockchain.State() if err != nil { return nil, err } - res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB) + res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB, stateDB) if err != nil { return nil, err } @@ -404,7 +422,7 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereu defer b.mu.Unlock() defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot()) - res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) + res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState, b.pendingState) if err != nil { return nil, err } @@ -475,7 +493,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs call.Gas = gas snapshot := b.pendingState.Snapshot() - res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState) + res, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState, b.pendingState) b.pendingState.RevertToSnapshot(snapshot) if err != nil { @@ -525,7 +543,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs // callContract implements common code between normal and pending contract calls. // state is modified during execution, make sure to copy it if necessary. -func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB) (*core.ExecutionResult, error) { +func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB, privateState *state.StateDB) (*core.ExecutionResult, error) { // Ensure message is initialized properly. if call.GasPrice == nil { call.GasPrice = big.NewInt(1) @@ -545,7 +563,7 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmEnv := vm.NewEVM(evmContext, stateDB, b.config, vm.Config{}) + vmEnv := vm.NewEVM(evmContext, stateDB, privateState, b.config, vm.Config{}) gasPool := new(core.GasPool).AddGas(math.MaxUint64) return core.NewStateTransition(vmEnv, msg, gasPool).TransitionDb() @@ -553,7 +571,7 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg // SendTransaction updates the pending block to include the given transaction. // It panics if the transaction is invalid. -func (b *SimulatedBackend) SendTransaction(_ context.Context, tx *types.Transaction) error { +func (b *SimulatedBackend) SendTransaction(_ context.Context, tx *types.Transaction, args bind.PrivateTxArgs) error { b.mu.Lock() defer b.mu.Unlock() @@ -572,13 +590,18 @@ func (b *SimulatedBackend) SendTransaction(_ context.Context, tx *types.Transact } block.AddTxWithChain(b.blockchain, tx) }) - stateDB, _ := b.blockchain.State() + stateDB, _, _ := b.blockchain.State() b.pendingBlock = blocks[0] b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) return nil } +// PreparePrivateTransaction dummy implementation +func (b *SimulatedBackend) PreparePrivateTransaction(data []byte, privateFrom string) (common.EncryptedPayloadHash, error) { + return common.EncryptedPayloadHash{}, nil +} + // FilterLogs executes a log filter operation, blocking during execution and // returning all the results in one batch. // @@ -587,7 +610,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.Filter var filter *filters.Filter if query.BlockHash != nil { // Block filter requested, construct a single-shot filter - filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) + filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics, query.PSI) } else { // Initialize unset filter boundaries to run from genesis to chain head from := int64(0) @@ -599,7 +622,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.Filter to = query.ToBlock.Int64() } // Construct the range filter - filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) + filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics, query.PSI) } // Run the filter and return all the logs logs, err := filter.Logs(ctx) @@ -687,7 +710,7 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) { block.OffsetTime(int64(adjustment.Seconds())) }) - stateDB, _ := b.blockchain.State() + stateDB, _, _ := b.blockchain.State() b.pendingBlock = blocks[0] b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database(), nil) @@ -721,7 +744,9 @@ type filterBackend struct { bc *core.BlockChain } -func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } +func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } +func (fb *filterBackend) PSMR() mps.PrivateStateMetadataResolver { return fb.bc.PrivateStateManager() } + func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } func (fb *filterBackend) HeaderByNumber(_ context.Context, block rpc.BlockNumber) (*types.Header, error) { @@ -785,6 +810,10 @@ func (fb *filterBackend) ServiceFilter(_ context.Context, _ *bloombits.MatcherSe panic("not supported") } +func (fb *filterBackend) AccountExtraDataStateGetterByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { + panic("not supported") +} + func nullSubscription() event.Subscription { return event.NewSubscription(func(quit <-chan struct{}) error { <-quit diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 2dffe26f6e..9cbab1f9b0 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -63,7 +63,7 @@ func TestSimulatedBackend(t *testing.T) { tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code)) tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key) - err = sim.SendTransaction(context.Background(), tx) + err = sim.SendTransaction(context.Background(), tx, bind.PrivateTxArgs{}) if err != nil { t.Fatal("error sending transaction") } @@ -78,7 +78,7 @@ func TestSimulatedBackend(t *testing.T) { } sim.Commit() - _, isPending, err = sim.TransactionByHash(context.Background(), txHash) + tx, isPending, err = sim.TransactionByHash(context.Background(), txHash) if err != nil { t.Fatalf("error getting transaction with hash: %v", txHash.String()) } @@ -129,7 +129,7 @@ func TestNewSimulatedBackend(t *testing.T) { t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config) } - stateDB, _ := sim.blockchain.State() + stateDB, _, _ := sim.blockchain.State() bal := stateDB.GetBalance(testAddr) if bal.Cmp(expectedBal) != 0 { t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) @@ -162,7 +162,10 @@ func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { if err != nil { t.Errorf("could not sign tx: %v", err) } - sim.SendTransaction(context.Background(), signedTx) + err = sim.SendTransaction(context.Background(), signedTx, bind.PrivateTxArgs{}) + if err != nil { + t.Error("Handled an error") + } // AdjustTime should fail on non-empty block if err := sim.AdjustTime(time.Second); err == nil { t.Error("Expected adjust time to error on non-empty block") @@ -183,7 +186,10 @@ func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { if err != nil { t.Errorf("could not sign tx: %v", err) } - sim.SendTransaction(context.Background(), signedTx2) + err = sim.SendTransaction(context.Background(), signedTx2, bind.PrivateTxArgs{}) + if err != nil { + t.Error("Handled an error") + } sim.Commit() newTime = sim.pendingBlock.Time() if newTime-prevTime >= uint64(time.Minute.Seconds()) { @@ -288,7 +294,7 @@ func TestSimulatedBackend_NonceAt(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } @@ -329,7 +335,7 @@ func TestSimulatedBackend_SendTransaction(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } @@ -364,7 +370,7 @@ func TestSimulatedBackend_TransactionByHash(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } @@ -677,7 +683,7 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } @@ -732,7 +738,7 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } @@ -787,7 +793,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } @@ -808,7 +814,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) { if err != nil { t.Errorf("could not sign tx: %v", err) } - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not send tx: %v", err) } @@ -839,7 +845,7 @@ func TestSimulatedBackend_TransactionReceipt(t *testing.T) { } // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) + err = sim.SendTransaction(bgCtx, signedTx, bind.PrivateTxArgs{}) if err != nil { t.Errorf("could not add tx to pending block: %v", err) } diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 311e4108cd..4e977ff87e 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -34,6 +34,13 @@ import ( // sign the transaction before submission. type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error) +// Quorum +// +// Additional arguments in order to support transaction privacy +type PrivateTxArgs struct { + PrivateFor []string `json:"privateFor"` +} + // CallOpts is the collection of options to fine tune a contract call request. type CallOpts struct { Pending bool // Whether to operate on the pending state or the last known one @@ -54,6 +61,10 @@ type TransactOpts struct { GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) + + // Quorum + PrivateFrom string // The public key of the Tessera/Constellation identity to send this tx from. + PrivateFor []string // The public keys of the Tessera/Constellation identities this tx is intended for. } // FilterOpts is the collection of options to fine tune filtering for events @@ -243,16 +254,38 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i } else { rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input) } + + // Quorum + // If this transaction is private, we need to substitute the data payload + // with the hash of the transaction from tessera/constellation. + if opts.PrivateFor != nil { + var payload []byte + hash, err := c.transactor.PreparePrivateTransaction(rawTx.Data(), opts.PrivateFrom) + if err != nil { + return nil, err + } + payload = hash.Bytes() + rawTx = c.createPrivateTransaction(rawTx, payload) + } + + // Choose signer to sign transaction if opts.Signer == nil { return nil, errors.New("no signer to authorize the transaction with") } - signedTx, err := opts.Signer(types.HomesteadSigner{}, opts.From, rawTx) + var signedTx *types.Transaction + if rawTx.IsPrivate() { + signedTx, err = opts.Signer(types.QuorumPrivateTxSigner{}, opts.From, rawTx) + } else { + signedTx, err = opts.Signer(types.HomesteadSigner{}, opts.From, rawTx) + } if err != nil { return nil, err } - if err := c.transactor.SendTransaction(ensureContext(opts.Context), signedTx); err != nil { + + if err := c.transactor.SendTransaction(ensureContext(opts.Context), signedTx, PrivateTxArgs{PrivateFor: opts.PrivateFor}); err != nil { return nil, err } + return signedTx, nil } @@ -368,6 +401,19 @@ func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event strin return abi.ParseTopicsIntoMap(out, indexed, log.Topics[1:]) } +// Quorum +// createPrivateTransaction replaces the payload of private transaction to the hash from Tessera/Constellation +func (c *BoundContract) createPrivateTransaction(tx *types.Transaction, payload []byte) *types.Transaction { + var privateTx *types.Transaction + if tx.To() == nil { + privateTx = types.NewContractCreation(tx.Nonce(), tx.Value(), tx.Gas(), tx.GasPrice(), payload) + } else { + privateTx = types.NewTransaction(tx.Nonce(), c.address, tx.Value(), tx.Gas(), tx.GasPrice(), payload) + } + privateTx.SetPrivate() + return privateTx +} + // ensureContext is a helper method to ensure a context is not nil, even if the // user specified it as such. func ensureContext(ctx context.Context) context.Context { diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index a5f08499d2..86d85f35af 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1751,6 +1751,13 @@ func TestGolangBindings(t *testing.T) { if out, err := replacer.CombinedOutput(); err != nil { t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) } + // Quorum - add package github.com/ConsenSys/quorum/crypto/secp256k1 that is defined as a standalone module + secp256Replacer := exec.Command(gocmd, "mod", "edit", "-replace", "github.com/ethereum/go-ethereum/crypto/secp256k1=github.com/ConsenSys/quorum/crypto/secp256k1@v0.0.0-20210223160031-6e8585c2a9ad") // Repo root + secp256Replacer.Dir = pkg + if out, err := secp256Replacer.CombinedOutput(); err != nil { + t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) + } + // Test the entire package and report any failures cmd := exec.Command(gocmd, "test", "-v", "-count", "1") cmd.Dir = pkg diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index e57b03cfa6..400e5c7617 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -122,6 +122,8 @@ var ( // {{.Type}}ABI is the input ABI used to generate the binding from. const {{.Type}}ABI = "{{.InputABI}}" + var {{.Type}}ParsedABI, _ = abi.JSON(strings.NewReader({{.Type}}ABI)) + {{if $contract.FuncSigs}} // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. var {{.Type}}FuncSigs = map[string]string{ @@ -486,6 +488,7 @@ var ( return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil } + var {{.Normalized.Name}}TopicHash = "0x{{printf "%x" .Original.ID}}" // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. // // Solidity: {{.Original.String}} diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 9f9b7a000d..d83cb0b412 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -79,7 +79,7 @@ func TestWaitDeployed(t *testing.T) { }() // Send and mine the transaction. - backend.SendTransaction(ctx, tx) + backend.SendTransaction(ctx, tx, bind.PrivateTxArgs{}) backend.Commit() select { @@ -111,7 +111,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - backend.SendTransaction(ctx, tx) + backend.SendTransaction(ctx, tx, bind.PrivateTxArgs{}) backend.Commit() notContentCreation := errors.New("tx is not contract creation") if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() { @@ -129,6 +129,6 @@ func TestWaitDeployedCornerCases(t *testing.T) { } }() - backend.SendTransaction(ctx, tx) + backend.SendTransaction(ctx, tx, bind.PrivateTxArgs{}) cancel() } diff --git a/accounts/external/backend.go b/accounts/external/backend.go index 17a747db0e..4dd59ec187 100644 --- a/accounts/external/backend.go +++ b/accounts/external/backend.go @@ -204,13 +204,14 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio to = &t } args := &core.SendTxArgs{ - Data: &data, - Nonce: hexutil.Uint64(tx.Nonce()), - Value: hexutil.Big(*tx.Value()), - Gas: hexutil.Uint64(tx.Gas()), - GasPrice: hexutil.Big(*tx.GasPrice()), - To: to, - From: common.NewMixedcaseAddress(account.Address), + Data: &data, + Nonce: hexutil.Uint64(tx.Nonce()), + Value: hexutil.Big(*tx.Value()), + Gas: hexutil.Uint64(tx.Gas()), + GasPrice: hexutil.Big(*tx.GasPrice()), + To: to, + From: common.NewMixedcaseAddress(account.Address), + IsPrivate: tx.IsPrivate(), } var res signTransactionResult if err := api.client.Call(&res, "account_signTransaction", args); err != nil { diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index fe9233c046..79e76ee392 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -299,7 +299,7 @@ func TestCacheFind(t *testing.T) { func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { var list []accounts.Account - for d := 200 * time.Millisecond; d < 8*time.Second; d *= 2 { + for d := 200 * time.Millisecond; d < 16*time.Second; d *= 2 { list = ks.Accounts() if reflect.DeepEqual(list, wantAccounts) { // ks should have also received change notifications diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 9d5e2cf6a2..c6466e5000 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -37,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" ) var ( @@ -283,6 +284,13 @@ func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *b if !found { return nil, ErrLocked } + + // start quorum specific + if tx.IsPrivate() { + log.Info("Private transaction signing with QuorumPrivateTxSigner") + return types.SignTx(tx, types.QuorumPrivateTxSigner{}, unlockedKey.PrivateKey) + } // End quorum specific + // Depending on the presence of the chain ID, sign with EIP155 or homestead if chainID != nil { return types.SignTx(tx, types.NewEIP155Signer(chainID), unlockedKey.PrivateKey) @@ -311,6 +319,9 @@ func (ks *KeyStore) SignTxWithPassphrase(a accounts.Account, passphrase string, } defer zeroKey(key.PrivateKey) + if tx.IsPrivate() { + return types.SignTx(tx, types.QuorumPrivateTxSigner{}, key.PrivateKey) + } // Depending on the presence of the chain ID, sign with EIP155 or homestead if chainID != nil { return types.SignTx(tx, types.NewEIP155Signer(chainID), key.PrivateKey) diff --git a/accounts/manager.go b/accounts/manager.go index acf41ed8e9..8847da8cb4 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -136,6 +136,22 @@ func (am *Manager) Backends(kind reflect.Type) []Backend { return am.backends[kind] } +// Quorum +func (am *Manager) Backend(account Account) (Backend, error) { + for _, b := range am.backends { + for _, bb := range b { + for _, w := range bb.Wallets() { + if w.Contains(account) { + return bb, nil + } + } + } + } + return nil, ErrUnknownWallet +} + +// end Quorum + // Wallets returns all signer accounts registered under this account manager. func (am *Manager) Wallets() []Wallet { am.lock.RLock() diff --git a/accounts/pluggable/backend.go b/accounts/pluggable/backend.go new file mode 100644 index 0000000000..d2a673c6ae --- /dev/null +++ b/accounts/pluggable/backend.go @@ -0,0 +1,74 @@ +package pluggable + +import ( + "reflect" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/event" + plugin "github.com/ethereum/go-ethereum/plugin/account" +) + +var BackendType = reflect.TypeOf(&Backend{}) + +type Backend struct { + wallets []accounts.Wallet +} + +func NewBackend() *Backend { + return &Backend{ + wallets: []accounts.Wallet{ + &wallet{ + url: accounts.URL{ + Scheme: "plugin", + Path: "account", + }, + }, + }, + } +} + +func (b *Backend) Wallets() []accounts.Wallet { + cpy := make([]accounts.Wallet, len(b.wallets)) + copy(cpy, b.wallets) + return cpy +} + +// Subscribe implements accounts.Backend, creating a new subscription that is a no-op and simply exits when the Unsubscribe is called +func (b *Backend) Subscribe(_ chan<- accounts.WalletEvent) event.Subscription { + return event.NewSubscription(func(quit <-chan struct{}) error { + <-quit + return nil + }) +} + +func (b *Backend) SetPluginService(s plugin.Service) error { + return b.wallet().setPluginService(s) +} + +func (b *Backend) TimedUnlock(account accounts.Account, password string, duration time.Duration) error { + return b.wallet().timedUnlock(account, password, duration) +} + +func (b *Backend) Lock(account accounts.Account) error { + return b.wallet().lock(account) +} + +// AccountCreator is the interface that wraps the plugin account creation methods. +// This interface is used to simplify the pluggable.Backend API available to the account plugin CLI and enables easier testing. +type AccountCreator interface { + NewAccount(newAccountConfig interface{}) (accounts.Account, error) + ImportRawKey(rawKey string, newAccountConfig interface{}) (accounts.Account, error) +} + +func (b *Backend) NewAccount(newAccountConfig interface{}) (accounts.Account, error) { + return b.wallet().newAccount(newAccountConfig) +} + +func (b *Backend) ImportRawKey(rawKey string, newAccountConfig interface{}) (accounts.Account, error) { + return b.wallet().importRawKey(rawKey, newAccountConfig) +} + +func (b *Backend) wallet() *wallet { + return b.wallets[0].(*wallet) +} diff --git a/accounts/pluggable/backend_test.go b/accounts/pluggable/backend_test.go new file mode 100644 index 0000000000..3836441500 --- /dev/null +++ b/accounts/pluggable/backend_test.go @@ -0,0 +1,131 @@ +package pluggable + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/pluggable/internal/testutils/mock_plugin" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func TestBackend_Subscribe_NoOp(t *testing.T) { + b := NewBackend() + + subscriber := make(chan accounts.WalletEvent, 4) + sub := b.Subscribe(subscriber) + require.NotNil(t, sub) + require.Len(t, subscriber, 0) + + sub.Unsubscribe() + require.Len(t, subscriber, 0) +} + +func TestBackend_Wallets_ReturnsCopy(t *testing.T) { + wallets := []accounts.Wallet{ + &wallet{ + url: accounts.URL{ + Scheme: "http", + Path: "url1", + }, + }, + &wallet{ + url: accounts.URL{ + Scheme: "http", + Path: "url2", + }, + }, + } + + b := NewBackend() + b.wallets = wallets + + got := b.Wallets() + got[0] = &wallet{ + url: accounts.URL{ + Scheme: "http", + Path: "changedurl", + }, + } + require.Equal(t, "changedurl", got[0].URL().Path) + + unchanged := b.Wallets() + require.Equal(t, "url1", unchanged[0].URL().Path) +} + +func TestBackend_TimedUnlock(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + TimedUnlock(gomock.Any(), gomock.Eq(acct1), gomock.Eq("pwd"), gomock.Eq(time.Minute)). + Return(nil) + + b := NewBackend() + b.wallets[0].(*wallet).pluginService = mockClient + + err := b.TimedUnlock(acct1, "pwd", time.Minute) + require.NoError(t, err) +} + +func TestBackend_Lock(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Lock(gomock.Any(), gomock.Eq(acct1)). + Return(nil) + + b := NewBackend() + b.wallets[0].(*wallet).pluginService = mockClient + + err := b.Lock(acct1) + require.NoError(t, err) +} + +func TestBackend_NewAccount(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + newAccountConfig := struct{ config string }{config: "someconfig"} + newAccount := accounts.Account{} + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + NewAccount(gomock.Any(), gomock.Eq(newAccountConfig)). + Return(newAccount, nil) + + b := NewBackend() + b.wallets[0].(*wallet).pluginService = mockClient + + got, err := b.NewAccount(newAccountConfig) + require.NoError(t, err) + require.Equal(t, newAccount, got) +} + +func TestBackend_ImportRawKey(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + newAccountConfig := struct{ config string }{config: "someconfig"} + newAccount := accounts.Account{} + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + ImportRawKey(gomock.Any(), gomock.Eq("rawkey"), gomock.Eq(newAccountConfig)). + Return(newAccount, nil) + + b := NewBackend() + b.wallets[0].(*wallet).pluginService = mockClient + + got, err := b.ImportRawKey("rawkey", newAccountConfig) + require.NoError(t, err) + require.Equal(t, newAccount, got) +} diff --git a/accounts/pluggable/internal/testutils/matchers.go b/accounts/pluggable/internal/testutils/matchers.go new file mode 100644 index 0000000000..ee2a18d5bc --- /dev/null +++ b/accounts/pluggable/internal/testutils/matchers.go @@ -0,0 +1,19 @@ +package testutils + +import ( + "fmt" +) + +type PointerMatcher struct { + C chan<- interface{} +} + +func (m PointerMatcher) Matches(x interface{}) bool { + xAddr := fmt.Sprintf("%p", x) + CAddr := fmt.Sprintf("%p", m.C) + return xAddr == CAddr +} + +func (m PointerMatcher) String() string { + return fmt.Sprintf("is %v", m.C) +} diff --git a/accounts/pluggable/internal/testutils/mock_plugin/mock_plugin.go b/accounts/pluggable/internal/testutils/mock_plugin/mock_plugin.go new file mode 100644 index 0000000000..4bf9bf9ba5 --- /dev/null +++ b/accounts/pluggable/internal/testutils/mock_plugin/mock_plugin.go @@ -0,0 +1,196 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ethereum/go-ethereum/plugin/account (interfaces: Service) + +// Package mock_plugin is a generated GoMock package. +package mock_plugin + +import ( + context "context" + reflect "reflect" + time "time" + + accounts "github.com/ethereum/go-ethereum/accounts" + gomock "github.com/golang/mock/gomock" +) + +// MockService is a mock of Service interface +type MockService struct { + ctrl *gomock.Controller + recorder *MockServiceMockRecorder +} + +// MockServiceMockRecorder is the mock recorder for MockService +type MockServiceMockRecorder struct { + mock *MockService +} + +// NewMockService creates a new mock instance +func NewMockService(ctrl *gomock.Controller) *MockService { + mock := &MockService{ctrl: ctrl} + mock.recorder = &MockServiceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockService) EXPECT() *MockServiceMockRecorder { + return m.recorder +} + +// Accounts mocks base method +func (m *MockService) Accounts(arg0 context.Context) []accounts.Account { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Accounts", arg0) + ret0, _ := ret[0].([]accounts.Account) + return ret0 +} + +// Accounts indicates an expected call of Accounts +func (mr *MockServiceMockRecorder) Accounts(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accounts", reflect.TypeOf((*MockService)(nil).Accounts), arg0) +} + +// Close mocks base method +func (m *MockService) Close(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close +func (mr *MockServiceMockRecorder) Close(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) +} + +// Contains mocks base method +func (m *MockService) Contains(arg0 context.Context, arg1 accounts.Account) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Contains", arg0, arg1) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Contains indicates an expected call of Contains +func (mr *MockServiceMockRecorder) Contains(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Contains", reflect.TypeOf((*MockService)(nil).Contains), arg0, arg1) +} + +// ImportRawKey mocks base method +func (m *MockService) ImportRawKey(arg0 context.Context, arg1 string, arg2 interface{}) (accounts.Account, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImportRawKey", arg0, arg1, arg2) + ret0, _ := ret[0].(accounts.Account) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImportRawKey indicates an expected call of ImportRawKey +func (mr *MockServiceMockRecorder) ImportRawKey(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImportRawKey", reflect.TypeOf((*MockService)(nil).ImportRawKey), arg0, arg1, arg2) +} + +// Lock mocks base method +func (m *MockService) Lock(arg0 context.Context, arg1 accounts.Account) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Lock", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Lock indicates an expected call of Lock +func (mr *MockServiceMockRecorder) Lock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lock", reflect.TypeOf((*MockService)(nil).Lock), arg0, arg1) +} + +// NewAccount mocks base method +func (m *MockService) NewAccount(arg0 context.Context, arg1 interface{}) (accounts.Account, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewAccount", arg0, arg1) + ret0, _ := ret[0].(accounts.Account) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewAccount indicates an expected call of NewAccount +func (mr *MockServiceMockRecorder) NewAccount(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAccount", reflect.TypeOf((*MockService)(nil).NewAccount), arg0, arg1) +} + +// Open mocks base method +func (m *MockService) Open(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Open", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Open indicates an expected call of Open +func (mr *MockServiceMockRecorder) Open(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockService)(nil).Open), arg0, arg1) +} + +// Sign mocks base method +func (m *MockService) Sign(arg0 context.Context, arg1 accounts.Account, arg2 []byte) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Sign", arg0, arg1, arg2) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Sign indicates an expected call of Sign +func (mr *MockServiceMockRecorder) Sign(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sign", reflect.TypeOf((*MockService)(nil).Sign), arg0, arg1, arg2) +} + +// Status mocks base method +func (m *MockService) Status(arg0 context.Context) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Status", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Status indicates an expected call of Status +func (mr *MockServiceMockRecorder) Status(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockService)(nil).Status), arg0) +} + +// TimedUnlock mocks base method +func (m *MockService) TimedUnlock(arg0 context.Context, arg1 accounts.Account, arg2 string, arg3 time.Duration) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TimedUnlock", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// TimedUnlock indicates an expected call of TimedUnlock +func (mr *MockServiceMockRecorder) TimedUnlock(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimedUnlock", reflect.TypeOf((*MockService)(nil).TimedUnlock), arg0, arg1, arg2, arg3) +} + +// UnlockAndSign mocks base method +func (m *MockService) UnlockAndSign(arg0 context.Context, arg1 accounts.Account, arg2 []byte, arg3 string) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UnlockAndSign", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UnlockAndSign indicates an expected call of UnlockAndSign +func (mr *MockServiceMockRecorder) UnlockAndSign(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnlockAndSign", reflect.TypeOf((*MockService)(nil).UnlockAndSign), arg0, arg1, arg2, arg3) +} diff --git a/accounts/pluggable/wallet.go b/accounts/pluggable/wallet.go new file mode 100644 index 0000000000..1941ab92ae --- /dev/null +++ b/accounts/pluggable/wallet.go @@ -0,0 +1,129 @@ +package pluggable + +import ( + "context" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + plugin "github.com/ethereum/go-ethereum/plugin/account" +) + +type wallet struct { + url accounts.URL + mu sync.Mutex + pluginService plugin.Service +} + +func (w *wallet) setPluginService(s plugin.Service) error { + w.mu.Lock() + defer w.mu.Unlock() + + w.pluginService = s + + return nil +} + +func (w *wallet) URL() accounts.URL { + return w.url +} + +func (w *wallet) Status() (string, error) { + return w.pluginService.Status(context.Background()) +} + +func (w *wallet) Open(passphrase string) error { + return w.pluginService.Open(context.Background(), passphrase) +} + +func (w *wallet) Close() error { + return w.pluginService.Close(context.Background()) +} + +func (w *wallet) Accounts() []accounts.Account { + return w.pluginService.Accounts(context.Background()) +} + +func (w *wallet) Contains(account accounts.Account) bool { + return w.pluginService.Contains(context.Background(), account) +} + +func (w *wallet) Derive(_ accounts.DerivationPath, _ bool) (accounts.Account, error) { + return accounts.Account{}, accounts.ErrNotSupported +} + +func (w *wallet) SelfDerive(_ []accounts.DerivationPath, _ ethereum.ChainStateReader) {} + +func (w *wallet) SignData(account accounts.Account, _ string, data []byte) ([]byte, error) { + return w.pluginService.Sign(context.Background(), account, crypto.Keccak256(data)) +} + +func (w *wallet) SignDataWithPassphrase(account accounts.Account, passphrase, _ string, data []byte) ([]byte, error) { + return w.pluginService.UnlockAndSign(context.Background(), account, crypto.Keccak256(data), passphrase) +} + +func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.pluginService.Sign(context.Background(), account, accounts.TextHash(text)) +} + +func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + return w.pluginService.UnlockAndSign(context.Background(), account, accounts.TextHash(text), passphrase) +} + +func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + toSign, signer := prepareTxForSign(tx, chainID) + + sig, err := w.pluginService.Sign(context.Background(), account, toSign.Bytes()) + if err != nil { + return nil, err + } + + return tx.WithSignature(signer, sig) +} + +func (w *wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + toSign, signer := prepareTxForSign(tx, chainID) + + sig, err := w.pluginService.UnlockAndSign(context.Background(), account, toSign.Bytes(), passphrase) + if err != nil { + return nil, err + } + + return tx.WithSignature(signer, sig) +} + +func (w *wallet) timedUnlock(account accounts.Account, password string, duration time.Duration) error { + return w.pluginService.TimedUnlock(context.Background(), account, password, duration) +} + +func (w *wallet) lock(account accounts.Account) error { + return w.pluginService.Lock(context.Background(), account) +} + +func (w *wallet) newAccount(newAccountConfig interface{}) (accounts.Account, error) { + return w.pluginService.NewAccount(context.Background(), newAccountConfig) +} + +func (w *wallet) importRawKey(rawKey string, newAccountConfig interface{}) (accounts.Account, error) { + return w.pluginService.ImportRawKey(context.Background(), rawKey, newAccountConfig) +} + +// prepareTxForSign determines which Signer to use for the given tx and chainID, and returns the Signer's hash of the tx and the Signer itself +func prepareTxForSign(tx *types.Transaction, chainID *big.Int) (common.Hash, types.Signer) { + var s types.Signer + + if tx.IsPrivate() { + s = types.QuorumPrivateTxSigner{} + } else if chainID == nil { + s = types.HomesteadSigner{} + } else { + s = types.NewEIP155Signer(chainID) + } + + return s.Hash(tx), s +} diff --git a/accounts/pluggable/wallet_test.go b/accounts/pluggable/wallet_test.go new file mode 100644 index 0000000000..022486df01 --- /dev/null +++ b/accounts/pluggable/wallet_test.go @@ -0,0 +1,397 @@ +package pluggable + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/pluggable/internal/testutils/mock_plugin" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + scheme = "scheme" + + wltUrl = accounts.URL{ + Scheme: scheme, + Path: "uripath", + } + + acct1 = accounts.Account{ + Address: common.HexToAddress("0x4d6d744b6da435b5bbdde2526dc20e9a41cb72e5"), + URL: wltUrl, + } + + acct2 = accounts.Account{ + Address: common.HexToAddress("0x2332f90a329c2c55ba120b1449d36a144d1f9fe4"), + URL: accounts.URL{Scheme: scheme, Path: "path/to/file2.json"}, + } + acct3 = accounts.Account{ + Address: common.HexToAddress("0x992d7a8fca612c963796ecbfe78b300370b9545a"), + URL: accounts.URL{Scheme: scheme, Path: "path/to/file3.json"}, + } + acct4 = accounts.Account{ + Address: common.HexToAddress("0x39ac8f3ae3681b4422fdf808ae18ba4365e37da8"), + URL: accounts.URL{Scheme: scheme, Path: "path/to/file4.json"}, + } +) + +func validWallet(m *mock_plugin.MockService) *wallet { + return &wallet{ + url: wltUrl, + pluginService: m, + } +} + +func TestWallet_Url(t *testing.T) { + w := validWallet(nil) + got := w.URL() + assert.Equal(t, wltUrl, got) +} + +func TestWallet_Status(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + want := "status" + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Status(gomock.Any()). + Return(want, nil) + + w := validWallet(mockClient) + status, err := w.Status() + + assert.NoError(t, err) + assert.Equal(t, want, status) +} + +func TestWallet_Open(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Open(gomock.Any(), "pwd"). + Return(nil) + + w := validWallet(mockClient) + err := w.Open("pwd") + + assert.NoError(t, err) +} + +func TestWallet_Close(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Close(gomock.Any()). + Return(nil) + + w := validWallet(mockClient) + err := w.Close() + + assert.NoError(t, err) +} + +func TestWallet_Accounts(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + want := []accounts.Account{acct1, acct2, acct3, acct4} + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Accounts(gomock.Any()). + Return(want) + + w := validWallet(mockClient) + got := w.Accounts() + + assert.Equal(t, want, got) +} + +func TestWallet_Contains(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Contains(gomock.Any(), acct1). + Return(true) + + w := validWallet(mockClient) + got := w.Contains(acct1) + + assert.True(t, got) +} + +func TestWallet_Derive(t *testing.T) { + w := validWallet(nil) + _, err := w.Derive(accounts.DerivationPath{}, true) + if assert.Error(t, err) { + assert.Equal(t, accounts.ErrNotSupported, err) + } +} + +func TestWallet_SelfDerive(t *testing.T) { + w := validWallet(nil) + // does nothing + w.SelfDerive([]accounts.DerivationPath{}, nil) +} + +func TestWallet_SignData(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + toSign := []byte("somedata") + want := []byte("signeddata") + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Sign(gomock.Any(), acct1, crypto.Keccak256(toSign)). + Return(want, nil) + + w := validWallet(mockClient) + got, err := w.SignData(acct1, "", toSign) + + assert.NoError(t, err) + assert.Equal(t, want, got) +} + +func TestWallet_SignDataWithPassphrase(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + toSign := []byte("somedata") + want := []byte("signeddata") + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + UnlockAndSign(gomock.Any(), acct1, crypto.Keccak256(toSign), "pwd"). + Return(want, nil) + + w := validWallet(mockClient) + got, err := w.SignDataWithPassphrase(acct1, "pwd", "", toSign) + + assert.NoError(t, err) + assert.Equal(t, want, got) +} + +func TestWallet_SignText(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + toSign := []byte("somedata") + want := []byte("signeddata") + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Sign(gomock.Any(), acct1, accounts.TextHash(toSign)). + Return(want, nil) + + w := validWallet(mockClient) + got, err := w.SignText(acct1, toSign) + + assert.NoError(t, err) + assert.Equal(t, want, got) +} + +func TestWallet_SignTextWithPassphrase(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + toSign := []byte("somedata") + want := []byte("signeddata") + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + UnlockAndSign(gomock.Any(), acct1, accounts.TextHash(toSign), "pwd"). + Return(want, nil) + + w := validWallet(mockClient) + got, err := w.SignTextWithPassphrase(acct1, "pwd", toSign) + + assert.NoError(t, err) + assert.Equal(t, want, got) +} + +func TestWallet_SignTx(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tests := []struct { + name string + isPrivate bool + chainID *big.Int + signer types.Signer + }{ + { + name: "Public EIP155 tx", + isPrivate: false, + chainID: big.NewInt(20), + signer: types.NewEIP155Signer(big.NewInt(20)), + }, + { + name: "Public Homestead tx", + isPrivate: false, + chainID: nil, + signer: types.HomesteadSigner{}, + }, + { + name: "Private tx", + isPrivate: true, + chainID: nil, + signer: types.QuorumPrivateTxSigner{}, + }, + } + + toSign := types.NewTransaction( + 1, + common.HexToAddress("0x2332f90a329c2c55ba120b1449d36a144d1f9fe4"), + big.NewInt(1), + 0, + big.NewInt(1), + nil, + ) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.isPrivate { + toSign.SetPrivate() + } + + hashToSign := tt.signer.Hash(toSign) + + mockSig := make([]byte, 65) + rand.Read(mockSig) + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + Sign(gomock.Any(), acct1, hashToSign.Bytes()). + Return(mockSig, nil) + + w := validWallet(mockClient) + got, err := w.SignTx(acct1, toSign, tt.chainID) + require.NoError(t, err) + + gotV, gotR, gotS := got.RawSignatureValues() + + wantR, wantS, wantV, err := tt.signer.SignatureValues(&types.Transaction{}, mockSig) // tx param is unused by method + require.NoError(t, err) + + // assert the correct signature is added to the tx + assert.Equal(t, wantV, gotV) + assert.Equal(t, wantR, gotR) + assert.Equal(t, wantS, gotS) + + // assert the rest of the tx is unchanged + assert.Equal(t, toSign.Nonce(), got.Nonce()) + assert.Equal(t, toSign.GasPrice(), got.GasPrice()) + assert.Equal(t, toSign.Gas(), got.Gas()) + assert.Equal(t, toSign.To(), got.To()) + assert.Equal(t, toSign.Value(), got.Value()) + assert.Equal(t, toSign.Data(), got.Data()) + }) + } +} + +func TestWallet_SignTxWithPassphrase(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tests := []struct { + name string + isPrivate bool + chainID *big.Int + signer types.Signer + }{ + { + name: "Public EIP155 tx", + isPrivate: false, + chainID: big.NewInt(20), + signer: types.NewEIP155Signer(big.NewInt(20)), + }, + { + name: "Public Homestead tx", + isPrivate: false, + chainID: nil, + signer: types.HomesteadSigner{}, + }, + { + name: "Private tx", + isPrivate: true, + chainID: nil, + signer: types.QuorumPrivateTxSigner{}, + }, + } + + toSign := types.NewTransaction( + 1, + common.HexToAddress("0x2332f90a329c2c55ba120b1449d36a144d1f9fe4"), + big.NewInt(1), + 0, + big.NewInt(1), + nil, + ) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.isPrivate { + toSign.SetPrivate() + } + + hashToSign := tt.signer.Hash(toSign) + + mockSig := make([]byte, 65) + rand.Read(mockSig) + + mockClient := mock_plugin.NewMockService(ctrl) + mockClient. + EXPECT(). + UnlockAndSign(gomock.Any(), acct1, hashToSign.Bytes(), "pwd"). + Return(mockSig, nil) + + w := validWallet(mockClient) + got, err := w.SignTxWithPassphrase(acct1, "pwd", toSign, tt.chainID) + require.NoError(t, err) + + gotV, gotR, gotS := got.RawSignatureValues() + + wantR, wantS, wantV, err := tt.signer.SignatureValues(&types.Transaction{}, mockSig) // tx param is unused by method + require.NoError(t, err) + + // assert the correct signature is added to the tx + assert.Equal(t, wantV, gotV) + assert.Equal(t, wantR, gotR) + assert.Equal(t, wantS, gotS) + + // assert the rest of the tx is unchanged + assert.Equal(t, toSign.Nonce(), got.Nonce()) + assert.Equal(t, toSign.GasPrice(), got.GasPrice()) + assert.Equal(t, toSign.Gas(), got.Gas()) + assert.Equal(t, toSign.To(), got.To()) + assert.Equal(t, toSign.Value(), got.Value()) + assert.Equal(t, toSign.Data(), got.Data()) + }) + } +} diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 993c599346..e31bc143f0 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -19,6 +19,7 @@ package usbwallet import ( "context" + "errors" "fmt" "io" "math/big" @@ -549,6 +550,10 @@ func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID w.stateLock.RLock() // Comms have own mutex, this is for the state fields defer w.stateLock.RUnlock() + if tx.IsPrivate() { + return nil, errors.New("Signing Quorum Private transactions with a USB wallet not yet supported") + } + // If the wallet is closed, abort if w.device == nil { return nil, accounts.ErrWalletClosed diff --git a/build/ci.go b/build/ci.go index ea708d5e7b..1105ed46b6 100644 --- a/build/ci.go +++ b/build/ci.go @@ -318,12 +318,16 @@ func doTest(cmdline []string) { if len(flag.CommandLine.Args()) > 0 { packages = flag.CommandLine.Args() } + // Quorum + // Ignore not Quorum related packages to accelerate build + packages = build.ExpandPackagesNoVendor(packages) + packages = build.IgnorePackages(packages) // Run the actual tests. // Test a single package at a time. CI builders are slow // and some tests run into timeouts under load. gotest := goTool("test", buildFlags(env)...) - gotest.Args = append(gotest.Args, "-p", "1") + gotest.Args = append(gotest.Args, "-p", "1", "--short") if *coverage { gotest.Args = append(gotest.Args, "-covermode=atomic", "-cover") } diff --git a/build/install-constellation-linux.sh b/build/install-constellation-linux.sh new file mode 100755 index 0000000000..17cb323a5d --- /dev/null +++ b/build/install-constellation-linux.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +curl -L https://github.com/jpmorganchase/constellation/releases/download/v0.3.2/constellation-0.3.2-ubuntu1604.tar.xz -o constellation.tar.xz + +tar xf constellation.tar.xz + +export PATH \ No newline at end of file diff --git a/build/install-constellation-mac.sh b/build/install-constellation-mac.sh new file mode 100755 index 0000000000..6bae76b0cb --- /dev/null +++ b/build/install-constellation-mac.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +echo "Going into $HOME" +cd $HOME + +echo "Cloning Constellation repo" +git clone https://github.com/jpmorganchase/constellation.git + +cd constellation + +echo "Running stack setup in $(pwd)" +stack setup + +echo "Now installing Constellation from $(pwd)" +stack install \ No newline at end of file diff --git a/build/travis-install-linux.sh b/build/travis-install-linux.sh new file mode 100755 index 0000000000..e18e2139e5 --- /dev/null +++ b/build/travis-install-linux.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -e +# install geth and dependencies for acceptance tests +echo "---> install started ..." +echo "---> installing tools ..." +sudo apt-get update +# upgrade dpkg to fix issue with trusty: dpkg-deb: error +sudo apt-get -y install dpkg +java -version +mvn --version + +sudo wget https://github.com/ethereum/solidity/releases/download/v0.5.4/solc-static-linux -O /usr/local/bin/solc -q +sudo chmod +x /usr/local/bin/solc +solc --version +echo "---> tools installation done" + +echo "---> building geth ..." +sudo modprobe fuse +sudo chmod 666 /dev/fuse +sudo chown root:${USER} /etc/fuse.conf +go run build/ci.go install +echo "---> building geth done" + +echo "---> cloning quorum-cloud and quorum-acceptance-tests ..." +git clone https://github.com/jpmorganchase/quorum-acceptance-tests.git ${TRAVIS_HOME}/quorum-acceptance-tests +git clone https://github.com/jpmorganchase/quorum-cloud.git ${TRAVIS_HOME}/quorum-cloud + +echo "---> cloning done" + +echo "---> getting tessera jar ..." +wget https://oss.sonatype.org/service/local/repositories/releases/content/com/jpmorgan/quorum/tessera-app/0.10.4/tessera-app-0.10.4-app.jar -O $HOME/tessera.jar -q +echo "---> tessera done" + +echo "---> getting gauge jar ..." +wget https://github.com/getgauge/gauge/releases/download/v1.0.8/gauge-1.0.8-linux.x86_64.zip -O gauge.zip -q +sudo unzip -o gauge.zip -d /usr/local/bin +gauge telemetry off +cd ${TRAVIS_HOME}/quorum-acceptance-tests +gauge install +echo "---> gauge installation done" + +echo "---> install done" \ No newline at end of file diff --git a/build/travis-run-acceptance-tests-linux.sh b/build/travis-run-acceptance-tests-linux.sh new file mode 100755 index 0000000000..66ad3c5605 --- /dev/null +++ b/build/travis-run-acceptance-tests-linux.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e +# start network and run acceptance tests +echo "---> start quorum network for consensus ${TF_VAR_consensus_mechanism} ..." +java --version +export PATH=${TRAVIS_BUILD_DIR}/build/bin:$PATH +export TESSERA_JAR=${HOME}/tessera.jar +cd ${TRAVIS_HOME}/quorum-cloud/travis/4nodes +./init.sh ${TF_VAR_consensus_mechanism} +./start.sh ${TF_VAR_consensus_mechanism} tessera +echo "---> network started" +cd ${TRAVIS_HOME}/quorum-acceptance-tests +cp config/application-local.4nodes.yml config/application-local.yml +echo "---> run acceptance tests for consensus ${TF_VAR_consensus_mechanism} ..." +java --version +./src/travis/run_tests.sh +echo "---> acceptance tests finished" +echo "---> stop the network..." +${TRAVIS_HOME}/quorum-cloud/travis/4nodes/stop.sh +echo "---> network stopped" \ No newline at end of file diff --git a/cmd/clef/README.md b/cmd/clef/README.md index 700f0a144b..50ba93b681 100644 --- a/cmd/clef/README.md +++ b/cmd/clef/README.md @@ -223,9 +223,10 @@ Response - `gas` [number]: maximum amount of gas to burn - `gasPrice` [number]: gas price - `value` [number:optional]: amount of Wei to send with the transaction - - `data` [data:optional]: input data + - `data` [data:optional]: input data (transaction manager hash if transaction is private) - `nonce` [number]: account nonce - 1. method signature [string:optional] + - `isPrivate` [boolean:optional]: whether the transaction is a Quorum private transaction + 3. method signature [string:optional] - The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected. diff --git a/cmd/clef/main.go b/cmd/clef/main.go index 8c8778c249..c57e9ecddd 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -34,20 +34,25 @@ import ( "runtime" "sort" "strings" + "syscall" "time" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/pluggable" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/plugin" + "github.com/ethereum/go-ethereum/plugin/account" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/signer/core" @@ -223,6 +228,11 @@ The gendoc generates example structures of the json-rpc communication types. `} ) +// +var supportedPlugins = []plugin.PluginInterfaceName{plugin.AccountPluginInterfaceName} + +// + // AppHelpFlagGroups is the application flags, grouped by functionality. var AppHelpFlagGroups = []flags.FlagGroup{ { @@ -249,6 +259,12 @@ var AppHelpFlagGroups = []flags.FlagGroup{ testFlag, advancedMode, acceptFlag, + // + utils.PluginSettingsFlag, + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.PluginSkipVerifyFlag, + // }, }, { @@ -285,6 +301,12 @@ func init() { advancedMode, acceptFlag, legacyRPCPortFlag, + // + utils.PluginSettingsFlag, + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.PluginSkipVerifyFlag, + // } app.Action = signer app.Commands = []cli.Command{initCommand, @@ -499,7 +521,10 @@ func newAccount(c *cli.Context) error { lightKdf = c.GlobalBool(utils.LightKDFFlag.Name) ) log.Info("Starting clef", "keystore", ksLoc, "light-kdf", lightKdf) - am := core.StartClefAccountManager(ksLoc, true, lightKdf, "") + am, _, err := startClefAccountManagerWithPlugins(c, ksLoc, true, lightKdf, "") + if err != nil { + return err + } // This gives is us access to the external API apiImpl := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage) // This gives us access to the internal API @@ -638,7 +663,12 @@ func signer(c *cli.Context) error { ) log.Info("Starting signer", "chainid", chainId, "keystore", ksLoc, "light-kdf", lightKdf, "advanced", advanced) - am := core.StartClefAccountManager(ksLoc, nousb, lightKdf, scpath) + + am, pm, err := startClefAccountManagerWithPlugins(c, ksLoc, nousb, lightKdf, scpath) + if err != nil { + return err + } + apiImpl := core.NewSignerAPI(am, chainId, nousb, ui, db, advanced, pwStorage) // Establish the bidirectional communication, by creating a new UI backend and registering @@ -665,6 +695,13 @@ func signer(c *cli.Context) error { Service: api, Version: "1.0"}, } + + // + if pm != nil { + rpcAPI = addPluginAPIs(pm, rpcAPI, ui) + } + // + if c.GlobalBool(utils.HTTPEnabledFlag.Name) { vhosts := splitAndTrim(c.GlobalString(utils.HTTPVirtualHostsFlag.Name)) cors := splitAndTrim(c.GlobalString(utils.HTTPCORSDomainFlag.Name)) @@ -687,7 +724,7 @@ func signer(c *cli.Context) error { // start http server httpEndpoint := fmt.Sprintf("%s:%d", c.GlobalString(utils.HTTPListenAddrFlag.Name), port) - httpServer, addr, err := node.StartHTTPEndpoint(httpEndpoint, rpc.DefaultHTTPTimeouts, handler) + httpServer, addr, _, err := node.StartHTTPEndpoint(httpEndpoint, rpc.DefaultHTTPTimeouts, handler, nil) if err != nil { utils.Fatalf("Could not start RPC api: %v", err) } @@ -736,6 +773,48 @@ func signer(c *cli.Context) error { return nil } +// +// startPluginManager gets plugin config and starts a new PluginManager +func startPluginManager(c *cli.Context) (*plugin.PluginManager, *plugin.Settings, error) { + nodeConf := new(node.Config) + if err := utils.SetPlugins(c, nodeConf); err != nil { + return nil, nil, err + } + pluginConf := nodeConf.Plugins + + if err := pluginConf.CheckSettingsAreSupported(supportedPlugins); err != nil { + return nil, nil, err + } + + pm, err := plugin.NewPluginManager("clef", pluginConf, c.Bool(utils.PluginSkipVerifyFlag.Name), c.Bool(utils.PluginLocalVerifyFlag.Name), c.String(utils.PluginPublicKeyFlag.Name)) + if err != nil { + return nil, nil, err + } + if err := pm.Start(); err != nil { + return nil, nil, err + } + return pm, pluginConf, nil +} + +// addPluginAPIs adds the exposed plugin APIs to Clef's API. +// It alters some of the plugin APIs so that calls to them will require UI approval. +func addPluginAPIs(pm *plugin.PluginManager, rpcAPI []rpc.API, ui core.UIClientAPI) []rpc.API { + // pm.APIs() returns a slice of values hence the following approach that may look clumsy + var ( + stdPluginAPIs = pm.APIs() + approvalPluginAPIs = make([]rpc.API, len(stdPluginAPIs)) + ) + + for i, api := range stdPluginAPIs { + switch s := api.Service.(type) { + case account.CreatorService: + api.Service = core.NewApprovalCreatorService(s, ui) + } + approvalPluginAPIs[i] = api + } + return append(rpcAPI, approvalPluginAPIs...) +} + // splitAndTrim splits input separated by a comma // and trims excessive white space from the substrings. func splitAndTrim(input string) []string { @@ -1186,3 +1265,53 @@ These data types are defined in the channel between clef and the UI`) fmt.Println(elem) } } + +// Quorum +// startClefAccountManagerWithPlugins - wrapped function to create a CLEF account manager with Plugin Support +func startClefAccountManagerWithPlugins(c *cli.Context, ksLocation string, nousb, lightKDF bool, scpath string) (*accounts.Manager, *plugin.PluginManager, error) { + var err error + // start the plugin manager + var ( + pm *plugin.PluginManager + pluginConf *plugin.Settings + ) + if c.IsSet(utils.PluginSettingsFlag.Name) { + log.Info("Using plugins") + pm, pluginConf, err = startPluginManager(c) + if err != nil { + utils.Fatalf(err.Error()) + } + + // setup goroutine to stop plugin manager when clef stops + go func() { + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) + defer signal.Stop(sigc) + <-sigc + log.Info("Got interrupt, shutting down...") + go pm.Stop() + for i := 10; i > 0; i-- { + <-sigc + if i > 1 { + log.Warn("Already shutting down, interrupt more to panic.", "times", i-1) + } + } + debug.Exit() // ensure trace and CPU profile data is flushed. + debug.LoudPanic("boom") + }() + } + // + + am := core.StartClefAccountManager(ksLocation, nousb, lightKDF, pluginConf, scpath) + + // setup the pluggable accounts backend with the plugin + if pm != nil && pm.IsEnabled(plugin.AccountPluginInterfaceName) { + b := am.Backends(pluggable.BackendType)[0].(*pluggable.Backend) + if err := pm.AddAccountPluginToBackend(b); err != nil { + return nil, nil, err + } + } + // + + return am, pm, nil +} diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 75586d588b..37b44e3c30 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -99,15 +99,16 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return h } var ( - statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre) - signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number)) - gaspool = new(core.GasPool) - blockHash = common.Hash{0x13, 0x37} - rejectedTxs []int - includedTxs types.Transactions - gasUsed = uint64(0) - receipts = make(types.Receipts, 0) - txIndex = 0 + statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre) + privateStatedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre) // Quorum private state db + signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number)) + gaspool = new(core.GasPool) + blockHash = common.Hash{0x13, 0x37} + rejectedTxs []int + includedTxs types.Transactions + gasUsed = uint64(0) + receipts = make(types.Receipts, 0) + txIndex = 0 ) gaspool.AddGas(pre.Env.GasLimit) vmContext := vm.Context{ @@ -146,7 +147,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, vmContext.GasPrice = msg.GasPrice() vmContext.Origin = msg.From() - evm := vm.NewEVM(vmContext, statedb, chainConfig, vmConfig) + evm := vm.NewEVM(vmContext, statedb, privateStatedb, chainConfig, vmConfig) snapshot := statedb.Snapshot() // (ret []byte, usedGas uint64, failed bool, err error) msgResult, err := core.ApplyMessage(evm, msg, gaspool) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 7dc5536eba..781e6e3026 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -41,6 +41,8 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" @@ -501,7 +503,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { continue } // Submit the transaction and mark as funded if successful - if err := f.client.SendTransaction(context.Background(), signed); err != nil { + if err := f.client.SendTransaction(context.Background(), signed, bind.PrivateTxArgs{}); err != nil { f.lock.Unlock() if err = sendError(conn, err); err != nil { log.Warn("Failed to send transaction transmission error to client", "err", err) diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 6d45c88763..6473a82744 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -187,6 +187,7 @@ this import mechanism is not needed when you transfer an account between nodes. `, }, + quorumAccountPluginCommands, }, } ) diff --git a/cmd/geth/accountcmd_plugin.go b/cmd/geth/accountcmd_plugin.go new file mode 100644 index 0000000000..2ad51b6986 --- /dev/null +++ b/cmd/geth/accountcmd_plugin.go @@ -0,0 +1,323 @@ +package main + +import ( + "encoding/hex" + "encoding/json" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/pluggable" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/plugin" + "gopkg.in/urfave/cli.v1" +) + +var ( + quorumAccountPluginCommands = cli.Command{ + Name: "plugin", + Usage: "Manage 'account' plugin accounts", + Description: ` + geth account plugin + + Quorum supports alternate account management methods through the use of 'account' plugins. + + See docs.goquorum.com for more info. + `, + Subcommands: []cli.Command{ + { + Name: "list", + Usage: "Print summary of existing 'account' plugin accounts", + Action: utils.MigrateFlags(listPluginAccountsCLIAction), + Flags: []cli.Flag{ + utils.PluginSettingsFlag, // flag is used implicitly by makeConfigNode() + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.PluginSkipVerifyFlag, + }, + Description: ` + geth account plugin list +Print a short summary of all accounts for the given plugin settings`, + }, + { + Name: "new", + Usage: "Create a new account using an 'account' plugin", + Action: utils.MigrateFlags(createPluginAccountCLIAction), + Flags: []cli.Flag{ + utils.PluginSettingsFlag, + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.PluginSkipVerifyFlag, + utils.AccountPluginNewAccountConfigFlag, + }, + Description: fmt.Sprintf(` + geth account plugin new + +Creates a new account using an 'account' plugin and prints the address. + +--%v and --%v flags are required. + +Each 'account' plugin will have different requirements for the value of --%v. +For more info see the documentation for the particular 'account' plugin being used. +`, utils.PluginSettingsFlag.Name, utils.AccountPluginNewAccountConfigFlag.Name, utils.AccountPluginNewAccountConfigFlag.Name), + }, + { + Name: "import", + Usage: "Import a private key into a new account using an 'account' plugin", + Action: utils.MigrateFlags(importPluginAccountCLIAction), + Flags: []cli.Flag{ + utils.PluginSettingsFlag, + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.PluginSkipVerifyFlag, + utils.AccountPluginNewAccountConfigFlag, + }, + ArgsUsage: "", + Description: ` + geth account plugin import + +Imports an unencrypted private key from and creates a new account using an 'account' plugin. +Prints the address. + +The keyfile must contain an unencrypted private key in hexadecimal format. + +--%v and --%v flags are required. + +Note: +Before using this import mechanism to transfer accounts that are already 'account' plugin-managed between nodes, consult +the documentation for the particular 'account' plugin being used as it may support alternate methods for transferring. +`, + }, + }, + } + + // supportedPlugins is the list of supported plugins for the account subcommand + supportedPlugins = []plugin.PluginInterfaceName{plugin.AccountPluginInterfaceName} + + invalidPluginFlagsErr = fmt.Errorf("--%v and --%v flags must be set", utils.PluginSettingsFlag.Name, utils.AccountPluginNewAccountConfigFlag.Name) + + // makeConfigNodeDelegate is a wrapper for the makeConfigNode function. + // It can be replaced with a stub for testing. + makeConfigNodeDelegate configNodeMaker = standardConfigNodeMaker{} +) + +func listPluginAccountsCLIAction(ctx *cli.Context) error { + accts, err := listPluginAccounts(ctx) + if err != nil { + utils.Fatalf("%v", err) + } + + var index int + for _, acct := range accts { + fmt.Printf("Account #%d: {%x} %s\n", index, acct.Address, &acct.URL) + index++ + } + + return nil +} + +func listPluginAccounts(ctx *cli.Context) ([]accounts.Account, error) { + if !ctx.IsSet(utils.PluginSettingsFlag.Name) { + return []accounts.Account{}, fmt.Errorf("--%v required", utils.PluginSettingsFlag.Name) + } + + p, err := setupAccountPluginForCLI(ctx) + if err != nil { + return []accounts.Account{}, err + } + defer func() { + if err := p.teardown(); err != nil { + log.Error("error tearing down account plugin", "err", err) + } + }() + + return p.accounts(), nil +} + +func createPluginAccountCLIAction(ctx *cli.Context) error { + account, err := createPluginAccount(ctx) + if err != nil { + utils.Fatalf("unable to create plugin-backed account: %v", err) + } + writePluginAccountToStdOut(account) + return nil +} + +func createPluginAccount(ctx *cli.Context) (accounts.Account, error) { + if !ctx.IsSet(utils.PluginSettingsFlag.Name) || !ctx.IsSet(utils.AccountPluginNewAccountConfigFlag.Name) { + return accounts.Account{}, invalidPluginFlagsErr + } + + newAcctCfg, err := getNewAccountConfigFromCLI(ctx) + if err != nil { + return accounts.Account{}, err + } + + p, err := setupAccountPluginForCLI(ctx) + if err != nil { + return accounts.Account{}, err + } + defer func() { + if err := p.teardown(); err != nil { + log.Error("error tearing down account plugin", "err", err) + } + }() + + return p.NewAccount(newAcctCfg) +} + +func importPluginAccountCLIAction(ctx *cli.Context) error { + account, err := importPluginAccount(ctx) + if err != nil { + utils.Fatalf("unable to import key and create plugin-backed account: %v", err) + } + writePluginAccountToStdOut(account) + return nil +} + +func importPluginAccount(ctx *cli.Context) (accounts.Account, error) { + keyfile := ctx.Args().First() + if len(keyfile) == 0 { + return accounts.Account{}, errors.New("keyfile must be given as argument") + } + key, err := crypto.LoadECDSA(keyfile) + if err != nil { + return accounts.Account{}, fmt.Errorf("Failed to load the private key: %v", err) + } + keyBytes := crypto.FromECDSA(key) + keyHex := hex.EncodeToString(keyBytes) + + if !ctx.IsSet(utils.PluginSettingsFlag.Name) || !ctx.IsSet(utils.AccountPluginNewAccountConfigFlag.Name) { + return accounts.Account{}, invalidPluginFlagsErr + } + + newAcctCfg, err := getNewAccountConfigFromCLI(ctx) + if err != nil { + return accounts.Account{}, err + } + + p, err := setupAccountPluginForCLI(ctx) + if err != nil { + return accounts.Account{}, err + } + defer func() { + if err := p.teardown(); err != nil { + log.Error("error tearing down account plugin", "err", err) + } + }() + + return p.ImportRawKey(keyHex, newAcctCfg) +} + +func getNewAccountConfigFromCLI(ctx *cli.Context) (map[string]interface{}, error) { + data := ctx.String(utils.AccountPluginNewAccountConfigFlag.Name) + conf, err := plugin.ReadMultiFormatConfig(data) + if err != nil { + return nil, fmt.Errorf("invalid account creation config provided: %v", err) + } + // plugin backend expects config to be json map + confMap := new(map[string]interface{}) + if err := json.Unmarshal(conf, confMap); err != nil { + return nil, fmt.Errorf("invalid account creation config provided: %v", err) + } + return *confMap, nil +} + +type accountPlugin struct { + pluggable.AccountCreator + am *accounts.Manager + pm *plugin.PluginManager +} + +func (c *accountPlugin) teardown() error { + return c.pm.Stop() +} + +func (c *accountPlugin) accounts() []accounts.Account { + b := c.am.Backends(pluggable.BackendType) + if b == nil { + return []accounts.Account{} + } + + var accts []accounts.Account + for _, wallet := range b[0].Wallets() { + accts = append(accts, wallet.Accounts()...) + } + return accts +} + +// startPluginManagerForAccountCLI is a helper func for use with the account plugin CLI. +// It creates and starts a new PluginManager with the provided CLI flags. +// The caller should call teardown on the returned accountPlugin to stop the plugin after use. +// The returned accountPlugin provides several methods necessary for the account plugin CLI, abstracting the underlying plugin/account types. +// +// This func should not be used for anything other than the account CLI. +// The account plugin, if present, is registered with the existing pluggable.Backend in the stack's AccountManager. +// This allows the AccountManager to use the account plugin even though the PluginManager is not registered with the stack. +// Instead of registering a plugin manager with the stack this is manually creating a plugin manager. +// This means that the plugin manager can be started without having to start the whole stack (P2P client, IPC interface, ...). +// The purpose of this is to help prevent issues/conflicts if an existing node is already running on this host. +// +func setupAccountPluginForCLI(ctx *cli.Context) (*accountPlugin, error) { + stack, cfg := makeConfigNodeDelegate.makeConfigNode(ctx) + + if cfg.Node.Plugins == nil { + return nil, errors.New("no plugin config provided") + } + if err := cfg.Node.Plugins.CheckSettingsAreSupported(supportedPlugins); err != nil { + return nil, err + } + if err := cfg.Node.ResolvePluginBaseDir(); err != nil { + return nil, fmt.Errorf("unable to resolve plugin base dir due to %s", err) + } + + pm, err := plugin.NewPluginManager( + cfg.Node.UserIdent, + cfg.Node.Plugins, + ctx.Bool(utils.PluginSkipVerifyFlag.Name), + ctx.Bool(utils.PluginLocalVerifyFlag.Name), + ctx.String(utils.PluginPublicKeyFlag.Name), + ) + if err != nil { + return nil, fmt.Errorf("unable to create plugin manager: %v", err) + } + if err := pm.Start(); err != nil { + return nil, fmt.Errorf("unable to start plugin manager: %v", err) + } + + b := stack.AccountManager().Backends(pluggable.BackendType)[0].(*pluggable.Backend) + if err := pm.AddAccountPluginToBackend(b); err != nil { + return nil, fmt.Errorf("unable to load pluggable account backend: %v", err) + } + + return &accountPlugin{ + AccountCreator: b, + am: stack.AccountManager(), + pm: pm, + }, nil +} + +func writePluginAccountToStdOut(account accounts.Account) { + fmt.Printf("\nYour new plugin-backed account was generated\n\n") + fmt.Printf("Public address of the account: %s\n", account.Address.Hex()) + fmt.Printf("Account URL: %s\n\n", account.URL.Path) + fmt.Printf("- You can share your public address with anyone. Others need it to interact with you.\n") + fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your funds!\n") + fmt.Printf("- Consider BACKING UP your account! The specifics of backing up will depend on the plugin backend being used.\n") + fmt.Printf("- The plugin backend may require you to REMEMBER part/all of the new account config to retrieve the key in the future!\n See the plugin specific documentation for more info.\n\n") + fmt.Printf("- See the documentation for the plugin being used for more info.\n\n") +} + +type configNodeMaker interface { + makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) +} + +// standardConfigNodeMaker is a wrapper around the makeConfigNode function to enable mocking in testing +type standardConfigNodeMaker struct{} + +func (f standardConfigNodeMaker) makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { + return makeConfigNode(ctx) +} diff --git a/cmd/geth/accountcmd_plugin_test.go b/cmd/geth/accountcmd_plugin_test.go new file mode 100644 index 0000000000..6967be360e --- /dev/null +++ b/cmd/geth/accountcmd_plugin_test.go @@ -0,0 +1,299 @@ +package main + +import ( + "flag" + "io/ioutil" + "os" + "testing" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/plugin" + "github.com/stretchr/testify/require" + "gopkg.in/urfave/cli.v1" +) + +// newAccountPluginCLIContext creates a cli.Context setup with the core account plugin CLI flags. +// args sets the values of the flags. +func newAccountPluginCLIContext(args []string) *cli.Context { + fs := &flag.FlagSet{} + fs.String(utils.PluginSettingsFlag.Name, "", "") + fs.String(utils.AccountPluginNewAccountConfigFlag.Name, "", "") + _ = fs.Parse(args) + + return cli.NewContext(nil, fs, nil) +} + +type mockConfigNodeMaker struct { + do func(ctx *cli.Context) (*node.Node, gethConfig) +} + +func (m *mockConfigNodeMaker) makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { + return m.do(ctx) +} + +func TestListPluginAccounts_ErrIfCLIFlagNotSet(t *testing.T) { + var args []string + ctx := newAccountPluginCLIContext(args) + + _, err := listPluginAccounts(ctx) + require.EqualError(t, err, "--plugins required") +} + +func TestListPluginAccounts_ErrIfUnsupportedPluginInConfig(t *testing.T) { + var unsupportedPlugin plugin.PluginInterfaceName = "somename" + pluginSettings := plugin.Settings{ + Providers: map[plugin.PluginInterfaceName]plugin.PluginDefinition{ + unsupportedPlugin: {}, + }, + } + + args := []string{ + "--plugins", "/path/to/config.json", + } + ctx := newAccountPluginCLIContext(args) + + makeConfigNodeDelegate = &mockConfigNodeMaker{ + do: func(ctx *cli.Context) (*node.Node, gethConfig) { + return nil, gethConfig{ + Node: node.Config{ + Plugins: &pluginSettings, + }, + } + }, + } + + _, err := listPluginAccounts(ctx) + require.EqualError(t, err, "unsupported plugins configured: [somename]") +} + +func TestCreatePluginAccount_ErrIfCLIFlagsNotSet(t *testing.T) { + tests := []struct { + name string + args []string + }{ + { + name: "no plugin flags", + args: []string{}, + }, + { + name: "only plugin settings flag", + args: []string{"--plugins", "/path/to/config.json"}, + }, + { + name: "only new plugin account config settings flag", + args: []string{"--plugins.account.config", "/path/to/new-acct-config.json"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := newAccountPluginCLIContext(tt.args) + + _, err := createPluginAccount(ctx) + require.EqualError(t, err, "--plugins and --plugins.account.config flags must be set") + }) + } +} + +func TestCreatePluginAccount_ErrIfInvalidNewAccountConfig(t *testing.T) { + tests := []struct { + name string + flagValue string + wantErrMsg string + }{ + { + name: "json: invalid json", + flagValue: "{invalidjson: abc}", + wantErrMsg: "invalid account creation config provided: invalid character 'i' looking for beginning of object key string", + }, + { + name: "file: does not exist", + flagValue: "file://doesnotexist", + wantErrMsg: "invalid account creation config provided: open doesnotexist: no such file or directory", + }, + { + name: "env: not set", + flagValue: "env://notset", + wantErrMsg: "invalid account creation config provided: env variable notset not found", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + args := []string{ + "--plugins", "/path/to/config.json", + "--plugins.account.config", tt.flagValue, + } + ctx := newAccountPluginCLIContext(args) + _, err := createPluginAccount(ctx) + require.EqualError(t, err, tt.wantErrMsg) + }) + } +} + +func TestCreatePluginAccount_ErrIfUnsupportedPluginInConfig(t *testing.T) { + var unsupportedPlugin plugin.PluginInterfaceName = "somename" + pluginSettings := plugin.Settings{ + Providers: map[plugin.PluginInterfaceName]plugin.PluginDefinition{ + unsupportedPlugin: {}, + }, + } + + args := []string{ + "--plugins", "/path/to/config.json", + "--plugins.account.config", "{}", + } + ctx := newAccountPluginCLIContext(args) + + makeConfigNodeDelegate = &mockConfigNodeMaker{ + do: func(ctx *cli.Context) (*node.Node, gethConfig) { + return nil, gethConfig{ + Node: node.Config{ + Plugins: &pluginSettings, + }, + } + }, + } + + _, err := createPluginAccount(ctx) + require.EqualError(t, err, "unsupported plugins configured: [somename]") +} + +func TestImportPluginAccount_ErrIfNoArg(t *testing.T) { + var args []string + ctx := newAccountPluginCLIContext(args) + + _, err := importPluginAccount(ctx) + require.EqualError(t, err, "keyfile must be given as argument") +} + +func TestImportPluginAccount_ErrIfInvalidRawkey(t *testing.T) { + args := []string{"/incorrect/path/to/file.key"} + ctx := newAccountPluginCLIContext(args) + + _, err := importPluginAccount(ctx) + require.EqualError(t, err, "Failed to load the private key: open /incorrect/path/to/file.key: no such file or directory") +} + +func TestImportPluginAccount_ErrIfCLIFlagsNotSet(t *testing.T) { + tmpfile, err := ioutil.TempFile("", "rawkey") + require.NoError(t, err) + t.Log("creating tmp file", "path", tmpfile.Name()) + defer os.Remove(tmpfile.Name()) + _, err = tmpfile.Write([]byte("1fe8f1ad4053326db20529257ac9401f2e6c769ef1d736b8c2f5aba5f787c72b")) + require.NoError(t, err) + err = tmpfile.Close() + require.NoError(t, err) + + tests := []struct { + name string + args []string + }{ + { + name: "no plugin flags", + args: []string{tmpfile.Name()}, + }, + { + name: "only plugin settings flag", + args: []string{"--plugins", "/path/to/config.json", tmpfile.Name()}, + }, + { + name: "only new plugin account config settings flag", + args: []string{"--plugins.account.config", "/path/to/new-acct-config.json", tmpfile.Name()}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := newAccountPluginCLIContext(tt.args) + + _, err := importPluginAccount(ctx) + require.EqualError(t, err, "--plugins and --plugins.account.config flags must be set") + }) + } +} + +func TestImportPluginAccount_ErrIfInvalidNewAccountConfig(t *testing.T) { + tmpfile, err := ioutil.TempFile("", "rawkey") + require.NoError(t, err) + t.Log("creating tmp file", "path", tmpfile.Name()) + defer os.Remove(tmpfile.Name()) + _, err = tmpfile.Write([]byte("1fe8f1ad4053326db20529257ac9401f2e6c769ef1d736b8c2f5aba5f787c72b")) + require.NoError(t, err) + err = tmpfile.Close() + require.NoError(t, err) + + tests := []struct { + name string + flagValue string + wantErrMsg string + }{ + { + name: "json: invalid json", + flagValue: "{invalidjson: abc}", + wantErrMsg: "invalid account creation config provided: invalid character 'i' looking for beginning of object key string", + }, + { + name: "file: does not exist", + flagValue: "file://doesnotexist", + wantErrMsg: "invalid account creation config provided: open doesnotexist: no such file or directory", + }, + { + name: "env: not set", + flagValue: "env://notset", + wantErrMsg: "invalid account creation config provided: env variable notset not found", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + args := []string{ + "--plugins", "/path/to/config.json", + "--plugins.account.config", tt.flagValue, + tmpfile.Name(), + } + ctx := newAccountPluginCLIContext(args) + _, err := importPluginAccount(ctx) + require.EqualError(t, err, tt.wantErrMsg) + }) + } +} + +func TestImportPluginAccount_ErrIfUnsupportedPluginInConfig(t *testing.T) { + tmpfile, err := ioutil.TempFile("", "rawkey") + require.NoError(t, err) + t.Log("creating tmp file", "path", tmpfile.Name()) + defer os.Remove(tmpfile.Name()) + _, err = tmpfile.Write([]byte("1fe8f1ad4053326db20529257ac9401f2e6c769ef1d736b8c2f5aba5f787c72b")) + require.NoError(t, err) + err = tmpfile.Close() + require.NoError(t, err) + + var unsupportedPlugin plugin.PluginInterfaceName = "somename" + pluginSettings := plugin.Settings{ + Providers: map[plugin.PluginInterfaceName]plugin.PluginDefinition{ + unsupportedPlugin: {}, + }, + } + + args := []string{ + "--plugins", "/path/to/config.json", + "--plugins.account.config", "{}", + tmpfile.Name(), + } + ctx := newAccountPluginCLIContext(args) + + makeConfigNodeDelegate = &mockConfigNodeMaker{ + do: func(ctx *cli.Context) (*node.Node, gethConfig) { + return nil, gethConfig{ + Node: node.Config{ + Plugins: &pluginSettings, + }, + } + }, + } + + _, err = importPluginAccount(ctx) + require.EqualError(t, err, "unsupported plugins configured: [somename]") +} diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go index 6213e5195d..32070e11bf 100644 --- a/cmd/geth/accountcmd_test.go +++ b/cmd/geth/accountcmd_test.go @@ -39,9 +39,20 @@ func tmpDatadirWithKeystore(t *testing.T) string { if err := cp.CopyAll(keystore, source); err != nil { t.Fatal(err) } + // add the necessary files for geth to start with the raft consensus + geth := filepath.Join(datadir, "geth") + sourceNodeKey := filepath.Join("testdata", "geth") + if err := cp.CopyAll(geth, sourceNodeKey); err != nil { + t.Fatal(err) + } return datadir } +func runGethWithRaftConsensus(t *testing.T, args ...string) *testgeth { + argsWithRaft := append([]string{"--raft"}, args...) + return runGeth(t, argsWithRaft...) +} + func TestAccountListEmpty(t *testing.T) { geth := runGeth(t, "account", "list") geth.ExpectExit() @@ -178,8 +189,9 @@ Fatal: could not decrypt key with given password } func TestUnlockFlag(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, + geth := runGethWithRaftConsensus(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js") @@ -201,7 +213,31 @@ Password: {{.InputLine "foobar"}} } } +func TestGethDoesntStartWithoutConfiguredConsensus(t *testing.T) { + defer SetResetPrivateConfig("ignore")() + + datadir := tmpDatadirWithKeystore(t) + geth := runGeth(t, + "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0") + + expectedText := "Consensus not specified. Exiting!!" + + // changed to expect regexp because fatalf writes the message to stdout/stderr + geth.ExpectRegexp(expectedText) +} + +func TestGethStartsWhenConsensusAndPrivateConfigAreConfigured(t *testing.T) { + defer SetResetPrivateConfig("ignore")() + + datadir := tmpDatadirWithKeystore(t) + geth := runGeth(t, + "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--raft") + + geth.ExpectExit() +} + func TestUnlockFlagWrongPassword(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", @@ -221,8 +257,9 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could // https://github.com/ethereum/go-ethereum/issues/1785 func TestUnlockFlagMultiIndex(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, + geth := runGethWithRaftConsensus(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "0,2", "js", "testdata/empty.js") @@ -248,8 +285,9 @@ Password: {{.InputLine "foobar"}} } func TestUnlockFlagPasswordFile(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) - geth := runGeth(t, + geth := runGethWithRaftConsensus(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--password", "testdata/passwords.txt", "--unlock", "0,2", "js", "testdata/empty.js") @@ -268,6 +306,7 @@ func TestUnlockFlagPasswordFile(t *testing.T) { } func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { + defer SetResetPrivateConfig("ignore")() datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", @@ -279,9 +318,11 @@ Fatal: Failed to unlock account 0 (could not decrypt key with given password) } func TestUnlockFlagAmbiguous(t *testing.T) { + defer SetResetPrivateConfig("ignore")() + datadir := tmpDatadirWithKeystore(t) store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") - geth := runGeth(t, - "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", + geth := runGethWithRaftConsensus(t, + "--datadir", datadir, "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", "--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js") defer geth.ExpectExit() @@ -317,6 +358,7 @@ In order to avoid this warning, you need to remove the following duplicate key f } func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { + defer SetResetPrivateConfig("ignore")() store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") geth := runGeth(t, "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0", diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index b98597e307..8cc798a0bf 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -19,6 +19,7 @@ package main import ( "encoding/json" "fmt" + "io" "os" "path/filepath" "runtime" @@ -133,7 +134,7 @@ be gzipped.`, }, Category: "BLOCKCHAIN COMMANDS", Description: ` - The import-preimages command imports hash preimages from an RLP encoded stream.`, +The import-preimages command imports hash preimages from an RLP encoded stream.`, } exportPreimagesCommand = cli.Command{ Action: utils.MigrateFlags(exportPreimages), @@ -221,6 +222,24 @@ Use "ethereum dump 0" to dump the genesis block.`, } ) +// In the regular Genesis / ChainConfig struct, due to the way go deserializes +// json, IsQuorum defaults to false (when not specified). Here we specify it as +// a pointer so we can make the distinction and default unspecified to true. +func getIsQuorum(file io.Reader) bool { + altGenesis := new(struct { + Config *struct { + IsQuorum *bool `json:"isQuorum"` + } `json:"config"` + }) + + if err := json.NewDecoder(file).Decode(altGenesis); err != nil { + utils.Fatalf("invalid genesis file: %v", err) + } + + // unspecified defaults to true + return altGenesis.Config.IsQuorum == nil || *altGenesis.Config.IsQuorum +} + // initGenesis will initialise the given JSON format genesis file and writes it as // the zero'd block (i.e. genesis) or will fail hard if it can't succeed. func initGenesis(ctx *cli.Context) error { @@ -239,6 +258,19 @@ func initGenesis(ctx *cli.Context) error { if err := json.NewDecoder(file).Decode(genesis); err != nil { utils.Fatalf("invalid genesis file: %v", err) } + + // Quorum + file.Seek(0, 0) + genesis.Config.IsQuorum = getIsQuorum(file) + + // check the data given as a part of newMaxConfigData to ensure that + // its in expected order + err = genesis.Config.CheckMaxCodeConfigData() + if err != nil { + utils.Fatalf("maxCodeSize data invalid: %v", err) + } + // End Quorum + // Open and initialise both full and light databases stack, _ := makeConfigNode(ctx) defer stack.Close() @@ -281,7 +313,7 @@ func importChain(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) defer stack.Close() - chain, db := utils.MakeChain(ctx, stack, false) + chain, db := utils.MakeChain(ctx, stack, false, true) defer db.Close() // Start periodically gathering memory profiles @@ -376,7 +408,7 @@ func exportChain(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) defer stack.Close() - chain, _ := utils.MakeChain(ctx, stack, true) + chain, _ := utils.MakeChain(ctx, stack, true, true) start := time.Now() var err error @@ -453,7 +485,7 @@ func copyDb(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) defer stack.Close() - chain, chainDb := utils.MakeChain(ctx, stack, false) + chain, chainDb := utils.MakeChain(ctx, stack, false, false) syncMode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode) var syncBloom *trie.SyncBloom @@ -561,7 +593,7 @@ func dump(ctx *cli.Context) error { stack, _ := makeConfigNode(ctx) defer stack.Close() - chain, chainDb := utils.MakeChain(ctx, stack, true) + chain, chainDb := utils.MakeChain(ctx, stack, true, false) defer chainDb.Close() for _, arg := range ctx.Args() { var block *types.Block @@ -600,7 +632,7 @@ func inspect(ctx *cli.Context) error { node, _ := makeConfigNode(ctx) defer node.Close() - _, chainDb := utils.MakeChain(ctx, node, true) + _, chainDb := utils.MakeChain(ctx, node, true, false) defer chainDb.Close() return rawdb.InspectDatabase(chainDb) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 2c15a4c832..2bf912d9c1 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -24,15 +24,18 @@ import ( "reflect" "unicode" - cli "gopkg.in/urfave/cli.v1" - "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common/http" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/extension/privacyExtension" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" "github.com/naoina/toml" + "gopkg.in/urfave/cli.v1" ) var ( @@ -106,6 +109,12 @@ func defaultNodeConfig() node.Config { // makeConfigNode loads geth configuration and creates a blank node instance. func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { + // Quorum: Must occur before setQuorumConfig, as it needs an initialised PTM to be enabled + // Extension Service and Multitenancy feature validation also depend on PTM availability + if err := quorumInitialisePrivacy(ctx); err != nil { + utils.Fatalf("Error initialising Private Transaction Manager: %s", err.Error()) + } + // Load defaults. cfg := gethConfig{ Eth: eth.DefaultConfig, @@ -147,7 +156,28 @@ func checkWhisper(ctx *cli.Context) { func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { stack, cfg := makeConfigNode(ctx) - backend := utils.RegisterEthService(stack, &cfg.Eth) + // Quorum - returning `ethService` too for the Raft and extension service + backend, ethService := utils.RegisterEthService(stack, &cfg.Eth) + + // Quorum + // plugin service must be after eth service so that eth service will be stopped gradually if any of the plugin + // fails to start + if cfg.Node.Plugins != nil { + utils.RegisterPluginService(stack, &cfg.Node, ctx.Bool(utils.PluginSkipVerifyFlag.Name), ctx.Bool(utils.PluginLocalVerifyFlag.Name), ctx.String(utils.PluginPublicKeyFlag.Name)) + } + + if cfg.Node.IsPermissionEnabled() { + utils.RegisterPermissionService(stack, ctx.Bool(utils.RaftDNSEnabledFlag.Name)) + } + + if ctx.GlobalBool(utils.RaftModeFlag.Name) { + utils.RegisterRaftService(stack, ctx, &cfg.Node, ethService) + } + + if private.IsQuorumPrivacyEnabled() { + utils.RegisterExtensionService(stack, ethService) + } + // End Quorum checkWhisper(ctx) // Configure GraphQL if requested @@ -189,3 +219,104 @@ func dumpConfig(ctx *cli.Context) error { return nil } + +// quorumValidateEthService checks quorum features that depend on the ethereum service +func quorumValidateEthService(stack *node.Node, isRaft bool) { + var ethereum *eth.Ethereum + + err := stack.Lifecycle(ðereum) + if err != nil { + utils.Fatalf("Error retrieving Ethereum service: %v", err) + } + + quorumValidateConsensus(ethereum, isRaft) + + quorumValidatePrivacyEnhancements(ethereum) +} + +// quorumValidateConsensus checks if a consensus was used. The node is killed if consensus was not used +func quorumValidateConsensus(ethereum *eth.Ethereum, isRaft bool) { + if !isRaft && ethereum.BlockChain().Config().Istanbul == nil && ethereum.BlockChain().Config().Clique == nil { + utils.Fatalf("Consensus not specified. Exiting!!") + } +} + +// quorumValidatePrivacyEnhancements checks if privacy enhancements are configured the transaction manager supports +// the PrivacyEnhancements feature +func quorumValidatePrivacyEnhancements(ethereum *eth.Ethereum) { + privacyEnhancementsBlock := ethereum.BlockChain().Config().PrivacyEnhancementsBlock + if privacyEnhancementsBlock != nil { + log.Info("Privacy enhancements is configured to be enabled from block ", "height", privacyEnhancementsBlock) + if !private.P.HasFeature(engine.PrivacyEnhancements) { + utils.Fatalf("Cannot start quorum with privacy enhancements enabled while the transaction manager does not support it") + } + } +} + +// configure and set up quorum transaction privacy +func quorumInitialisePrivacy(ctx *cli.Context) error { + cfg, err := QuorumSetupPrivacyConfiguration(ctx) + if err != nil { + return err + } + + err = private.InitialiseConnection(cfg) + if err != nil { + return err + } + privacyExtension.Init() + + return nil +} + +// Get private transaction manager configuration +func QuorumSetupPrivacyConfiguration(ctx *cli.Context) (http.Config, error) { + // get default configuration + cfg, err := private.GetLegacyEnvironmentConfig() + if err != nil { + return http.Config{}, err + } + + // override the config with command line parameters + if ctx.GlobalIsSet(utils.QuorumPTMUnixSocketFlag.Name) { + cfg.SetSocket(ctx.GlobalString(utils.QuorumPTMUnixSocketFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMUrlFlag.Name) { + cfg.SetHttpUrl(ctx.GlobalString(utils.QuorumPTMUrlFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMTimeoutFlag.Name) { + cfg.SetTimeout(ctx.GlobalUint(utils.QuorumPTMTimeoutFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMDialTimeoutFlag.Name) { + cfg.SetDialTimeout(ctx.GlobalUint(utils.QuorumPTMDialTimeoutFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMHttpIdleTimeoutFlag.Name) { + cfg.SetHttpIdleConnTimeout(ctx.GlobalUint(utils.QuorumPTMHttpIdleTimeoutFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMHttpWriteBufferSizeFlag.Name) { + cfg.SetHttpWriteBufferSize(ctx.GlobalInt(utils.QuorumPTMHttpWriteBufferSizeFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMHttpReadBufferSizeFlag.Name) { + cfg.SetHttpReadBufferSize(ctx.GlobalInt(utils.QuorumPTMHttpReadBufferSizeFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMTlsModeFlag.Name) { + cfg.SetTlsMode(ctx.GlobalString(utils.QuorumPTMTlsModeFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMTlsRootCaFlag.Name) { + cfg.SetTlsRootCA(ctx.GlobalString(utils.QuorumPTMTlsRootCaFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMTlsClientCertFlag.Name) { + cfg.SetTlsClientCert(ctx.GlobalString(utils.QuorumPTMTlsClientCertFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMTlsClientKeyFlag.Name) { + cfg.SetTlsClientKey(ctx.GlobalString(utils.QuorumPTMTlsClientKeyFlag.Name)) + } + if ctx.GlobalIsSet(utils.QuorumPTMTlsInsecureSkipVerify.Name) { + cfg.SetTlsInsecureSkipVerify(ctx.Bool(utils.QuorumPTMTlsInsecureSkipVerify.Name)) + } + + if err = cfg.Validate(); err != nil { + return cfg, err + } + return cfg, nil +} diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go index e2f733f844..649db0149f 100644 --- a/cmd/geth/consolecmd.go +++ b/cmd/geth/consolecmd.go @@ -17,7 +17,13 @@ package main import ( + "context" + "crypto/tls" + "crypto/x509" "fmt" + "io/ioutil" + "net/http" + "net/url" "os" "os/signal" "path/filepath" @@ -26,13 +32,16 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/console" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/plugin/security" "github.com/ethereum/go-ethereum/rpc" "gopkg.in/urfave/cli.v1" ) var ( - consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} + consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} + rpcClientFlags = []cli.Flag{utils.RPCClientToken, utils.RPCClientTLSCert, utils.RPCClientTLSCaCert, utils.RPCClientTLSCipherSuites, utils.RPCClientTLSInsecureSkipVerify} consoleCommand = cli.Command{ Action: utils.MigrateFlags(localConsole), @@ -51,7 +60,7 @@ See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console.`, Name: "attach", Usage: "Start an interactive JavaScript environment (connect to node)", ArgsUsage: "[endpoint]", - Flags: append(consoleFlags, utils.DataDirFlag), + Flags: append(append(consoleFlags, utils.DataDirFlag), rpcClientFlags...), Category: "CONSOLE COMMANDS", Description: ` The Geth console is an interactive shell for the JavaScript runtime environment @@ -73,6 +82,74 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Cons } ) +// Quorum +// +// read tls client configuration from command line arguments +// +// only for HTTPS or WSS +func readTLSClientConfig(endpoint string, ctx *cli.Context) (*tls.Config, bool, error) { + if !strings.HasPrefix(endpoint, "https://") && !strings.HasPrefix(endpoint, "wss://") { + return nil, false, nil + } + hasCustomTls := false + insecureSkipVerify := ctx.Bool(utils.RPCClientTLSInsecureSkipVerify.Name) + tlsConfig := &tls.Config{ + InsecureSkipVerify: insecureSkipVerify, + } + var certFile, caFile string + if !insecureSkipVerify { + var certPem, caPem []byte + certFile, caFile = ctx.String(utils.RPCClientTLSCert.Name), ctx.String(utils.RPCClientTLSCaCert.Name) + var err error + if certFile != "" { + if certPem, err = ioutil.ReadFile(certFile); err != nil { + return nil, true, err + } + } + if caFile != "" { + if caPem, err = ioutil.ReadFile(caFile); err != nil { + return nil, true, err + } + } + if len(certPem) != 0 || len(caPem) != 0 { + certPool, err := x509.SystemCertPool() + if err != nil { + certPool = x509.NewCertPool() + } + if len(certPem) != 0 { + certPool.AppendCertsFromPEM(certPem) + } + if len(caPem) != 0 { + certPool.AppendCertsFromPEM(caPem) + } + tlsConfig.RootCAs = certPool + hasCustomTls = true + } + } else { + hasCustomTls = true + } + cipherSuitesInput := ctx.String(utils.RPCClientTLSCipherSuites.Name) + cipherSuitesStrings := strings.FieldsFunc(cipherSuitesInput, func(r rune) bool { + return r == ',' + }) + if len(cipherSuitesStrings) > 0 { + cipherSuiteList := make(security.CipherSuiteList, len(cipherSuitesStrings)) + for i, s := range cipherSuitesStrings { + cipherSuiteList[i] = security.CipherSuite(strings.TrimSpace(s)) + } + cipherSuites, err := cipherSuiteList.ToUint16Array() + if err != nil { + return nil, true, err + } + tlsConfig.CipherSuites = cipherSuites + hasCustomTls = true + } + if !hasCustomTls { + return nil, false, nil + } + return tlsConfig, hasCustomTls, nil +} + // localConsole starts a new geth node, attaching a JavaScript console to it at the // same time. func localConsole(ctx *cli.Context) error { @@ -142,7 +219,7 @@ func remoteConsole(ctx *cli.Context) error { } endpoint = fmt.Sprintf("%s/geth.ipc", path) } - client, err := dialRPC(endpoint) + client, err := dialRPC(endpoint, ctx) if err != nil { utils.Fatalf("Unable to attach to remote geth: %v", err) } @@ -153,20 +230,20 @@ func remoteConsole(ctx *cli.Context) error { Preload: utils.MakeConsolePreloads(ctx), } - console, err := console.New(config) + consl, err := console.New(config) if err != nil { utils.Fatalf("Failed to start the JavaScript console: %v", err) } - defer console.Stop(false) + defer consl.Stop(false) if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { - console.Evaluate(script) + consl.Evaluate(script) return nil } // Otherwise print the welcome screen and enter interactive mode - console.Welcome() - console.Interactive() + consl.Welcome() + consl.Interactive() return nil } @@ -174,7 +251,12 @@ func remoteConsole(ctx *cli.Context) error { // dialRPC returns a RPC client which connects to the given endpoint. // The check for empty endpoint implements the defaulting logic // for "geth attach" and "geth monitor" with no argument. -func dialRPC(endpoint string) (*rpc.Client, error) { +// +// Quorum: passing the cli context to build security-aware client: +// 1. Custom TLS configuration +// 2. Access Token awareness via rpc.HttpCredentialsProviderFunc +// 3. PSI awareness from environment variable and endpoint query param +func dialRPC(endpoint string, ctx *cli.Context) (*rpc.Client, error) { if endpoint == "" { endpoint = node.DefaultIPCEndpoint(clientIdentifier) } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { @@ -182,7 +264,51 @@ func dialRPC(endpoint string) (*rpc.Client, error) { // these prefixes. endpoint = endpoint[4:] } - return rpc.Dial(endpoint) + var ( + client *rpc.Client + err error + dialCtx = context.Background() + ) + tlsConfig, hasCustomTls, tlsReadErr := readTLSClientConfig(endpoint, ctx) + if tlsReadErr != nil { + return nil, tlsReadErr + } + if token := ctx.String(utils.RPCClientToken.Name); token != "" { + var f rpc.HttpCredentialsProviderFunc = func(ctx context.Context) (string, error) { + return token, nil + } + // it's important that f MUST BE OF TYPE rpc.HttpCredentialsProviderFunc + dialCtx = rpc.WithCredentialsProvider(dialCtx, f) + } + if hasCustomTls { + u, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + switch u.Scheme { + case "https": + customHttpClient := &http.Client{ + Transport: http.DefaultTransport, + } + customHttpClient.Transport.(*http.Transport).TLSClientConfig = tlsConfig + client, _ = rpc.DialHTTPWithClient(endpoint, customHttpClient) + case "wss": + client, _ = rpc.DialWebsocketWithCustomTLS(dialCtx, endpoint, "", tlsConfig) + default: + log.Warn("unsupported scheme for custom TLS which is only for HTTPS/WSS", "scheme", u.Scheme) + client, _ = rpc.DialContext(dialCtx, endpoint) + } + } else { + client, err = rpc.DialContext(dialCtx, endpoint) + } + if err != nil { + return nil, err + } + // enrich clients with provider functions to populate HTTP request header + if f := rpc.CredentialsProviderFromContext(dialCtx); f != nil { + client = client.WithHTTPCredentials(f) + } + return client, nil } // ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 6c100e18d9..890b2405fd 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -18,6 +18,9 @@ package main import ( "crypto/rand" + "crypto/tls" + "flag" + "io/ioutil" "math/big" "os" "path/filepath" @@ -27,22 +30,60 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/params" + testifyassert "github.com/stretchr/testify/assert" + "gopkg.in/urfave/cli.v1" ) const ( - ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0" - httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" + ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0" + httpAPIs = "admin:1.0 eth:1.0 net:1.0 rpc:1.0 web3:1.0" + nodeKey = "b68c0338aa4b266bf38ebe84c6199ae9fac8b29f32998b3ed2fbeafebe8d65c9" ) +var genesis = `{ + "config": { + "chainId": 2017, + "homesteadBlock": 1, + "eip150Block": 2, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 3, + "eip158Block": 3, + "istanbul": { + "epoch": 30000, + "policy": 0 + } + }, + "nonce": "0x0", + "timestamp": "0x0", + "gasLimit": "0x47b760", + "difficulty": "0x1", + "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "491937757d1b26e29c507b8d4c0b233c2747e68d": { + "balance": "0x446c3b15f9926687d2c40534fdb564000000000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} +` + // Tests that a node embedded within a console can be started up properly and // then terminated by closing the input stream. func TestConsoleWelcome(t *testing.T) { - coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" + defer SetResetPrivateConfig("ignore")() + coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" + + datadir := setupIstanbul(t) + defer os.RemoveAll(datadir) // Start a geth console, make sure it's cleaned up and terminate the console geth := runGeth(t, - "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", + "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--etherbase", coinbase, "console") @@ -50,7 +91,8 @@ func TestConsoleWelcome(t *testing.T) { geth.SetTemplateFunc("goos", func() string { return runtime.GOOS }) geth.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) geth.SetTemplateFunc("gover", runtime.Version) - geth.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") }) + geth.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) + geth.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) geth.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") }) @@ -60,7 +102,7 @@ func TestConsoleWelcome(t *testing.T) { geth.Expect(` Welcome to the Geth JavaScript console! -instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}} +instance: Geth/v{{gethver}}(quorum-v{{quorumver}})/{{goos}}-{{goarch}}/{{gover}} coinbase: {{.Etherbase}} at block: 0 ({{niltime}}) datadir: {{.Datadir}} @@ -73,18 +115,21 @@ at block: 0 ({{niltime}}) // Tests that a console can be attached to a running node via various means. func TestIPCAttachWelcome(t *testing.T) { + defer SetResetPrivateConfig("ignore")() // Configure the instance for IPC attachment - coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" + coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" var ipc string + + datadir := setupIstanbul(t) + defer os.RemoveAll(datadir) + if runtime.GOOS == "windows" { ipc = `\\.\pipe\geth` + strconv.Itoa(trulyRandInt(100000, 999999)) } else { - ws := tmpdir(t) - defer os.RemoveAll(ws) - ipc = filepath.Join(ws, "geth.ipc") + ipc = filepath.Join(datadir, "geth.ipc") } geth := runGeth(t, - "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", + "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--etherbase", coinbase, "--ipcpath", ipc) defer func() { @@ -98,15 +143,16 @@ func TestIPCAttachWelcome(t *testing.T) { } func TestHTTPAttachWelcome(t *testing.T) { - coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" + defer SetResetPrivateConfig("ignore")() + coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P + + datadir := setupIstanbul(t) + defer os.RemoveAll(datadir) + geth := runGeth(t, - "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--etherbase", coinbase, "--http", "--http.port", port) - defer func() { - geth.Interrupt() - geth.ExpectExit() - }() + "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", + "--etherbase", coinbase, "--http", "--http.port", port, "--rpcapi", "admin,eth,net,web3") endpoint := "http://127.0.0.1:" + port waitForEndpoint(t, endpoint, 3*time.Second) @@ -114,16 +160,16 @@ func TestHTTPAttachWelcome(t *testing.T) { } func TestWSAttachWelcome(t *testing.T) { - coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" + defer SetResetPrivateConfig("ignore")() + coinbase := "0x491937757d1b26e29c507b8d4c0b233c2747e68d" port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P + datadir := setupIstanbul(t) + defer os.RemoveAll(datadir) + geth := runGeth(t, - "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", - "--etherbase", coinbase, "--ws", "--ws.port", port) - defer func() { - geth.Interrupt() - geth.ExpectExit() - }() + "--datadir", datadir, "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", + "--etherbase", coinbase, "--ws", "--ws.port", port, "--wsapi", "admin,eth,net,web3") endpoint := "ws://127.0.0.1:" + port waitForEndpoint(t, endpoint, 3*time.Second) @@ -140,12 +186,13 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) attach.SetTemplateFunc("gover", runtime.Version) - attach.SetTemplateFunc("gethver", func() string { return params.VersionWithCommit("", "") }) + attach.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta }) + attach.SetTemplateFunc("quorumver", func() string { return params.QuorumVersion }) attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase }) attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format("Mon Jan 02 2006 15:04:05 GMT-0700 (MST)") }) - attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) + attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") || strings.Contains(apis, "admin") }) attach.SetTemplateFunc("datadir", func() string { return geth.Datadir }) attach.SetTemplateFunc("apis", func() string { return apis }) @@ -153,7 +200,7 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) { attach.Expect(` Welcome to the Geth JavaScript console! -instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}} +instance: Geth/v{{gethver}}(quorum-v{{quorumver}})/{{goos}}-{{goarch}}/{{gover}} coinbase: {{etherbase}} at block: 0 ({{niltime}}){{if ipc}} datadir: {{datadir}}{{end}} @@ -170,3 +217,80 @@ func trulyRandInt(lo, hi int) int { num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo))) return int(num.Int64()) + lo } + +// setupIstanbul creates a temporary directory and copies nodekey and genesis.json. +// It initializes istanbul by calling geth init +func setupIstanbul(t *testing.T) string { + datadir := tmpdir(t) + gethPath := filepath.Join(datadir, "geth") + os.Mkdir(gethPath, 0700) + + // Initialize the data directory with the custom genesis block + json := filepath.Join(datadir, "genesis.json") + if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil { + t.Fatalf("failed to write genesis file: %v", err) + } + + nodeKeyFile := filepath.Join(gethPath, "nodekey") + if err := ioutil.WriteFile(nodeKeyFile, []byte(nodeKey), 0600); err != nil { + t.Fatalf("failed to write nodekey file: %v", err) + } + + runGeth(t, "--datadir", datadir, "init", json).WaitExit() + + return datadir +} + +func TestReadTLSClientConfig_whenCustomizeTLSCipherSuites(t *testing.T) { + assert := testifyassert.New(t) + + flagSet := new(flag.FlagSet) + flagSet.Bool(utils.RPCClientTLSInsecureSkipVerify.Name, true, "") + flagSet.String(utils.RPCClientTLSCipherSuites.Name, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "") + ctx := cli.NewContext(nil, flagSet, nil) + + tlsConf, ok, err := readTLSClientConfig("https://arbitraryendpoint", ctx) + + assert.NoError(err) + assert.True(ok, "has custom TLS client configuration") + assert.True(tlsConf.InsecureSkipVerify) + assert.Len(tlsConf.CipherSuites, 2) + assert.Contains(tlsConf.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) + assert.Contains(tlsConf.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) +} + +func TestReadTLSClientConfig_whenTypicalTLS(t *testing.T) { + assert := testifyassert.New(t) + + flagSet := new(flag.FlagSet) + ctx := cli.NewContext(nil, flagSet, nil) + + tlsConf, ok, err := readTLSClientConfig("https://arbitraryendpoint", ctx) + + assert.NoError(err) + assert.False(ok, "no custom TLS client configuration") + assert.Nil(tlsConf, "no custom TLS config is set") +} + +func TestReadTLSClientConfig_whenTLSInsecureFlagSet(t *testing.T) { + assert := testifyassert.New(t) + + flagSet := new(flag.FlagSet) + flagSet.Bool(utils.RPCClientTLSInsecureSkipVerify.Name, true, "") + ctx := cli.NewContext(nil, flagSet, nil) + + tlsConf, ok, err := readTLSClientConfig("https://arbitraryendpoint", ctx) + + assert.NoError(err) + assert.True(ok, "has custom TLS client configuration") + assert.True(tlsConf.InsecureSkipVerify) + assert.Len(tlsConf.CipherSuites, 0) +} + +func SetResetPrivateConfig(value string) func() { + existingValue := os.Getenv("PRIVATE_CONFIG") + os.Setenv("PRIVATE_CONFIG", value) + return func() { + os.Setenv("PRIVATE_CONFIG", existingValue) + } +} diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go index 6c36771e97..ff8ae0cded 100644 --- a/cmd/geth/dao_test.go +++ b/cmd/geth/dao_test.go @@ -105,6 +105,7 @@ func TestDAOForkBlockNewChain(t *testing.T) { } func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) { + defer SetResetPrivateConfig("ignore")() // Create a temporary data directory to use and inspect later datadir := tmpdir(t) defer os.RemoveAll(datadir) diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go index ee3991acd1..c58fc436c7 100644 --- a/cmd/geth/genesis_test.go +++ b/cmd/geth/genesis_test.go @@ -20,7 +20,10 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "testing" + + "github.com/cespare/cp" ) var customGenesisTests = []struct { @@ -40,7 +43,7 @@ var customGenesisTests = []struct { "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp" : "0x00", - "config" : {} + "config" : {"isQuorum":false } }`, query: "eth.getBlock(0).nonce", result: "0x0000000000001338", @@ -53,29 +56,38 @@ var customGenesisTests = []struct { "difficulty" : "0x20000", "extraData" : "", "gasLimit" : "0x2fefd8", - "nonce" : "0x0000000000001339", + "nonce" : "0x0000000000000042", "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp" : "0x00", "config" : { "homesteadBlock" : 42, "daoForkBlock" : 141, - "daoForkSupport" : true - } + "daoForkSupport" : true, + "isQuorum" : false + }, }`, query: "eth.getBlock(0).nonce", - result: "0x0000000000001339", + result: "0x0000000000000042", }, } // Tests that initializing Geth with a custom genesis block and chain definitions // work properly. func TestCustomGenesis(t *testing.T) { + defer SetResetPrivateConfig("ignore")() for i, tt := range customGenesisTests { // Create a temporary data directory to use and inspect later datadir := tmpdir(t) defer os.RemoveAll(datadir) + // copy the node key and static-nodes.json so that geth can start with the raft consensus + gethDir := filepath.Join(datadir, "geth") + sourceNodeKey := filepath.Join("testdata", "geth") + if err := cp.CopyAll(gethDir, sourceNodeKey); err != nil { + t.Fatal(err) + } + // Initialize the data directory with the custom genesis block json := filepath.Join(datadir, "genesis.json") if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil { @@ -87,8 +99,91 @@ func TestCustomGenesis(t *testing.T) { geth := runGeth(t, "--nousb", "--datadir", datadir, "--maxpeers", "0", "--port", "0", "--nodiscover", "--nat", "none", "--ipcdisable", + "--raft", "--exec", tt.query, "console") geth.ExpectRegexp(tt.result) geth.ExpectExit() } } + +func TestCustomGenesisUpgradeWithPrivacyEnhancementsBlock(t *testing.T) { + defer SetResetPrivateConfig("ignore")() + // Create a temporary data directory to use and inspect later + datadir := tmpdir(t) + defer os.RemoveAll(datadir) + + // copy the node key and static-nodes.json so that geth can start with the raft consensus + gethDir := filepath.Join(datadir, "geth") + sourceNodeKey := filepath.Join("testdata", "geth") + if err := cp.CopyAll(gethDir, sourceNodeKey); err != nil { + t.Fatal(err) + } + + genesisContentWithoutPrivacyEnhancements := + `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "homesteadBlock" : 42, + "daoForkBlock" : 141, + "daoForkSupport" : true, + "isQuorum" : false + } + }` + + // Initialize the data directory with the custom genesis block + json := filepath.Join(datadir, "genesis.json") + if err := ioutil.WriteFile(json, []byte(genesisContentWithoutPrivacyEnhancements), 0600); err != nil { + t.Fatalf("failed to write genesis file: %v", err) + } + geth := runGeth(t, "--datadir", datadir, "init", json) + geth.WaitExit() + + genesisContentWithPrivacyEnhancements := + `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "homesteadBlock" : 42, + "daoForkBlock" : 141, + "privacyEnhancementsBlock" : 1000, + "daoForkSupport" : true, + "isQuorum" : false + } + }` + + if err := ioutil.WriteFile(json, []byte(genesisContentWithPrivacyEnhancements), 0600); err != nil { + t.Fatalf("failed to write genesis file: %v", err) + } + geth = runGeth(t, "--datadir", datadir, "init", json) + geth.WaitExit() + + expectedText := "Privacy enhancements have been enabled from block height 1000. Please ensure your privacy manager is upgraded and supports privacy enhancements" + + result := strings.TrimSpace(geth.StderrText()) + if !strings.Contains(result, expectedText) { + geth.Fatalf("bad stderr text. want '%s', got '%s'", expectedText, result) + } + + // start quorum - it should fail the transaction manager PrivacyEnhancements feature validation + geth = runGeth(t, + "--datadir", datadir, "--maxpeers", "0", "--port", "0", + "--nodiscover", "--nat", "none", "--ipcdisable", + "--raft", "console") + geth.ExpectRegexp("Cannot start quorum with privacy enhancements enabled while the transaction manager does not support it") + geth.ExpectExit() +} diff --git a/cmd/geth/les_test.go b/cmd/geth/les_test.go index ae9ed5ecf5..8cd84d7ea7 100644 --- a/cmd/geth/les_test.go +++ b/cmd/geth/les_test.go @@ -132,6 +132,10 @@ func startClient(t *testing.T, name string) *gethrpc { } func TestPriorityClient(t *testing.T) { + // Quorum + t.Skip("skipping test in Quorum (no support for light sync mode).") + // End Quorum + lightServer := startLightServer(t) defer lightServer.killAndWait() diff --git a/cmd/geth/main.go b/cmd/geth/main.go index ccc6358996..f0d3ff8d53 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/accounts/pluggable" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/console/prompt" @@ -41,8 +42,10 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/permission" + "github.com/ethereum/go-ethereum/plugin" gopsutil "github.com/shirou/gopsutil/mem" - cli "gopkg.in/urfave/cli.v1" + "gopkg.in/urfave/cli.v1" ) const ( @@ -157,6 +160,37 @@ var ( utils.EWASMInterpreterFlag, utils.EVMInterpreterFlag, configFileFlag, + // Quorum + utils.QuorumImmutabilityThreshold, + utils.EnableNodePermissionFlag, + utils.RaftModeFlag, + utils.RaftBlockTimeFlag, + utils.RaftJoinExistingFlag, + utils.RaftPortFlag, + utils.RaftDNSEnabledFlag, + utils.EmitCheckpointsFlag, + utils.IstanbulRequestTimeoutFlag, + utils.IstanbulBlockPeriodFlag, + utils.PluginSettingsFlag, + utils.PluginSkipVerifyFlag, + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.AllowedFutureBlockTimeFlag, + utils.EVMCallTimeOutFlag, + utils.MultitenancyFlag, + utils.QuorumPTMUnixSocketFlag, + utils.QuorumPTMUrlFlag, + utils.QuorumPTMTimeoutFlag, + utils.QuorumPTMDialTimeoutFlag, + utils.QuorumPTMHttpIdleTimeoutFlag, + utils.QuorumPTMHttpWriteBufferSizeFlag, + utils.QuorumPTMHttpReadBufferSizeFlag, + utils.QuorumPTMTlsModeFlag, + utils.QuorumPTMTlsRootCaFlag, + utils.QuorumPTMTlsClientCertFlag, + utils.QuorumPTMTlsClientKeyFlag, + utils.QuorumPTMTlsInsecureSkipVerify, + // End-Quorum } rpcFlags = []cli.Flag{ @@ -350,10 +384,12 @@ func geth(ctx *cli.Context) error { } prepare(ctx) + stack, backend := makeFullNode(ctx) defer stack.Close() startNode(ctx, stack, backend) + stack.Wait() return nil } @@ -362,11 +398,25 @@ func geth(ctx *cli.Context) error { // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the // miner. func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { + log.DoEmitCheckpoints = ctx.GlobalBool(utils.EmitCheckpointsFlag.Name) debug.Memsize.Add("node", stack) + // raft mode does not support --exitwhensynced + if ctx.GlobalBool(utils.ExitWhenSyncedFlag.Name) && ctx.GlobalBool(utils.RaftModeFlag.Name) { + utils.Fatalf("raft consensus does not support --exitwhensynced") + } + // Start up the node itself utils.StartNode(stack) + // Now that the plugin manager has been started we register the account plugin with the corresponding account backend. All other account management is disabled when using External Signer + if !ctx.IsSet(utils.ExternalSignerFlag.Name) && stack.PluginManager().IsEnabled(plugin.AccountPluginInterfaceName) { + b := stack.AccountManager().Backends(pluggable.BackendType)[0].(*pluggable.Backend) + if err := stack.PluginManager().AddAccountPluginToBackend(b); err != nil { + log.Error("failed to setup account plugin", "err", err) + } + } + // Unlock any account specifically requested unlockAccounts(ctx, stack) @@ -381,6 +431,12 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { } ethClient := ethclient.NewClient(rpcClient) + // Quorum + if ctx.GlobalBool(utils.MultitenancyFlag.Name) && !stack.PluginManager().IsEnabled(plugin.SecurityPluginInterfaceName) { + utils.Fatalf("multitenancy requires RPC Security Plugin to be configured") + } + // End Quorum + go func() { // Open any wallets already attached for _, wallet := range stack.AccountManager().Wallets() { @@ -438,6 +494,22 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { }() } + // Quorum + // + // checking if permissions is enabled and staring the permissions service + if stack.Config().EnableNodePermission { + stack.Server().SetIsNodePermissioned(permission.IsNodePermissioned) + if stack.IsPermissionEnabled() { + var permissionService *permission.PermissionCtrl + if err := stack.Lifecycle(&permissionService); err != nil { + utils.Fatalf("Permission service not runnning: %v", err) + } + if err := permissionService.AfterStart(); err != nil { + utils.Fatalf("Permission service post construct failure: %v", err) + } + } + } + // Start auxiliary services if enabled if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { // Mining only makes sense if a full Ethereum node is running @@ -465,6 +537,9 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) { utils.Fatalf("Failed to start mining: %v", err) } } + + // checks quorum features that depend on the ethereum service + quorumValidateEthService(stack, ctx.GlobalBool(utils.RaftModeFlag.Name)) } // unlockAccounts unlocks any account specifically requested. diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go index 0e7ee96513..c626a9f95e 100644 --- a/cmd/geth/misccmd.go +++ b/cmd/geth/misccmd.go @@ -115,8 +115,10 @@ func version(ctx *cli.Context) error { if gitDate != "" { fmt.Println("Git Commit Date:", gitDate) } + fmt.Println("Quorum Version:", params.QuorumVersion) fmt.Println("Architecture:", runtime.GOARCH) fmt.Println("Protocol Versions:", eth.ProtocolVersions) + fmt.Println("Network Id:", eth.DefaultConfig.NetworkId) fmt.Println("Go Version:", runtime.Version()) fmt.Println("Operating System:", runtime.GOOS) fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) diff --git a/cmd/geth/retesteth.go b/cmd/geth/retesteth.go index 1d4c15d1e6..bacf36ef0c 100644 --- a/cmd/geth/retesteth.go +++ b/cmd/geth/retesteth.go @@ -196,6 +196,10 @@ type NoRewardEngine struct { rewardsOn bool } +func (sb *NoRewardEngine) Protocol() consensus.Protocol { + return consensus.NorewardsProtocol +} + func (e *NoRewardEngine) Author(header *types.Header) (common.Address, error) { return e.inner.Author(header) } @@ -493,7 +497,7 @@ func (api *RetestethAPI) mineBlock() error { } } } - statedb, err := api.blockchain.StateAt(parent.Root()) + statedb, pvtstdb, err := api.blockchain.StateAtPSI(parent.Root(), types.DefaultPrivateStateIdentifier) if err != nil { return err } @@ -516,13 +520,14 @@ func (api *RetestethAPI) mineBlock() error { statedb.Prepare(tx.Hash(), common.Hash{}, txCount) snap := statedb.Snapshot() - receipt, err := core.ApplyTransaction( + receipt, _, err := core.ApplyTransaction( api.chainConfig, api.blockchain, &api.author, gasPool, - statedb, + statedb, pvtstdb, header, tx, &header.GasUsed, *api.blockchain.GetVMConfig(), + false, ) if err != nil { statedb.RevertToSnapshot(snap) @@ -660,13 +665,14 @@ func (api *RetestethAPI) AccountRange(ctx context.Context, var err error if parentHeader == nil || int(txIndex) >= len(block.Transactions()) { root = header.Root - statedb, err = api.blockchain.StateAt(root) + statedb, _, err = api.blockchain.StateAtPSI(root, types.DefaultPrivateStateIdentifier) if err != nil { return AccountRangeResult{}, err } } else { + var pvtst *state.StateDB root = parentHeader.Root - statedb, err = api.blockchain.StateAt(root) + statedb, pvtst, err = api.blockchain.StateAtPSI(root, types.DefaultPrivateStateIdentifier) if err != nil { return AccountRangeResult{}, err } @@ -677,7 +683,7 @@ func (api *RetestethAPI) AccountRange(ctx context.Context, msg, _ := tx.AsMessage(signer) context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil) // Not yet the searched for transaction, execute on top of the current state - vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{}) + vmenv := vm.NewEVM(context, statedb, pvtst, api.blockchain.Config(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { return AccountRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) } @@ -717,7 +723,7 @@ func (api *RetestethAPI) AccountRange(ctx context.Context, func (api *RetestethAPI) GetBalance(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (*math.HexOrDecimal256, error) { //fmt.Printf("GetBalance %x, block %d\n", address, blockNr) header := api.blockchain.GetHeaderByNumber(uint64(blockNr)) - statedb, err := api.blockchain.StateAt(header.Root) + statedb, _, err := api.blockchain.StateAt(header.Root) if err != nil { return nil, err } @@ -726,7 +732,7 @@ func (api *RetestethAPI) GetBalance(ctx context.Context, address common.Address, func (api *RetestethAPI) GetCode(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (hexutil.Bytes, error) { header := api.blockchain.GetHeaderByNumber(uint64(blockNr)) - statedb, err := api.blockchain.StateAt(header.Root) + statedb, _, err := api.blockchain.StateAt(header.Root) if err != nil { return nil, err } @@ -735,7 +741,7 @@ func (api *RetestethAPI) GetCode(ctx context.Context, address common.Address, bl func (api *RetestethAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr math.HexOrDecimal64) (uint64, error) { header := api.blockchain.GetHeaderByNumber(uint64(blockNr)) - statedb, err := api.blockchain.StateAt(header.Root) + statedb, _, err := api.blockchain.StateAt(header.Root) if err != nil { return 0, err } @@ -770,13 +776,14 @@ func (api *RetestethAPI) StorageRangeAt(ctx context.Context, var err error if parentHeader == nil || int(txIndex) >= len(block.Transactions()) { root = header.Root - statedb, err = api.blockchain.StateAt(root) + statedb, _, err = api.blockchain.StateAtPSI(root, types.DefaultPrivateStateIdentifier) if err != nil { return StorageRangeResult{}, err } } else { + var pvtstdb *state.StateDB root = parentHeader.Root - statedb, err = api.blockchain.StateAt(root) + statedb, pvtstdb, err = api.blockchain.StateAtPSI(root, types.DefaultPrivateStateIdentifier) if err != nil { return StorageRangeResult{}, err } @@ -787,7 +794,7 @@ func (api *RetestethAPI) StorageRangeAt(ctx context.Context, msg, _ := tx.AsMessage(signer) context := core.NewEVMContext(msg, block.Header(), api.blockchain, nil) // Not yet the searched for transaction, execute on top of the current state - vmenv := vm.NewEVM(context, statedb, api.blockchain.Config(), vm.Config{}) + vmenv := vm.NewEVM(context, statedb, pvtstdb, api.blockchain.Config(), vm.Config{}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { return StorageRangeResult{}, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) } @@ -905,7 +912,7 @@ func retesteth(ctx *cli.Context) error { IdleTimeout: 120 * time.Second, } httpEndpoint := fmt.Sprintf("%s:%d", ctx.GlobalString(utils.HTTPListenAddrFlag.Name), ctx.Int(rpcPortFlag.Name)) - httpServer, _, err := node.StartHTTPEndpoint(httpEndpoint, RetestethHTTPTimeouts, handler) + httpServer, _, _, err := node.StartHTTPEndpoint(httpEndpoint, RetestethHTTPTimeouts, handler, nil) if err != nil { utils.Fatalf("Could not start RPC api: %v", err) } diff --git a/cmd/geth/testdata/clique.json b/cmd/geth/testdata/clique.json index b54b4a7d3b..8d9021df77 100644 --- a/cmd/geth/testdata/clique.json +++ b/cmd/geth/testdata/clique.json @@ -11,7 +11,8 @@ "clique": { "period": 5, "epoch": 30000 - } + }, + "isQuorum": false }, "difficulty": "1", "gasLimit": "8000000", diff --git a/cmd/geth/testdata/geth/nodekey b/cmd/geth/testdata/geth/nodekey new file mode 100644 index 0000000000..c4380139cd --- /dev/null +++ b/cmd/geth/testdata/geth/nodekey @@ -0,0 +1 @@ +1be3b50b31734be48452c29d714941ba165ef0cbf3ccea8ca16c45e3d8d45fb0 \ No newline at end of file diff --git a/cmd/geth/testdata/geth/static-nodes.json b/cmd/geth/testdata/geth/static-nodes.json new file mode 100644 index 0000000000..65d46e9e8e --- /dev/null +++ b/cmd/geth/testdata/geth/static-nodes.json @@ -0,0 +1,3 @@ +[ + "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@127.0.0.1:21000?discport=0&raftport=50401" +] diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 5e004c42be..41c1e199bf 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -28,6 +28,11 @@ import ( cli "gopkg.in/urfave/cli.v1" ) +// Quorum +var quorumAccountFlagGroup = "QUORUM ACCOUNT" + +// End Quorum + // AppHelpFlagGroups is the application flags, grouped by functionality. var AppHelpFlagGroups = []flags.FlagGroup{ { @@ -149,6 +154,11 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag, + utils.RPCClientToken, + utils.RPCClientTLSInsecureSkipVerify, + utils.RPCClientTLSCert, + utils.RPCClientTLSCaCert, + utils.RPCClientTLSCipherSuites, }, }, { @@ -197,6 +207,8 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.VMEnableDebugFlag, utils.EVMInterpreterFlag, utils.EWASMInterpreterFlag, + // Quorum - timout for calls + utils.EVMCallTimeOutFlag, }, }, { @@ -233,6 +245,61 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.LegacyGraphQLPortFlag, }, debug.DeprecatedFlags...), }, + // QUORUM + { + Name: "QUORUM", + Flags: []cli.Flag{ + utils.QuorumImmutabilityThreshold, + utils.EnableNodePermissionFlag, + utils.PluginSettingsFlag, + utils.PluginSkipVerifyFlag, + utils.PluginLocalVerifyFlag, + utils.PluginPublicKeyFlag, + utils.AllowedFutureBlockTimeFlag, + utils.MultitenancyFlag, + }, + }, + { + Name: "QUORUM PRIVATE TRANSACTION MANAGER", + Flags: []cli.Flag{ + utils.QuorumPTMUnixSocketFlag, + utils.QuorumPTMUrlFlag, + utils.QuorumPTMTimeoutFlag, + utils.QuorumPTMDialTimeoutFlag, + utils.QuorumPTMHttpIdleTimeoutFlag, + utils.QuorumPTMHttpWriteBufferSizeFlag, + utils.QuorumPTMHttpReadBufferSizeFlag, + utils.QuorumPTMTlsModeFlag, + utils.QuorumPTMTlsRootCaFlag, + utils.QuorumPTMTlsClientCertFlag, + utils.QuorumPTMTlsClientKeyFlag, + utils.QuorumPTMTlsInsecureSkipVerify, + }, + }, + { + Name: quorumAccountFlagGroup, + Flags: []cli.Flag{ + utils.AccountPluginNewAccountConfigFlag, + }, + }, + { + Name: "RAFT", + Flags: []cli.Flag{ + utils.RaftModeFlag, + utils.RaftBlockTimeFlag, + utils.RaftJoinExistingFlag, + utils.RaftPortFlag, + utils.RaftDNSEnabledFlag, + }, + }, + { + Name: "ISTANBUL", + Flags: []cli.Flag{ + utils.IstanbulRequestTimeoutFlag, + utils.IstanbulBlockPeriodFlag, + }, + }, + // END QUORUM { Name: "MISC", Flags: []cli.Flag{ @@ -280,6 +347,14 @@ func init() { AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs] }() } + + // remove the Quorum account options from the main app usage as these should only be used by the geth account sub commands + for i, group := range AppHelpFlagGroups { + if group.Name == quorumAccountFlagGroup { + AppHelpFlagGroups = append(AppHelpFlagGroups[:i], AppHelpFlagGroups[i+1:]...) + } + } + // Render out custom usage screen originalHelpPrinter(w, tmpl, flags.HelpData{App: data, FlagGroups: AppHelpFlagGroups}) } else if tmpl == flags.CommandHelpTemplate { diff --git a/cmd/puppeth/genesis_test.go b/cmd/puppeth/genesis_test.go index aaa72d73cb..45937d06d3 100644 --- a/cmd/puppeth/genesis_test.go +++ b/cmd/puppeth/genesis_test.go @@ -30,6 +30,10 @@ import ( // Tests the go-ethereum to Aleth chainspec conversion for the Stureby testnet. func TestAlethSturebyConverter(t *testing.T) { + // //Quorum - skip this test as MinGasLimit and GasLimitBoundDivisor has been overridden for quorum + t.Skipf("skipping this test as MinGasLimit and GasLimitBoundDivisor has been overridden for quorum") + + // /Quorum blob, err := ioutil.ReadFile("testdata/stureby_geth.json") if err != nil { t.Fatalf("could not read file: %v", err) @@ -69,6 +73,10 @@ func TestAlethSturebyConverter(t *testing.T) { // Tests the go-ethereum to Parity chainspec conversion for the Stureby testnet. func TestParitySturebyConverter(t *testing.T) { + // //Quorum - skip this test as MinGasLimit and GasLimitBoundDivisor has been overridden for quorum + t.Skipf("skipping this test as MinGasLimit and GasLimitBoundDivisor has been overridden for quorum") + + // /Quorum blob, err := ioutil.ReadFile("testdata/stureby_geth.json") if err != nil { t.Fatalf("could not read file: %v", err) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e6382c1634..7fc270376d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -19,10 +19,12 @@ package utils import ( "crypto/ecdsa" + "encoding/json" "fmt" "io" "io/ioutil" "math/big" + "net/url" "os" "path/filepath" "strconv" @@ -35,9 +37,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" + http2 "github.com/ethereum/go-ethereum/common/http" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/istanbul" + istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/vm" @@ -47,6 +52,7 @@ import ( "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethstats" + "github.com/ethereum/go-ethereum/extension" "github.com/ethereum/go-ethereum/graphql" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/flags" @@ -63,8 +69,13 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/permission" + "github.com/ethereum/go-ethereum/permission/core/types" + "github.com/ethereum/go-ethereum/plugin" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/raft" pcsclite "github.com/gballet/go-libpcsclite" - cli "gopkg.in/urfave/cli.v1" + "gopkg.in/urfave/cli.v1" ) func init() { @@ -477,6 +488,27 @@ var ( Name: "nocompaction", Usage: "Disables db compaction after import", } + // RPC Client Settings + RPCClientToken = cli.StringFlag{ + Name: "rpcclitoken", + Usage: "RPC Client access token", + } + RPCClientTLSCert = cli.StringFlag{ + Name: "rpcclitls.cert", + Usage: "Server's TLS certificate PEM file on connection by client", + } + RPCClientTLSCaCert = cli.StringFlag{ + Name: "rpcclitls.cacert", + Usage: "CA certificate PEM file for provided server's TLS certificate on connection by client", + } + RPCClientTLSCipherSuites = cli.StringFlag{ + Name: "rpcclitls.ciphersuites", + Usage: "Customize supported cipher suites when using TLS connection. Value is a comma-separated cipher suite string", + } + RPCClientTLSInsecureSkipVerify = cli.BoolFlag{ + Name: "rpcclitls.insecureskipverify", + Usage: "Disable verification of server's TLS certificate on connection by client", + } // RPC settings IPCDisabledFlag = cli.BoolFlag{ Name: "ipcdisable", @@ -717,6 +749,154 @@ var ( Usage: "External EVM configuration (default = built-in interpreter)", Value: "", } + + // Quorum - added configurable call timeout for execution of calls + EVMCallTimeOutFlag = cli.IntFlag{ + Name: "vm.calltimeout", + Usage: "Timeout duration in seconds for message call execution without creating a transaction. Value 0 means no timeout.", + Value: 5, + } + + // Quorum + // immutability threshold which can be passed as a parameter at geth start + QuorumImmutabilityThreshold = cli.IntFlag{ + Name: "immutabilitythreshold", + Usage: "overrides the default immutability threshold for Quorum nodes. Its the threshold beyond which block data will be moved to ancient db", + Value: 3162240, + } + // Raft flags + RaftModeFlag = cli.BoolFlag{ + Name: "raft", + Usage: "If enabled, uses Raft instead of Quorum Chain for consensus", + } + RaftBlockTimeFlag = cli.IntFlag{ + Name: "raftblocktime", + Usage: "Amount of time between raft block creations in milliseconds", + Value: 50, + } + RaftJoinExistingFlag = cli.IntFlag{ + Name: "raftjoinexisting", + Usage: "The raft ID to assume when joining an pre-existing cluster", + Value: 0, + } + + EmitCheckpointsFlag = cli.BoolFlag{ + Name: "emitcheckpoints", + Usage: "If enabled, emit specially formatted logging checkpoints", + } + RaftPortFlag = cli.IntFlag{ + Name: "raftport", + Usage: "The port to bind for the raft transport", + Value: 50400, + } + RaftDNSEnabledFlag = cli.BoolFlag{ + Name: "raftdnsenable", + Usage: "Enable DNS resolution of peers", + } + + // Permission + EnableNodePermissionFlag = cli.BoolFlag{ + Name: "permissioned", + Usage: "If enabled, the node will allow only a defined list of nodes to connect", + } + AllowedFutureBlockTimeFlag = cli.Uint64Flag{ + Name: "allowedfutureblocktime", + Usage: "Max time (in seconds) from current time allowed for blocks, before they're considered future blocks", + Value: 0, + } + // Plugins settings + PluginSettingsFlag = cli.StringFlag{ + Name: "plugins", + Usage: "The URI of configuration which describes plugins being used. E.g.: file:///opt/geth/plugins.json", + } + PluginLocalVerifyFlag = cli.BoolFlag{ + Name: "plugins.localverify", + Usage: "If enabled, verify plugin integrity from local file system. This requires plugin signature file and PGP public key file to be available", + } + PluginPublicKeyFlag = cli.StringFlag{ + Name: "plugins.publickey", + Usage: fmt.Sprintf("The URI of PGP public key for local plugin verification. E.g.: file:///opt/geth/pubkey.pgp.asc. This flag is only valid if --%s is set (default = file:////%s)", PluginLocalVerifyFlag.Name, plugin.DefaultPublicKeyFile), + } + PluginSkipVerifyFlag = cli.BoolFlag{ + Name: "plugins.skipverify", + Usage: "If enabled, plugin integrity is NOT verified", + } + // account plugin flags + AccountPluginNewAccountConfigFlag = cli.StringFlag{ + Name: "plugins.account.config", + Usage: "Value will be passed to an account plugin if being used. See the account plugin implementation's documentation for further details", + } + // Istanbul settings + IstanbulRequestTimeoutFlag = cli.Uint64Flag{ + Name: "istanbul.requesttimeout", + Usage: "Timeout for each Istanbul round in milliseconds", + Value: eth.DefaultConfig.Istanbul.RequestTimeout, + } + IstanbulBlockPeriodFlag = cli.Uint64Flag{ + Name: "istanbul.blockperiod", + Usage: "Default minimum difference between two consecutive block's timestamps in seconds", + Value: eth.DefaultConfig.Istanbul.BlockPeriod, + } + // Multitenancy setting + MultitenancyFlag = cli.BoolFlag{ + Name: "multitenancy", + Usage: "Enable multitenancy support for this node. This requires RPC Security Plugin to also be configured.", + } + + // Quorum Private Transaction Manager connection options + QuorumPTMUnixSocketFlag = DirectoryFlag{ + Name: "ptm.socket", + Usage: "Path to the ipc file when using unix domain socket for the private transaction manager connection", + } + QuorumPTMUrlFlag = cli.StringFlag{ + Name: "ptm.url", + Usage: "URL when using http connection to private transaction manager", + } + QuorumPTMTimeoutFlag = cli.UintFlag{ + Name: "ptm.timeout", + Usage: "Timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", + Value: http2.DefaultConfig.Timeout, + } + QuorumPTMDialTimeoutFlag = cli.UintFlag{ + Name: "ptm.dialtimeout", + Usage: "Dial timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", + Value: http2.DefaultConfig.DialTimeout, + } + QuorumPTMHttpIdleTimeoutFlag = cli.UintFlag{ + Name: "ptm.http.idletimeout", + Usage: "Idle timeout (seconds) for the private transaction manager connection. Zero value means timeout disabled.", + Value: http2.DefaultConfig.HttpIdleConnTimeout, + } + QuorumPTMHttpWriteBufferSizeFlag = cli.IntFlag{ + Name: "ptm.http.writebuffersize", + Usage: "Size of the write buffer (bytes) for the private transaction manager connection. Zero value uses http.Transport default.", + Value: 0, + } + QuorumPTMHttpReadBufferSizeFlag = cli.IntFlag{ + Name: "ptm.http.readbuffersize", + Usage: "Size of the read buffer (bytes) for the private transaction manager connection. Zero value uses http.Transport default.", + Value: 0, + } + QuorumPTMTlsModeFlag = cli.StringFlag{ + Name: "ptm.tls.mode", + Usage: `If "off" then TLS disabled (default). If "strict" then will use TLS for http connection to private transaction manager`, + } + QuorumPTMTlsRootCaFlag = DirectoryFlag{ + Name: "ptm.tls.rootca", + Usage: "Path to file containing root CA certificate for TLS connection to private transaction manager (defaults to host's certificates)", + } + QuorumPTMTlsClientCertFlag = DirectoryFlag{ + Name: "ptm.tls.clientcert", + Usage: "Path to file containing client certificate (or chain of certs) for TLS connection to private transaction manager", + } + QuorumPTMTlsClientKeyFlag = DirectoryFlag{ + Name: "ptm.tls.clientkey", + Usage: "Path to file containing client's private key for TLS connection to private transaction manager", + } + QuorumPTMTlsInsecureSkipVerify = cli.BoolFlag{ + Name: "ptm.tls.insecureskipverify", + Usage: "Disable verification of server's TLS certificate on connection to private transaction manager", + } ) // MakeDataDir retrieves the currently requested data directory, terminating @@ -1129,7 +1309,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { setBootstrapNodesV5(ctx, cfg) lightClient := ctx.GlobalString(SyncModeFlag.Name) == "light" - lightServer := (ctx.GlobalInt(LegacyLightServFlag.Name) != 0 || ctx.GlobalInt(LightServeFlag.Name) != 0) + lightServer := ctx.GlobalInt(LegacyLightServFlag.Name) != 0 || ctx.GlobalInt(LightServeFlag.Name) != 0 lightPeers := ctx.GlobalInt(LegacyLightPeersFlag.Name) if ctx.GlobalIsSet(LightMaxPeersFlag.Name) { @@ -1223,6 +1403,14 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) { cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name) } + + // Quorum + if ctx.GlobalIsSet(EnableNodePermissionFlag.Name) { + cfg.EnableNodePermission = ctx.GlobalBool(EnableNodePermissionFlag.Name) + } + if ctx.GlobalIsSet(MultitenancyFlag.Name) { + cfg.EnableMultitenancy = ctx.GlobalBool(MultitenancyFlag.Name) + } } func setSmartCard(ctx *cli.Context, cfg *node.Config) { @@ -1268,6 +1456,51 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) { case ctx.GlobalBool(YoloV1Flag.Name) && cfg.DataDir == node.DefaultDataDir(): cfg.DataDir = filepath.Join(node.DefaultDataDir(), "yolo-v1") } + if err := SetPlugins(ctx, cfg); err != nil { + Fatalf(err.Error()) + } +} + +// Quorum +// +// Read plugin settings from --plugins flag. Overwrite settings defined in --config if any +func SetPlugins(ctx *cli.Context, cfg *node.Config) error { + if ctx.GlobalIsSet(PluginSettingsFlag.Name) { + // validate flag combination + if ctx.GlobalBool(PluginSkipVerifyFlag.Name) && ctx.GlobalBool(PluginLocalVerifyFlag.Name) { + return fmt.Errorf("only --%s or --%s must be set", PluginSkipVerifyFlag.Name, PluginLocalVerifyFlag.Name) + } + if !ctx.GlobalBool(PluginLocalVerifyFlag.Name) && ctx.GlobalIsSet(PluginPublicKeyFlag.Name) { + return fmt.Errorf("--%s is required for setting --%s", PluginLocalVerifyFlag.Name, PluginPublicKeyFlag.Name) + } + pluginSettingsURL, err := url.Parse(ctx.GlobalString(PluginSettingsFlag.Name)) + if err != nil { + return fmt.Errorf("plugins: Invalid URL for --%s due to %s", PluginSettingsFlag.Name, err) + } + var pluginSettings plugin.Settings + r, err := urlReader(pluginSettingsURL) + if err != nil { + return fmt.Errorf("plugins: unable to create reader due to %s", err) + } + defer func() { + _ = r.Close() + }() + if err := json.NewDecoder(r).Decode(&pluginSettings); err != nil { + return fmt.Errorf("plugins: unable to parse settings due to %s", err) + } + pluginSettings.SetDefaults() + cfg.Plugins = &pluginSettings + } + return nil +} + +func urlReader(u *url.URL) (io.ReadCloser, error) { + s := u.Scheme + switch s { + case "file": + return os.Open(filepath.Join(u.Host, u.Path)) + } + return nil, fmt.Errorf("unsupported scheme %s", s) } func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { @@ -1397,6 +1630,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) { if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) { cfg.Noverify = ctx.GlobalBool(MinerNoVerfiyFlag.Name) } + if ctx.GlobalIsSet(AllowedFutureBlockTimeFlag.Name) { + cfg.AllowedFutureBlockTime = ctx.GlobalUint64(AllowedFutureBlockTimeFlag.Name) //Quorum + } } func setWhitelist(ctx *cli.Context, cfg *eth.Config) { @@ -1422,6 +1658,27 @@ func setWhitelist(ctx *cli.Context, cfg *eth.Config) { } } +// Quorum +func setIstanbul(ctx *cli.Context, cfg *eth.Config) { + if ctx.GlobalIsSet(IstanbulRequestTimeoutFlag.Name) { + cfg.Istanbul.RequestTimeout = ctx.GlobalUint64(IstanbulRequestTimeoutFlag.Name) + } + if ctx.GlobalIsSet(IstanbulBlockPeriodFlag.Name) { + cfg.Istanbul.BlockPeriod = ctx.GlobalUint64(IstanbulBlockPeriodFlag.Name) + } +} + +func setRaft(ctx *cli.Context, cfg *eth.Config) { + cfg.RaftMode = ctx.GlobalBool(RaftModeFlag.Name) +} + +func setQuorumConfig(ctx *cli.Context, cfg *eth.Config) { + cfg.EVMCallTimeOut = time.Duration(ctx.GlobalInt(EVMCallTimeOutFlag.Name)) * time.Second + cfg.EnableMultitenancy = ctx.GlobalBool(MultitenancyFlag.Name) + setIstanbul(ctx, cfg) + setRaft(ctx, cfg) +} + // CheckExclusive verifies that only a single instance of the provided flags was // set by the user. Each flag might optionally be followed by a string type to // specialize it further. @@ -1496,6 +1753,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { setWhitelist(ctx, cfg) setLes(ctx, cfg) + // Quorum + setQuorumConfig(ctx, cfg) + if ctx.GlobalIsSet(SyncModeFlag.Name) { cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode) } @@ -1576,6 +1836,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { } } + // set immutability threshold in config + params.SetQuorumImmutabilityThreshold(ctx.GlobalInt(QuorumImmutabilityThreshold.Name)) + // Override any default configs for hard coded networks. switch { case ctx.GlobalBool(LegacyTestnetFlag.Name) || ctx.GlobalBool(RopstenFlag.Name): @@ -1671,13 +1934,14 @@ func setDNSDiscoveryDefaults(cfg *eth.Config, genesis common.Hash) { } // RegisterEthService adds an Ethereum client to the stack. -func RegisterEthService(stack *node.Node, cfg *eth.Config) ethapi.Backend { +// Quorum => returns also the ethereum service which is used by the raft service +func RegisterEthService(stack *node.Node, cfg *eth.Config) (ethapi.Backend, *eth.Ethereum) { if cfg.SyncMode == downloader.LightSync { backend, err := les.New(stack, cfg) if err != nil { Fatalf("Failed to register the Ethereum service: %v", err) } - return backend.ApiBackend + return backend.ApiBackend, nil } else { backend, err := eth.New(stack, cfg) if err != nil { @@ -1689,7 +1953,7 @@ func RegisterEthService(stack *node.Node, cfg *eth.Config) ethapi.Backend { Fatalf("Failed to create the LES server: %v", err) } } - return backend.APIBackend + return backend.APIBackend, backend } } @@ -1708,6 +1972,95 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, cfg node.C } } +// Quorum +// +// Register plugin manager as a service in geth +func RegisterPluginService(stack *node.Node, cfg *node.Config, skipVerify bool, localVerify bool, publicKey string) { + // ricardolyn: I can't adapt this Plugin Service construction to the new approach as there are circular dependencies between Node and Plugin + if err := cfg.ResolvePluginBaseDir(); err != nil { + Fatalf("plugins: unable to resolve plugin base dir due to %s", err) + } + pluginManager, err := plugin.NewPluginManager(cfg.UserIdent, cfg.Plugins, skipVerify, localVerify, publicKey) + if err != nil { + Fatalf("plugins: Failed to register the Plugins service: %v", err) + } + stack.SetPluginManager(pluginManager) + stack.RegisterAPIs(pluginManager.APIs()) + stack.RegisterLifecycle(pluginManager) + log.Info("plugin service registered") +} + +// Configure smart-contract-based permissioning service +func RegisterPermissionService(stack *node.Node, useDns bool) { + permissionConfig, err := types.ParsePermissionConfig(stack.DataDir()) + if err != nil { + Fatalf("loading of %s failed due to %v", params.PERMISSION_MODEL_CONFIG, err) + } + // start the permissions management service + _, err = permission.NewQuorumPermissionCtrl(stack, &permissionConfig, useDns) + if err != nil { + Fatalf("failed to load the permission contracts as given in %s due to %v", params.PERMISSION_MODEL_CONFIG, err) + } + log.Info("permission service registered") +} + +func RegisterRaftService(stack *node.Node, ctx *cli.Context, nodeCfg *node.Config, ethService *eth.Ethereum) { + blockTimeMillis := ctx.GlobalInt(RaftBlockTimeFlag.Name) + datadir := ctx.GlobalString(DataDirFlag.Name) + joinExistingId := ctx.GlobalInt(RaftJoinExistingFlag.Name) + useDns := ctx.GlobalBool(RaftDNSEnabledFlag.Name) + raftPort := uint16(ctx.GlobalInt(RaftPortFlag.Name)) + + privkey := nodeCfg.NodeKey() + strId := enode.PubkeyToIDV4(&privkey.PublicKey).String() + blockTimeNanos := time.Duration(blockTimeMillis) * time.Millisecond + peers := nodeCfg.StaticNodes() + + var myId uint16 + var joinExisting bool + + if joinExistingId > 0 { + myId = uint16(joinExistingId) + joinExisting = true + } else if len(peers) == 0 { + Fatalf("Raft-based consensus requires either (1) an initial peers list (in static-nodes.json) including this enode hash (%v), or (2) the flag --raftjoinexisting RAFT_ID, where RAFT_ID has been issued by an existing cluster member calling `raft.addPeer(ENODE_ID)` with an enode ID containing this node's enode hash.", strId) + } else { + peerIds := make([]string, len(peers)) + + for peerIdx, peer := range peers { + if !peer.HasRaftPort() { + Fatalf("raftport querystring parameter not specified in static-node enode ID: %v. please check your static-nodes.json file.", peer.String()) + } + + peerId := peer.ID().String() + peerIds[peerIdx] = peerId + if peerId == strId { + myId = uint16(peerIdx) + 1 + } + } + + if myId == 0 { + Fatalf("failed to find local enode ID (%v) amongst peer IDs: %v", strId, peerIds) + } + } + + _, err := raft.New(stack, ethService.BlockChain().Config(), myId, raftPort, joinExisting, blockTimeNanos, ethService, peers, datadir, useDns) + if err != nil { + Fatalf("raft: Failed to register the Raft service: %v", err) + } + + log.Info("raft service registered") +} + +func RegisterExtensionService(stack *node.Node, ethService *eth.Ethereum) { + _, err := extension.NewServicesFactory(stack, private.P, ethService) + if err != nil { + Fatalf("Failed to register the Extension service: %v", err) + } + + log.Info("extension service registered") +} + func SetupMetrics(ctx *cli.Context) { if metrics.Enabled { log.Info("Enabling metrics collection") @@ -1793,16 +2146,41 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis { } // MakeChain creates a chain manager from set command line flags. -func MakeChain(ctx *cli.Context, stack *node.Node, readOnly bool) (chain *core.BlockChain, chainDb ethdb.Database) { - var err error +func MakeChain(ctx *cli.Context, stack *node.Node, readOnly bool, useExist bool) (chain *core.BlockChain, chainDb ethdb.Database) { + var ( + config *params.ChainConfig + err error + ) chainDb = MakeChainDatabase(ctx, stack) - config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx)) - if err != nil { - Fatalf("%v", err) + + if useExist { + stored := rawdb.ReadCanonicalHash(chainDb, 0) + if (stored == common.Hash{}) { + Fatalf("No existing genesis") + } + config = rawdb.ReadChainConfig(chainDb, stored) + } else { + config, _, err = core.SetupGenesisBlock(chainDb, MakeGenesis(ctx)) + if err != nil { + Fatalf("%v", err) + } } + var engine consensus.Engine if config.Clique != nil { engine = clique.New(config.Clique, chainDb) + } else if config.Istanbul != nil { + // for IBFT + istanbulConfig := istanbul.DefaultConfig + if config.Istanbul.Epoch != 0 { + istanbulConfig.Epoch = config.Istanbul.Epoch + } + istanbulConfig.ProposerPolicy = istanbul.ProposerPolicy(config.Istanbul.ProposerPolicy) + istanbulConfig.Ceil2Nby3Block = config.Istanbul.Ceil2Nby3Block + engine = istanbulBackend.New(istanbulConfig, stack.GetNodeKey(), chainDb) + } else if config.IsQuorum { + // for Raft + engine = ethash.NewFullFaker() } else { engine = ethash.NewFaker() if !ctx.GlobalBool(FakePoWFlag.Name) { @@ -1844,6 +2222,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readOnly bool) (chain *core.B l := ctx.GlobalUint64(TxLookupLimitFlag.Name) limit = &l } + // TODO should multiple private states work with import/export/inspect commands chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, limit) if err != nil { Fatalf("Can't create BlockChain: %v", err) diff --git a/cmd/utils/flags_test.go b/cmd/utils/flags_test.go index adfdd0903e..15ff4313ff 100644 --- a/cmd/utils/flags_test.go +++ b/cmd/utils/flags_test.go @@ -18,10 +18,103 @@ package utils import ( + "flag" + "io/ioutil" + "os" + "path" "reflect" + "strconv" "testing" + + "github.com/ethereum/go-ethereum/node" + "github.com/stretchr/testify/assert" + "gopkg.in/urfave/cli.v1" ) +func TestSetPlugins_whenPluginsNotEnabled(t *testing.T) { + arbitraryNodeConfig := &node.Config{} + arbitraryCLIContext := cli.NewContext(nil, &flag.FlagSet{}, nil) + + assert.NoError(t, SetPlugins(arbitraryCLIContext, arbitraryNodeConfig)) + + assert.Nil(t, arbitraryNodeConfig.Plugins) +} + +func TestSetPlugins_whenInvalidFlagsCombination(t *testing.T) { + arbitraryNodeConfig := &node.Config{} + fs := &flag.FlagSet{} + fs.String(PluginSettingsFlag.Name, "", "") + fs.Bool(PluginSkipVerifyFlag.Name, true, "") + fs.Bool(PluginLocalVerifyFlag.Name, true, "") + fs.String(PluginPublicKeyFlag.Name, "", "") + arbitraryCLIContext := cli.NewContext(nil, fs, nil) + assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSettingsFlag.Name, "arbitrary value")) + + verifyErrorMessage(t, arbitraryCLIContext, arbitraryNodeConfig, "only --plugins.skipverify or --plugins.localverify must be set") + + assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSkipVerifyFlag.Name, "false")) + assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginLocalVerifyFlag.Name, "false")) + assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginPublicKeyFlag.Name, "arbitry value")) + + verifyErrorMessage(t, arbitraryCLIContext, arbitraryNodeConfig, "--plugins.localverify is required for setting --plugins.publickey") +} + +func TestSetPlugins_whenInvalidPluginSettingsURL(t *testing.T) { + arbitraryNodeConfig := &node.Config{} + fs := &flag.FlagSet{} + fs.String(PluginSettingsFlag.Name, "", "") + arbitraryCLIContext := cli.NewContext(nil, fs, nil) + assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSettingsFlag.Name, "arbitrary value")) + + verifyErrorMessage(t, arbitraryCLIContext, arbitraryNodeConfig, "plugins: unable to create reader due to unsupported scheme ") +} + +func TestSetImmutabilityThreshold(t *testing.T) { + fs := &flag.FlagSet{} + fs.Int(QuorumImmutabilityThreshold.Name, 0, "") + arbitraryCLIContext := cli.NewContext(nil, fs, nil) + assert.NoError(t, arbitraryCLIContext.GlobalSet(QuorumImmutabilityThreshold.Name, strconv.Itoa(100000))) + assert.True(t, arbitraryCLIContext.GlobalIsSet(QuorumImmutabilityThreshold.Name), "immutability threshold flag not set") + assert.Equal(t, 100000, arbitraryCLIContext.GlobalInt(QuorumImmutabilityThreshold.Name), "immutability threshold value not set") +} + +func TestSetTimeOutForCall(t *testing.T) { + fs := &flag.FlagSet{} + fs.Int(EVMCallTimeOutFlag.Name, 0, "") + arbitraryCLIContext := cli.NewContext(nil, fs, nil) + assert.NoError(t, arbitraryCLIContext.GlobalSet(EVMCallTimeOutFlag.Name, strconv.Itoa(10))) + assert.True(t, arbitraryCLIContext.GlobalIsSet(EVMCallTimeOutFlag.Name), "timeoutforcall flag not set") + assert.Equal(t, 10, arbitraryCLIContext.GlobalInt(EVMCallTimeOutFlag.Name), "timeoutforcall value not set") +} + +func TestSetPlugins_whenTypical(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "q-") + if err != nil { + t.Fatal(err) + } + defer func() { + _ = os.RemoveAll(tmpDir) + }() + arbitraryJSONFile := path.Join(tmpDir, "arbitary.json") + if err := ioutil.WriteFile(arbitraryJSONFile, []byte("{}"), 0644); err != nil { + t.Fatal(err) + } + arbitraryNodeConfig := &node.Config{} + fs := &flag.FlagSet{} + fs.String(PluginSettingsFlag.Name, "", "") + arbitraryCLIContext := cli.NewContext(nil, fs, nil) + assert.NoError(t, arbitraryCLIContext.GlobalSet(PluginSettingsFlag.Name, "file://"+arbitraryJSONFile)) + + assert.NoError(t, SetPlugins(arbitraryCLIContext, arbitraryNodeConfig)) + + assert.NotNil(t, arbitraryNodeConfig.Plugins) +} + +func verifyErrorMessage(t *testing.T, ctx *cli.Context, cfg *node.Config, expectedMsg string) { + err := SetPlugins(ctx, cfg) + assert.EqualError(t, err, expectedMsg) +} + func Test_SplitTagsFlag(t *testing.T) { tests := []struct { name string diff --git a/common/http/certificate.go b/common/http/certificate.go new file mode 100644 index 0000000000..7a9bd9c36f --- /dev/null +++ b/common/http/certificate.go @@ -0,0 +1,61 @@ +package http + +import ( + "crypto/x509" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/ethereum/go-ethereum/log" +) + +// Load Root CA certificate(s). +// Path can be a single certificate file, or a comma separated list containing a combination of +// certificate files or directories containing certificate files. +func loadRootCaCerts(rootCAPath string) (*x509.CertPool, error) { + rootCAPool, err := x509.SystemCertPool() + if err != nil { + rootCAPool = x509.NewCertPool() + } + if len(rootCAPath) == 0 { + return rootCAPool, nil + } + + list := strings.Split(rootCAPath, ",") + for _, thisFileOrDirEntry := range list { + info, err := os.Lstat(thisFileOrDirEntry) + if err != nil { + return nil, fmt.Errorf("unable to check whether RootCA entry '%v' is a file or directory, due to: %s", thisFileOrDirEntry, err) + } + + if info.Mode()&os.ModeDir != 0 { + fileList, err := ioutil.ReadDir(thisFileOrDirEntry) + if err != nil { + return nil, fmt.Errorf("unable to read contents of RootCA directory '%v', due to: %s", thisFileOrDirEntry, err) + } + + for _, fileinfo := range fileList { + if err := loadRootCAFromFile(thisFileOrDirEntry+"/"+fileinfo.Name(), rootCAPool); err != nil { + return nil, err + } + } + } else if err := loadRootCAFromFile(thisFileOrDirEntry, rootCAPool); err != nil { + return nil, err + } + } + + return rootCAPool, nil +} + +func loadRootCAFromFile(file string, roots *x509.CertPool) error { + log.Debug("loading RootCA certificate for connection to private transaction manager", "file", file) + data, err := ioutil.ReadFile(file) + if err != nil { + return fmt.Errorf("unable to read contents of RootCA certificate file '%v', due to: %s", file, err) + } + if !roots.AppendCertsFromPEM(data) { + return fmt.Errorf("failed to add TlsRootCA certificate to pool, check that '%v' contains a valid RootCA certificate", file) + } + return nil +} diff --git a/common/http/client.go b/common/http/client.go new file mode 100644 index 0000000000..3de525ef9f --- /dev/null +++ b/common/http/client.go @@ -0,0 +1,49 @@ +package http + +import ( + "fmt" + "net/http" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private/engine" +) + +func CreateClient(cfg Config) (*engine.Client, error) { + var client *engine.Client + if IsSocketConfigured(cfg) { + + log.Info("Connecting to private tx manager using IPC socket") + client = &engine.Client{ + HttpClient: &http.Client{ + Transport: unixTransport(cfg), + }, + BaseURL: "http+unix://c", + } + + } else { + + transport := httpTransport(cfg) + if cfg.TlsMode == TlsOff { + log.Info("Connecting to private tx manager using HTTP") + } else { + log.Info("Connecting to private tx manager using HTTPS") + tlsConfig, err := newTLSConfig(cfg) + if err != nil { + return nil, fmt.Errorf("unable to create http.client to private tx manager due to: %s", err) + } + transport.TLSClientConfig = tlsConfig + } + + client = &engine.Client{ + HttpClient: &http.Client{ + Timeout: time.Duration(cfg.Timeout) * time.Second, + Transport: transport, + }, + BaseURL: cfg.HttpUrl, + } + + } + + return client, nil +} diff --git a/common/http/config.go b/common/http/config.go new file mode 100644 index 0000000000..1eb22a783a --- /dev/null +++ b/common/http/config.go @@ -0,0 +1,206 @@ +package http + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/BurntSushi/toml" +) + +const ( + NoConnection string = "none" + UnixDomainSocketConnection string = "unix" + HttpConnection string = "http" +) + +const ( + TlsOff string = "off" + TlsStrict string = "strict" +) + +type Config struct { + ConnectionType string `toml:"-"` // connection type is not loaded from toml + Socket string // filename for unix domain socket + WorkDir string // directory for unix domain socket + HttpUrl string // transaction manager URL for HTTP connection + Timeout uint // timeout for overall client call (seconds), zero means timeout disabled + DialTimeout uint // timeout for connecting to unix socket (seconds) + HttpIdleConnTimeout uint // timeout for idle http connection (seconds), zero means timeout disabled + HttpWriteBufferSize int // size of http connection write buffer (bytes), if zero then uses http.Transport default + HttpReadBufferSize int // size of http connection read buffer (bytes), if zero then uses http.Transport default + TlsMode string // whether TLS is enabled on HTTP connection (can be "off" or "strict") + TlsRootCA string // path to file containing certificate for root CA (defaults to host's certificates) + TlsClientCert string // path to file containing client certificate (or chain of certs) + TlsClientKey string // path to file containing client's private key + TlsInsecureSkipVerify bool // if true then does not verify that server certificate is CA signed +} + +var NoConnectionConfig = Config{ + ConnectionType: NoConnection, + TlsMode: TlsOff, +} + +var DefaultConfig = Config{ + Timeout: 5, + DialTimeout: 1, + HttpIdleConnTimeout: 10, + TlsMode: TlsOff, +} + +func IsSocketConfigured(cfg Config) bool { + return cfg.ConnectionType == UnixDomainSocketConnection +} + +// This will accept path as any of the following and return relevant configuration: +// - path set to "ignore" +// - path to an ipc file +// - path to a config file +func FetchConfigOrIgnore(path string) (Config, error) { + if path == "" || strings.EqualFold(path, "ignore") { + return NoConnectionConfig, nil + } + + return FetchConfig(path) +} + +// FetchConfig sets up the configuration for the connection to a txn manager. +// It will accept a path to an ipc file or a path to a config file, +// and returns the full configuration info for the specified type of connection. +func FetchConfig(path string) (Config, error) { + info, err := os.Lstat(path) + if err != nil { + return Config{}, fmt.Errorf("unable to check whether connection details are specified as a config file or ipc file '%s', due to: %s", path, err) + } + + var cfg Config + isSocket := info.Mode()&os.ModeSocket != 0 + if isSocket { + cfg = DefaultConfig + cfg.ConnectionType = UnixDomainSocketConnection + cfg.WorkDir, cfg.Socket = filepath.Split(path) + } else { + cfg, err = LoadConfigFile(path) + if err != nil { + return Config{}, fmt.Errorf("error reading config from '%s' due to: %s", path, err) + } + } + + return cfg, nil +} + +func LoadConfigFile(path string) (Config, error) { + cfg := DefaultConfig + if _, err := toml.DecodeFile(path, &cfg); err != nil { + return Config{}, err + } + cfg.TlsMode = strings.ToLower(cfg.TlsMode) + + if cfg.Socket != "" { + cfg.ConnectionType = UnixDomainSocketConnection + } else if cfg.HttpUrl != "" { + cfg.ConnectionType = HttpConnection + } else { + return Config{}, fmt.Errorf("either Socket or HTTP connection must be specified in config file") + } + + return cfg, nil +} + +func (cfg *Config) Validate() error { + switch cfg.ConnectionType { + case "": // no connection type defined + case NoConnection: + case UnixDomainSocketConnection: + if len(cfg.Socket) == 0 { //sanity check - should never occur + return fmt.Errorf("ipc file configuration is missing for private transaction manager connection") + } + if len(cfg.HttpUrl) != 0 { + return fmt.Errorf("HTTP URL and unix ipc file cannot both be specified for private transaction manager connection") + } + if cfg.TlsMode != TlsOff { + return fmt.Errorf("TLS is not supported over unix domain socket for private transaction manager connection") + } + case HttpConnection: + if len(cfg.Socket) != 0 { + return fmt.Errorf("HTTP URL and unix ipc file cannot both be specified for private transaction manager connection") + } + if len(cfg.HttpUrl) == 0 { //sanity check - should never occur + return fmt.Errorf("URL configuration is missing for private transaction manager HTTP connection") + } + switch cfg.TlsMode { + case TlsOff: + //no action needed + case TlsStrict: + if !strings.Contains(strings.ToLower(cfg.HttpUrl), "https") { + return fmt.Errorf("connection is configured with TLS but HTTPS url is not specified") + } + if (len(cfg.TlsClientCert) == 0 && len(cfg.TlsClientKey) != 0) || (len(cfg.TlsClientCert) != 0 && len(cfg.TlsClientKey) == 0) { + return fmt.Errorf("invalid details for HTTP connection with TLS, configuration must specify both clientCert and clientKey, or neither one") + } + default: + return fmt.Errorf("invalid value for TLS mode in config file, must be either OFF or STRICT") + } + } + + return nil +} + +// +// Setters for the various config fields +// + +func (cfg *Config) SetSocket(socketPath string) { + cfg.ConnectionType = UnixDomainSocketConnection + workDir, socketFilename := filepath.Split(socketPath) + if workDir != "" { + cfg.WorkDir = workDir + } + cfg.Socket = socketFilename +} + +func (cfg *Config) SetHttpUrl(httpUrl string) { + cfg.ConnectionType = HttpConnection + cfg.HttpUrl = httpUrl +} + +func (cfg *Config) SetTimeout(timeout uint) { + cfg.Timeout = timeout +} + +func (cfg *Config) SetDialTimeout(dialTimeout uint) { + cfg.DialTimeout = dialTimeout +} + +func (cfg *Config) SetHttpIdleConnTimeout(httpIdleConnTimeout uint) { + cfg.HttpIdleConnTimeout = httpIdleConnTimeout +} + +func (cfg *Config) SetHttpWriteBufferSize(httpWriteBufferSize int) { + cfg.HttpWriteBufferSize = httpWriteBufferSize +} + +func (cfg *Config) SetHttpReadBufferSize(httpReadBufferSize int) { + cfg.HttpReadBufferSize = httpReadBufferSize +} + +func (cfg *Config) SetTlsMode(tlsMode string) { + cfg.TlsMode = tlsMode +} + +func (cfg *Config) SetTlsRootCA(tlsRootCA string) { + cfg.TlsRootCA = tlsRootCA +} + +func (cfg *Config) SetTlsClientCert(tlsClientCert string) { + cfg.TlsClientCert = tlsClientCert +} + +func (cfg *Config) SetTlsClientKey(tlsClientKey string) { + cfg.TlsClientKey = tlsClientKey +} + +func (cfg *Config) SetTlsInsecureSkipVerify(tlsInsecureSkipVerify bool) { + cfg.TlsInsecureSkipVerify = tlsInsecureSkipVerify +} diff --git a/common/http/config_test.go b/common/http/config_test.go new file mode 100644 index 0000000000..86fbf1e777 --- /dev/null +++ b/common/http/config_test.go @@ -0,0 +1,342 @@ +package http + +import ( + "io/ioutil" + "net" + "os" + "path/filepath" + "runtime" + "syscall" + "testing" + + "github.com/stretchr/testify/assert" +) + +var socketConfigFileWithTimeouts = ` +socket = "tm.ipc" +workdir = "qdata/c1" +dialTimeout = 8 +timeout = 9 +` +var socketConfigFileNoTimeouts = ` +socket = "tm.ipc" +workdir = "qdata/c1" +` +var httpConfigFileWithTimeouts = ` +httpUrl = "http:localhost:9101" +tlsMode = "OFF" +timeout = 101 +httpIdleConnTimeout = 102 +httpWriteBufferSize = 1001 +httpReadBufferSize = 1002 +` +var httpConfigFileWithInvalidTlsMode = ` +httpUrl = "http:localhost:9101" +tlsMode = "ABC" +` +var httpTlsConfigFileWithTimeouts = ` +httpUrl = "https:localhost:9101" +tlsMode = "STRICT" +tlsRootCA = "mydir/rootca.cert.pem" +tlsClientCert = "mydir/client.cert.pem" +tlsClientKey = "mydir/client.key.pem" +timeout = 101 +httpIdleConnTimeout = 102 +httpWriteBufferSize = 1001 +httpReadBufferSize = 1002 +` +var httpTlsConfigFileNoTimeouts = ` +httpUrl = "https:localhost:9101" +tlsMode = "strict" +tlsRootCA = "mydir/rootca.cert.pem" +tlsClientCert = "mydir/client.cert.pem" +tlsClientKey = "mydir/client.key.pem" +tlsInsecureSkipVerify = true +` +var httpTlsConfigFileNoRootCert = ` +httpUrl = "https:localhost:9101" +tlsMode = "STRICT" +tlsClientCert = "mydir/client.cert.pem" +tlsClientKey = "mydir/client.key.pem" +` +var invalidHttpTlsConfigFileNoClientCert = ` +httpUrl = "https:localhost:9101" +tlsMode = "STRICT" +tlsRootCA = "mydir/rootca.cert.pem" +` +var invalidHttpTlsConfigFileOnlyClientCert = ` +httpUrl = "https:localhost:9101" +tlsMode = "STRICT" +tlsRootCA = "mydir/rootca.cert.pem" +tlsClientCert = "mydir/client.cert.pem" +` +var invalidHttpTlsConfigFileOnlyClientKey = ` +httpUrl = "https:localhost:9101" +tlsMode = "STRICT" +tlsRootCA = "mydir/rootca.cert.pem" +tlsClientKey = "mydir/client.key.pem" +` +var httpTlsConfigFileWithHTTPOnly = ` +httpUrl = "http:localhost:9101" +tlsMode = "strict" +tlsRootCA = "mydir/rootca.cert.pem" +tlsClientCert = "mydir/client.cert.pem" +tlsClientKey = "mydir/client.key.pem" +` +var invalidConfigWithSocketAndHttp = ` +socket = "tm.ipc" +workdir = "qdata/c1" +httpUrl = "http:localhost:9101" +` +var invalidConfigWithNoSocketOrHttp = ` +` + +func TestDefaultTimeoutsUsedWhenNoConfigFileSpecified(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("this test case is not supported for windows") + } + + socketFile := filepath.Join(os.TempDir(), "socket-file.ipc") + syscall.Unlink(socketFile) + l, err := net.Listen("unix", socketFile) + if err != nil { + t.Fatalf("Could not create socket file '%v' for unit test, error: %v", socketFile, err) + } + defer l.Close() + + cfg, err := FetchConfig(socketFile) + if assert.NoError(t, err, "Failed to retrieve socket configuration") { + assert.True(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned false, when expecting true") + assert.Equal(t, socketFile, filepath.Join(cfg.WorkDir, cfg.Socket), "Socket path unexpectedly changed when loading default config") + assert.Equal(t, DefaultConfig.DialTimeout, cfg.DialTimeout, "Did not get expected socket default DialTimeout") + assert.Equal(t, DefaultConfig.Timeout, cfg.Timeout, "Did not get expected socket default Timeout") + } + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestLoadSocketConfigWithTimeouts(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "socketConfigFileWithTimeouts.toml") + if err := ioutil.WriteFile(configFile, []byte(socketConfigFileWithTimeouts), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + if assert.NoError(t, err, "Failed to load config file") { + assert.True(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned false, when expecting true") + assert.Equal(t, "qdata/c1/tm.ipc", filepath.Join(cfg.WorkDir, cfg.Socket), "Did not get expected socket path from config file") + assert.Equal(t, uint(8), cfg.DialTimeout, "Did not get expected socket DialTimeout from config file") + assert.Equal(t, uint(9), cfg.Timeout, "Did not get expected socket Timeout from config file") + } + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestLoadSocketConfigWithDefaultTimeouts(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "socketConfigFileNoTimeouts.toml") + if err := ioutil.WriteFile(configFile, []byte(socketConfigFileNoTimeouts), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + if assert.NoError(t, err, "Failed to load config file") { + assert.True(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned false, when expecting true") + assert.Equal(t, DefaultConfig.DialTimeout, cfg.DialTimeout, "Did not get expected socket default DialTimeout from config file") + assert.Equal(t, DefaultConfig.Timeout, cfg.Timeout, "Did not get expected socket default Timeout from config file") + } + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestLoadHttpConfigWithTimeouts(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "httpConfigFileWithTimeouts.toml") + if err := ioutil.WriteFile(configFile, []byte(httpConfigFileWithTimeouts), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + if assert.NoError(t, err, "Failed to load config file") { + assert.False(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned true, when expecting false") + assert.Equal(t, "http:localhost:9101", cfg.HttpUrl, "Did not get expected http url from config file") + assert.Equal(t, cfg.TlsMode, TlsOff, "Did not get expected IsTlsConfigured() value from config file") + assert.Equal(t, uint(101), cfg.Timeout, "Did not get expected http Timeout from config file") + assert.Equal(t, uint(102), cfg.HttpIdleConnTimeout, "Did not get expected http HttpIdleConnTimeout from config file") + assert.Equal(t, int(1001), cfg.HttpWriteBufferSize, "Did not get expected http HttpWriteBufferSize from config file") + assert.Equal(t, int(1002), cfg.HttpReadBufferSize, "Did not get expected http HttpReadBufferSize from config file") + } + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestLoadHttpConfigWithInvalidTls(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "httpConfigFileWithInvalidTlsMode.toml") + if err := ioutil.WriteFile(configFile, []byte(httpConfigFileWithInvalidTlsMode), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "invalid value for TLS mode in config file, must be either OFF or STRICT") + } +} + +func TestLoadHttpTlsConfigWithTimeouts(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileWithTimeouts.toml") + if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileWithTimeouts), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + if assert.NoError(t, err, "Failed to load config file") { + assert.False(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned true, when expecting false") + assert.Equal(t, "https:localhost:9101", cfg.HttpUrl, "Did not get expected http url from config file") + assert.Equal(t, cfg.TlsMode, TlsStrict, "Did not get expected IsTlsConfigured() value from config file") + assert.Equal(t, "mydir/rootca.cert.pem", cfg.TlsRootCA, "Did not get expected TlsRootCA from config file") + assert.Equal(t, "mydir/client.cert.pem", cfg.TlsClientCert, "Did not get expected TlsClientCert from config file") + assert.Equal(t, "mydir/client.key.pem", cfg.TlsClientKey, "Did not get expected TlsClientKey from config file") + assert.Equal(t, uint(101), cfg.Timeout, "Did not get expected http Timeout from config file") + assert.Equal(t, uint(102), cfg.HttpIdleConnTimeout, "Did not get expected http HttpIdleConnTimeout from config file") + assert.Equal(t, int(1001), cfg.HttpWriteBufferSize, "Did not get expected http HttpWriteBufferSize from config file") + assert.Equal(t, int(1002), cfg.HttpReadBufferSize, "Did not get expected http HttpReadBufferSize from config file") + assert.False(t, cfg.TlsInsecureSkipVerify, "Did not get expected TlsInsecureSkipVerify value from config file") + } + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestLoadHttpConfigWithDefaultTimeouts(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileNoTimeouts.toml") + if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileNoTimeouts), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + if assert.NoError(t, err, "Failed to load config file") { + assert.False(t, IsSocketConfigured(cfg), "IsSocketConfigured() returned true, when expecting false") + assert.Equal(t, "https:localhost:9101", cfg.HttpUrl, "Did not get expected http url from config file") + assert.Equal(t, DefaultConfig.Timeout, cfg.Timeout, "Did not get expected http Timeout from config file") + assert.True(t, cfg.TlsInsecureSkipVerify, "Did not get expected TlsInsecureSkipVerify value from config file") + } + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestHTTPTlsWithBlankRootCert(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileNoRootCert.toml") + if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileNoRootCert), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestHTTPTlsMissingClientCerts(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "invalidHttpTlsConfigFileNoClientCert.toml") + if err := ioutil.WriteFile(configFile, []byte(invalidHttpTlsConfigFileNoClientCert), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + assert.NoError(t, err) +} + +func TestHTTPTlsMissingOnlyClientKey(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "invalidHttpTlsConfigFileOnlyClientCert.toml") + if err := ioutil.WriteFile(configFile, []byte(invalidHttpTlsConfigFileOnlyClientCert), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "invalid details for HTTP connection with TLS, configuration must specify both clientCert and clientKey, or neither one") + } +} + +func TestHTTPTlsMissingOnlyClientCert(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "invalidHttpTlsConfigFileOnlyClientKey.toml") + if err := ioutil.WriteFile(configFile, []byte(invalidHttpTlsConfigFileOnlyClientKey), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "invalid details for HTTP connection with TLS, configuration must specify both clientCert and clientKey, or neither one") + } +} + +func TestTlsWithHTTPUrlOnly(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "httpTlsConfigFileWithHTTPOnly.toml") + if err := ioutil.WriteFile(configFile, []byte(httpTlsConfigFileWithHTTPOnly), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "connection is configured with TLS but HTTPS url is not specified") + } +} + +func TestSocketWithHTTPNotAllowed(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "invalidConfigWithSocketAndHttp.toml") + if err := ioutil.WriteFile(configFile, []byte(invalidConfigWithSocketAndHttp), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + cfg, err := FetchConfig(configFile) + assert.NoError(t, err) + + err = cfg.Validate() + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "HTTP URL and unix ipc file cannot both be specified for private transaction manager connection") + } +} + +func TestEitherSocketOrHTTPMustBeSpecified(t *testing.T) { + configFile := filepath.Join(os.TempDir(), "invalidConfigWithNoSocketOrHttp.toml") + if err := ioutil.WriteFile(configFile, []byte(invalidConfigWithNoSocketOrHttp), 0600); err != nil { + t.Fatalf("Failed to create config file for unit test, error: %v", err) + } + defer os.Remove(configFile) + + _, err := FetchConfig(configFile) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "either Socket or HTTP connection must be specified in config file") + } +} diff --git a/common/http/transport.go b/common/http/transport.go new file mode 100644 index 0000000000..593b78767d --- /dev/null +++ b/common/http/transport.go @@ -0,0 +1,55 @@ +package http + +import ( + "crypto/tls" + "fmt" + "net/http" + "path/filepath" + "time" + + "github.com/tv42/httpunix" +) + +func unixTransport(cfg Config) *httpunix.Transport { + // Note that clientTimeout doesn't work when using httpunix.Transport, so we set ResponseHeaderTimeout instead + t := &httpunix.Transport{ + DialTimeout: time.Duration(cfg.DialTimeout) * time.Second, + RequestTimeout: 5 * time.Second, + ResponseHeaderTimeout: time.Duration(cfg.Timeout) * time.Second, + } + t.RegisterLocation("c", filepath.Join(cfg.WorkDir, cfg.Socket)) + return t +} + +func httpTransport(cfg Config) *http.Transport { + t := &http.Transport{ + IdleConnTimeout: time.Duration(cfg.HttpIdleConnTimeout) * time.Second, + WriteBufferSize: cfg.HttpWriteBufferSize, + ReadBufferSize: cfg.HttpReadBufferSize, + } + return t +} + +func newTLSConfig(cfg Config) (*tls.Config, error) { + rootCAPool, err := loadRootCaCerts(cfg.TlsRootCA) + if err != nil { + return nil, err + } + + var getClientCertFunc func(*tls.CertificateRequestInfo) (*tls.Certificate, error) = nil + if len(cfg.TlsClientCert) != 0 && len(cfg.TlsClientKey) != 0 { + getClientCertFunc = func(info *tls.CertificateRequestInfo) (certificate *tls.Certificate, e error) { + c, err := tls.LoadX509KeyPair(cfg.TlsClientCert, cfg.TlsClientKey) + if err != nil { + return nil, fmt.Errorf("failed to load client key pair from '%v', '%v': %v", cfg.TlsClientCert, cfg.TlsClientKey, err) + } + return &c, nil + } + } + + return &tls.Config{ + RootCAs: rootCAPool, + InsecureSkipVerify: cfg.TlsInsecureSkipVerify, + GetClientCertificate: getClientCertFunc, + }, nil +} diff --git a/common/slice.go b/common/slice.go new file mode 100644 index 0000000000..2ca2ea1f43 --- /dev/null +++ b/common/slice.go @@ -0,0 +1,55 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package common + +// ContainsAll returns true if all elements in one of the targets are in the source, +// false otherwise. +func ContainsAll(source []string, targets ...[]string) bool { + mark := make(map[string]bool, len(source)) + for _, str := range source { + mark[str] = true + } + for _, target := range targets { + foundAll := true + for _, str := range target { + if _, found := mark[str]; !found { + foundAll = false + break + } + } + if foundAll { + return true + } + } + return false +} + +// AppendSkipDuplicates appends source with elements with a condition +// that those elemments must NOT already exist in the source +func AppendSkipDuplicates(slice []string, elems ...string) (result []string) { + mark := make(map[string]bool, len(slice)) + for _, val := range slice { + mark[val] = true + } + result = slice + for _, val := range elems { + if _, ok := mark[val]; !ok { + result = append(result, val) + } + } + return result +} diff --git a/common/slice_test.go b/common/slice_test.go new file mode 100644 index 0000000000..3603a6c74e --- /dev/null +++ b/common/slice_test.go @@ -0,0 +1,94 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestContainsAll_whenTypical(t *testing.T) { + source := []string{"1", "2"} + target1 := []string{"3"} + target2 := []string{"1", "2"} + + assert.True(t, ContainsAll(source, target1, target2)) +} + +func TestContainsAll_whenNot(t *testing.T) { + source := []string{"1", "2"} + target := []string{"3", "4"} + + assert.False(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenTargetIsSubset(t *testing.T) { + source := []string{"1", "2"} + target := []string{"1"} + + assert.True(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenTargetIsSuperSet(t *testing.T) { + source := []string{"2"} + target := []string{"1", "2"} + + assert.False(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenSourceIsEmpty(t *testing.T) { + var source []string + target := []string{"1", "2"} + + assert.False(t, ContainsAll(source, target)) +} + +func TestContainsAll_whenSourceIsNil(t *testing.T) { + target := []string{"1", "2"} + + assert.False(t, ContainsAll(nil, target)) +} + +func TestContainsAll_whenTargetIsEmpty(t *testing.T) { + source := []string{"1", "2"} + + assert.True(t, ContainsAll(source, []string{})) +} + +func TestContainsAll_whenTargetIsNil(t *testing.T) { + source := []string{"1", "2"} + + assert.True(t, ContainsAll(source, nil)) +} + +func TestAppendSkipDuplicates_whenTypical(t *testing.T) { + source := []string{"1", "2"} + additional := []string{"1", "3"} + + assert.Equal(t, []string{"1", "2", "3"}, AppendSkipDuplicates(source, additional...)) +} + +func TestAppendSkipDuplicates_whenSourceIsNil(t *testing.T) { + additional := []string{"1", "3"} + + assert.Equal(t, []string{"1", "3"}, AppendSkipDuplicates(nil, additional...)) +} + +func TestAppendSkipDuplicates_whenElementIsNil(t *testing.T) { + assert.Equal(t, []string{"1", "3"}, AppendSkipDuplicates([]string{"1", "3"}, nil...)) +} diff --git a/common/types.go b/common/types.go index cdcc6c20ad..fb94b29362 100644 --- a/common/types.go +++ b/common/types.go @@ -18,6 +18,7 @@ package common import ( "database/sql/driver" + "encoding/base64" "encoding/hex" "encoding/json" "errors" @@ -37,13 +38,77 @@ const ( HashLength = 32 // AddressLength is the expected length of the address AddressLength = 20 + // length of the hash returned by Private Transaction Manager + EncryptedPayloadHashLength = 64 ) var ( + ErrNotPrivateContract = errors.New("the provided address is not a private contract") + ErrNoAccountExtraData = errors.New("no account extra data found") + hashT = reflect.TypeOf(Hash{}) addressT = reflect.TypeOf(Address{}) ) +// Hash, returned by Private Transaction Manager, represents the 64-byte hash of encrypted payload +type EncryptedPayloadHash [EncryptedPayloadHashLength]byte + +// Using map to enable fast lookup +type EncryptedPayloadHashes map[EncryptedPayloadHash]struct{} + +// BytesToEncryptedPayloadHash sets b to EncryptedPayloadHash. +// If b is larger than len(h), b will be cropped from the left. +func BytesToEncryptedPayloadHash(b []byte) EncryptedPayloadHash { + var h EncryptedPayloadHash + h.SetBytes(b) + return h +} + +func Base64ToEncryptedPayloadHash(b64 string) (EncryptedPayloadHash, error) { + bytes, err := base64.StdEncoding.DecodeString(b64) + if err != nil { + return EncryptedPayloadHash{}, fmt.Errorf("unable to convert base64 string %s to EncryptedPayloadHash. Cause: %v", b64, err) + } + return BytesToEncryptedPayloadHash(bytes), nil +} + +func (eph *EncryptedPayloadHash) SetBytes(b []byte) { + if len(b) > len(eph) { + b = b[len(b)-EncryptedPayloadHashLength:] + } + + copy(eph[EncryptedPayloadHashLength-len(b):], b) +} + +func (eph EncryptedPayloadHash) Hex() string { + return hexutil.Encode(eph[:]) +} + +func (eph EncryptedPayloadHash) Bytes() []byte { + return eph[:] +} + +func (eph EncryptedPayloadHash) String() string { + return eph.Hex() +} + +func (eph EncryptedPayloadHash) ToBase64() string { + return base64.StdEncoding.EncodeToString(eph[:]) +} + +func (eph EncryptedPayloadHash) TerminalString() string { + return fmt.Sprintf("%x…%x", eph[:3], eph[EncryptedPayloadHashLength-3:]) +} + +func (eph EncryptedPayloadHash) BytesTypeRef() *hexutil.Bytes { + b := hexutil.Bytes(eph.Bytes()) + return &b +} + +func EmptyEncryptedPayloadHash(eph EncryptedPayloadHash) bool { + return eph == EncryptedPayloadHash{} +} + // Hash represents the 32 byte Keccak256 hash of arbitrary data. type Hash [HashLength]byte @@ -55,6 +120,8 @@ func BytesToHash(b []byte) Hash { return h } +func StringToHash(s string) Hash { return BytesToHash([]byte(s)) } // dep: Istanbul + // BigToHash sets byte representation of b to hash. // If b is larger than len(h), b will be cropped from the left. func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } @@ -115,6 +182,10 @@ func (h *Hash) SetBytes(b []byte) { copy(h[HashLength-len(b):], b) } +func EmptyHash(h Hash) bool { + return h == Hash{} +} + // Generate implements testing/quick.Generator. func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { m := rand.Intn(len(h)) @@ -124,6 +195,23 @@ func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { return reflect.ValueOf(h) } +func (h Hash) ToBase64() string { + return base64.StdEncoding.EncodeToString(h.Bytes()) +} + +// Decode base64 string to Hash +// if String is empty then return empty hash +func Base64ToHash(b64 string) (Hash, error) { + if b64 == "" { + return Hash{}, nil + } + bytes, err := base64.StdEncoding.DecodeString(b64) + if err != nil { + return Hash{}, fmt.Errorf("unable to convert base64 string %s to Hash. Cause: %v", b64, err) + } + return BytesToHash(bytes), nil +} + // Scan implements Scanner for database/sql. func (h *Hash) Scan(src interface{}) error { srcB, ok := src.([]byte) @@ -170,6 +258,48 @@ func (h UnprefixedHash) MarshalText() ([]byte, error) { return []byte(hex.EncodeToString(h[:])), nil } +func (ephs EncryptedPayloadHashes) ToBase64s() []string { + a := make([]string, 0, len(ephs)) + for eph := range ephs { + a = append(a, eph.ToBase64()) + } + return a +} + +func (ephs EncryptedPayloadHashes) NotExist(eph EncryptedPayloadHash) bool { + _, ok := ephs[eph] + return !ok +} + +func (ephs EncryptedPayloadHashes) Add(eph EncryptedPayloadHash) { + ephs[eph] = struct{}{} +} + +func Base64sToEncryptedPayloadHashes(b64s []string) (EncryptedPayloadHashes, error) { + ephs := make(EncryptedPayloadHashes) + for _, b64 := range b64s { + data, err := Base64ToEncryptedPayloadHash(b64) + if err != nil { + return nil, err + } + ephs.Add(data) + } + return ephs, nil +} + +// Print hex but only first 3 and last 3 bytes +func FormatTerminalString(data []byte) string { + l := len(data) + if l > 0 { + if l > 6 { + return fmt.Sprintf("%x…%x", data[:3], data[l-3:]) + } else { + return fmt.Sprintf("%x", data[:]) + } + } + return "" +} + /////////// Address // Address represents the 20 byte address of an Ethereum account. @@ -183,6 +313,8 @@ func BytesToAddress(b []byte) Address { return a } +func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) } // dep: Istanbul + // BigToAddress returns Address with byte values of b. // If b is larger than len(h), b will be cropped from the left. func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } @@ -368,3 +500,12 @@ func (ma *MixedcaseAddress) ValidChecksum() bool { func (ma *MixedcaseAddress) Original() string { return ma.original } + +type DecryptRequest struct { + SenderKey []byte `json:"senderKey"` + CipherText []byte `json:"cipherText"` + CipherTextNonce []byte `json:"cipherTextNonce"` + RecipientBoxes []string `json:"recipientBoxes"` + RecipientNonce []byte `json:"recipientNonce"` + RecipientKeys []string `json:"recipientKeys"` +} diff --git a/common/types_test.go b/common/types_test.go index fffd673c6e..83df78a477 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -18,11 +18,14 @@ package common import ( "database/sql/driver" + "encoding/base64" "encoding/json" "math/big" "reflect" "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestBytesConversion(t *testing.T) { @@ -195,6 +198,68 @@ func TestMixedcaseAccount_Address(t *testing.T) { } +func TestBytesToEncryptedPayloadHash_whenTypical(t *testing.T) { + arbitraryBytes := []byte{10} + var expected EncryptedPayloadHash + expected[EncryptedPayloadHashLength-1] = 10 + + actual := BytesToEncryptedPayloadHash(arbitraryBytes) + + assert.Equal(t, expected, actual) +} + +func TestEncryptedPayloadHash_Bytes(t *testing.T) { + arbitraryBytes := []byte{10} + h := BytesToEncryptedPayloadHash(arbitraryBytes) + + actual := h.Bytes() + + assert.Equal(t, arbitraryBytes[0], actual[EncryptedPayloadHashLength-1]) +} + +func TestEncryptedPayloadHash_BytesTypeRef(t *testing.T) { + arbitraryBytes := []byte{10} + h := BytesToEncryptedPayloadHash(arbitraryBytes) + expected := h.Hex() + + bt := h.BytesTypeRef() + actual := bt.String() + + assert.Equal(t, expected, actual) +} + +func TestEncryptedPayloadHash_ToBase64(t *testing.T) { + arbitraryBytes := []byte{10} + h := BytesToEncryptedPayloadHash(arbitraryBytes) + expected := base64.StdEncoding.EncodeToString(h.Bytes()) + + actual := h.ToBase64() + + assert.Equal(t, expected, actual) +} + +func TestEmptyEncryptedPayloadHash(t *testing.T) { + + emptyHash := EncryptedPayloadHash{} + + assert.True(t, EmptyEncryptedPayloadHash(emptyHash)) +} + +func TestEncryptedPayloadHashes_whenTypical(t *testing.T) { + arbitraryBytes1 := []byte{10} + arbitraryBytes2 := []byte{5} + h, err := Base64sToEncryptedPayloadHashes([]string{base64.StdEncoding.EncodeToString(arbitraryBytes1), base64.StdEncoding.EncodeToString(arbitraryBytes2)}) + if err != nil { + t.Fatalf("must be able to convert but fail due to %s", err) + } + + arbitraryBytes3 := []byte{7} + newItem := BytesToEncryptedPayloadHash(arbitraryBytes3) + h.Add(newItem) + + assert.False(t, h.NotExist(newItem)) +} + func TestHash_Scan(t *testing.T) { type args struct { src interface{} @@ -371,3 +436,15 @@ func TestAddress_Value(t *testing.T) { }) } } + +func TestFormatTerminalString_Value(t *testing.T) { + assert.Equal(t, "", FormatTerminalString(nil)) + assert.Equal(t, "", FormatTerminalString([]byte{})) + b := []byte{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, + } + str := FormatTerminalString(b) + assert.Equal(t, "123456…90abcd", str) + str = FormatTerminalString(b[1:]) + assert.Equal(t, "34567890abcd", str) +} diff --git a/consensus/clique/api.go b/consensus/clique/api.go index 8e9a1e7deb..6f0d7772a7 100644 --- a/consensus/clique/api.go +++ b/consensus/clique/api.go @@ -17,6 +17,7 @@ package clique import ( + "errors" "fmt" "github.com/ethereum/go-ethereum/common" @@ -120,7 +121,7 @@ func (api *API) Discard(address common.Address) { delete(api.clique.proposals, address) } -type status struct { +type Status struct { InturnPercent float64 `json:"inturnPercent"` SigningStatus map[common.Address]int `json:"sealerActivity"` NumBlocks uint64 `json:"numBlocks"` @@ -130,21 +131,50 @@ type status struct { // - the number of active signers, // - the number of signers, // - the percentage of in-turn blocks -func (api *API) Status() (*status, error) { +func (api *API) Status(startBlockNum *rpc.BlockNumber, endBlockNum *rpc.BlockNumber) (*Status, error) { var ( - numBlocks = uint64(64) - header = api.chain.CurrentHeader() + numBlocks uint64 + header *types.Header diff = uint64(0) optimals = 0 + + start uint64 + end uint64 ) - snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) + if startBlockNum != nil && endBlockNum == nil { + return nil, errors.New("pass the end block number") + } + + if startBlockNum == nil && endBlockNum != nil { + return nil, errors.New("pass the start block number") + } + + if startBlockNum == nil && endBlockNum == nil { + numBlocks = uint64(64) + header = api.chain.CurrentHeader() + end = header.Number.Uint64() + start = end - numBlocks + } else { + end = uint64(*endBlockNum) + start = uint64(*startBlockNum) + if start > end { + return nil, errors.New("start block number should be less than end block number") + } + + if end > api.chain.CurrentHeader().Number.Uint64() { + return nil, errors.New("end block number should be less than or equal to current block height") + } + + numBlocks = end - start + header = api.chain.GetHeaderByNumber(end) + } + + snap, err := api.clique.snapshot(api.chain, end, header.Hash(), nil) if err != nil { return nil, err } var ( signers = snap.signers() - end = header.Number.Uint64() - start = end - numBlocks ) if numBlocks > end { start = 1 @@ -169,7 +199,7 @@ func (api *API) Status() (*status, error) { } signStatus[sealer]++ } - return &status{ + return &Status{ InturnPercent: float64(100*optimals) / float64(numBlocks), SigningStatus: signStatus, NumBlocks: numBlocks, diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 02f2451133..35a00af5be 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -248,8 +248,9 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H } number := header.Number.Uint64() - // Don't waste time checking blocks from the future - if header.Time > uint64(time.Now().Unix()) { + // Don't waste time checking blocks from the future (adjusting for allowed threshold) + adjustedTimeNow := time.Now().Add(time.Duration(c.config.AllowedFutureBlockTime) * time.Second).Unix() + if header.Time > uint64(adjustedTimeNow) { return consensus.ErrFutureBlock } // Checkpoint blocks need to enforce zero beneficiary @@ -369,7 +370,7 @@ func (c *Clique) snapshot(chain consensus.ChainHeaderReader, number uint64, hash // at a checkpoint block without a parent (light client CHT), or we have piled // up more headers than allowed to be reorged (chain reinit from a freezer), // consider the checkpoint trusted and snapshot it. - if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) { + if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > params.GetImmutabilityThreshold() || chain.GetHeaderByNumber(number-1) == nil)) { checkpoint := chain.GetHeaderByNumber(number) if checkpoint != nil { hash := checkpoint.Hash() @@ -736,3 +737,8 @@ func encodeSigHeader(w io.Writer, header *types.Header) { panic("can't encode: " + err.Error()) } } + +// Protocol implements consensus.Engine.Protocol +func (c *Clique) Protocol() consensus.Protocol { + return consensus.CliqueProtocol +} diff --git a/consensus/consensus.go b/consensus/consensus.go index f7a4d0ff0b..aba291e1fa 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -118,10 +119,25 @@ type Engine interface { // APIs returns the RPC APIs this consensus engine provides. APIs(chain ChainHeaderReader) []rpc.API + // Protocol returns the protocol for this consensus + Protocol() Protocol + // Close terminates any background threads maintained by the consensus engine. Close() error } +// Handler should be implemented is the consensus needs to handle and send peer's message +type Handler interface { + // NewChainHead handles a new head block comes + NewChainHead() error + + // HandleMsg handles a message from peer + HandleMsg(address common.Address, data p2p.Msg) (bool, error) + + // SetBroadcaster sets the broadcaster to send message to peers + SetBroadcaster(Broadcaster) +} + // PoW is a consensus engine based on proof-of-work. type PoW interface { Engine @@ -129,3 +145,14 @@ type PoW interface { // Hashrate returns the current mining hashrate of a PoW consensus engine. Hashrate() float64 } + +// Istanbul is a consensus engine to avoid byzantine failure +type Istanbul interface { + Engine + + // Start starts the engine + Start(chain ChainHeaderReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error + + // Stop stops the engine + Stop() error +} diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index bdc02098af..1fcec4a5f4 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -245,6 +245,10 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo // stock Ethereum ethash engine. // See YP section 4.3.4. "Block Header Validity" func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header, uncle bool, seal bool) error { + // Quorum: ethash consensus is only used in raft for Quorum, skip verifyHeader + if chain != nil && chain.Config().IsQuorum { + return nil + } // Ensure that the header's extra-data section is of a reasonable size if uint64(len(header.Extra)) > params.MaximumExtraDataSize { return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), params.MaximumExtraDataSize) @@ -279,9 +283,9 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa if diff < 0 { diff *= -1 } - limit := parent.GasLimit / params.GasLimitBoundDivisor + limit := parent.GasLimit / params.OriginalGasLimitBoundDivisor - if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { + if uint64(diff) >= limit || header.GasLimit < params.OriginalMinGasLimit { return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) } // Verify that the block number is parent's +1 @@ -495,6 +499,10 @@ func (ethash *Ethash) VerifySeal(chain consensus.ChainHeaderReader, header *type // either using the usual ethash cache for it, or alternatively using a full DAG // to make remote mining fast. func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, fulldag bool) error { + // Quorum: ethash consensus is only used in raft for Quorum, skip verifySeal + if chain != nil && chain.Config().IsQuorum { + return nil + } // If we're running a fake PoW, accept any seal as valid if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { time.Sleep(ethash.fakeDelay) @@ -643,3 +651,8 @@ func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header } state.AddBalance(header.Coinbase, reward) } + +// Quorum: wrapper for accumulateRewards to be called by raft minter +func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { + accumulateRewards(config, state, header, uncles) +} diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index aa3f002c0d..4c52539481 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -638,6 +638,9 @@ func (ethash *Ethash) SetThreads(threads int) { // Note the returned hashrate includes local hashrate, but also includes the total // hashrate of all remote miner. func (ethash *Ethash) Hashrate() float64 { + if ethash.hashrate == nil { + return 0 + } // Short circuit if we are run the ethash in normal/test mode. if ethash.config.PowMode != ModeNormal && ethash.config.PowMode != ModeTest { return ethash.hashrate.Rate1() @@ -680,3 +683,8 @@ func (ethash *Ethash) APIs(chain consensus.ChainHeaderReader) []rpc.API { func SeedHash(block uint64) []byte { return seedHash(block) } + +// Protocol implements consensus.Engine.Protocol +func (ethash *Ethash) Protocol() consensus.Protocol { + return consensus.EthProtocol +} diff --git a/consensus/istanbul/backend.go b/consensus/istanbul/backend.go new file mode 100644 index 0000000000..22abed096e --- /dev/null +++ b/consensus/istanbul/backend.go @@ -0,0 +1,75 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import ( + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Backend provides application specific functions for Istanbul core +type Backend interface { + // Address returns the owner's address + Address() common.Address + + // Validators returns the validator set + Validators(proposal Proposal) ValidatorSet + + // EventMux returns the event mux in backend + EventMux() *event.TypeMux + + // Broadcast sends a message to all validators (include self) + Broadcast(valSet ValidatorSet, payload []byte) error + + // Gossip sends a message to all validators (exclude self) + Gossip(valSet ValidatorSet, payload []byte) error + + // Commit delivers an approved proposal to backend. + // The delivered proposal will be put into blockchain. + Commit(proposal Proposal, seals [][]byte) error + + // Verify verifies the proposal. If a consensus.ErrFutureBlock error is returned, + // the time difference of the proposal and current time is also returned. + Verify(Proposal) (time.Duration, error) + + // Sign signs input data with the backend's private key + Sign([]byte) ([]byte, error) + + // CheckSignature verifies the signature by checking if it's signed by + // the given validator + CheckSignature(data []byte, addr common.Address, sig []byte) error + + // LastProposal retrieves latest committed proposal and the address of proposer + LastProposal() (Proposal, common.Address) + + // HasPropsal checks if the combination of the given hash and height matches any existing blocks + HasPropsal(hash common.Hash, number *big.Int) bool + + // GetProposer returns the proposer of the given block height + GetProposer(number uint64) common.Address + + // ParentValidators returns the validator set of the given proposal's parent block + ParentValidators(proposal Proposal) ValidatorSet + + // HasBadBlock returns whether the block with the hash is a bad block + HasBadProposal(hash common.Hash) bool + + Close() error +} diff --git a/consensus/istanbul/backend/api.go b/consensus/istanbul/backend/api.go new file mode 100644 index 0000000000..24e45cb9e4 --- /dev/null +++ b/consensus/istanbul/backend/api.go @@ -0,0 +1,272 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" +) + +// API is a user facing RPC API to dump Istanbul state +type API struct { + chain consensus.ChainHeaderReader + istanbul *backend +} + +// BlockSigners is contains who created and who signed a particular block, denoted by its number and hash +type BlockSigners struct { + Number uint64 + Hash common.Hash + Author common.Address + Committers []common.Address +} + +type Status struct { + SigningStatus map[common.Address]int `json:"sealerActivity"` + NumBlocks uint64 `json:"numBlocks"` +} + +// NodeAddress returns the public address that is used to sign block headers in IBFT +func (api *API) NodeAddress() common.Address { + return api.istanbul.Address() +} + +// GetSignersFromBlock returns the signers and minter for a given block number, or the +// latest block available if none is specified +func (api *API) GetSignersFromBlock(number *rpc.BlockNumber) (*BlockSigners, error) { + // Retrieve the requested block number (or current if none requested) + var header *types.Header + if number == nil || *number == rpc.LatestBlockNumber { + header = api.chain.CurrentHeader() + } else { + header = api.chain.GetHeaderByNumber(uint64(number.Int64())) + } + + if header == nil { + return nil, errUnknownBlock + } + + return api.signers(header) +} + +// GetSignersFromBlockByHash returns the signers and minter for a given block hash +func (api *API) GetSignersFromBlockByHash(hash common.Hash) (*BlockSigners, error) { + header := api.chain.GetHeaderByHash(hash) + if header == nil { + return nil, errUnknownBlock + } + + return api.signers(header) +} + +func (api *API) signers(header *types.Header) (*BlockSigners, error) { + author, err := api.istanbul.Author(header) + if err != nil { + return nil, err + } + + committers, err := api.istanbul.Signers(header) + if err != nil { + return nil, err + } + + return &BlockSigners{ + Number: header.Number.Uint64(), + Hash: header.Hash(), + Author: author, + Committers: committers, + }, nil +} + +// GetSnapshot retrieves the state snapshot at a given block. +func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { + // Retrieve the requested block number (or current if none requested) + var header *types.Header + if number == nil || *number == rpc.LatestBlockNumber { + header = api.chain.CurrentHeader() + } else { + header = api.chain.GetHeaderByNumber(uint64(number.Int64())) + } + // Ensure we have an actually valid block and return its snapshot + if header == nil { + return nil, errUnknownBlock + } + return api.istanbul.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) +} + +// GetSnapshotAtHash retrieves the state snapshot at a given block. +func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { + header := api.chain.GetHeaderByHash(hash) + if header == nil { + return nil, errUnknownBlock + } + return api.istanbul.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) +} + +// GetValidators retrieves the list of authorized validators at the specified block. +func (api *API) GetValidators(number *rpc.BlockNumber) ([]common.Address, error) { + // Retrieve the requested block number (or current if none requested) + var header *types.Header + if number == nil || *number == rpc.LatestBlockNumber { + header = api.chain.CurrentHeader() + } else { + header = api.chain.GetHeaderByNumber(uint64(number.Int64())) + } + // Ensure we have an actually valid block and return the validators from its snapshot + if header == nil { + return nil, errUnknownBlock + } + snap, err := api.istanbul.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) + if err != nil { + return nil, err + } + return snap.validators(), nil +} + +// GetValidatorsAtHash retrieves the state snapshot at a given block. +func (api *API) GetValidatorsAtHash(hash common.Hash) ([]common.Address, error) { + header := api.chain.GetHeaderByHash(hash) + if header == nil { + return nil, errUnknownBlock + } + snap, err := api.istanbul.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil) + if err != nil { + return nil, err + } + return snap.validators(), nil +} + +// Candidates returns the current candidates the node tries to uphold and vote on. +func (api *API) Candidates() map[common.Address]bool { + api.istanbul.candidatesLock.RLock() + defer api.istanbul.candidatesLock.RUnlock() + + proposals := make(map[common.Address]bool) + for address, auth := range api.istanbul.candidates { + proposals[address] = auth + } + return proposals +} + +// Propose injects a new authorization candidate that the validator will attempt to +// push through. +func (api *API) Propose(address common.Address, auth bool) { + api.istanbul.candidatesLock.Lock() + defer api.istanbul.candidatesLock.Unlock() + + api.istanbul.candidates[address] = auth +} + +// Discard drops a currently running candidate, stopping the validator from casting +// further votes (either for or against). +func (api *API) Discard(address common.Address) { + api.istanbul.candidatesLock.Lock() + defer api.istanbul.candidatesLock.Unlock() + + delete(api.istanbul.candidates, address) +} + +func (api *API) Status(startBlockNum *rpc.BlockNumber, endBlockNum *rpc.BlockNumber) (*Status, error) { + var ( + numBlocks uint64 + header = api.chain.CurrentHeader() + start uint64 + end uint64 + blockNumber rpc.BlockNumber + ) + if startBlockNum != nil && endBlockNum == nil { + return nil, errors.New("pass the end block number") + } + + if startBlockNum == nil && endBlockNum != nil { + return nil, errors.New("pass the start block number") + } + + if startBlockNum == nil && endBlockNum == nil { + numBlocks = uint64(64) + header = api.chain.CurrentHeader() + end = header.Number.Uint64() + start = end - numBlocks + blockNumber = rpc.BlockNumber(header.Number.Int64()) + } else { + end = uint64(*endBlockNum) + start = uint64(*startBlockNum) + if start > end { + return nil, errors.New("start block number should be less than end block number") + } + + if end > api.chain.CurrentHeader().Number.Uint64() { + return nil, errors.New("end block number should be less than or equal to current block height") + } + + numBlocks = end - start + header = api.chain.GetHeaderByNumber(end) + blockNumber = rpc.BlockNumber(end) + } + + signers, err := api.GetValidators(&blockNumber) + + if err != nil { + return nil, err + } + + if numBlocks >= end { + start = 1 + if end > start { + numBlocks = end - start + } else { + numBlocks = 0 + } + } + signStatus := make(map[common.Address]int) + for _, s := range signers { + signStatus[s] = 0 + } + + for n := start; n < end; n++ { + blockNum := rpc.BlockNumber(int64(n)) + s, _ := api.GetSignersFromBlock(&blockNum) + signStatus[s.Author]++ + + } + return &Status{ + SigningStatus: signStatus, + NumBlocks: numBlocks, + }, nil +} + +func (api *API) IsValidator(blockNum *rpc.BlockNumber) (bool, error) { + var blockNumber rpc.BlockNumber + if blockNum != nil { + blockNumber = *blockNum + } else { + header := api.chain.CurrentHeader() + blockNumber = rpc.BlockNumber(header.Number.Int64()) + } + s, _ := api.GetValidators(&blockNumber) + + for _, v := range s { + if v == api.istanbul.address { + return true, nil + } + } + return false, nil +} diff --git a/consensus/istanbul/backend/backend.go b/consensus/istanbul/backend/backend.go new file mode 100644 index 0000000000..69f0b90a1f --- /dev/null +++ b/consensus/istanbul/backend/backend.go @@ -0,0 +1,318 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "crypto/ecdsa" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/istanbul" + istanbulCore "github.com/ethereum/go-ethereum/consensus/istanbul/core" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/trie" + lru "github.com/hashicorp/golang-lru" +) + +const ( + // fetcherID is the ID indicates the block is from Istanbul engine + fetcherID = "istanbul" +) + +// New creates an Ethereum backend for Istanbul core engine. +func New(config *istanbul.Config, privateKey *ecdsa.PrivateKey, db ethdb.Database) consensus.Istanbul { + // Allocate the snapshot caches and create the engine + recents, _ := lru.NewARC(inmemorySnapshots) + recentMessages, _ := lru.NewARC(inmemoryPeers) + knownMessages, _ := lru.NewARC(inmemoryMessages) + backend := &backend{ + config: config, + istanbulEventMux: new(event.TypeMux), + privateKey: privateKey, + address: crypto.PubkeyToAddress(privateKey.PublicKey), + logger: log.New(), + db: db, + commitCh: make(chan *types.Block, 1), + recents: recents, + candidates: make(map[common.Address]bool), + coreStarted: false, + recentMessages: recentMessages, + knownMessages: knownMessages, + } + backend.core = istanbulCore.New(backend, backend.config) + return backend +} + +// ---------------------------------------------------------------------------- + +type backend struct { + config *istanbul.Config + istanbulEventMux *event.TypeMux + privateKey *ecdsa.PrivateKey + address common.Address + core istanbulCore.Engine + logger log.Logger + db ethdb.Database + chain consensus.ChainHeaderReader + currentBlock func() *types.Block + hasBadBlock func(hash common.Hash) bool + + // the channels for istanbul engine notifications + commitCh chan *types.Block + proposedBlockHash common.Hash + sealMu sync.Mutex + coreStarted bool + coreMu sync.RWMutex + + // Current list of candidates we are pushing + candidates map[common.Address]bool + // Protects the signer fields + candidatesLock sync.RWMutex + // Snapshots for recent block to speed up reorgs + recents *lru.ARCCache + + // event subscription for ChainHeadEvent event + broadcaster consensus.Broadcaster + + recentMessages *lru.ARCCache // the cache of peer's messages + knownMessages *lru.ARCCache // the cache of self messages +} + +// zekun: HACK +func (sb *backend) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { + return new(big.Int) +} + +// Address implements istanbul.Backend.Address +func (sb *backend) Address() common.Address { + return sb.address +} + +// Validators implements istanbul.Backend.Validators +func (sb *backend) Validators(proposal istanbul.Proposal) istanbul.ValidatorSet { + return sb.getValidators(proposal.Number().Uint64(), proposal.Hash()) +} + +// Broadcast implements istanbul.Backend.Broadcast +func (sb *backend) Broadcast(valSet istanbul.ValidatorSet, payload []byte) error { + // send to others + sb.Gossip(valSet, payload) + // send to self + msg := istanbul.MessageEvent{ + Payload: payload, + } + go sb.istanbulEventMux.Post(msg) + return nil +} + +// Broadcast implements istanbul.Backend.Gossip +func (sb *backend) Gossip(valSet istanbul.ValidatorSet, payload []byte) error { + hash := istanbul.RLPHash(payload) + sb.knownMessages.Add(hash, true) + + targets := make(map[common.Address]bool) + for _, val := range valSet.List() { + if val.Address() != sb.Address() { + targets[val.Address()] = true + } + } + if sb.broadcaster != nil && len(targets) > 0 { + ps := sb.broadcaster.FindPeers(targets) + for addr, p := range ps { + ms, ok := sb.recentMessages.Get(addr) + var m *lru.ARCCache + if ok { + m, _ = ms.(*lru.ARCCache) + if _, k := m.Get(hash); k { + // This peer had this event, skip it + continue + } + } else { + m, _ = lru.NewARC(inmemoryMessages) + } + + m.Add(hash, true) + sb.recentMessages.Add(addr, m) + go p.SendConsensus(istanbulMsg, payload) + } + } + return nil +} + +// Commit implements istanbul.Backend.Commit +func (sb *backend) Commit(proposal istanbul.Proposal, seals [][]byte) error { + // Check if the proposal is a valid block + block, ok := proposal.(*types.Block) + if !ok { + sb.logger.Error("Invalid proposal, %v", proposal) + return errInvalidProposal + } + + h := block.Header() + // Append seals into extra-data + err := writeCommittedSeals(h, seals) + if err != nil { + return err + } + // update block's header + block = block.WithSeal(h) + + sb.logger.Info("Committed", "address", sb.Address(), "hash", proposal.Hash(), "number", proposal.Number().Uint64()) + // - if the proposed and committed blocks are the same, send the proposed hash + // to commit channel, which is being watched inside the engine.Seal() function. + // - otherwise, we try to insert the block. + // -- if success, the ChainHeadEvent event will be broadcasted, try to build + // the next block and the previous Seal() will be stopped. + // -- otherwise, a error will be returned and a round change event will be fired. + if sb.proposedBlockHash == block.Hash() { + // feed block hash to Seal() and wait the Seal() result + sb.commitCh <- block + return nil + } + + if sb.broadcaster != nil { + sb.broadcaster.Enqueue(fetcherID, block) + } + return nil +} + +// EventMux implements istanbul.Backend.EventMux +func (sb *backend) EventMux() *event.TypeMux { + return sb.istanbulEventMux +} + +// Verify implements istanbul.Backend.Verify +func (sb *backend) Verify(proposal istanbul.Proposal) (time.Duration, error) { + // Check if the proposal is a valid block + block, ok := proposal.(*types.Block) + if !ok { + sb.logger.Error("Invalid proposal, %v", proposal) + return 0, errInvalidProposal + } + + // check bad block + if sb.HasBadProposal(block.Hash()) { + return 0, core.ErrBlacklistedHash + } + + // check block body + txnHash := types.DeriveSha(block.Transactions(), new(trie.Trie)) + uncleHash := types.CalcUncleHash(block.Uncles()) + if txnHash != block.Header().TxHash { + return 0, errMismatchTxhashes + } + if uncleHash != nilUncleHash { + return 0, errInvalidUncleHash + } + + // verify the header of proposed block + err := sb.VerifyHeader(sb.chain, block.Header(), false) + // ignore errEmptyCommittedSeals error because we don't have the committed seals yet + if err == nil || err == errEmptyCommittedSeals { + return 0, nil + } else if err == consensus.ErrFutureBlock { + return time.Unix(int64(block.Header().Time), 0).Sub(now()), consensus.ErrFutureBlock + } + return 0, err +} + +// Sign implements istanbul.Backend.Sign +func (sb *backend) Sign(data []byte) ([]byte, error) { + hashData := crypto.Keccak256(data) + return crypto.Sign(hashData, sb.privateKey) +} + +// CheckSignature implements istanbul.Backend.CheckSignature +func (sb *backend) CheckSignature(data []byte, address common.Address, sig []byte) error { + signer, err := istanbul.GetSignatureAddress(data, sig) + if err != nil { + log.Error("Failed to get signer address", "err", err) + return err + } + // Compare derived addresses + if signer != address { + return errInvalidSignature + } + return nil +} + +// HasPropsal implements istanbul.Backend.HashBlock +func (sb *backend) HasPropsal(hash common.Hash, number *big.Int) bool { + return sb.chain.GetHeader(hash, number.Uint64()) != nil +} + +// GetProposer implements istanbul.Backend.GetProposer +func (sb *backend) GetProposer(number uint64) common.Address { + if h := sb.chain.GetHeaderByNumber(number); h != nil { + a, _ := sb.Author(h) + return a + } + return common.Address{} +} + +// ParentValidators implements istanbul.Backend.GetParentValidators +func (sb *backend) ParentValidators(proposal istanbul.Proposal) istanbul.ValidatorSet { + if block, ok := proposal.(*types.Block); ok { + return sb.getValidators(block.Number().Uint64()-1, block.ParentHash()) + } + return validator.NewSet(nil, sb.config.ProposerPolicy) +} + +func (sb *backend) getValidators(number uint64, hash common.Hash) istanbul.ValidatorSet { + snap, err := sb.snapshot(sb.chain, number, hash, nil) + if err != nil { + return validator.NewSet(nil, sb.config.ProposerPolicy) + } + return snap.ValSet +} + +func (sb *backend) LastProposal() (istanbul.Proposal, common.Address) { + block := sb.currentBlock() + + var proposer common.Address + if block.Number().Cmp(common.Big0) > 0 { + var err error + proposer, err = sb.Author(block.Header()) + if err != nil { + sb.logger.Error("Failed to get block proposer", "err", err) + return nil, common.Address{} + } + } + + // Return header only block here since we don't need block body + return block, proposer +} + +func (sb *backend) HasBadProposal(hash common.Hash) bool { + if sb.hasBadBlock == nil { + return false + } + return sb.hasBadBlock(hash) +} + +func (sb *backend) Close() error { + return nil +} diff --git a/consensus/istanbul/backend/backend_test.go b/consensus/istanbul/backend/backend_test.go new file mode 100644 index 0000000000..0f51ecd2e0 --- /dev/null +++ b/consensus/istanbul/backend/backend_test.go @@ -0,0 +1,239 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "crypto/ecdsa" + "sort" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" +) + +func TestSign(t *testing.T) { + b := newBackend() + data := []byte("Here is a string....") + sig, err := b.Sign(data) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + //Check signature recover + hashData := crypto.Keccak256(data) + pubkey, _ := crypto.Ecrecover(hashData, sig) + var signer common.Address + copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) + if signer != getAddress() { + t.Errorf("address mismatch: have %v, want %s", signer.Hex(), getAddress().Hex()) + } +} + +func TestCheckSignature(t *testing.T) { + key, _ := generatePrivateKey() + data := []byte("Here is a string....") + hashData := crypto.Keccak256(data) + sig, _ := crypto.Sign(hashData, key) + b := newBackend() + a := getAddress() + err := b.CheckSignature(data, a, sig) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + a = getInvalidAddress() + err = b.CheckSignature(data, a, sig) + if err != errInvalidSignature { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidSignature) + } +} + +func TestCheckValidatorSignature(t *testing.T) { + vset, keys := newTestValidatorSet(5) + + // 1. Positive test: sign with validator's key should succeed + data := []byte("dummy data") + hashData := crypto.Keccak256(data) + for i, k := range keys { + // Sign + sig, err := crypto.Sign(hashData, k) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + // CheckValidatorSignature should succeed + addr, err := istanbul.CheckValidatorSignature(vset, data, sig) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + validator := vset.GetByIndex(uint64(i)) + if addr != validator.Address() { + t.Errorf("validator address mismatch: have %v, want %v", addr, validator.Address()) + } + } + + // 2. Negative test: sign with any key other than validator's key should return error + key, err := crypto.GenerateKey() + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + // Sign + sig, err := crypto.Sign(hashData, key) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + // CheckValidatorSignature should return ErrUnauthorizedAddress + addr, err := istanbul.CheckValidatorSignature(vset, data, sig) + if err != istanbul.ErrUnauthorizedAddress { + t.Errorf("error mismatch: have %v, want %v", err, istanbul.ErrUnauthorizedAddress) + } + emptyAddr := common.Address{} + if addr != emptyAddr { + t.Errorf("address mismatch: have %v, want %v", addr, emptyAddr) + } +} + +func TestCommit(t *testing.T) { + backend := newBackend() + + commitCh := make(chan *types.Block) + // Case: it's a proposer, so the backend.commit will receive channel result from backend.Commit function + testCases := []struct { + expectedErr error + expectedSignature [][]byte + expectedBlock func() *types.Block + }{ + { + // normal case + nil, + [][]byte{append([]byte{1}, bytes.Repeat([]byte{0x00}, types.IstanbulExtraSeal-1)...)}, + func() *types.Block { + chain, engine := newBlockChain(1) + block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) + expectedBlock, _ := engine.updateBlock(engine.chain.GetHeader(block.ParentHash(), block.NumberU64()-1), block) + return expectedBlock + }, + }, + { + // invalid signature + errInvalidCommittedSeals, + nil, + func() *types.Block { + chain, engine := newBlockChain(1) + block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) + expectedBlock, _ := engine.updateBlock(engine.chain.GetHeader(block.ParentHash(), block.NumberU64()-1), block) + return expectedBlock + }, + }, + } + + for _, test := range testCases { + expBlock := test.expectedBlock() + go func() { + result := <-backend.commitCh + commitCh <- result + }() + + backend.proposedBlockHash = expBlock.Hash() + if err := backend.Commit(expBlock, test.expectedSignature); err != nil { + if err != test.expectedErr { + t.Errorf("error mismatch: have %v, want %v", err, test.expectedErr) + } + } + + if test.expectedErr == nil { + // to avoid race condition is occurred by goroutine + select { + case result := <-commitCh: + if result.Hash() != expBlock.Hash() { + t.Errorf("hash mismatch: have %v, want %v", result.Hash(), expBlock.Hash()) + } + case <-time.After(10 * time.Second): + t.Fatal("timeout") + } + } + } +} + +func TestGetProposer(t *testing.T) { + chain, engine := newBlockChain(1) + block := makeBlock(chain, engine, chain.Genesis()) + chain.InsertChain(types.Blocks{block}) + expected := engine.GetProposer(1) + actual := engine.Address() + if actual != expected { + t.Errorf("proposer mismatch: have %v, want %v", actual.Hex(), expected.Hex()) + } +} + +/** + * SimpleBackend + * Private key: bb047e5940b6d83354d9432db7c449ac8fca2248008aaa7271369880f9f11cc1 + * Public key: 04a2bfb0f7da9e1b9c0c64e14f87e8fb82eb0144e97c25fe3a977a921041a50976984d18257d2495e7bfd3d4b280220217f429287d25ecdf2b0d7c0f7aae9aa624 + * Address: 0x70524d664ffe731100208a0154e556f9bb679ae6 + */ +func getAddress() common.Address { + return common.HexToAddress("0x70524d664ffe731100208a0154e556f9bb679ae6") +} + +func getInvalidAddress() common.Address { + return common.HexToAddress("0x9535b2e7faaba5288511d89341d94a38063a349b") +} + +func generatePrivateKey() (*ecdsa.PrivateKey, error) { + key := "bb047e5940b6d83354d9432db7c449ac8fca2248008aaa7271369880f9f11cc1" + return crypto.HexToECDSA(key) +} + +func newTestValidatorSet(n int) (istanbul.ValidatorSet, []*ecdsa.PrivateKey) { + // generate validators + keys := make(Keys, n) + addrs := make([]common.Address, n) + for i := 0; i < n; i++ { + privateKey, _ := crypto.GenerateKey() + keys[i] = privateKey + addrs[i] = crypto.PubkeyToAddress(privateKey.PublicKey) + } + vset := validator.NewSet(addrs, istanbul.RoundRobin) + sort.Sort(keys) //Keys need to be sorted by its public key address + return vset, keys +} + +type Keys []*ecdsa.PrivateKey + +func (slice Keys) Len() int { + return len(slice) +} + +func (slice Keys) Less(i, j int) bool { + return strings.Compare(crypto.PubkeyToAddress(slice[i].PublicKey).String(), crypto.PubkeyToAddress(slice[j].PublicKey).String()) < 0 +} + +func (slice Keys) Swap(i, j int) { + slice[i], slice[j] = slice[j], slice[i] +} + +func newBackend() (b *backend) { + _, b = newBlockChain(4) + key, _ := generatePrivateKey() + b.privateKey = key + return +} diff --git a/consensus/istanbul/backend/engine.go b/consensus/istanbul/backend/engine.go new file mode 100644 index 0000000000..01a52a55eb --- /dev/null +++ b/consensus/istanbul/backend/engine.go @@ -0,0 +1,759 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "errors" + "math/big" + "math/rand" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/istanbul" + istanbulCore "github.com/ethereum/go-ethereum/consensus/istanbul/core" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/trie" + lru "github.com/hashicorp/golang-lru" + "golang.org/x/crypto/sha3" +) + +const ( + checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database + inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory + inmemoryPeers = 40 + inmemoryMessages = 1024 +) + +var ( + // errInvalidProposal is returned when a prposal is malformed. + errInvalidProposal = errors.New("invalid proposal") + // errInvalidSignature is returned when given signature is not signed by given + // address. + errInvalidSignature = errors.New("invalid signature") + // errUnknownBlock is returned when the list of validators is requested for a block + // that is not part of the local blockchain. + errUnknownBlock = errors.New("unknown block") + // errUnauthorized is returned if a header is signed by a non authorized entity. + errUnauthorized = errors.New("unauthorized") + // errInvalidDifficulty is returned if the difficulty of a block is not 1 + errInvalidDifficulty = errors.New("invalid difficulty") + // errInvalidExtraDataFormat is returned when the extra data format is incorrect + errInvalidExtraDataFormat = errors.New("invalid extra data format") + // errInvalidMixDigest is returned if a block's mix digest is not Istanbul digest. + errInvalidMixDigest = errors.New("invalid Istanbul mix digest") + // errInvalidNonce is returned if a block's nonce is invalid + errInvalidNonce = errors.New("invalid nonce") + // errInvalidUncleHash is returned if a block contains an non-empty uncle list. + errInvalidUncleHash = errors.New("non empty uncle hash") + // errInconsistentValidatorSet is returned if the validator set is inconsistent + // errInconsistentValidatorSet = errors.New("non empty uncle hash") + // errInvalidTimestamp is returned if the timestamp of a block is lower than the previous block's timestamp + the minimum block period. + errInvalidTimestamp = errors.New("invalid timestamp") + // errInvalidVotingChain is returned if an authorization list is attempted to + // be modified via out-of-range or non-contiguous headers. + errInvalidVotingChain = errors.New("invalid voting chain") + // errInvalidVote is returned if a nonce value is something else that the two + // allowed constants of 0x00..0 or 0xff..f. + errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f") + // errInvalidCommittedSeals is returned if the committed seal is not signed by any of parent validators. + errInvalidCommittedSeals = errors.New("invalid committed seals") + // errEmptyCommittedSeals is returned if the field of committed seals is zero. + errEmptyCommittedSeals = errors.New("zero committed seals") + // errMismatchTxhashes is returned if the TxHash in header is mismatch. + errMismatchTxhashes = errors.New("mismatch transactions hashes") +) +var ( + defaultDifficulty = big.NewInt(1) + nilUncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. + emptyNonce = types.BlockNonce{} + now = time.Now + + nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new validator + nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a validator. + + inmemoryAddresses = 20 // Number of recent addresses from ecrecover + recentAddresses, _ = lru.NewARC(inmemoryAddresses) +) + +// Author retrieves the Ethereum address of the account that minted the given +// block, which may be different from the header's coinbase if a consensus +// engine is based on signatures. +func (sb *backend) Author(header *types.Header) (common.Address, error) { + return ecrecover(header) +} + +// Signers extracts all the addresses who have signed the given header +// It will extract for each seal who signed it, regardless of if the seal is +// repeated +func (sb *backend) Signers(header *types.Header) ([]common.Address, error) { + extra, err := types.ExtractIstanbulExtra(header) + if err != nil { + return []common.Address{}, err + } + + var addrs []common.Address + proposalSeal := istanbulCore.PrepareCommittedSeal(header.Hash()) + + // 1. Get committed seals from current header + for _, seal := range extra.CommittedSeal { + // 2. Get the original address by seal and parent block hash + addr, err := istanbul.GetSignatureAddress(proposalSeal, seal) + if err != nil { + sb.logger.Error("not a valid address", "err", err) + return nil, errInvalidSignature + } + addrs = append(addrs, addr) + } + return addrs, nil +} + +// VerifyHeader checks whether a header conforms to the consensus rules of a +// given engine. Verifying the seal may be done optionally here, or explicitly +// via the VerifySeal method. +func (sb *backend) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error { + return sb.verifyHeader(chain, header, nil) +} + +// verifyHeader checks whether a header conforms to the consensus rules.The +// caller may optionally pass in a batch of parents (ascending order) to avoid +// looking those up from the database. This is useful for concurrently verifying +// a batch of new headers. +func (sb *backend) verifyHeader(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { + if header.Number == nil { + return errUnknownBlock + } + + // Don't waste time checking blocks from the future (adjusting for allowed threshold) + adjustedTimeNow := now().Add(time.Duration(sb.config.AllowedFutureBlockTime) * time.Second).Unix() + if header.Time > uint64(adjustedTimeNow) { + return consensus.ErrFutureBlock + } + + // Ensure that the extra data format is satisfied + if _, err := types.ExtractIstanbulExtra(header); err != nil { + return errInvalidExtraDataFormat + } + + // Ensure that the coinbase is valid + if header.Nonce != (emptyNonce) && !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) { + return errInvalidNonce + } + // Ensure that the mix digest is zero as we don't have fork protection currently + if header.MixDigest != types.IstanbulDigest { + return errInvalidMixDigest + } + // Ensure that the block doesn't contain any uncles which are meaningless in Istanbul + if header.UncleHash != nilUncleHash { + return errInvalidUncleHash + } + // Ensure that the block's difficulty is meaningful (may not be correct at this point) + if header.Difficulty == nil || header.Difficulty.Cmp(defaultDifficulty) != 0 { + return errInvalidDifficulty + } + + return sb.verifyCascadingFields(chain, header, parents) +} + +// verifyCascadingFields verifies all the header fields that are not standalone, +// rather depend on a batch of previous headers. The caller may optionally pass +// in a batch of parents (ascending order) to avoid looking those up from the +// database. This is useful for concurrently verifying a batch of new headers. +func (sb *backend) verifyCascadingFields(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { + // The genesis block is the always valid dead-end + number := header.Number.Uint64() + if number == 0 { + return nil + } + // Ensure that the block's timestamp isn't too close to it's parent + var parent *types.Header + if len(parents) > 0 { + parent = parents[len(parents)-1] + } else { + parent = chain.GetHeader(header.ParentHash, number-1) + } + if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash { + return consensus.ErrUnknownAncestor + } + if parent.Time+sb.config.BlockPeriod > header.Time { + return errInvalidTimestamp + } + // Verify validators in extraData. Validators in snapshot and extraData should be the same. + snap, err := sb.snapshot(chain, number-1, header.ParentHash, parents) + if err != nil { + return err + } + validators := make([]byte, len(snap.validators())*common.AddressLength) + for i, validator := range snap.validators() { + copy(validators[i*common.AddressLength:], validator[:]) + } + if err := sb.verifySigner(chain, header, parents); err != nil { + return err + } + + return sb.verifyCommittedSeals(chain, header, parents) +} + +// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers +// concurrently. The method returns a quit channel to abort the operations and +// a results channel to retrieve the async verifications (the order is that of +// the input slice). +func (sb *backend) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { + abort := make(chan struct{}) + results := make(chan error, len(headers)) + go func() { + errored := false + for i, header := range headers { + var err error + if errored { + err = consensus.ErrUnknownAncestor + } else { + err = sb.verifyHeader(chain, header, headers[:i]) + } + + if err != nil { + errored = true + } + + select { + case <-abort: + return + case results <- err: + } + } + }() + return abort, results +} + +// VerifyUncles verifies that the given block's uncles conform to the consensus +// rules of a given engine. +func (sb *backend) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { + if len(block.Uncles()) > 0 { + return errInvalidUncleHash + } + return nil +} + +// verifySigner checks whether the signer is in parent's validator set +func (sb *backend) verifySigner(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { + // Verifying the genesis block is not supported + number := header.Number.Uint64() + if number == 0 { + return errUnknownBlock + } + + // Retrieve the snapshot needed to verify this header and cache it + snap, err := sb.snapshot(chain, number-1, header.ParentHash, parents) + if err != nil { + return err + } + + // resolve the authorization key and check against signers + signer, err := ecrecover(header) + if err != nil { + return err + } + + // Signer should be in the validator set of previous block's extraData. + if _, v := snap.ValSet.GetByAddress(signer); v == nil { + return errUnauthorized + } + return nil +} + +// verifyCommittedSeals checks whether every committed seal is signed by one of the parent's validators +func (sb *backend) verifyCommittedSeals(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { + number := header.Number.Uint64() + // We don't need to verify committed seals in the genesis block + if number == 0 { + return nil + } + + // Retrieve the snapshot needed to verify this header and cache it + snap, err := sb.snapshot(chain, number-1, header.ParentHash, parents) + if err != nil { + return err + } + + extra, err := types.ExtractIstanbulExtra(header) + if err != nil { + return err + } + // The length of Committed seals should be larger than 0 + if len(extra.CommittedSeal) == 0 { + return errEmptyCommittedSeals + } + + validators := snap.ValSet.Copy() + // Check whether the committed seals are generated by parent's validators + validSeal := 0 + committers, err := sb.Signers(header) + if err != nil { + return err + } + for _, addr := range committers { + if validators.RemoveValidator(addr) { + validSeal++ + continue + } + return errInvalidCommittedSeals + } + + // The length of validSeal should be larger than number of faulty node + 1 + if validSeal <= snap.ValSet.F() { + return errInvalidCommittedSeals + } + + return nil +} + +// VerifySeal checks whether the crypto seal on a header is valid according to +// the consensus rules of the given engine. +func (sb *backend) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error { + // get parent header and ensure the signer is in parent's validator set + number := header.Number.Uint64() + if number == 0 { + return errUnknownBlock + } + + // ensure that the difficulty equals to defaultDifficulty + if header.Difficulty.Cmp(defaultDifficulty) != 0 { + return errInvalidDifficulty + } + return sb.verifySigner(chain, header, nil) +} + +// Prepare initializes the consensus fields of a block header according to the +// rules of a particular engine. The changes are executed inline. +func (sb *backend) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { + // unused fields, force to set to empty + header.Coinbase = common.Address{} + header.Nonce = emptyNonce + header.MixDigest = types.IstanbulDigest + + // copy the parent extra data as the header extra data + number := header.Number.Uint64() + parent := chain.GetHeader(header.ParentHash, number-1) + if parent == nil { + return consensus.ErrUnknownAncestor + } + // use the same difficulty for all blocks + header.Difficulty = defaultDifficulty + + // Assemble the voting snapshot + snap, err := sb.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + return err + } + + // get valid candidate list + sb.candidatesLock.RLock() + var addresses []common.Address + var authorizes []bool + for address, authorize := range sb.candidates { + if snap.checkVote(address, authorize) { + addresses = append(addresses, address) + authorizes = append(authorizes, authorize) + } + } + sb.candidatesLock.RUnlock() + + // pick one of the candidates randomly + if len(addresses) > 0 { + index := rand.Intn(len(addresses)) + // add validator voting in coinbase + header.Coinbase = addresses[index] + if authorizes[index] { + copy(header.Nonce[:], nonceAuthVote) + } else { + copy(header.Nonce[:], nonceDropVote) + } + } + + // add validators in snapshot to extraData's validators section + extra, err := prepareExtra(header, snap.validators()) + if err != nil { + return err + } + header.Extra = extra + + // set header's timestamp + header.Time = parent.Time + sb.config.BlockPeriod + if header.Time < uint64(time.Now().Unix()) { + header.Time = uint64(time.Now().Unix()) + } + return nil +} + +// Finalize runs any post-transaction state modifications (e.g. block rewards) +// and assembles the final block. +// +// Note, the block header and state database might be updated to reflect any +// consensus rules that happen at finalization (e.g. block rewards). +func (sb *backend) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, + uncles []*types.Header) { + // No block rewards in Istanbul, so the state remains as is and uncles are dropped + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.UncleHash = nilUncleHash +} + +// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, +// nor block rewards given, and returns the final block. +func (sb *backend) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { + /// No block rewards in Istanbul, so the state remains as is and uncles are dropped + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.UncleHash = nilUncleHash + + // Assemble and return the final block for sealing + return types.NewBlock(header, txs, nil, receipts, new(trie.Trie)), nil +} + +// Seal generates a new block for the given input block with the local miner's +// seal place on top. +func (sb *backend) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + + // update the block header timestamp and signature and propose the block to core engine + header := block.Header() + number := header.Number.Uint64() + // Bail out if we're unauthorized to sign a block + snap, err := sb.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + return err + } + if _, v := snap.ValSet.GetByAddress(sb.address); v == nil { + return errUnauthorized + } + + parent := chain.GetHeader(header.ParentHash, number-1) + if parent == nil { + return consensus.ErrUnknownAncestor + } + block, err = sb.updateBlock(parent, block) + if err != nil { + return err + } + + delay := time.Unix(int64(block.Header().Time), 0).Sub(now()) + + go func() { + // wait for the timestamp of header, use this to adjust the block period + select { + case <-time.After(delay): + case <-stop: + results <- nil + return + } + + // get the proposed block hash and clear it if the seal() is completed. + sb.sealMu.Lock() + sb.proposedBlockHash = block.Hash() + + defer func() { + sb.proposedBlockHash = common.Hash{} + sb.sealMu.Unlock() + }() + // post block into Istanbul engine + go sb.EventMux().Post(istanbul.RequestEvent{ + Proposal: block, + }) + for { + select { + case result := <-sb.commitCh: + // if the block hash and the hash from channel are the same, + // return the result. Otherwise, keep waiting the next hash. + if result != nil && block.Hash() == result.Hash() { + results <- result + return + } + case <-stop: + results <- nil + return + } + } + }() + return nil +} + +// update timestamp and signature of the block based on its number of transactions +func (sb *backend) updateBlock(parent *types.Header, block *types.Block) (*types.Block, error) { + header := block.Header() + // sign the hash + seal, err := sb.Sign(sigHash(header).Bytes()) + if err != nil { + return nil, err + } + + err = writeSeal(header, seal) + if err != nil { + return nil, err + } + + return block.WithSeal(header), nil +} + +// APIs returns the RPC APIs this consensus engine provides. +func (sb *backend) APIs(chain consensus.ChainHeaderReader) []rpc.API { + return []rpc.API{{ + Namespace: "istanbul", + Version: "1.0", + Service: &API{chain: chain, istanbul: sb}, + Public: true, + }} +} + +// Start implements consensus.Istanbul.Start +func (sb *backend) Start(chain consensus.ChainHeaderReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error { + sb.coreMu.Lock() + defer sb.coreMu.Unlock() + if sb.coreStarted { + return istanbul.ErrStartedEngine + } + + // clear previous data + sb.proposedBlockHash = common.Hash{} + if sb.commitCh != nil { + close(sb.commitCh) + } + sb.commitCh = make(chan *types.Block, 1) + + sb.chain = chain + sb.currentBlock = currentBlock + sb.hasBadBlock = hasBadBlock + + if err := sb.core.Start(); err != nil { + return err + } + + sb.coreStarted = true + return nil +} + +// Stop implements consensus.Istanbul.Stop +func (sb *backend) Stop() error { + sb.coreMu.Lock() + defer sb.coreMu.Unlock() + if !sb.coreStarted { + return istanbul.ErrStoppedEngine + } + if err := sb.core.Stop(); err != nil { + return err + } + sb.coreStarted = false + return nil +} + +// snapshot retrieves the authorization snapshot at a given point in time. +func (sb *backend) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { + // Search for a snapshot in memory or on disk for checkpoints + var ( + headers []*types.Header + snap *Snapshot + ) + for snap == nil { + // If an in-memory snapshot was found, use that + if s, ok := sb.recents.Get(hash); ok { + snap = s.(*Snapshot) + break + } + // If an on-disk checkpoint snapshot can be found, use that + if number%checkpointInterval == 0 { + if s, err := loadSnapshot(sb.config.Epoch, sb.db, hash); err == nil { + log.Trace("Loaded voting snapshot form disk", "number", number, "hash", hash) + snap = s + break + } + } + // If we're at block zero, make a snapshot + if number == 0 { + genesis := chain.GetHeaderByNumber(0) + if err := sb.VerifyHeader(chain, genesis, false); err != nil { + return nil, err + } + istanbulExtra, err := types.ExtractIstanbulExtra(genesis) + if err != nil { + return nil, err + } + snap = newSnapshot(sb.config.Epoch, 0, genesis.Hash(), validator.NewSet(istanbulExtra.Validators, sb.config.ProposerPolicy)) + if err := snap.store(sb.db); err != nil { + return nil, err + } + log.Trace("Stored genesis voting snapshot to disk") + break + } + // No snapshot for this header, gather the header and move backward + var header *types.Header + if len(parents) > 0 { + // If we have explicit parents, pick from there (enforced) + header = parents[len(parents)-1] + if header.Hash() != hash || header.Number.Uint64() != number { + return nil, consensus.ErrUnknownAncestor + } + parents = parents[:len(parents)-1] + } else { + // No explicit parents (or no more left), reach out to the database + header = chain.GetHeader(hash, number) + if header == nil { + return nil, consensus.ErrUnknownAncestor + } + } + headers = append(headers, header) + number, hash = number-1, header.ParentHash + } + // Previous snapshot found, apply any pending headers on top of it + for i := 0; i < len(headers)/2; i++ { + headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] + } + snap, err := snap.apply(headers) + if err != nil { + return nil, err + } + sb.recents.Add(snap.Hash, snap) + + // If we've generated a new checkpoint snapshot, save to disk + if snap.Number%checkpointInterval == 0 && len(headers) > 0 { + if err = snap.store(sb.db); err != nil { + return nil, err + } + log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash) + } + return snap, err +} + +// FIXME: Need to update this for Istanbul +// sigHash returns the hash which is used as input for the Istanbul +// signing. It is the hash of the entire header apart from the 65 byte signature +// contained at the end of the extra data. +// +// Note, the method requires the extra data to be at least 65 bytes, otherwise it +// panics. This is done to avoid accidentally using both forms (signature present +// or not), which could be abused to produce different hashes for the same header. +func sigHash(header *types.Header) (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + + // Clean seal is required for calculating proposer seal. + rlp.Encode(hasher, types.IstanbulFilteredHeader(header, false)) + hasher.Sum(hash[:0]) + return hash +} + +// SealHash returns the hash of a block prior to it being sealed. +func (sb *backend) SealHash(header *types.Header) common.Hash { + return sigHash(header) +} + +// ecrecover extracts the Ethereum account address from a signed header. +func ecrecover(header *types.Header) (common.Address, error) { + hash := header.Hash() + if addr, ok := recentAddresses.Get(hash); ok { + return addr.(common.Address), nil + } + + // Retrieve the signature from the header extra-data + istanbulExtra, err := types.ExtractIstanbulExtra(header) + if err != nil { + return common.Address{}, err + } + + addr, err := istanbul.GetSignatureAddress(sigHash(header).Bytes(), istanbulExtra.Seal) + if err != nil { + return addr, err + } + recentAddresses.Add(hash, addr) + return addr, nil +} + +// prepareExtra returns a extra-data of the given header and validators +func prepareExtra(header *types.Header, vals []common.Address) ([]byte, error) { + var buf bytes.Buffer + + // compensate the lack bytes if header.Extra is not enough IstanbulExtraVanity bytes. + if len(header.Extra) < types.IstanbulExtraVanity { + header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity-len(header.Extra))...) + } + buf.Write(header.Extra[:types.IstanbulExtraVanity]) + + ist := &types.IstanbulExtra{ + Validators: vals, + Seal: []byte{}, + CommittedSeal: [][]byte{}, + } + + payload, err := rlp.EncodeToBytes(&ist) + if err != nil { + return nil, err + } + + return append(buf.Bytes(), payload...), nil +} + +// writeSeal writes the extra-data field of the given header with the given seals. +// suggest to rename to writeSeal. +func writeSeal(h *types.Header, seal []byte) error { + if len(seal)%types.IstanbulExtraSeal != 0 { + return errInvalidSignature + } + + istanbulExtra, err := types.ExtractIstanbulExtra(h) + if err != nil { + return err + } + + istanbulExtra.Seal = seal + payload, err := rlp.EncodeToBytes(&istanbulExtra) + if err != nil { + return err + } + + h.Extra = append(h.Extra[:types.IstanbulExtraVanity], payload...) + return nil +} + +// writeCommittedSeals writes the extra-data field of a block header with given committed seals. +func writeCommittedSeals(h *types.Header, committedSeals [][]byte) error { + if len(committedSeals) == 0 { + return errInvalidCommittedSeals + } + + for _, seal := range committedSeals { + if len(seal) != types.IstanbulExtraSeal { + return errInvalidCommittedSeals + } + } + + istanbulExtra, err := types.ExtractIstanbulExtra(h) + if err != nil { + return err + } + + istanbulExtra.CommittedSeal = make([][]byte, len(committedSeals)) + copy(istanbulExtra.CommittedSeal, committedSeals) + + payload, err := rlp.EncodeToBytes(&istanbulExtra) + if err != nil { + return err + } + + h.Extra = append(h.Extra[:types.IstanbulExtraVanity], payload...) + return nil +} diff --git a/consensus/istanbul/backend/engine_test.go b/consensus/istanbul/backend/engine_test.go new file mode 100644 index 0000000000..410cdc6d9d --- /dev/null +++ b/consensus/istanbul/backend/engine_test.go @@ -0,0 +1,579 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "crypto/ecdsa" + "math/big" + "reflect" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// in this test, we can set n to 1, and it means we can process Istanbul and commit a +// block by one node. Otherwise, if n is larger than 1, we have to generate +// other fake events to process Istanbul. +func newBlockChain(n int) (*core.BlockChain, *backend) { + genesis, nodeKeys := getGenesisAndKeys(n) + memDB := rawdb.NewMemoryDatabase() + config := istanbul.DefaultConfig + // Use the first key as private key + b, _ := New(config, nodeKeys[0], memDB).(*backend) + genesis.MustCommit(memDB) + blockchain, err := core.NewBlockChain(memDB, nil, genesis.Config, b, vm.Config{}, nil, nil) + if err != nil { + panic(err) + } + b.Start(blockchain, blockchain.CurrentBlock, blockchain.HasBadBlock) + snap, err := b.snapshot(blockchain, 0, common.Hash{}, nil) + if err != nil { + panic(err) + } + if snap == nil { + panic("failed to get snapshot") + } + proposerAddr := snap.ValSet.GetProposer().Address() + + // find proposer key + for _, key := range nodeKeys { + addr := crypto.PubkeyToAddress(key.PublicKey) + if addr.String() == proposerAddr.String() { + b.privateKey = key + b.address = addr + } + } + + return blockchain, b +} + +func getGenesisAndKeys(n int) (*core.Genesis, []*ecdsa.PrivateKey) { + // Setup validators + var nodeKeys = make([]*ecdsa.PrivateKey, n) + var addrs = make([]common.Address, n) + for i := 0; i < n; i++ { + nodeKeys[i], _ = crypto.GenerateKey() + addrs[i] = crypto.PubkeyToAddress(nodeKeys[i].PublicKey) + } + + // generate genesis block + genesis := core.DefaultGenesisBlock() + genesis.Config = params.TestChainConfig + // force enable Istanbul engine + genesis.Config.Istanbul = ¶ms.IstanbulConfig{} + genesis.Config.Ethash = nil + genesis.Difficulty = defaultDifficulty + genesis.Nonce = emptyNonce.Uint64() + genesis.Mixhash = types.IstanbulDigest + + appendValidators(genesis, addrs) + return genesis, nodeKeys +} + +func appendValidators(genesis *core.Genesis, addrs []common.Address) { + + if len(genesis.ExtraData) < types.IstanbulExtraVanity { + genesis.ExtraData = append(genesis.ExtraData, bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity)...) + } + genesis.ExtraData = genesis.ExtraData[:types.IstanbulExtraVanity] + + ist := &types.IstanbulExtra{ + Validators: addrs, + Seal: []byte{}, + CommittedSeal: [][]byte{}, + } + + istPayload, err := rlp.EncodeToBytes(&ist) + if err != nil { + panic("failed to encode istanbul extra") + } + genesis.ExtraData = append(genesis.ExtraData, istPayload...) +} + +func makeHeader(parent *types.Block, config *istanbul.Config) *types.Header { + header := &types.Header{ + ParentHash: parent.Hash(), + Number: parent.Number().Add(parent.Number(), common.Big1), + GasLimit: core.CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()), + GasUsed: 0, + Extra: parent.Extra(), + Time: parent.Time() + config.BlockPeriod, + + Difficulty: defaultDifficulty, + } + return header +} + +func makeBlock(chain *core.BlockChain, engine *backend, parent *types.Block) *types.Block { + block := makeBlockWithoutSeal(chain, engine, parent) + stopCh := make(chan struct{}) + resultCh := make(chan *types.Block, 10) + go engine.Seal(chain, block, resultCh, stopCh) + blk := <-resultCh + return blk +} + +func makeBlockWithoutSeal(chain *core.BlockChain, engine *backend, parent *types.Block) *types.Block { + header := makeHeader(parent, engine.config) + engine.Prepare(chain, header) + state, _, _ := chain.StateAt(parent.Root()) + block, _ := engine.FinalizeAndAssemble(chain, header, state, nil, nil, nil) + return block +} + +func TestPrepare(t *testing.T) { + chain, engine := newBlockChain(1) + header := makeHeader(chain.Genesis(), engine.config) + err := engine.Prepare(chain, header) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + header.ParentHash = common.StringToHash("1234567890") + err = engine.Prepare(chain, header) + if err != consensus.ErrUnknownAncestor { + t.Errorf("error mismatch: have %v, want %v", err, consensus.ErrUnknownAncestor) + } +} + +func TestSealStopChannel(t *testing.T) { + chain, engine := newBlockChain(4) + block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) + stop := make(chan struct{}, 1) + eventSub := engine.EventMux().Subscribe(istanbul.RequestEvent{}) + eventLoop := func() { + ev := <-eventSub.Chan() + _, ok := ev.Data.(istanbul.RequestEvent) + if !ok { + t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data)) + } + stop <- struct{}{} + eventSub.Unsubscribe() + } + go eventLoop() + resultCh := make(chan *types.Block, 10) + go func() { + err := engine.Seal(chain, block, resultCh, stop) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + }() + + finalBlock := <-resultCh + if finalBlock != nil { + t.Errorf("block mismatch: have %v, want nil", finalBlock) + } +} + +func TestSealCommittedOtherHash(t *testing.T) { + chain, engine := newBlockChain(4) + block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) + otherBlock := makeBlockWithoutSeal(chain, engine, block) + expectedCommittedSeal := append([]byte{1, 2, 3}, bytes.Repeat([]byte{0x00}, types.IstanbulExtraSeal-3)...) + + eventSub := engine.EventMux().Subscribe(istanbul.RequestEvent{}) + blockOutputChannel := make(chan *types.Block) + stopChannel := make(chan struct{}) + + go func() { + ev := <-eventSub.Chan() + if _, ok := ev.Data.(istanbul.RequestEvent); !ok { + t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data)) + } + if err := engine.Commit(otherBlock, [][]byte{expectedCommittedSeal}); err != nil { + t.Error(err.Error()) + } + eventSub.Unsubscribe() + }() + + go func() { + if err := engine.Seal(chain, block, blockOutputChannel, stopChannel); err != nil { + t.Error(err.Error()) + } + }() + + select { + case <-blockOutputChannel: + t.Error("Wrong block found!") + default: + //no block found, stop the sealing + close(stopChannel) + } + + output := <-blockOutputChannel + if output != nil { + t.Error("Block not nil!") + } +} + +func TestSealCommitted(t *testing.T) { + chain, engine := newBlockChain(1) + block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) + expectedBlock, _ := engine.updateBlock(engine.chain.GetHeader(block.ParentHash(), block.NumberU64()-1), block) + resultCh := make(chan *types.Block, 10) + go func() { + err := engine.Seal(chain, block, resultCh, make(chan struct{})) + + if err != nil { + t.Errorf("error mismatch: have %v, want %v", err, expectedBlock) + } + }() + + finalBlock := <-resultCh + if finalBlock.Hash() != expectedBlock.Hash() { + t.Errorf("hash mismatch: have %v, want %v", finalBlock.Hash(), expectedBlock.Hash()) + } +} + +func TestVerifyHeader(t *testing.T) { + chain, engine := newBlockChain(1) + + // errEmptyCommittedSeals case + block := makeBlockWithoutSeal(chain, engine, chain.Genesis()) + block, _ = engine.updateBlock(chain.Genesis().Header(), block) + err := engine.VerifyHeader(chain, block.Header(), false) + if err != errEmptyCommittedSeals { + t.Errorf("error mismatch: have %v, want %v", err, errEmptyCommittedSeals) + } + + // short extra data + header := block.Header() + header.Extra = []byte{} + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidExtraDataFormat { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidExtraDataFormat) + } + // incorrect extra format + header.Extra = []byte("0000000000000000000000000000000012300000000000000000000000000000000000000000000000000000000000000000") + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidExtraDataFormat { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidExtraDataFormat) + } + + // non zero MixDigest + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + header.MixDigest = common.StringToHash("123456789") + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidMixDigest { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidMixDigest) + } + + // invalid uncles hash + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + header.UncleHash = common.StringToHash("123456789") + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidUncleHash { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidUncleHash) + } + + // invalid difficulty + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + header.Difficulty = big.NewInt(2) + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidDifficulty { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidDifficulty) + } + + // invalid timestamp + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + header.Time = chain.Genesis().Time() + (engine.config.BlockPeriod - 1) + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidTimestamp { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidTimestamp) + } + + // future block + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + header.Time = uint64(now().Unix() + 10) + err = engine.VerifyHeader(chain, header, false) + if err != consensus.ErrFutureBlock { + t.Errorf("error mismatch: have %v, want %v", err, consensus.ErrFutureBlock) + } + + // future block which is within AllowedFutureBlockTime + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + header.Time = new(big.Int).Add(big.NewInt(now().Unix()), new(big.Int).SetUint64(10)).Uint64() + priorValue := engine.config.AllowedFutureBlockTime + engine.config.AllowedFutureBlockTime = 10 + err = engine.VerifyHeader(chain, header, false) + engine.config.AllowedFutureBlockTime = priorValue //restore changed value + if err == consensus.ErrFutureBlock { + t.Errorf("error mismatch: have %v, want nil", err) + } + + // invalid nonce + block = makeBlockWithoutSeal(chain, engine, chain.Genesis()) + header = block.Header() + copy(header.Nonce[:], hexutil.MustDecode("0x111111111111")) + header.Number = big.NewInt(int64(engine.config.Epoch)) + err = engine.VerifyHeader(chain, header, false) + if err != errInvalidNonce { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidNonce) + } +} + +func TestVerifySeal(t *testing.T) { + chain, engine := newBlockChain(1) + genesis := chain.Genesis() + // cannot verify genesis + err := engine.VerifySeal(chain, genesis.Header()) + if err != errUnknownBlock { + t.Errorf("error mismatch: have %v, want %v", err, errUnknownBlock) + } + + block := makeBlock(chain, engine, genesis) + // change block content + header := block.Header() + header.Number = big.NewInt(4) + block1 := block.WithSeal(header) + err = engine.VerifySeal(chain, block1.Header()) + if err != errUnauthorized { + t.Errorf("error mismatch: have %v, want %v", err, errUnauthorized) + } + + // unauthorized users but still can get correct signer address + engine.privateKey, _ = crypto.GenerateKey() + err = engine.VerifySeal(chain, block.Header()) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } +} + +func TestVerifyHeaders(t *testing.T) { + chain, engine := newBlockChain(1) + genesis := chain.Genesis() + + // success case + headers := []*types.Header{} + blocks := []*types.Block{} + size := 100 + + for i := 0; i < size; i++ { + var b *types.Block + if i == 0 { + b = makeBlockWithoutSeal(chain, engine, genesis) + b, _ = engine.updateBlock(genesis.Header(), b) + } else { + b = makeBlockWithoutSeal(chain, engine, blocks[i-1]) + b, _ = engine.updateBlock(blocks[i-1].Header(), b) + } + blocks = append(blocks, b) + headers = append(headers, blocks[i].Header()) + } + now = func() time.Time { + return time.Unix(int64(headers[size-1].Time), 0) + } + _, results := engine.VerifyHeaders(chain, headers, nil) + const timeoutDura = 2 * time.Second + timeout := time.NewTimer(timeoutDura) + index := 0 +OUT1: + for { + select { + case err := <-results: + if err != nil { + if err != errEmptyCommittedSeals && err != errInvalidCommittedSeals && err != consensus.ErrUnknownAncestor { + t.Errorf("error mismatch: have %v, want errEmptyCommittedSeals|errInvalidCommittedSeals|ErrUnknownAncestor", err) + break OUT1 + } + } + index++ + if index == size { + break OUT1 + } + case <-timeout.C: + break OUT1 + } + } + _, results = engine.VerifyHeaders(chain, headers, nil) + timeout = time.NewTimer(timeoutDura) +OUT2: + for { + select { + case err := <-results: + if err != nil { + if err != errEmptyCommittedSeals && err != errInvalidCommittedSeals && err != consensus.ErrUnknownAncestor { + t.Errorf("error mismatch: have %v, want errEmptyCommittedSeals|errInvalidCommittedSeals|ErrUnknownAncestor", err) + break OUT2 + } + } + case <-timeout.C: + break OUT2 + } + } + // error header cases + headers[2].Number = big.NewInt(100) + _, results = engine.VerifyHeaders(chain, headers, nil) + timeout = time.NewTimer(timeoutDura) + index = 0 + errors := 0 + expectedErrors := 0 +OUT3: + for { + select { + case err := <-results: + if err != nil { + if err != errEmptyCommittedSeals && err != errInvalidCommittedSeals && err != consensus.ErrUnknownAncestor { + errors++ + } + } + index++ + if index == size { + if errors != expectedErrors { + t.Errorf("error mismatch: have %v, want %v", errors, expectedErrors) + } + break OUT3 + } + case <-timeout.C: + break OUT3 + } + } +} + +func TestPrepareExtra(t *testing.T) { + validators := make([]common.Address, 4) + validators[0] = common.BytesToAddress(hexutil.MustDecode("0x44add0ec310f115a0e603b2d7db9f067778eaf8a")) + validators[1] = common.BytesToAddress(hexutil.MustDecode("0x294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212")) + validators[2] = common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")) + validators[3] = common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")) + + vanity := make([]byte, types.IstanbulExtraVanity) + expectedResult := append(vanity, hexutil.MustDecode("0xf858f8549444add0ec310f115a0e603b2d7db9f067778eaf8a94294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212946beaaed781d2d2ab6350f5c4566a2c6eaac407a6948be76812f765c24641ec63dc2852b378aba2b44080c0")...) + + h := &types.Header{ + Extra: vanity, + } + + payload, err := prepareExtra(h, validators) + if err != nil { + t.Errorf("error mismatch: have %v, want: nil", err) + } + if !reflect.DeepEqual(payload, expectedResult) { + t.Errorf("payload mismatch: have %v, want %v", payload, expectedResult) + } + + // append useless information to extra-data + h.Extra = append(vanity, make([]byte, 15)...) + + payload, _ = prepareExtra(h, validators) + if !reflect.DeepEqual(payload, expectedResult) { + t.Errorf("payload mismatch: have %v, want %v", payload, expectedResult) + } +} + +func TestWriteSeal(t *testing.T) { + vanity := bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity) + istRawData := hexutil.MustDecode("0xf858f8549444add0ec310f115a0e603b2d7db9f067778eaf8a94294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212946beaaed781d2d2ab6350f5c4566a2c6eaac407a6948be76812f765c24641ec63dc2852b378aba2b44080c0") + expectedSeal := append([]byte{1, 2, 3}, bytes.Repeat([]byte{0x00}, types.IstanbulExtraSeal-3)...) + expectedIstExtra := &types.IstanbulExtra{ + Validators: []common.Address{ + common.BytesToAddress(hexutil.MustDecode("0x44add0ec310f115a0e603b2d7db9f067778eaf8a")), + common.BytesToAddress(hexutil.MustDecode("0x294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212")), + common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")), + common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")), + }, + Seal: expectedSeal, + CommittedSeal: [][]byte{}, + } + var expectedErr error + + h := &types.Header{ + Extra: append(vanity, istRawData...), + } + + // normal case + err := writeSeal(h, expectedSeal) + if err != expectedErr { + t.Errorf("error mismatch: have %v, want %v", err, expectedErr) + } + + // verify istanbul extra-data + istExtra, err := types.ExtractIstanbulExtra(h) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + if !reflect.DeepEqual(istExtra, expectedIstExtra) { + t.Errorf("extra data mismatch: have %v, want %v", istExtra, expectedIstExtra) + } + + // invalid seal + unexpectedSeal := append(expectedSeal, make([]byte, 1)...) + err = writeSeal(h, unexpectedSeal) + if err != errInvalidSignature { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidSignature) + } +} + +func TestWriteCommittedSeals(t *testing.T) { + vanity := bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity) + istRawData := hexutil.MustDecode("0xf858f8549444add0ec310f115a0e603b2d7db9f067778eaf8a94294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212946beaaed781d2d2ab6350f5c4566a2c6eaac407a6948be76812f765c24641ec63dc2852b378aba2b44080c0") + expectedCommittedSeal := append([]byte{1, 2, 3}, bytes.Repeat([]byte{0x00}, types.IstanbulExtraSeal-3)...) + expectedIstExtra := &types.IstanbulExtra{ + Validators: []common.Address{ + common.BytesToAddress(hexutil.MustDecode("0x44add0ec310f115a0e603b2d7db9f067778eaf8a")), + common.BytesToAddress(hexutil.MustDecode("0x294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212")), + common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")), + common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")), + }, + Seal: []byte{}, + CommittedSeal: [][]byte{expectedCommittedSeal}, + } + var expectedErr error + + h := &types.Header{ + Extra: append(vanity, istRawData...), + } + + // normal case + err := writeCommittedSeals(h, [][]byte{expectedCommittedSeal}) + if err != expectedErr { + t.Errorf("error mismatch: have %v, want %v", err, expectedErr) + } + + // verify istanbul extra-data + istExtra, err := types.ExtractIstanbulExtra(h) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + if !reflect.DeepEqual(istExtra, expectedIstExtra) { + t.Errorf("extra data mismatch: have %v, want %v", istExtra, expectedIstExtra) + } + + // invalid seal + unexpectedCommittedSeal := append(expectedCommittedSeal, make([]byte, 1)...) + err = writeCommittedSeals(h, [][]byte{unexpectedCommittedSeal}) + if err != errInvalidCommittedSeals { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidCommittedSeals) + } +} diff --git a/consensus/istanbul/backend/handler.go b/consensus/istanbul/backend/handler.go new file mode 100644 index 0000000000..8592092c9e --- /dev/null +++ b/consensus/istanbul/backend/handler.go @@ -0,0 +1,138 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "errors" + "io/ioutil" + "math/big" + "reflect" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + lru "github.com/hashicorp/golang-lru" +) + +const ( + istanbulMsg = 0x11 + NewBlockMsg = 0x07 +) + +var ( + // errDecodeFailed is returned when decode message fails + errDecodeFailed = errors.New("fail to decode istanbul message") +) + +// Protocol implements consensus.Engine.Protocol +func (sb *backend) Protocol() consensus.Protocol { + return consensus.IstanbulProtocol +} + +func (sb *backend) decode(msg p2p.Msg) ([]byte, common.Hash, error) { + var data []byte + if err := msg.Decode(&data); err != nil { + return nil, common.Hash{}, errDecodeFailed + } + + return data, istanbul.RLPHash(data), nil +} + +// HandleMsg implements consensus.Handler.HandleMsg +func (sb *backend) HandleMsg(addr common.Address, msg p2p.Msg) (bool, error) { + sb.coreMu.Lock() + defer sb.coreMu.Unlock() + if msg.Code == istanbulMsg { + if !sb.coreStarted { + return true, istanbul.ErrStoppedEngine + } + + data, hash, err := sb.decode(msg) + if err != nil { + return true, errDecodeFailed + } + // Mark peer's message + ms, ok := sb.recentMessages.Get(addr) + var m *lru.ARCCache + if ok { + m, _ = ms.(*lru.ARCCache) + } else { + m, _ = lru.NewARC(inmemoryMessages) + sb.recentMessages.Add(addr, m) + } + m.Add(hash, true) + + // Mark self known message + if _, ok := sb.knownMessages.Get(hash); ok { + return true, nil + } + sb.knownMessages.Add(hash, true) + + go sb.istanbulEventMux.Post(istanbul.MessageEvent{ + Payload: data, + }) + return true, nil + } + //https://github.com/ConsenSys/quorum/pull/539 + //https://github.com/ConsenSys/quorum/issues/389 + if msg.Code == NewBlockMsg && sb.core.IsProposer() { // eth.NewBlockMsg: import cycle + // this case is to safeguard the race of similar block which gets propagated from other node while this node is proposing + // as p2p.Msg can only be decoded once (get EOF for any subsequence read), we need to make sure the payload is restored after we decode it + log.Debug("Proposer received NewBlockMsg", "size", msg.Size, "payload.type", reflect.TypeOf(msg.Payload), "sender", addr) + if reader, ok := msg.Payload.(*bytes.Reader); ok { + payload, err := ioutil.ReadAll(reader) + if err != nil { + return true, err + } + reader.Reset(payload) // ready to be decoded + defer reader.Reset(payload) // restore so main eth/handler can decode + var request struct { // this has to be same as eth/protocol.go#newBlockData as we are reading NewBlockMsg + Block *types.Block + TD *big.Int + } + if err := msg.Decode(&request); err != nil { + log.Debug("Proposer was unable to decode the NewBlockMsg", "error", err) + return false, nil + } + newRequestedBlock := request.Block + if newRequestedBlock.Header().MixDigest == types.IstanbulDigest && sb.core.IsCurrentProposal(newRequestedBlock.Hash()) { + log.Debug("Proposer already proposed this block", "hash", newRequestedBlock.Hash(), "sender", addr) + return true, nil + } + } + } + return false, nil +} + +// SetBroadcaster implements consensus.Handler.SetBroadcaster +func (sb *backend) SetBroadcaster(broadcaster consensus.Broadcaster) { + sb.broadcaster = broadcaster +} + +func (sb *backend) NewChainHead() error { + sb.coreMu.RLock() + defer sb.coreMu.RUnlock() + if !sb.coreStarted { + return istanbul.ErrStoppedEngine + } + go sb.istanbulEventMux.Post(istanbul.FinalCommittedEvent{}) + return nil +} diff --git a/consensus/istanbul/backend/handler_test.go b/consensus/istanbul/backend/handler_test.go new file mode 100644 index 0000000000..62061d4ef6 --- /dev/null +++ b/consensus/istanbul/backend/handler_test.go @@ -0,0 +1,182 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "io/ioutil" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + lru "github.com/hashicorp/golang-lru" +) + +func TestIstanbulMessage(t *testing.T) { + _, backend := newBlockChain(1) + + // generate one msg + data := []byte("data1") + hash := istanbul.RLPHash(data) + msg := makeMsg(istanbulMsg, data) + addr := common.StringToAddress("address") + + // 1. this message should not be in cache + // for peers + if _, ok := backend.recentMessages.Get(addr); ok { + t.Fatalf("the cache of messages for this peer should be nil") + } + + // for self + if _, ok := backend.knownMessages.Get(hash); ok { + t.Fatalf("the cache of messages should be nil") + } + + // 2. this message should be in cache after we handle it + _, err := backend.HandleMsg(addr, msg) + if err != nil { + t.Fatalf("handle message failed: %v", err) + } + // for peers + if ms, ok := backend.recentMessages.Get(addr); ms == nil || !ok { + t.Fatalf("the cache of messages for this peer cannot be nil") + } else if m, ok := ms.(*lru.ARCCache); !ok { + t.Fatalf("the cache of messages for this peer cannot be casted") + } else if _, ok := m.Get(hash); !ok { + t.Fatalf("the cache of messages for this peer cannot be found") + } + + // for self + if _, ok := backend.knownMessages.Get(hash); !ok { + t.Fatalf("the cache of messages cannot be found") + } +} + +func makeMsg(msgcode uint64, data interface{}) p2p.Msg { + size, r, _ := rlp.EncodeToReader(data) + return p2p.Msg{Code: msgcode, Size: uint32(size), Payload: r} +} + +func TestHandleNewBlockMessage_whenTypical(t *testing.T) { + _, backend := newBlockChain(1) + arbitraryAddress := common.StringToAddress("arbitrary") + arbitraryBlock, arbitraryP2PMessage := buildArbitraryP2PNewBlockMessage(t, false) + postAndWait(backend, arbitraryBlock, t) + + handled, err := backend.HandleMsg(arbitraryAddress, arbitraryP2PMessage) + + if err != nil { + t.Errorf("expected message being handled successfully but got %s", err) + } + if !handled { + t.Errorf("expected message being handled but not") + } + if _, err := ioutil.ReadAll(arbitraryP2PMessage.Payload); err != nil { + t.Errorf("expected p2p message payload is restored") + } +} + +func TestHandleNewBlockMessage_whenNotAProposedBlock(t *testing.T) { + _, backend := newBlockChain(1) + arbitraryAddress := common.StringToAddress("arbitrary") + _, arbitraryP2PMessage := buildArbitraryP2PNewBlockMessage(t, false) + postAndWait(backend, types.NewBlock(&types.Header{ + Number: big.NewInt(1), + Root: common.StringToHash("someroot"), + GasLimit: 1, + MixDigest: types.IstanbulDigest, + }, nil, nil, nil, new(trie.Trie)), t) + + handled, err := backend.HandleMsg(arbitraryAddress, arbitraryP2PMessage) + + if err != nil { + t.Errorf("expected message being handled successfully but got %s", err) + } + if handled { + t.Errorf("expected message not being handled") + } + if _, err := ioutil.ReadAll(arbitraryP2PMessage.Payload); err != nil { + t.Errorf("expected p2p message payload is restored") + } +} + +func TestHandleNewBlockMessage_whenFailToDecode(t *testing.T) { + _, backend := newBlockChain(1) + arbitraryAddress := common.StringToAddress("arbitrary") + _, arbitraryP2PMessage := buildArbitraryP2PNewBlockMessage(t, true) + postAndWait(backend, types.NewBlock(&types.Header{ + Number: big.NewInt(1), + GasLimit: 1, + MixDigest: types.IstanbulDigest, + }, nil, nil, nil, new(trie.Trie)), t) + + handled, err := backend.HandleMsg(arbitraryAddress, arbitraryP2PMessage) + + if err != nil { + t.Errorf("expected message being handled successfully but got %s", err) + } + if handled { + t.Errorf("expected message not being handled") + } + if _, err := ioutil.ReadAll(arbitraryP2PMessage.Payload); err != nil { + t.Errorf("expected p2p message payload is restored") + } +} + +func postAndWait(backend *backend, block *types.Block, t *testing.T) { + eventSub := backend.EventMux().Subscribe(istanbul.RequestEvent{}) + defer eventSub.Unsubscribe() + stop := make(chan struct{}, 1) + eventLoop := func() { + <-eventSub.Chan() + stop <- struct{}{} + } + go eventLoop() + if err := backend.EventMux().Post(istanbul.RequestEvent{ + Proposal: block, + }); err != nil { + t.Fatalf("%s", err) + } + <-stop +} + +func buildArbitraryP2PNewBlockMessage(t *testing.T, invalidMsg bool) (*types.Block, p2p.Msg) { + arbitraryBlock := types.NewBlock(&types.Header{ + Number: big.NewInt(1), + GasLimit: 0, + MixDigest: types.IstanbulDigest, + }, nil, nil, nil, new(trie.Trie)) + request := []interface{}{&arbitraryBlock, big.NewInt(1)} + if invalidMsg { + request = []interface{}{"invalid msg"} + } + size, r, err := rlp.EncodeToReader(request) + if err != nil { + t.Fatalf("can't encode due to %s", err) + } + payload, err := ioutil.ReadAll(r) + if err != nil { + t.Fatalf("can't read payload due to %s", err) + } + arbitraryP2PMessage := p2p.Msg{Code: 0x07, Size: uint32(size), Payload: bytes.NewReader(payload)} + return arbitraryBlock, arbitraryP2PMessage +} diff --git a/consensus/istanbul/backend/snapshot.go b/consensus/istanbul/backend/snapshot.go new file mode 100644 index 0000000000..e369147f81 --- /dev/null +++ b/consensus/istanbul/backend/snapshot.go @@ -0,0 +1,321 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" +) + +const ( + dbKeySnapshotPrefix = "istanbul-snapshot" +) + +// Vote represents a single vote that an authorized validator made to modify the +// list of authorizations. +type Vote struct { + Validator common.Address `json:"validator"` // Authorized validator that cast this vote + Block uint64 `json:"block"` // Block number the vote was cast in (expire old votes) + Address common.Address `json:"address"` // Account being voted on to change its authorization + Authorize bool `json:"authorize"` // Whether to authorize or deauthorize the voted account +} + +// Tally is a simple vote tally to keep the current score of votes. Votes that +// go against the proposal aren't counted since it's equivalent to not voting. +type Tally struct { + Authorize bool `json:"authorize"` // Whether the vote it about authorizing or kicking someone + Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal +} + +// Snapshot is the state of the authorization voting at a given point in time. +type Snapshot struct { + Epoch uint64 // The number of blocks after which to checkpoint and reset the pending votes + + Number uint64 // Block number where the snapshot was created + Hash common.Hash // Block hash where the snapshot was created + Votes []*Vote // List of votes cast in chronological order + Tally map[common.Address]Tally // Current vote tally to avoid recalculating + ValSet istanbul.ValidatorSet // Set of authorized validators at this moment +} + +// newSnapshot create a new snapshot with the specified startup parameters. This +// method does not initialize the set of recent validators, so only ever use if for +// the genesis block. +func newSnapshot(epoch uint64, number uint64, hash common.Hash, valSet istanbul.ValidatorSet) *Snapshot { + snap := &Snapshot{ + Epoch: epoch, + Number: number, + Hash: hash, + ValSet: valSet, + Tally: make(map[common.Address]Tally), + } + return snap +} + +// loadSnapshot loads an existing snapshot from the database. +func loadSnapshot(epoch uint64, db ethdb.Database, hash common.Hash) (*Snapshot, error) { + blob, err := db.Get(append([]byte(dbKeySnapshotPrefix), hash[:]...)) + if err != nil { + return nil, err + } + snap := new(Snapshot) + if err := json.Unmarshal(blob, snap); err != nil { + return nil, err + } + snap.Epoch = epoch + + return snap, nil +} + +// store inserts the snapshot into the database. +func (s *Snapshot) store(db ethdb.Database) error { + blob, err := json.Marshal(s) + if err != nil { + return err + } + return db.Put(append([]byte(dbKeySnapshotPrefix), s.Hash[:]...), blob) +} + +// copy creates a deep copy of the snapshot, though not the individual votes. +func (s *Snapshot) copy() *Snapshot { + cpy := &Snapshot{ + Epoch: s.Epoch, + Number: s.Number, + Hash: s.Hash, + ValSet: s.ValSet.Copy(), + Votes: make([]*Vote, len(s.Votes)), + Tally: make(map[common.Address]Tally), + } + + for address, tally := range s.Tally { + cpy.Tally[address] = tally + } + copy(cpy.Votes, s.Votes) + + return cpy +} + +// checkVote return whether it's a valid vote +func (s *Snapshot) checkVote(address common.Address, authorize bool) bool { + _, validator := s.ValSet.GetByAddress(address) + return (validator != nil && !authorize) || (validator == nil && authorize) +} + +// cast adds a new vote into the tally. +func (s *Snapshot) cast(address common.Address, authorize bool) bool { + // Ensure the vote is meaningful + if !s.checkVote(address, authorize) { + return false + } + // Cast the vote into an existing or new tally + if old, ok := s.Tally[address]; ok { + old.Votes++ + s.Tally[address] = old + } else { + s.Tally[address] = Tally{Authorize: authorize, Votes: 1} + } + return true +} + +// uncast removes a previously cast vote from the tally. +func (s *Snapshot) uncast(address common.Address, authorize bool) bool { + // If there's no tally, it's a dangling vote, just drop + tally, ok := s.Tally[address] + if !ok { + return false + } + // Ensure we only revert counted votes + if tally.Authorize != authorize { + return false + } + // Otherwise revert the vote + if tally.Votes > 1 { + tally.Votes-- + s.Tally[address] = tally + } else { + delete(s.Tally, address) + } + return true +} + +// apply creates a new authorization snapshot by applying the given headers to +// the original one. +func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { + // Allow passing in no headers for cleaner code + if len(headers) == 0 { + return s, nil + } + // Sanity check that the headers can be applied + for i := 0; i < len(headers)-1; i++ { + if headers[i+1].Number.Uint64() != headers[i].Number.Uint64()+1 { + return nil, errInvalidVotingChain + } + } + if headers[0].Number.Uint64() != s.Number+1 { + return nil, errInvalidVotingChain + } + // Iterate through the headers and create a new snapshot + snap := s.copy() + + for _, header := range headers { + // Remove any votes on checkpoint blocks + number := header.Number.Uint64() + if number%s.Epoch == 0 { + snap.Votes = nil + snap.Tally = make(map[common.Address]Tally) + } + // Resolve the authorization key and check against validators + validator, err := ecrecover(header) + if err != nil { + return nil, err + } + if _, v := snap.ValSet.GetByAddress(validator); v == nil { + return nil, errUnauthorized + } + + // Header authorized, discard any previous votes from the validator + for i, vote := range snap.Votes { + if vote.Validator == validator && vote.Address == header.Coinbase { + // Uncast the vote from the cached tally + snap.uncast(vote.Address, vote.Authorize) + + // Uncast the vote from the chronological list + snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...) + break // only one vote allowed + } + } + // Tally up the new vote from the validator + var authorize bool + switch { + case bytes.Equal(header.Nonce[:], nonceAuthVote): + authorize = true + case bytes.Equal(header.Nonce[:], nonceDropVote): + authorize = false + default: + return nil, errInvalidVote + } + if snap.cast(header.Coinbase, authorize) { + snap.Votes = append(snap.Votes, &Vote{ + Validator: validator, + Block: number, + Address: header.Coinbase, + Authorize: authorize, + }) + } + // If the vote passed, update the list of validators + if tally := snap.Tally[header.Coinbase]; tally.Votes > snap.ValSet.Size()/2 { + if tally.Authorize { + snap.ValSet.AddValidator(header.Coinbase) + } else { + snap.ValSet.RemoveValidator(header.Coinbase) + + // Discard any previous votes the deauthorized validator cast + for i := 0; i < len(snap.Votes); i++ { + if snap.Votes[i].Validator == header.Coinbase { + // Uncast the vote from the cached tally + snap.uncast(snap.Votes[i].Address, snap.Votes[i].Authorize) + + // Uncast the vote from the chronological list + snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...) + + i-- + } + } + } + // Discard any previous votes around the just changed account + for i := 0; i < len(snap.Votes); i++ { + if snap.Votes[i].Address == header.Coinbase { + snap.Votes = append(snap.Votes[:i], snap.Votes[i+1:]...) + i-- + } + } + delete(snap.Tally, header.Coinbase) + } + } + snap.Number += uint64(len(headers)) + snap.Hash = headers[len(headers)-1].Hash() + + return snap, nil +} + +// validators retrieves the list of authorized validators in ascending order. +func (s *Snapshot) validators() []common.Address { + validators := make([]common.Address, 0, s.ValSet.Size()) + for _, validator := range s.ValSet.List() { + validators = append(validators, validator.Address()) + } + for i := 0; i < len(validators); i++ { + for j := i + 1; j < len(validators); j++ { + if bytes.Compare(validators[i][:], validators[j][:]) > 0 { + validators[i], validators[j] = validators[j], validators[i] + } + } + } + return validators +} + +type snapshotJSON struct { + Epoch uint64 `json:"epoch"` + Number uint64 `json:"number"` + Hash common.Hash `json:"hash"` + Votes []*Vote `json:"votes"` + Tally map[common.Address]Tally `json:"tally"` + + // for validator set + Validators []common.Address `json:"validators"` + Policy istanbul.ProposerPolicy `json:"policy"` +} + +func (s *Snapshot) toJSONStruct() *snapshotJSON { + return &snapshotJSON{ + Epoch: s.Epoch, + Number: s.Number, + Hash: s.Hash, + Votes: s.Votes, + Tally: s.Tally, + Validators: s.validators(), + Policy: s.ValSet.Policy(), + } +} + +// Unmarshal from a json byte array +func (s *Snapshot) UnmarshalJSON(b []byte) error { + var j snapshotJSON + if err := json.Unmarshal(b, &j); err != nil { + return err + } + + s.Epoch = j.Epoch + s.Number = j.Number + s.Hash = j.Hash + s.Votes = j.Votes + s.Tally = j.Tally + s.ValSet = validator.NewSet(j.Validators, j.Policy) + return nil +} + +// Marshal to a json byte array +func (s *Snapshot) MarshalJSON() ([]byte, error) { + j := s.toJSONStruct() + return json.Marshal(j) +} diff --git a/consensus/istanbul/backend/snapshot_test.go b/consensus/istanbul/backend/snapshot_test.go new file mode 100644 index 0000000000..75d4272feb --- /dev/null +++ b/consensus/istanbul/backend/snapshot_test.go @@ -0,0 +1,457 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package backend + +import ( + "bytes" + "crypto/ecdsa" + "math/big" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +type testerVote struct { + validator string + voted string + auth bool +} + +// testerAccountPool is a pool to maintain currently active tester accounts, +// mapped from textual names used in the tests below to actual Ethereum private +// keys capable of signing transactions. +type testerAccountPool struct { + accounts map[string]*ecdsa.PrivateKey +} + +func newTesterAccountPool() *testerAccountPool { + return &testerAccountPool{ + accounts: make(map[string]*ecdsa.PrivateKey), + } +} + +func (ap *testerAccountPool) sign(header *types.Header, validator string) { + // Ensure we have a persistent key for the validator + if ap.accounts[validator] == nil { + ap.accounts[validator], _ = crypto.GenerateKey() + } + // Sign the header and embed the signature in extra data + hashData := crypto.Keccak256(sigHash(header).Bytes()) + sig, _ := crypto.Sign(hashData, ap.accounts[validator]) + + writeSeal(header, sig) +} + +func (ap *testerAccountPool) address(account string) common.Address { + // Ensure we have a persistent key for the account + if ap.accounts[account] == nil { + ap.accounts[account], _ = crypto.GenerateKey() + } + // Resolve and return the Ethereum address + return crypto.PubkeyToAddress(ap.accounts[account].PublicKey) +} + +// Tests that voting is evaluated correctly for various simple and complex scenarios. +func TestVoting(t *testing.T) { + // Define the various voting scenarios to test + tests := []struct { + epoch uint64 + validators []string + votes []testerVote + results []string + }{ + { + // Single validator, no votes cast + validators: []string{"A"}, + votes: []testerVote{{validator: "A"}}, + results: []string{"A"}, + }, { + // Single validator, voting to add two others (only accept first, second needs 2 votes) + validators: []string{"A"}, + votes: []testerVote{ + {validator: "A", voted: "B", auth: true}, + {validator: "B"}, + {validator: "A", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, { + // Two validators, voting to add three others (only accept first two, third needs 3 votes already) + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: true}, + {validator: "B", voted: "C", auth: true}, + {validator: "A", voted: "D", auth: true}, + {validator: "B", voted: "D", auth: true}, + {validator: "C"}, + {validator: "A", voted: "E", auth: true}, + {validator: "B", voted: "E", auth: true}, + }, + results: []string{"A", "B", "C", "D"}, + }, { + // Single validator, dropping itself (weird, but one less cornercase by explicitly allowing this) + validators: []string{"A"}, + votes: []testerVote{ + {validator: "A", voted: "A", auth: false}, + }, + results: []string{}, + }, { + // Two validators, actually needing mutual consent to drop either of them (not fulfilled) + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Two validators, actually needing mutual consent to drop either of them (fulfilled) + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "B", auth: false}, + {validator: "B", voted: "B", auth: false}, + }, + results: []string{"A"}, + }, { + // Three validators, two of them deciding to drop the third + validators: []string{"A", "B", "C"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: false}, + {validator: "B", voted: "C", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Four validators, consensus of two not being enough to drop anyone + validators: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: false}, + {validator: "B", voted: "C", auth: false}, + }, + results: []string{"A", "B", "C", "D"}, + }, { + // Four validators, consensus of three already being enough to drop someone + validators: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {validator: "A", voted: "D", auth: false}, + {validator: "B", voted: "D", auth: false}, + {validator: "C", voted: "D", auth: false}, + }, + results: []string{"A", "B", "C"}, + }, { + // Authorizations are counted once per validator per target + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: true}, + {validator: "B"}, + {validator: "A", voted: "C", auth: true}, + {validator: "B"}, + {validator: "A", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, { + // Authorizing multiple accounts concurrently is permitted + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: true}, + {validator: "B"}, + {validator: "A", voted: "D", auth: true}, + {validator: "B"}, + {validator: "A"}, + {validator: "B", voted: "D", auth: true}, + {validator: "A"}, + {validator: "B", voted: "C", auth: true}, + }, + results: []string{"A", "B", "C", "D"}, + }, { + // Deauthorizations are counted once per validator per target + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "B", auth: false}, + {validator: "B"}, + {validator: "A", voted: "B", auth: false}, + {validator: "B"}, + {validator: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Deauthorizing multiple accounts concurrently is permitted + validators: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: false}, + {validator: "B"}, + {validator: "C"}, + {validator: "A", voted: "D", auth: false}, + {validator: "B"}, + {validator: "C"}, + {validator: "A"}, + {validator: "B", voted: "D", auth: false}, + {validator: "C", voted: "D", auth: false}, + {validator: "A"}, + {validator: "B", voted: "C", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Votes from deauthorized validators are discarded immediately (deauth votes) + validators: []string{"A", "B", "C"}, + votes: []testerVote{ + {validator: "C", voted: "B", auth: false}, + {validator: "A", voted: "C", auth: false}, + {validator: "B", voted: "C", auth: false}, + {validator: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Votes from deauthorized validators are discarded immediately (auth votes) + validators: []string{"A", "B", "C"}, + votes: []testerVote{ + {validator: "C", voted: "B", auth: false}, + {validator: "A", voted: "C", auth: false}, + {validator: "B", voted: "C", auth: false}, + {validator: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Cascading changes are not allowed, only the the account being voted on may change + validators: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: false}, + {validator: "B"}, + {validator: "C"}, + {validator: "A", voted: "D", auth: false}, + {validator: "B", voted: "C", auth: false}, + {validator: "C"}, + {validator: "A"}, + {validator: "B", voted: "D", auth: false}, + {validator: "C", voted: "D", auth: false}, + }, + results: []string{"A", "B", "C"}, + }, { + // Changes reaching consensus out of bounds (via a deauth) execute on touch + validators: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: false}, + {validator: "B"}, + {validator: "C"}, + {validator: "A", voted: "D", auth: false}, + {validator: "B", voted: "C", auth: false}, + {validator: "C"}, + {validator: "A"}, + {validator: "B", voted: "D", auth: false}, + {validator: "C", voted: "D", auth: false}, + {validator: "A"}, + {validator: "C", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, { + // Changes reaching consensus out of bounds (via a deauth) may go out of consensus on first touch + validators: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: false}, + {validator: "B"}, + {validator: "C"}, + {validator: "A", voted: "D", auth: false}, + {validator: "B", voted: "C", auth: false}, + {validator: "C"}, + {validator: "A"}, + {validator: "B", voted: "D", auth: false}, + {validator: "C", voted: "D", auth: false}, + {validator: "A"}, + {validator: "B", voted: "C", auth: true}, + }, + results: []string{"A", "B", "C"}, + }, { + // Ensure that pending votes don't survive authorization status changes. This + // corner case can only appear if a validator is quickly added, remove and then + // readded (or the inverse), while one of the original voters dropped. If a + // past vote is left cached in the system somewhere, this will interfere with + // the final validator outcome. + validators: []string{"A", "B", "C", "D", "E"}, + votes: []testerVote{ + {validator: "A", voted: "F", auth: true}, // Authorize F, 3 votes needed + {validator: "B", voted: "F", auth: true}, + {validator: "C", voted: "F", auth: true}, + {validator: "D", voted: "F", auth: false}, // Deauthorize F, 4 votes needed (leave A's previous vote "unchanged") + {validator: "E", voted: "F", auth: false}, + {validator: "B", voted: "F", auth: false}, + {validator: "C", voted: "F", auth: false}, + {validator: "D", voted: "F", auth: true}, // Almost authorize F, 2/3 votes needed + {validator: "E", voted: "F", auth: true}, + {validator: "B", voted: "A", auth: false}, // Deauthorize A, 3 votes needed + {validator: "C", voted: "A", auth: false}, + {validator: "D", voted: "A", auth: false}, + {validator: "B", voted: "F", auth: true}, // Finish authorizing F, 3/3 votes needed + }, + results: []string{"B", "C", "D", "E", "F"}, + }, { + // Epoch transitions reset all votes to allow chain checkpointing + epoch: 3, + validators: []string{"A", "B"}, + votes: []testerVote{ + {validator: "A", voted: "C", auth: true}, + {validator: "B"}, + {validator: "A"}, // Checkpoint block, (don't vote here, it's validated outside of snapshots) + {validator: "B", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, + } + // Run through the scenarios and test them + for i, tt := range tests { + // Create the account pool and generate the initial set of validators + accounts := newTesterAccountPool() + + validators := make([]common.Address, len(tt.validators)) + for j, validator := range tt.validators { + validators[j] = accounts.address(validator) + } + for j := 0; j < len(validators); j++ { + for k := j + 1; k < len(validators); k++ { + if bytes.Compare(validators[j][:], validators[k][:]) > 0 { + validators[j], validators[k] = validators[k], validators[j] + } + } + } + // Create the genesis block with the initial set of validators + genesis := &core.Genesis{ + Difficulty: defaultDifficulty, + Mixhash: types.IstanbulDigest, + } + b := genesis.ToBlock(nil) + extra, _ := prepareExtra(b.Header(), validators) + genesis.ExtraData = extra + // Create a pristine blockchain with the genesis injected + db := rawdb.NewMemoryDatabase() + genesis.Commit(db) + + config := istanbul.DefaultConfig + if tt.epoch != 0 { + config.Epoch = tt.epoch + } + engine := New(config, accounts.accounts[tt.validators[0]], db).(*backend) + // TODO - rebase - chain, _ := core.NewBlockChain(db, nil, genesis.Config, engine, vm.Config{}, nil, nil) + chain, _ := core.NewBlockChain(db, nil, params.QuorumTestChainConfig, engine, vm.Config{}, nil, nil) + + // Assemble a chain of headers from the cast votes + headers := make([]*types.Header, len(tt.votes)) + for j, vote := range tt.votes { + headers[j] = &types.Header{ + Number: big.NewInt(int64(j) + 1), + Time: uint64(int64(j) * int64(config.BlockPeriod)), + Coinbase: accounts.address(vote.voted), + Difficulty: defaultDifficulty, + MixDigest: types.IstanbulDigest, + } + extra, _ := prepareExtra(headers[j], validators) + headers[j].Extra = extra + if j > 0 { + headers[j].ParentHash = headers[j-1].Hash() + } + if vote.auth { + copy(headers[j].Nonce[:], nonceAuthVote) + } + copy(headers[j].Extra, genesis.ExtraData) + accounts.sign(headers[j], vote.validator) + } + // Pass all the headers through clique and ensure tallying succeeds + head := headers[len(headers)-1] + + snap, err := engine.snapshot(chain, head.Number.Uint64(), head.Hash(), headers) + if err != nil { + t.Errorf("test %d: failed to create voting snapshot: %v", i, err) + continue + } + // Verify the final list of validators against the expected ones + validators = make([]common.Address, len(tt.results)) + for j, validator := range tt.results { + validators[j] = accounts.address(validator) + } + for j := 0; j < len(validators); j++ { + for k := j + 1; k < len(validators); k++ { + if bytes.Compare(validators[j][:], validators[k][:]) > 0 { + validators[j], validators[k] = validators[k], validators[j] + } + } + } + result := snap.validators() + if len(result) != len(validators) { + t.Errorf("test %d: validators mismatch: have %x, want %x", i, result, validators) + continue + } + for j := 0; j < len(result); j++ { + if !bytes.Equal(result[j][:], validators[j][:]) { + t.Errorf("test %d, validator %d: validator mismatch: have %x, want %x", i, j, result[j], validators[j]) + } + } + } +} + +func TestSaveAndLoad(t *testing.T) { + snap := &Snapshot{ + Epoch: 5, + Number: 10, + Hash: common.HexToHash("1234567890"), + Votes: []*Vote{ + { + Validator: common.StringToAddress("1234567891"), + Block: 15, + Address: common.StringToAddress("1234567892"), + Authorize: false, + }, + }, + Tally: map[common.Address]Tally{ + common.StringToAddress("1234567893"): { + Authorize: false, + Votes: 20, + }, + }, + ValSet: validator.NewSet([]common.Address{ + common.StringToAddress("1234567894"), + common.StringToAddress("1234567895"), + }, istanbul.RoundRobin), + } + db := rawdb.NewMemoryDatabase() + err := snap.store(db) + if err != nil { + t.Errorf("store snapshot failed: %v", err) + } + + snap1, err := loadSnapshot(snap.Epoch, db, snap.Hash) + if err != nil { + t.Errorf("load snapshot failed: %v", err) + } + if snap.Epoch != snap1.Epoch { + t.Errorf("epoch mismatch: have %v, want %v", snap1.Epoch, snap.Epoch) + } + if snap.Hash != snap1.Hash { + t.Errorf("hash mismatch: have %v, want %v", snap1.Number, snap.Number) + } + if !reflect.DeepEqual(snap.Votes, snap.Votes) { + t.Errorf("votes mismatch: have %v, want %v", snap1.Votes, snap.Votes) + } + if !reflect.DeepEqual(snap.Tally, snap.Tally) { + t.Errorf("tally mismatch: have %v, want %v", snap1.Tally, snap.Tally) + } + if !reflect.DeepEqual(snap.ValSet, snap.ValSet) { + t.Errorf("validator set mismatch: have %v, want %v", snap1.ValSet, snap.ValSet) + } +} diff --git a/consensus/istanbul/config.go b/consensus/istanbul/config.go new file mode 100644 index 0000000000..dfe6c087d0 --- /dev/null +++ b/consensus/istanbul/config.go @@ -0,0 +1,44 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import "math/big" + +type ProposerPolicy uint64 + +const ( + RoundRobin ProposerPolicy = iota + Sticky +) + +type Config struct { + RequestTimeout uint64 `toml:",omitempty"` // The timeout for each Istanbul round in milliseconds. + BlockPeriod uint64 `toml:",omitempty"` // Default minimum difference between two consecutive block's timestamps in second + ProposerPolicy ProposerPolicy `toml:",omitempty"` // The policy for proposer selection + Epoch uint64 `toml:",omitempty"` // The number of blocks after which to checkpoint and reset the pending votes + Ceil2Nby3Block *big.Int `toml:",omitempty"` // Number of confirmations required to move from one state to next [2F + 1 to Ceil(2N/3)] + AllowedFutureBlockTime uint64 `toml:",omitempty"` // Max time (in seconds) from current time allowed for blocks, before they're considered future blocks +} + +var DefaultConfig = &Config{ + RequestTimeout: 10000, + BlockPeriod: 1, + ProposerPolicy: RoundRobin, + Epoch: 30000, + Ceil2Nby3Block: big.NewInt(0), + AllowedFutureBlockTime: 0, +} diff --git a/consensus/istanbul/core/backlog.go b/consensus/istanbul/core/backlog.go new file mode 100644 index 0000000000..ac62c37e71 --- /dev/null +++ b/consensus/istanbul/core/backlog.go @@ -0,0 +1,188 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/consensus/istanbul" + "gopkg.in/karalabe/cookiejar.v2/collections/prque" +) + +var ( + // msgPriority is defined for calculating processing priority to speedup consensus + // msgPreprepare > msgCommit > msgPrepare + msgPriority = map[uint64]int{ + msgPreprepare: 1, + msgCommit: 2, + msgPrepare: 3, + } +) + +// checkMessage checks the message state +// return errInvalidMessage if the message is invalid +// return errFutureMessage if the message view is larger than current view +// return errOldMessage if the message view is smaller than current view +func (c *core) checkMessage(msgCode uint64, view *istanbul.View) error { + if view == nil || view.Sequence == nil || view.Round == nil { + return errInvalidMessage + } + + if msgCode == msgRoundChange { + if view.Sequence.Cmp(c.currentView().Sequence) > 0 { + return errFutureMessage + } else if view.Cmp(c.currentView()) < 0 { + return errOldMessage + } + return nil + } + + if view.Cmp(c.currentView()) > 0 { + return errFutureMessage + } + + if view.Cmp(c.currentView()) < 0 { + return errOldMessage + } + + if c.waitingForRoundChange { + return errFutureMessage + } + + // StateAcceptRequest only accepts msgPreprepare + // other messages are future messages + if c.state == StateAcceptRequest { + if msgCode > msgPreprepare { + return errFutureMessage + } + return nil + } + + // For states(StatePreprepared, StatePrepared, StateCommitted), + // can accept all message types if processing with same view + return nil +} + +func (c *core) storeBacklog(msg *message, src istanbul.Validator) { + logger := c.logger.New("from", src, "state", c.state) + + if src.Address() == c.Address() { + logger.Warn("Backlog from self") + return + } + + logger.Trace("Store future message") + + c.backlogsMu.Lock() + defer c.backlogsMu.Unlock() + + logger.Debug("Retrieving backlog queue", "for", src.Address(), "backlogs_size", len(c.backlogs)) + backlog := c.backlogs[src.Address()] + if backlog == nil { + backlog = prque.New() + } + switch msg.Code { + case msgPreprepare: + var p *istanbul.Preprepare + err := msg.Decode(&p) + if err == nil { + backlog.Push(msg, toPriority(msg.Code, p.View)) + } + // for msgRoundChange, msgPrepare and msgCommit cases + default: + var p *istanbul.Subject + err := msg.Decode(&p) + if err == nil { + backlog.Push(msg, toPriority(msg.Code, p.View)) + } + } + c.backlogs[src.Address()] = backlog +} + +func (c *core) processBacklog() { + c.backlogsMu.Lock() + defer c.backlogsMu.Unlock() + + for srcAddress, backlog := range c.backlogs { + if backlog == nil { + continue + } + _, src := c.valSet.GetByAddress(srcAddress) + if src == nil { + // validator is not available + delete(c.backlogs, srcAddress) + continue + } + logger := c.logger.New("from", src, "state", c.state) + isFuture := false + + // We stop processing if + // 1. backlog is empty + // 2. The first message in queue is a future message + for !(backlog.Empty() || isFuture) { + m, prio := backlog.Pop() + msg := m.(*message) + var view *istanbul.View + switch msg.Code { + case msgPreprepare: + var m *istanbul.Preprepare + err := msg.Decode(&m) + if err == nil { + view = m.View + } + // for msgRoundChange, msgPrepare and msgCommit cases + default: + var sub *istanbul.Subject + err := msg.Decode(&sub) + if err == nil { + view = sub.View + } + } + if view == nil { + logger.Debug("Nil view", "msg", msg) + continue + } + // Push back if it's a future message + err := c.checkMessage(msg.Code, view) + if err != nil { + if err == errFutureMessage { + logger.Trace("Stop processing backlog", "msg", msg) + backlog.Push(msg, prio) + isFuture = true + break + } + logger.Trace("Skip the backlog event", "msg", msg, "err", err) + continue + } + logger.Trace("Post backlog event", "msg", msg) + + go c.sendEvent(backlogEvent{ + src: src, + msg: msg, + }) + } + } +} + +func toPriority(msgCode uint64, view *istanbul.View) float32 { + if msgCode == msgRoundChange { + // For msgRoundChange, set the message priority based on its sequence + return -float32(view.Sequence.Uint64() * 1000) + } + // FIXME: round will be reset as 0 while new sequence + // 10 * Round limits the range of message code is from 0 to 9 + // 1000 * Sequence limits the range of round is from 0 to 99 + return -float32(view.Sequence.Uint64()*1000 + view.Round.Uint64()*10 + uint64(msgPriority[msgCode])) +} diff --git a/consensus/istanbul/core/backlog_test.go b/consensus/istanbul/core/backlog_test.go new file mode 100644 index 0000000000..64e5e5ec5b --- /dev/null +++ b/consensus/istanbul/core/backlog_test.go @@ -0,0 +1,364 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "reflect" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "gopkg.in/karalabe/cookiejar.v2/collections/prque" +) + +func TestCheckMessage(t *testing.T) { + c := &core{ + state: StateAcceptRequest, + current: newRoundState(&istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(0), + }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), + } + + // invalid view format + err := c.checkMessage(msgPreprepare, nil) + if err != errInvalidMessage { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage) + } + + testStates := []State{StateAcceptRequest, StatePreprepared, StatePrepared, StateCommitted} + testCode := []uint64{msgPreprepare, msgPrepare, msgCommit, msgRoundChange} + + // future sequence + v := &istanbul.View{ + Sequence: big.NewInt(2), + Round: big.NewInt(0), + } + for i := 0; i < len(testStates); i++ { + c.state = testStates[i] + for j := 0; j < len(testCode); j++ { + err := c.checkMessage(testCode[j], v) + if err != errFutureMessage { + t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage) + } + } + } + + // future round + v = &istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(1), + } + for i := 0; i < len(testStates); i++ { + c.state = testStates[i] + for j := 0; j < len(testCode); j++ { + err := c.checkMessage(testCode[j], v) + if testCode[j] == msgRoundChange { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else if err != errFutureMessage { + t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage) + } + } + } + + // current view but waiting for round change + v = &istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(0), + } + c.waitingForRoundChange = true + for i := 0; i < len(testStates); i++ { + c.state = testStates[i] + for j := 0; j < len(testCode); j++ { + err := c.checkMessage(testCode[j], v) + if testCode[j] == msgRoundChange { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else if err != errFutureMessage { + t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage) + } + } + } + c.waitingForRoundChange = false + + v = c.currentView() + // current view, state = StateAcceptRequest + c.state = StateAcceptRequest + for i := 0; i < len(testCode); i++ { + err = c.checkMessage(testCode[i], v) + if testCode[i] == msgRoundChange { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else if testCode[i] == msgPreprepare { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else { + if err != errFutureMessage { + t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage) + } + } + } + + // current view, state = StatePreprepared + c.state = StatePreprepared + for i := 0; i < len(testCode); i++ { + err = c.checkMessage(testCode[i], v) + if testCode[i] == msgRoundChange { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } + + // current view, state = StatePrepared + c.state = StatePrepared + for i := 0; i < len(testCode); i++ { + err = c.checkMessage(testCode[i], v) + if testCode[i] == msgRoundChange { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } + + // current view, state = StateCommitted + c.state = StateCommitted + for i := 0; i < len(testCode); i++ { + err = c.checkMessage(testCode[i], v) + if testCode[i] == msgRoundChange { + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } else if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + } + +} + +func TestStoreBacklog(t *testing.T) { + c := &core{ + logger: log.New("backend", "test", "id", 0), + valSet: newTestValidatorSet(1), + backlogs: make(map[common.Address]*prque.Prque), + backlogsMu: new(sync.Mutex), + } + v := &istanbul.View{ + Round: big.NewInt(10), + Sequence: big.NewInt(10), + } + p := c.valSet.GetByIndex(0) + // push preprepare msg + preprepare := &istanbul.Preprepare{ + View: v, + Proposal: makeBlock(1), + } + prepreparePayload, _ := Encode(preprepare) + m := &message{ + Code: msgPreprepare, + Msg: prepreparePayload, + } + c.storeBacklog(m, p) + msg := c.backlogs[p.Address()].PopItem() + if !reflect.DeepEqual(msg, m) { + t.Errorf("message mismatch: have %v, want %v", msg, m) + } + + // push prepare msg + subject := &istanbul.Subject{ + View: v, + Digest: common.StringToHash("1234567890"), + } + subjectPayload, _ := Encode(subject) + + m = &message{ + Code: msgPrepare, + Msg: subjectPayload, + } + c.storeBacklog(m, p) + msg = c.backlogs[p.Address()].PopItem() + if !reflect.DeepEqual(msg, m) { + t.Errorf("message mismatch: have %v, want %v", msg, m) + } + + // push commit msg + m = &message{ + Code: msgCommit, + Msg: subjectPayload, + } + c.storeBacklog(m, p) + msg = c.backlogs[p.Address()].PopItem() + if !reflect.DeepEqual(msg, m) { + t.Errorf("message mismatch: have %v, want %v", msg, m) + } + + // push roundChange msg + m = &message{ + Code: msgRoundChange, + Msg: subjectPayload, + } + c.storeBacklog(m, p) + msg = c.backlogs[p.Address()].PopItem() + if !reflect.DeepEqual(msg, m) { + t.Errorf("message mismatch: have %v, want %v", msg, m) + } +} + +func TestProcessFutureBacklog(t *testing.T) { + backend := &testSystemBackend{ + events: new(event.TypeMux), + } + c := &core{ + logger: log.New("backend", "test", "id", 0), + valSet: newTestValidatorSet(1), + backlogs: make(map[common.Address]*prque.Prque), + backlogsMu: new(sync.Mutex), + backend: backend, + current: newRoundState(&istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(0), + }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), + state: StateAcceptRequest, + } + c.subscribeEvents() + defer c.unsubscribeEvents() + + v := &istanbul.View{ + Round: big.NewInt(10), + Sequence: big.NewInt(10), + } + p := c.valSet.GetByIndex(0) + // push a future msg + subject := &istanbul.Subject{ + View: v, + Digest: common.StringToHash("1234567890"), + } + subjectPayload, _ := Encode(subject) + m := &message{ + Code: msgCommit, + Msg: subjectPayload, + } + c.storeBacklog(m, p) + c.processBacklog() + + const timeoutDura = 2 * time.Second + timeout := time.NewTimer(timeoutDura) + select { + case e, ok := <-c.events.Chan(): + if !ok { + return + } + t.Errorf("unexpected events comes: %v", e) + case <-timeout.C: + // success + } +} + +func TestProcessBacklog(t *testing.T) { + v := &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(1), + } + preprepare := &istanbul.Preprepare{ + View: v, + Proposal: makeBlock(1), + } + prepreparePayload, _ := Encode(preprepare) + + subject := &istanbul.Subject{ + View: v, + Digest: common.StringToHash("1234567890"), + } + subjectPayload, _ := Encode(subject) + + msgs := []*message{ + { + Code: msgPreprepare, + Msg: prepreparePayload, + }, + { + Code: msgPrepare, + Msg: subjectPayload, + }, + { + Code: msgCommit, + Msg: subjectPayload, + }, + { + Code: msgRoundChange, + Msg: subjectPayload, + }, + } + for i := 0; i < len(msgs); i++ { + testProcessBacklog(t, msgs[i]) + } +} + +func testProcessBacklog(t *testing.T, msg *message) { + vset := newTestValidatorSet(1) + backend := &testSystemBackend{ + events: new(event.TypeMux), + peers: vset, + } + c := &core{ + logger: log.New("backend", "test", "id", 0), + backlogs: make(map[common.Address]*prque.Prque), + backlogsMu: new(sync.Mutex), + valSet: vset, + backend: backend, + state: State(msg.Code), + current: newRoundState(&istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(0), + }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), + } + c.subscribeEvents() + defer c.unsubscribeEvents() + + c.storeBacklog(msg, vset.GetByIndex(0)) + c.processBacklog() + + const timeoutDura = 2 * time.Second + timeout := time.NewTimer(timeoutDura) + select { + case ev := <-c.events.Chan(): + e, ok := ev.Data.(backlogEvent) + if !ok { + t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data)) + } + if e.msg.Code != msg.Code { + t.Errorf("message code mismatch: have %v, want %v", e.msg.Code, msg.Code) + } + // success + case <-timeout.C: + t.Error("unexpected timeout occurs") + } +} diff --git a/consensus/istanbul/core/commit.go b/consensus/istanbul/core/commit.go new file mode 100644 index 0000000000..166d1925eb --- /dev/null +++ b/consensus/istanbul/core/commit.go @@ -0,0 +1,107 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "reflect" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func (c *core) sendCommit() { + sub := c.current.Subject() + c.broadcastCommit(sub) +} + +func (c *core) sendCommitForOldBlock(view *istanbul.View, digest common.Hash) { + sub := &istanbul.Subject{ + View: view, + Digest: digest, + } + c.broadcastCommit(sub) +} + +func (c *core) broadcastCommit(sub *istanbul.Subject) { + logger := c.logger.New("state", c.state) + + encodedSubject, err := Encode(sub) + if err != nil { + logger.Error("Failed to encode", "subject", sub) + return + } + c.broadcast(&message{ + Code: msgCommit, + Msg: encodedSubject, + }) +} + +func (c *core) handleCommit(msg *message, src istanbul.Validator) error { + // Decode COMMIT message + var commit *istanbul.Subject + err := msg.Decode(&commit) + if err != nil { + return errFailedDecodeCommit + } + + if err := c.checkMessage(msgCommit, commit.View); err != nil { + return err + } + + if err := c.verifyCommit(commit, src); err != nil { + return err + } + + c.acceptCommit(msg, src) + + // Commit the proposal once we have enough COMMIT messages and we are not in the Committed state. + // + // If we already have a proposal, we may have chance to speed up the consensus process + // by committing the proposal without PREPARE messages. + if c.current.Commits.Size() >= c.QuorumSize() && c.state.Cmp(StateCommitted) < 0 { + // Still need to call LockHash here since state can skip Prepared state and jump directly to the Committed state. + c.current.LockHash() + c.commit() + } + + return nil +} + +// verifyCommit verifies if the received COMMIT message is equivalent to our subject +func (c *core) verifyCommit(commit *istanbul.Subject, src istanbul.Validator) error { + logger := c.logger.New("from", src, "state", c.state) + + sub := c.current.Subject() + if !reflect.DeepEqual(commit, sub) { + logger.Warn("Inconsistent subjects between commit and proposal", "expected", sub, "got", commit) + return errInconsistentSubject + } + + return nil +} + +func (c *core) acceptCommit(msg *message, src istanbul.Validator) error { + logger := c.logger.New("from", src, "state", c.state) + + // Add the COMMIT message to current round state + if err := c.current.Commits.Add(msg); err != nil { + logger.Error("Failed to record commit message", "msg", msg, "err", err) + return err + } + + return nil +} diff --git a/consensus/istanbul/core/commit_test.go b/consensus/istanbul/core/commit_test.go new file mode 100644 index 0000000000..9e74893318 --- /dev/null +++ b/consensus/istanbul/core/commit_test.go @@ -0,0 +1,325 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "bytes" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/crypto" +) + +func TestHandleCommit(t *testing.T) { + N := uint64(4) + F := uint64(1) + + proposal := newTestProposal() + expectedSubject := &istanbul.Subject{ + View: &istanbul.View{ + Round: big.NewInt(0), + Sequence: proposal.Number(), + }, + Digest: proposal.Hash(), + } + + testCases := []struct { + system *testSystem + expectedErr error + }{ + { + // normal case + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(1), + }, + c.valSet, + ) + + if i == 0 { + // replica 0 is the proposer + c.state = StatePrepared + } + } + return sys + }(), + nil, + }, + { + // future message + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i == 0 { + // replica 0 is the proposer + c.current = newTestRoundState( + expectedSubject.View, + c.valSet, + ) + c.state = StatePreprepared + } else { + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(2), + Sequence: big.NewInt(3), + }, + c.valSet, + ) + } + } + return sys + }(), + errFutureMessage, + }, + { + // subject not match + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i == 0 { + // replica 0 is the proposer + c.current = newTestRoundState( + expectedSubject.View, + c.valSet, + ) + c.state = StatePreprepared + } else { + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(0), + }, + c.valSet, + ) + } + } + return sys + }(), + errOldMessage, + }, + { + // jump state + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: proposal.Number(), + }, + c.valSet, + ) + + // only replica0 stays at StatePreprepared + // other replicas are at StatePrepared + if i != 0 { + c.state = StatePrepared + } else { + c.state = StatePreprepared + } + } + return sys + }(), + nil, + }, + // TODO: double send message + } + +OUTER: + for _, test := range testCases { + test.system.Run(false) + + v0 := test.system.backends[0] + r0 := v0.engine.(*core) + + for i, v := range test.system.backends { + validator := r0.valSet.GetByIndex(uint64(i)) + m, _ := Encode(v.engine.(*core).current.Subject()) + if err := r0.handleCommit(&message{ + Code: msgCommit, + Msg: m, + Address: validator.Address(), + Signature: []byte{}, + CommittedSeal: validator.Address().Bytes(), // small hack + }, validator); err != nil { + if err != test.expectedErr { + t.Errorf("error mismatch: have %v, want %v", err, test.expectedErr) + } + if r0.current.IsHashLocked() { + t.Errorf("block should not be locked") + } + continue OUTER + } + } + + // prepared is normal case + if r0.state != StateCommitted { + // There are not enough commit messages in core + if r0.state != StatePrepared { + t.Errorf("state mismatch: have %v, want %v", r0.state, StatePrepared) + } + if r0.current.Commits.Size() >= r0.QuorumSize() { + t.Errorf("the size of commit messages should be less than %v", r0.QuorumSize()) + } + if r0.current.IsHashLocked() { + t.Errorf("block should not be locked") + } + continue + } + + // core should have 2F+1 before Ceil2Nby3Block or Ceil(2N/3) prepare messages + if r0.current.Commits.Size() < r0.QuorumSize() { + t.Errorf("the size of commit messages should be larger than 2F+1 or Ceil(2N/3): size %v", r0.QuorumSize()) + } + + // check signatures large than F + signedCount := 0 + committedSeals := v0.committedMsgs[0].committedSeals + for _, validator := range r0.valSet.List() { + for _, seal := range committedSeals { + if bytes.Equal(validator.Address().Bytes(), seal[:common.AddressLength]) { + signedCount++ + break + } + } + } + if signedCount <= r0.valSet.F() { + t.Errorf("the expected signed count should be larger than %v, but got %v", r0.valSet.F(), signedCount) + } + if !r0.current.IsHashLocked() { + t.Errorf("block should be locked") + } + } +} + +// round is not checked for now +func TestVerifyCommit(t *testing.T) { + // for log purpose + privateKey, _ := crypto.GenerateKey() + peer := validator.New(getPublicKeyAddress(privateKey)) + valSet := validator.NewSet([]common.Address{peer.Address()}, istanbul.RoundRobin) + + sys := NewTestSystemWithBackend(uint64(1), uint64(0)) + + testCases := []struct { + expected error + commit *istanbul.Subject + roundState *roundState + }{ + { + // normal case + expected: nil, + commit: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + valSet, + ), + }, + { + // old message + expected: errInconsistentSubject, + commit: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(1)}, + valSet, + ), + }, + { + // different digest + expected: errInconsistentSubject, + commit: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + Digest: common.StringToHash("1234567890"), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(1)}, + valSet, + ), + }, + { + // malicious package(lack of sequence) + expected: errInconsistentSubject, + commit: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: nil}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(1)}, + valSet, + ), + }, + { + // wrong prepare message with same sequence but different round + expected: errInconsistentSubject, + commit: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(0)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + valSet, + ), + }, + { + // wrong prepare message with same round but different sequence + expected: errInconsistentSubject, + commit: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(1)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + valSet, + ), + }, + } + for i, test := range testCases { + c := sys.backends[0].engine.(*core) + c.current = test.roundState + + if err := c.verifyCommit(test.commit, peer); err != nil { + if err != test.expected { + t.Errorf("result %d: error mismatch: have %v, want %v", i, err, test.expected) + } + } + } +} diff --git a/consensus/istanbul/core/core.go b/consensus/istanbul/core/core.go new file mode 100644 index 0000000000..121067d04b --- /dev/null +++ b/consensus/istanbul/core/core.go @@ -0,0 +1,359 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "bytes" + "math" + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + metrics "github.com/ethereum/go-ethereum/metrics" + "gopkg.in/karalabe/cookiejar.v2/collections/prque" +) + +// New creates an Istanbul consensus core +func New(backend istanbul.Backend, config *istanbul.Config) Engine { + r := metrics.NewRegistry() + c := &core{ + config: config, + address: backend.Address(), + state: StateAcceptRequest, + handlerWg: new(sync.WaitGroup), + logger: log.New("address", backend.Address()), + backend: backend, + backlogs: make(map[common.Address]*prque.Prque), + backlogsMu: new(sync.Mutex), + pendingRequests: prque.New(), + pendingRequestsMu: new(sync.Mutex), + consensusTimestamp: time.Time{}, + roundMeter: metrics.NewMeter(), + sequenceMeter: metrics.NewMeter(), + consensusTimer: metrics.NewTimer(), + } + + r.Register("consensus/istanbul/core/round", c.roundMeter) + r.Register("consensus/istanbul/core/sequence", c.sequenceMeter) + r.Register("consensus/istanbul/core/consensus", c.consensusTimer) + + c.validateFn = c.checkValidatorSignature + return c +} + +// ---------------------------------------------------------------------------- + +type core struct { + config *istanbul.Config + address common.Address + state State + logger log.Logger + + backend istanbul.Backend + events *event.TypeMuxSubscription + finalCommittedSub *event.TypeMuxSubscription + timeoutSub *event.TypeMuxSubscription + futurePreprepareTimer *time.Timer + + valSet istanbul.ValidatorSet + waitingForRoundChange bool + validateFn func([]byte, []byte) (common.Address, error) + + backlogs map[common.Address]*prque.Prque + backlogsMu *sync.Mutex + + current *roundState + handlerWg *sync.WaitGroup + + roundChangeSet *roundChangeSet + roundChangeTimer *time.Timer + + pendingRequests *prque.Prque + pendingRequestsMu *sync.Mutex + + consensusTimestamp time.Time + // the meter to record the round change rate + roundMeter metrics.Meter + // the meter to record the sequence update rate + sequenceMeter metrics.Meter + // the timer to record consensus duration (from accepting a preprepare to final committed stage) + consensusTimer metrics.Timer +} + +func (c *core) finalizeMessage(msg *message) ([]byte, error) { + var err error + // Add sender address + msg.Address = c.Address() + + // Add proof of consensus + msg.CommittedSeal = []byte{} + // Assign the CommittedSeal if it's a COMMIT message and proposal is not nil + if msg.Code == msgCommit && c.current.Proposal() != nil { + seal := PrepareCommittedSeal(c.current.Proposal().Hash()) + msg.CommittedSeal, err = c.backend.Sign(seal) + if err != nil { + return nil, err + } + } + + // Sign message + data, err := msg.PayloadNoSig() + if err != nil { + return nil, err + } + msg.Signature, err = c.backend.Sign(data) + if err != nil { + return nil, err + } + + // Convert to payload + payload, err := msg.Payload() + if err != nil { + return nil, err + } + + return payload, nil +} + +func (c *core) broadcast(msg *message) { + logger := c.logger.New("state", c.state) + + payload, err := c.finalizeMessage(msg) + if err != nil { + logger.Error("Failed to finalize message", "msg", msg, "err", err) + return + } + + // Broadcast payload + if err = c.backend.Broadcast(c.valSet, payload); err != nil { + logger.Error("Failed to broadcast message", "msg", msg, "err", err) + return + } +} + +func (c *core) currentView() *istanbul.View { + return &istanbul.View{ + Sequence: new(big.Int).Set(c.current.Sequence()), + Round: new(big.Int).Set(c.current.Round()), + } +} + +func (c *core) IsProposer() bool { + v := c.valSet + if v == nil { + return false + } + return v.IsProposer(c.backend.Address()) +} + +func (c *core) IsCurrentProposal(blockHash common.Hash) bool { + return c.current != nil && c.current.pendingRequest != nil && c.current.pendingRequest.Proposal.Hash() == blockHash +} + +func (c *core) commit() { + c.setState(StateCommitted) + + proposal := c.current.Proposal() + if proposal != nil { + committedSeals := make([][]byte, c.current.Commits.Size()) + for i, v := range c.current.Commits.Values() { + committedSeals[i] = make([]byte, types.IstanbulExtraSeal) + copy(committedSeals[i][:], v.CommittedSeal[:]) + } + + if err := c.backend.Commit(proposal, committedSeals); err != nil { + c.current.UnlockHash() //Unlock block when insertion fails + c.sendNextRoundChange() + return + } + } +} + +// startNewRound starts a new round. if round equals to 0, it means to starts a new sequence +func (c *core) startNewRound(round *big.Int) { + var logger log.Logger + if c.current == nil { + logger = c.logger.New("old_round", -1, "old_seq", 0) + } else { + logger = c.logger.New("old_round", c.current.Round(), "old_seq", c.current.Sequence()) + } + + roundChange := false + // Try to get last proposal + lastProposal, lastProposer := c.backend.LastProposal() + if c.current == nil { + logger.Trace("Start to the initial round") + } else if lastProposal.Number().Cmp(c.current.Sequence()) >= 0 { + diff := new(big.Int).Sub(lastProposal.Number(), c.current.Sequence()) + c.sequenceMeter.Mark(new(big.Int).Add(diff, common.Big1).Int64()) + + if !c.consensusTimestamp.IsZero() { + c.consensusTimer.UpdateSince(c.consensusTimestamp) + c.consensusTimestamp = time.Time{} + } + logger.Trace("Catch up latest proposal", "number", lastProposal.Number().Uint64(), "hash", lastProposal.Hash()) + } else if lastProposal.Number().Cmp(big.NewInt(c.current.Sequence().Int64()-1)) == 0 { + if round.Cmp(common.Big0) == 0 { + // same seq and round, don't need to start new round + return + } else if round.Cmp(c.current.Round()) < 0 { + logger.Warn("New round should not be smaller than current round", "seq", lastProposal.Number().Int64(), "new_round", round, "old_round", c.current.Round()) + return + } + roundChange = true + } else { + logger.Warn("New sequence should be larger than current sequence", "new_seq", lastProposal.Number().Int64()) + return + } + + var newView *istanbul.View + if roundChange { + newView = &istanbul.View{ + Sequence: new(big.Int).Set(c.current.Sequence()), + Round: new(big.Int).Set(round), + } + } else { + newView = &istanbul.View{ + Sequence: new(big.Int).Add(lastProposal.Number(), common.Big1), + Round: new(big.Int), + } + c.valSet = c.backend.Validators(lastProposal) + } + + // Update logger + logger = logger.New("old_proposer", c.valSet.GetProposer()) + // Clear invalid ROUND CHANGE messages + c.roundChangeSet = newRoundChangeSet(c.valSet) + // New snapshot for new round + c.updateRoundState(newView, c.valSet, roundChange) + // Calculate new proposer + c.valSet.CalcProposer(lastProposer, newView.Round.Uint64()) + c.waitingForRoundChange = false + c.setState(StateAcceptRequest) + if roundChange && c.IsProposer() && c.current != nil { + // If it is locked, propose the old proposal + // If we have pending request, propose pending request + if c.current.IsHashLocked() { + r := &istanbul.Request{ + Proposal: c.current.Proposal(), //c.current.Proposal would be the locked proposal by previous proposer, see updateRoundState + } + c.sendPreprepare(r) + } else if c.current.pendingRequest != nil { + c.sendPreprepare(c.current.pendingRequest) + } + } + c.newRoundChangeTimer() + + logger.Debug("New round", "new_round", newView.Round, "new_seq", newView.Sequence, "new_proposer", c.valSet.GetProposer(), "valSet", c.valSet.List(), "size", c.valSet.Size(), "IsProposer", c.IsProposer()) +} + +func (c *core) catchUpRound(view *istanbul.View) { + logger := c.logger.New("old_round", c.current.Round(), "old_seq", c.current.Sequence(), "old_proposer", c.valSet.GetProposer()) + + if view.Round.Cmp(c.current.Round()) > 0 { + c.roundMeter.Mark(new(big.Int).Sub(view.Round, c.current.Round()).Int64()) + } + c.waitingForRoundChange = true + + // Need to keep block locked for round catching up + c.updateRoundState(view, c.valSet, true) + c.roundChangeSet.Clear(view.Round) + c.newRoundChangeTimer() + + logger.Trace("Catch up round", "new_round", view.Round, "new_seq", view.Sequence, "new_proposer", c.valSet) +} + +// updateRoundState updates round state by checking if locking block is necessary +func (c *core) updateRoundState(view *istanbul.View, validatorSet istanbul.ValidatorSet, roundChange bool) { + // Lock only if both roundChange is true and it is locked + if roundChange && c.current != nil { + if c.current.IsHashLocked() { + c.current = newRoundState(view, validatorSet, c.current.GetLockedHash(), c.current.Preprepare, c.current.pendingRequest, c.backend.HasBadProposal) + } else { + c.current = newRoundState(view, validatorSet, common.Hash{}, nil, c.current.pendingRequest, c.backend.HasBadProposal) + } + } else { + c.current = newRoundState(view, validatorSet, common.Hash{}, nil, nil, c.backend.HasBadProposal) + } +} + +func (c *core) setState(state State) { + if c.state != state { + c.state = state + } + if state == StateAcceptRequest { + c.processPendingRequests() + } + c.processBacklog() +} + +func (c *core) Address() common.Address { + return c.address +} + +func (c *core) stopFuturePreprepareTimer() { + if c.futurePreprepareTimer != nil { + c.futurePreprepareTimer.Stop() + } +} + +func (c *core) stopTimer() { + c.stopFuturePreprepareTimer() + if c.roundChangeTimer != nil { + c.roundChangeTimer.Stop() + } +} + +func (c *core) newRoundChangeTimer() { + c.stopTimer() + + // set timeout based on the round number + timeout := time.Duration(c.config.RequestTimeout) * time.Millisecond + round := c.current.Round().Uint64() + if round > 0 { + timeout += time.Duration(math.Pow(2, float64(round))) * time.Second + } + c.roundChangeTimer = time.AfterFunc(timeout, func() { + c.sendEvent(timeoutEvent{}) + }) +} + +func (c *core) checkValidatorSignature(data []byte, sig []byte) (common.Address, error) { + return istanbul.CheckValidatorSignature(c.valSet, data, sig) +} + +func (c *core) QuorumSize() int { + if c.config.Ceil2Nby3Block == nil || (c.current != nil && c.current.sequence.Cmp(c.config.Ceil2Nby3Block) < 0) { + c.logger.Trace("Confirmation Formula used 2F+ 1") + return (2 * c.valSet.F()) + 1 + } + c.logger.Trace("Confirmation Formula used ceil(2N/3)") + return int(math.Ceil(float64(2*c.valSet.Size()) / 3)) +} + +// PrepareCommittedSeal returns a committed seal for the given hash +func PrepareCommittedSeal(hash common.Hash) []byte { + var buf bytes.Buffer + buf.Write(hash.Bytes()) + buf.Write([]byte{byte(msgCommit)}) + return buf.Bytes() +} diff --git a/consensus/istanbul/core/core_test.go b/consensus/istanbul/core/core_test.go new file mode 100644 index 0000000000..2212d7d863 --- /dev/null +++ b/consensus/istanbul/core/core_test.go @@ -0,0 +1,97 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "fmt" + "math/big" + "reflect" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/core/types" + elog "github.com/ethereum/go-ethereum/log" +) + +func makeBlock(number int64) *types.Block { + header := &types.Header{ + Difficulty: big.NewInt(0), + Number: big.NewInt(number), + GasLimit: 0, + GasUsed: 0, + Time: 0, + } + block := &types.Block{} + return block.WithSeal(header) +} + +func newTestProposal() istanbul.Proposal { + return makeBlock(1) +} + +func TestNewRequest(t *testing.T) { + testLogger.SetHandler(elog.StdoutHandler) + + N := uint64(4) + F := uint64(1) + + sys := NewTestSystemWithBackend(N, F) + + close := sys.Run(true) + defer close() + + request1 := makeBlock(1) + sys.backends[0].NewRequest(request1) + + <-time.After(1 * time.Second) + + request2 := makeBlock(2) + sys.backends[0].NewRequest(request2) + + <-time.After(1 * time.Second) + + for _, backend := range sys.backends { + if len(backend.committedMsgs) != 2 { + t.Errorf("the number of executed requests mismatch: have %v, want 2", len(backend.committedMsgs)) + } + if !reflect.DeepEqual(request1.Number(), backend.committedMsgs[0].commitProposal.Number()) { + t.Errorf("the number of requests mismatch: have %v, want %v", request1.Number(), backend.committedMsgs[0].commitProposal.Number()) + } + if !reflect.DeepEqual(request2.Number(), backend.committedMsgs[1].commitProposal.Number()) { + t.Errorf("the number of requests mismatch: have %v, want %v", request2.Number(), backend.committedMsgs[1].commitProposal.Number()) + } + } +} + +func TestQuorumSize(t *testing.T) { + N := uint64(4) + F := uint64(1) + + sys := NewTestSystemWithBackend(N, F) + backend := sys.backends[0] + c := backend.engine.(*core) + + valSet := c.valSet + for i := 1; i <= 1000; i++ { + valSet.AddValidator(common.StringToAddress(fmt.Sprint(i))) + if 2*c.QuorumSize() <= (valSet.Size()+valSet.F()) || 2*c.QuorumSize() > (valSet.Size()+valSet.F()+2) { + t.Errorf("quorumSize constraint failed, expected value (2*QuorumSize > Size+F && 2*QuorumSize <= Size+F+2) to be:%v, got: %v, for size: %v", true, false, valSet.Size()) + } + } +} diff --git a/consensus/istanbul/core/errors.go b/consensus/istanbul/core/errors.go new file mode 100644 index 0000000000..23aebba5f5 --- /dev/null +++ b/consensus/istanbul/core/errors.go @@ -0,0 +1,48 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import "errors" + +var ( + // errInconsistentSubject is returned when received subject is different from + // current subject. + errInconsistentSubject = errors.New("inconsistent subjects") + // errNotFromProposer is returned when received message is supposed to be from + // proposer. + errNotFromProposer = errors.New("message does not come from proposer") + // errIgnored is returned when a message was ignored. + errIgnored = errors.New("message is ignored") + // errFutureMessage is returned when current view is earlier than the + // view of the received message. + errFutureMessage = errors.New("future message") + // errOldMessage is returned when the received message's view is earlier + // than current view. + errOldMessage = errors.New("old message") + // errInvalidMessage is returned when the message is malformed. + errInvalidMessage = errors.New("invalid message") + // errFailedDecodePreprepare is returned when the PRE-PREPARE message is malformed. + errFailedDecodePreprepare = errors.New("failed to decode PRE-PREPARE") + // errFailedDecodePrepare is returned when the PREPARE message is malformed. + errFailedDecodePrepare = errors.New("failed to decode PREPARE") + // errFailedDecodeCommit is returned when the COMMIT message is malformed. + errFailedDecodeCommit = errors.New("failed to decode COMMIT") + // errFailedDecodeMessageSet is returned when the message set is malformed. + // errFailedDecodeMessageSet = errors.New("failed to decode message set") + // errInvalidSigner is returned when the message is signed by a validator different than message sender + errInvalidSigner = errors.New("message not signed by the sender") +) diff --git a/consensus/istanbul/core/events.go b/consensus/istanbul/core/events.go new file mode 100644 index 0000000000..c3292fa174 --- /dev/null +++ b/consensus/istanbul/core/events.go @@ -0,0 +1,28 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +type backlogEvent struct { + src istanbul.Validator + msg *message +} + +type timeoutEvent struct{} diff --git a/consensus/istanbul/core/final_committed.go b/consensus/istanbul/core/final_committed.go new file mode 100644 index 0000000000..35e84d4f1d --- /dev/null +++ b/consensus/istanbul/core/final_committed.go @@ -0,0 +1,26 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import "github.com/ethereum/go-ethereum/common" + +func (c *core) handleFinalCommitted() error { + logger := c.logger.New("state", c.state) + logger.Trace("Received a final committed proposal") + c.startNewRound(common.Big0) + return nil +} diff --git a/consensus/istanbul/core/handler.go b/consensus/istanbul/core/handler.go new file mode 100644 index 0000000000..299824cd41 --- /dev/null +++ b/consensus/istanbul/core/handler.go @@ -0,0 +1,201 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +// Start implements core.Engine.Start +func (c *core) Start() error { + // Start a new round from last sequence + 1 + c.startNewRound(common.Big0) + + // Tests will handle events itself, so we have to make subscribeEvents() + // be able to call in test. + c.subscribeEvents() + go c.handleEvents() + + return nil +} + +// Stop implements core.Engine.Stop +func (c *core) Stop() error { + c.stopTimer() + c.unsubscribeEvents() + + // Make sure the handler goroutine exits + c.handlerWg.Wait() + return nil +} + +// ---------------------------------------------------------------------------- + +// Subscribe both internal and external events +func (c *core) subscribeEvents() { + c.events = c.backend.EventMux().Subscribe( + // external events + istanbul.RequestEvent{}, + istanbul.MessageEvent{}, + // internal events + backlogEvent{}, + ) + c.timeoutSub = c.backend.EventMux().Subscribe( + timeoutEvent{}, + ) + c.finalCommittedSub = c.backend.EventMux().Subscribe( + istanbul.FinalCommittedEvent{}, + ) +} + +// Unsubscribe all events +func (c *core) unsubscribeEvents() { + c.events.Unsubscribe() + c.timeoutSub.Unsubscribe() + c.finalCommittedSub.Unsubscribe() +} + +func (c *core) handleEvents() { + // Clear state + defer func() { + c.current = nil + c.handlerWg.Done() + }() + + c.handlerWg.Add(1) + for { + select { + case event, ok := <-c.events.Chan(): + if !ok { + return + } + // A real event arrived, process interesting content + switch ev := event.Data.(type) { + case istanbul.RequestEvent: + r := &istanbul.Request{ + Proposal: ev.Proposal, + } + err := c.handleRequest(r) + if err == errFutureMessage { + c.storeRequestMsg(r) + } + case istanbul.MessageEvent: + if err := c.handleMsg(ev.Payload); err == nil { + c.backend.Gossip(c.valSet, ev.Payload) + } + case backlogEvent: + // No need to check signature for internal messages + if err := c.handleCheckedMsg(ev.msg, ev.src); err == nil { + p, err := ev.msg.Payload() + if err != nil { + c.logger.Warn("Get message payload failed", "err", err) + continue + } + c.backend.Gossip(c.valSet, p) + } + } + case _, ok := <-c.timeoutSub.Chan(): + if !ok { + return + } + c.handleTimeoutMsg() + case event, ok := <-c.finalCommittedSub.Chan(): + if !ok { + return + } + switch event.Data.(type) { + case istanbul.FinalCommittedEvent: + c.handleFinalCommitted() + } + } + } +} + +// sendEvent sends events to mux +func (c *core) sendEvent(ev interface{}) { + c.backend.EventMux().Post(ev) +} + +func (c *core) handleMsg(payload []byte) error { + logger := c.logger.New() + + // Decode message and check its signature + msg := new(message) + if err := msg.FromPayload(payload, c.validateFn); err != nil { + logger.Error("Failed to decode message from payload", "err", err) + return err + } + + // Only accept message if the address is valid + _, src := c.valSet.GetByAddress(msg.Address) + if src == nil { + logger.Error("Invalid address in message", "msg", msg) + return istanbul.ErrUnauthorizedAddress + } + + return c.handleCheckedMsg(msg, src) +} + +func (c *core) handleCheckedMsg(msg *message, src istanbul.Validator) error { + logger := c.logger.New("address", c.address, "from", src) + + // Store the message if it's a future message + testBacklog := func(err error) error { + if err == errFutureMessage { + c.storeBacklog(msg, src) + } + + return err + } + + switch msg.Code { + case msgPreprepare: + return testBacklog(c.handlePreprepare(msg, src)) + case msgPrepare: + return testBacklog(c.handlePrepare(msg, src)) + case msgCommit: + return testBacklog(c.handleCommit(msg, src)) + case msgRoundChange: + return testBacklog(c.handleRoundChange(msg, src)) + default: + logger.Error("Invalid message", "msg", msg) + } + + return errInvalidMessage +} + +func (c *core) handleTimeoutMsg() { + // If we're not waiting for round change yet, we can try to catch up + // the max round with F+1 round change message. We only need to catch up + // if the max round is larger than current round. + if !c.waitingForRoundChange { + maxRound := c.roundChangeSet.MaxRound(c.valSet.F() + 1) + if maxRound != nil && maxRound.Cmp(c.current.Round()) > 0 { + c.sendRoundChange(maxRound) + return + } + } + + lastProposal, _ := c.backend.LastProposal() + if lastProposal != nil && lastProposal.Number().Cmp(c.current.Sequence()) >= 0 { + c.logger.Trace("round change timeout, catch up latest sequence", "number", lastProposal.Number().Uint64()) + c.startNewRound(common.Big0) + } else { + c.sendNextRoundChange() + } +} diff --git a/consensus/istanbul/core/handler_test.go b/consensus/istanbul/core/handler_test.go new file mode 100644 index 0000000000..a54b1f9ccc --- /dev/null +++ b/consensus/istanbul/core/handler_test.go @@ -0,0 +1,127 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +// notice: the normal case have been tested in integration tests. +func TestHandleMsg(t *testing.T) { + N := uint64(4) + F := uint64(1) + sys := NewTestSystemWithBackend(N, F) + + closer := sys.Run(true) + defer closer() + + v0 := sys.backends[0] + r0 := v0.engine.(*core) + + m, _ := Encode(&istanbul.Subject{ + View: &istanbul.View{ + Sequence: big.NewInt(0), + Round: big.NewInt(0), + }, + Digest: common.StringToHash("1234567890"), + }) + // with a matched payload. msgPreprepare should match with *istanbul.Preprepare in normal case. + msg := &message{ + Code: msgPreprepare, + Msg: m, + Address: v0.Address(), + Signature: []byte{}, + CommittedSeal: []byte{}, + } + + _, val := v0.Validators(nil).GetByAddress(v0.Address()) + if err := r0.handleCheckedMsg(msg, val); err != errFailedDecodePreprepare { + t.Errorf("error mismatch: have %v, want %v", err, errFailedDecodePreprepare) + } + + m, _ = Encode(&istanbul.Preprepare{ + View: &istanbul.View{ + Sequence: big.NewInt(0), + Round: big.NewInt(0), + }, + Proposal: makeBlock(1), + }) + // with a unmatched payload. msgPrepare should match with *istanbul.Subject in normal case. + msg = &message{ + Code: msgPrepare, + Msg: m, + Address: v0.Address(), + Signature: []byte{}, + CommittedSeal: []byte{}, + } + + _, val = v0.Validators(nil).GetByAddress(v0.Address()) + if err := r0.handleCheckedMsg(msg, val); err != errFailedDecodePrepare { + t.Errorf("error mismatch: have %v, want %v", err, errFailedDecodePreprepare) + } + + m, _ = Encode(&istanbul.Preprepare{ + View: &istanbul.View{ + Sequence: big.NewInt(0), + Round: big.NewInt(0), + }, + Proposal: makeBlock(2), + }) + // with a unmatched payload. istanbul.MsgCommit should match with *istanbul.Subject in normal case. + msg = &message{ + Code: msgCommit, + Msg: m, + Address: v0.Address(), + Signature: []byte{}, + CommittedSeal: []byte{}, + } + + _, val = v0.Validators(nil).GetByAddress(v0.Address()) + if err := r0.handleCheckedMsg(msg, val); err != errFailedDecodeCommit { + t.Errorf("error mismatch: have %v, want %v", err, errFailedDecodeCommit) + } + + m, _ = Encode(&istanbul.Preprepare{ + View: &istanbul.View{ + Sequence: big.NewInt(0), + Round: big.NewInt(0), + }, + Proposal: makeBlock(3), + }) + // invalid message code. message code is not exists in list + msg = &message{ + Code: uint64(99), + Msg: m, + Address: v0.Address(), + Signature: []byte{}, + CommittedSeal: []byte{}, + } + + _, val = v0.Validators(nil).GetByAddress(v0.Address()) + if err := r0.handleCheckedMsg(msg, val); err == nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + // with malicious payload + if err := r0.handleMsg([]byte{1}); err == nil { + t.Errorf("error mismatch: have %v, want nil", err) + } +} diff --git a/consensus/istanbul/core/message_set.go b/consensus/istanbul/core/message_set.go new file mode 100644 index 0000000000..82b1c06776 --- /dev/null +++ b/consensus/istanbul/core/message_set.go @@ -0,0 +1,115 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "fmt" + "math/big" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +// Construct a new message set to accumulate messages for given sequence/view number. +func newMessageSet(valSet istanbul.ValidatorSet) *messageSet { + return &messageSet{ + view: &istanbul.View{ + Round: new(big.Int), + Sequence: new(big.Int), + }, + messagesMu: new(sync.Mutex), + messages: make(map[common.Address]*message), + valSet: valSet, + } +} + +// ---------------------------------------------------------------------------- + +type messageSet struct { + view *istanbul.View + valSet istanbul.ValidatorSet + messagesMu *sync.Mutex + messages map[common.Address]*message +} + +func (ms *messageSet) View() *istanbul.View { + return ms.view +} + +func (ms *messageSet) Add(msg *message) error { + ms.messagesMu.Lock() + defer ms.messagesMu.Unlock() + + if err := ms.verify(msg); err != nil { + return err + } + + return ms.addVerifiedMessage(msg) +} + +func (ms *messageSet) Values() (result []*message) { + ms.messagesMu.Lock() + defer ms.messagesMu.Unlock() + + for _, v := range ms.messages { + result = append(result, v) + } + + return result +} + +func (ms *messageSet) Size() int { + ms.messagesMu.Lock() + defer ms.messagesMu.Unlock() + return len(ms.messages) +} + +func (ms *messageSet) Get(addr common.Address) *message { + ms.messagesMu.Lock() + defer ms.messagesMu.Unlock() + return ms.messages[addr] +} + +// ---------------------------------------------------------------------------- + +func (ms *messageSet) verify(msg *message) error { + // verify if the message comes from one of the validators + if _, v := ms.valSet.GetByAddress(msg.Address); v == nil { + return istanbul.ErrUnauthorizedAddress + } + + // TODO: check view number and sequence number + + return nil +} + +func (ms *messageSet) addVerifiedMessage(msg *message) error { + ms.messages[msg.Address] = msg + return nil +} + +func (ms *messageSet) String() string { + ms.messagesMu.Lock() + defer ms.messagesMu.Unlock() + addresses := make([]string, 0, len(ms.messages)) + for _, v := range ms.messages { + addresses = append(addresses, v.Address.String()) + } + return fmt.Sprintf("[%v]", strings.Join(addresses, ", ")) +} diff --git a/consensus/istanbul/core/message_set_test.go b/consensus/istanbul/core/message_set_test.go new file mode 100644 index 0000000000..bd76b5b10c --- /dev/null +++ b/consensus/istanbul/core/message_set_test.go @@ -0,0 +1,106 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/rlp" +) + +func TestMessageSetWithPreprepare(t *testing.T) { + valSet := newTestValidatorSet(4) + + ms := newMessageSet(valSet) + + view := &istanbul.View{ + Round: new(big.Int), + Sequence: new(big.Int), + } + pp := &istanbul.Preprepare{ + View: view, + Proposal: makeBlock(1), + } + + rawPP, err := rlp.EncodeToBytes(pp) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + msg := &message{ + Code: msgPreprepare, + Msg: rawPP, + Address: valSet.GetProposer().Address(), + } + + err = ms.Add(msg) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + err = ms.Add(msg) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + if ms.Size() != 1 { + t.Errorf("the size of message set mismatch: have %v, want 1", ms.Size()) + } +} + +func TestMessageSetWithSubject(t *testing.T) { + valSet := newTestValidatorSet(4) + + ms := newMessageSet(valSet) + + view := &istanbul.View{ + Round: new(big.Int), + Sequence: new(big.Int), + } + + sub := &istanbul.Subject{ + View: view, + Digest: common.StringToHash("1234567890"), + } + + rawSub, err := rlp.EncodeToBytes(sub) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + msg := &message{ + Code: msgPrepare, + Msg: rawSub, + Address: valSet.GetProposer().Address(), + } + + err = ms.Add(msg) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + err = ms.Add(msg) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + if ms.Size() != 1 { + t.Errorf("the size of message set mismatch: have %v, want 1", ms.Size()) + } +} diff --git a/consensus/istanbul/core/prepare.go b/consensus/istanbul/core/prepare.go new file mode 100644 index 0000000000..4a1154c06e --- /dev/null +++ b/consensus/istanbul/core/prepare.go @@ -0,0 +1,95 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "reflect" + + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func (c *core) sendPrepare() { + logger := c.logger.New("state", c.state) + + sub := c.current.Subject() + encodedSubject, err := Encode(sub) + if err != nil { + logger.Error("Failed to encode", "subject", sub) + return + } + c.broadcast(&message{ + Code: msgPrepare, + Msg: encodedSubject, + }) +} + +func (c *core) handlePrepare(msg *message, src istanbul.Validator) error { + // Decode PREPARE message + var prepare *istanbul.Subject + err := msg.Decode(&prepare) + if err != nil { + return errFailedDecodePrepare + } + + if err := c.checkMessage(msgPrepare, prepare.View); err != nil { + return err + } + + // If it is locked, it can only process on the locked block. + // Passing verifyPrepare and checkMessage implies it is processing on the locked block since it was verified in the Preprepared state. + if err := c.verifyPrepare(prepare, src); err != nil { + return err + } + + c.acceptPrepare(msg, src) + + // Change to Prepared state if we've received enough PREPARE messages or it is locked + // and we are in earlier state before Prepared state. + if ((c.current.IsHashLocked() && prepare.Digest == c.current.GetLockedHash()) || c.current.GetPrepareOrCommitSize() >= c.QuorumSize()) && + c.state.Cmp(StatePrepared) < 0 { + c.current.LockHash() + c.setState(StatePrepared) + c.sendCommit() + } + + return nil +} + +// verifyPrepare verifies if the received PREPARE message is equivalent to our subject +func (c *core) verifyPrepare(prepare *istanbul.Subject, src istanbul.Validator) error { + logger := c.logger.New("from", src, "state", c.state) + + sub := c.current.Subject() + if !reflect.DeepEqual(prepare, sub) { + logger.Warn("Inconsistent subjects between PREPARE and proposal", "expected", sub, "got", prepare) + return errInconsistentSubject + } + + return nil +} + +func (c *core) acceptPrepare(msg *message, src istanbul.Validator) error { + logger := c.logger.New("from", src, "state", c.state) + + // Add the PREPARE message to current round state + if err := c.current.Prepares.Add(msg); err != nil { + logger.Error("Failed to add PREPARE message to round state", "msg", msg, "err", err) + return err + } + + return nil +} diff --git a/consensus/istanbul/core/prepare_test.go b/consensus/istanbul/core/prepare_test.go new file mode 100644 index 0000000000..ac6ef475c1 --- /dev/null +++ b/consensus/istanbul/core/prepare_test.go @@ -0,0 +1,359 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math" + "math/big" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/crypto" +) + +func TestHandlePrepare(t *testing.T) { + N := uint64(4) + F := uint64(1) + + proposal := newTestProposal() + expectedSubject := &istanbul.Subject{ + View: &istanbul.View{ + Round: big.NewInt(0), + Sequence: proposal.Number(), + }, + Digest: proposal.Hash(), + } + + testCases := []struct { + system *testSystem + expectedErr error + }{ + { + // normal case + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(1), + }, + c.valSet, + ) + + if i == 0 { + // replica 0 is the proposer + c.state = StatePreprepared + } + } + return sys + }(), + nil, + }, + { + // future message + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i == 0 { + // replica 0 is the proposer + c.current = newTestRoundState( + expectedSubject.View, + c.valSet, + ) + c.state = StatePreprepared + } else { + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(2), + Sequence: big.NewInt(3), + }, + c.valSet, + ) + } + } + return sys + }(), + errFutureMessage, + }, + { + // subject not match + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i == 0 { + // replica 0 is the proposer + c.current = newTestRoundState( + expectedSubject.View, + c.valSet, + ) + c.state = StatePreprepared + } else { + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(0), + }, + c.valSet, + ) + } + } + return sys + }(), + errOldMessage, + }, + { + // subject not match + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i == 0 { + // replica 0 is the proposer + c.current = newTestRoundState( + expectedSubject.View, + c.valSet, + ) + c.state = StatePreprepared + } else { + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(1)}, + c.valSet, + ) + } + } + return sys + }(), + errInconsistentSubject, + }, + { + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + // save less than Ceil(2*N/3) replica + sys.backends = sys.backends[int(math.Ceil(float64(2*N)/3)):] + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + c.current = newTestRoundState( + expectedSubject.View, + c.valSet, + ) + + if i == 0 { + // replica 0 is the proposer + c.state = StatePreprepared + } + } + return sys + }(), + nil, + }, + // TODO: double send message + } + +OUTER: + for _, test := range testCases { + test.system.Run(false) + + v0 := test.system.backends[0] + r0 := v0.engine.(*core) + + for i, v := range test.system.backends { + validator := r0.valSet.GetByIndex(uint64(i)) + m, _ := Encode(v.engine.(*core).current.Subject()) + if err := r0.handlePrepare(&message{ + Code: msgPrepare, + Msg: m, + Address: validator.Address(), + }, validator); err != nil { + if err != test.expectedErr { + t.Errorf("error mismatch: have %v, want %v", err, test.expectedErr) + } + if r0.current.IsHashLocked() { + t.Errorf("block should not be locked") + } + continue OUTER + } + } + + // prepared is normal case + if r0.state != StatePrepared { + // There are not enough PREPARE messages in core + if r0.state != StatePreprepared { + t.Errorf("state mismatch: have %v, want %v", r0.state, StatePreprepared) + } + if r0.current.Prepares.Size() >= r0.QuorumSize() { + t.Errorf("the size of PREPARE messages should be less than %v", r0.QuorumSize()) + } + if r0.current.IsHashLocked() { + t.Errorf("block should not be locked") + } + + continue + } + + // core should have 2F+1 before Ceil2Nby3Block and Ceil(2N/3) after Ceil2Nby3Block PREPARE messages + if r0.current.Prepares.Size() < r0.QuorumSize() { + t.Errorf("the size of PREPARE messages should be larger than 2F+1 or ceil(2N/3): size %v", r0.current.Commits.Size()) + } + + // a message will be delivered to backend if ceil(2N/3) + if int64(len(v0.sentMsgs)) != 1 { + t.Errorf("the Send() should be called once: times %v", len(test.system.backends[0].sentMsgs)) + } + + // verify COMMIT messages + decodedMsg := new(message) + err := decodedMsg.FromPayload(v0.sentMsgs[0], nil) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + if decodedMsg.Code != msgCommit { + t.Errorf("message code mismatch: have %v, want %v", decodedMsg.Code, msgCommit) + } + var m *istanbul.Subject + err = decodedMsg.Decode(&m) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + if !reflect.DeepEqual(m, expectedSubject) { + t.Errorf("subject mismatch: have %v, want %v", m, expectedSubject) + } + if !r0.current.IsHashLocked() { + t.Errorf("block should be locked") + } + } +} + +// round is not checked for now +func TestVerifyPrepare(t *testing.T) { + // for log purpose + privateKey, _ := crypto.GenerateKey() + peer := validator.New(getPublicKeyAddress(privateKey)) + valSet := validator.NewSet([]common.Address{peer.Address()}, istanbul.RoundRobin) + + sys := NewTestSystemWithBackend(uint64(1), uint64(0)) + + testCases := []struct { + expected error + + prepare *istanbul.Subject + roundState *roundState + }{ + { + // normal case + expected: nil, + prepare: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + valSet, + ), + }, + { + // old message + expected: errInconsistentSubject, + prepare: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(1)}, + valSet, + ), + }, + { + // different digest + expected: errInconsistentSubject, + prepare: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + Digest: common.StringToHash("1234567890"), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(1)}, + valSet, + ), + }, + { + // malicious package(lack of sequence) + expected: errInconsistentSubject, + prepare: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: nil}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(1)}, + valSet, + ), + }, + { + // wrong PREPARE message with same sequence but different round + expected: errInconsistentSubject, + prepare: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(1), Sequence: big.NewInt(0)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + valSet, + ), + }, + { + // wrong PREPARE message with same round but different sequence + expected: errInconsistentSubject, + prepare: &istanbul.Subject{ + View: &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(1)}, + Digest: newTestProposal().Hash(), + }, + roundState: newTestRoundState( + &istanbul.View{Round: big.NewInt(0), Sequence: big.NewInt(0)}, + valSet, + ), + }, + } + for i, test := range testCases { + c := sys.backends[0].engine.(*core) + c.current = test.roundState + + if err := c.verifyPrepare(test.prepare, peer); err != nil { + if err != test.expected { + t.Errorf("result %d: error mismatch: have %v, want %v", i, err, test.expected) + } + } + } +} diff --git a/consensus/istanbul/core/preprepare.go b/consensus/istanbul/core/preprepare.go new file mode 100644 index 0000000000..dc789206ed --- /dev/null +++ b/consensus/istanbul/core/preprepare.go @@ -0,0 +1,129 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "time" + + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func (c *core) sendPreprepare(request *istanbul.Request) { + logger := c.logger.New("state", c.state) + // If I'm the proposer and I have the same sequence with the proposal + if c.current.Sequence().Cmp(request.Proposal.Number()) == 0 && c.IsProposer() { + curView := c.currentView() + preprepare, err := Encode(&istanbul.Preprepare{ + View: curView, + Proposal: request.Proposal, + }) + if err != nil { + logger.Error("Failed to encode", "view", curView) + return + } + c.broadcast(&message{ + Code: msgPreprepare, + Msg: preprepare, + }) + } +} + +func (c *core) handlePreprepare(msg *message, src istanbul.Validator) error { + logger := c.logger.New("from", src, "state", c.state) + + // Decode PRE-PREPARE + var preprepare *istanbul.Preprepare + err := msg.Decode(&preprepare) + if err != nil { + return errFailedDecodePreprepare + } + + // Ensure we have the same view with the PRE-PREPARE message + // If it is old message, see if we need to broadcast COMMIT + if err := c.checkMessage(msgPreprepare, preprepare.View); err != nil { + if err == errOldMessage { + // Get validator set for the given proposal + valSet := c.backend.ParentValidators(preprepare.Proposal).Copy() + previousProposer := c.backend.GetProposer(preprepare.Proposal.Number().Uint64() - 1) + valSet.CalcProposer(previousProposer, preprepare.View.Round.Uint64()) + // Broadcast COMMIT if it is an existing block + // 1. The proposer needs to be a proposer matches the given (Sequence + Round) + // 2. The given block must exist + if valSet.IsProposer(src.Address()) && c.backend.HasPropsal(preprepare.Proposal.Hash(), preprepare.Proposal.Number()) { + c.sendCommitForOldBlock(preprepare.View, preprepare.Proposal.Hash()) + return nil + } + } + return err + } + + // Check if the message comes from current proposer + if !c.valSet.IsProposer(src.Address()) { + logger.Warn("Ignore preprepare messages from non-proposer") + return errNotFromProposer + } + + // Verify the proposal we received + if duration, err := c.backend.Verify(preprepare.Proposal); err != nil { + // if it's a future block, we will handle it again after the duration + if err == consensus.ErrFutureBlock { + logger.Info("Proposed block will be handled in the future", "err", err, "duration", duration) + c.stopFuturePreprepareTimer() + c.futurePreprepareTimer = time.AfterFunc(duration, func() { + c.sendEvent(backlogEvent{ + src: src, + msg: msg, + }) + }) + } else { + logger.Warn("Failed to verify proposal", "err", err, "duration", duration) + c.sendNextRoundChange() + } + return err + } + + // Here is about to accept the PRE-PREPARE + if c.state == StateAcceptRequest { + // Send ROUND CHANGE if the locked proposal and the received proposal are different + if c.current.IsHashLocked() { + if preprepare.Proposal.Hash() == c.current.GetLockedHash() { + // Broadcast COMMIT and enters Prepared state directly + c.acceptPreprepare(preprepare) + c.setState(StatePrepared) + c.sendCommit() + } else { + // Send round change + c.sendNextRoundChange() + } + } else { + // Either + // 1. the locked proposal and the received proposal match + // 2. we have no locked proposal + c.acceptPreprepare(preprepare) + c.setState(StatePreprepared) + c.sendPrepare() + } + } + + return nil +} + +func (c *core) acceptPreprepare(preprepare *istanbul.Preprepare) { + c.consensusTimestamp = time.Now() + c.current.SetPreprepare(preprepare) +} diff --git a/consensus/istanbul/core/preprepare_test.go b/consensus/istanbul/core/preprepare_test.go new file mode 100644 index 0000000000..1097cfeba9 --- /dev/null +++ b/consensus/istanbul/core/preprepare_test.go @@ -0,0 +1,298 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func newTestPreprepare(v *istanbul.View) *istanbul.Preprepare { + return &istanbul.Preprepare{ + View: v, + Proposal: newTestProposal(), + } +} + +func TestHandlePreprepare(t *testing.T) { + N := uint64(4) // replica 0 is the proposer, it will send messages to others + F := uint64(1) // F does not affect tests + + testCases := []struct { + system *testSystem + expectedRequest istanbul.Proposal + expectedErr error + existingBlock bool + }{ + { + // normal case + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i != 0 { + c.state = StateAcceptRequest + } + } + return sys + }(), + newTestProposal(), + nil, + false, + }, + { + // future message + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i != 0 { + c.state = StateAcceptRequest + // hack: force set subject that future message can be simulated + c.current = newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(0), + }, + c.valSet, + ) + + } else { + c.current.SetSequence(big.NewInt(10)) + } + } + return sys + }(), + makeBlock(1), + errFutureMessage, + false, + }, + { + // non-proposer + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + // force remove replica 0, let replica 1 be the proposer + sys.backends = sys.backends[1:] + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i != 0 { + // replica 0 is the proposer + c.state = StatePreprepared + } + } + return sys + }(), + makeBlock(1), + errNotFromProposer, + false, + }, + { + // errOldMessage + func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i != 0 { + c.state = StatePreprepared + c.current.SetSequence(big.NewInt(10)) + c.current.SetRound(big.NewInt(10)) + } + } + return sys + }(), + makeBlock(1), + errOldMessage, + false, + }, + } + +OUTER: + for _, test := range testCases { + test.system.Run(false) + + v0 := test.system.backends[0] + r0 := v0.engine.(*core) + + curView := r0.currentView() + + preprepare := &istanbul.Preprepare{ + View: curView, + Proposal: test.expectedRequest, + } + + for i, v := range test.system.backends { + // i == 0 is primary backend, it is responsible for send PRE-PREPARE messages to others. + if i == 0 { + continue + } + + c := v.engine.(*core) + + m, _ := Encode(preprepare) + _, val := r0.valSet.GetByAddress(v0.Address()) + // run each backends and verify handlePreprepare function. + if err := c.handlePreprepare(&message{ + Code: msgPreprepare, + Msg: m, + Address: v0.Address(), + }, val); err != nil { + if err != test.expectedErr { + t.Errorf("error mismatch: have %v, want %v", err, test.expectedErr) + } + continue OUTER + } + + if c.state != StatePreprepared { + t.Errorf("state mismatch: have %v, want %v", c.state, StatePreprepared) + } + + if !test.existingBlock && !reflect.DeepEqual(c.current.Subject().View, curView) { + t.Errorf("view mismatch: have %v, want %v", c.current.Subject().View, curView) + } + + // verify prepare messages + decodedMsg := new(message) + err := decodedMsg.FromPayload(v.sentMsgs[0], nil) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + expectedCode := msgPrepare + if test.existingBlock { + expectedCode = msgCommit + } + if decodedMsg.Code != expectedCode { + t.Errorf("message code mismatch: have %v, want %v", decodedMsg.Code, expectedCode) + } + + var subject *istanbul.Subject + err = decodedMsg.Decode(&subject) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + if !test.existingBlock && !reflect.DeepEqual(subject, c.current.Subject()) { + t.Errorf("subject mismatch: have %v, want %v", subject, c.current.Subject()) + } + + } + } +} + +func TestHandlePreprepareWithLock(t *testing.T) { + N := uint64(4) // replica 0 is the proposer, it will send messages to others + F := uint64(1) // F does not affect tests + proposal := newTestProposal() + mismatchProposal := makeBlock(10) + newSystem := func() *testSystem { + sys := NewTestSystemWithBackend(N, F) + + for i, backend := range sys.backends { + c := backend.engine.(*core) + c.valSet = backend.peers + if i != 0 { + c.state = StateAcceptRequest + } + c.roundChangeSet = newRoundChangeSet(c.valSet) + } + return sys + } + + testCases := []struct { + system *testSystem + proposal istanbul.Proposal + lockProposal istanbul.Proposal + }{ + { + newSystem(), + proposal, + proposal, + }, + { + newSystem(), + proposal, + mismatchProposal, + }, + } + + for _, test := range testCases { + test.system.Run(false) + v0 := test.system.backends[0] + r0 := v0.engine.(*core) + curView := r0.currentView() + preprepare := &istanbul.Preprepare{ + View: curView, + Proposal: test.proposal, + } + lockPreprepare := &istanbul.Preprepare{ + View: curView, + Proposal: test.lockProposal, + } + + for i, v := range test.system.backends { + // i == 0 is primary backend, it is responsible for send PRE-PREPARE messages to others. + if i == 0 { + continue + } + + c := v.engine.(*core) + c.current.SetPreprepare(lockPreprepare) + c.current.LockHash() + m, _ := Encode(preprepare) + _, val := r0.valSet.GetByAddress(v0.Address()) + if err := c.handlePreprepare(&message{ + Code: msgPreprepare, + Msg: m, + Address: v0.Address(), + }, val); err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + if test.proposal == test.lockProposal { + if c.state != StatePrepared { + t.Errorf("state mismatch: have %v, want %v", c.state, StatePreprepared) + } + if !reflect.DeepEqual(curView, c.currentView()) { + t.Errorf("view mismatch: have %v, want %v", c.currentView(), curView) + } + } else { + // Should stay at StateAcceptRequest + if c.state != StateAcceptRequest { + t.Errorf("state mismatch: have %v, want %v", c.state, StateAcceptRequest) + } + // Should have triggered a round change + expectedView := &istanbul.View{ + Sequence: curView.Sequence, + Round: big.NewInt(1), + } + if !reflect.DeepEqual(expectedView, c.currentView()) { + t.Errorf("view mismatch: have %v, want %v", c.currentView(), expectedView) + } + } + } + } +} diff --git a/consensus/istanbul/core/request.go b/consensus/istanbul/core/request.go new file mode 100644 index 0000000000..7b73c5ff2a --- /dev/null +++ b/consensus/istanbul/core/request.go @@ -0,0 +1,99 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func (c *core) handleRequest(request *istanbul.Request) error { + logger := c.logger.New("state", c.state, "seq", c.current.sequence) + if err := c.checkRequestMsg(request); err != nil { + if err == errInvalidMessage { + logger.Warn("invalid request") + return err + } + logger.Warn("unexpected request", "err", err, "number", request.Proposal.Number(), "hash", request.Proposal.Hash()) + return err + } + logger.Trace("handleRequest", "number", request.Proposal.Number(), "hash", request.Proposal.Hash()) + + c.current.pendingRequest = request + if c.state == StateAcceptRequest { + c.sendPreprepare(request) + } + return nil +} + +// check request state +// return errInvalidMessage if the message is invalid +// return errFutureMessage if the sequence of proposal is larger than current sequence +// return errOldMessage if the sequence of proposal is smaller than current sequence +func (c *core) checkRequestMsg(request *istanbul.Request) error { + if request == nil || request.Proposal == nil { + return errInvalidMessage + } + + if c := c.current.sequence.Cmp(request.Proposal.Number()); c > 0 { + return errOldMessage + } else if c < 0 { + return errFutureMessage + } else { + return nil + } +} + +func (c *core) storeRequestMsg(request *istanbul.Request) { + logger := c.logger.New("state", c.state) + + logger.Trace("Store future request", "number", request.Proposal.Number(), "hash", request.Proposal.Hash()) + + c.pendingRequestsMu.Lock() + defer c.pendingRequestsMu.Unlock() + + c.pendingRequests.Push(request, float32(-request.Proposal.Number().Int64())) +} + +func (c *core) processPendingRequests() { + c.pendingRequestsMu.Lock() + defer c.pendingRequestsMu.Unlock() + + for !(c.pendingRequests.Empty()) { + m, prio := c.pendingRequests.Pop() + r, ok := m.(*istanbul.Request) + if !ok { + c.logger.Warn("Malformed request, skip", "msg", m) + continue + } + // Push back if it's a future message + err := c.checkRequestMsg(r) + if err != nil { + if err == errFutureMessage { + c.logger.Trace("Stop processing request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash()) + c.pendingRequests.Push(m, prio) + break + } + c.logger.Trace("Skip the pending request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash(), "err", err) + continue + } + c.logger.Trace("Post pending request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash()) + + go c.sendEvent(istanbul.RequestEvent{ + Proposal: r.Proposal, + }) + } +} diff --git a/consensus/istanbul/core/request_test.go b/consensus/istanbul/core/request_test.go new file mode 100644 index 0000000000..5ee179c1c8 --- /dev/null +++ b/consensus/istanbul/core/request_test.go @@ -0,0 +1,138 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "reflect" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "gopkg.in/karalabe/cookiejar.v2/collections/prque" +) + +func TestCheckRequestMsg(t *testing.T) { + c := &core{ + state: StateAcceptRequest, + current: newRoundState(&istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(0), + }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), + } + + // invalid request + err := c.checkRequestMsg(nil) + if err != errInvalidMessage { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage) + } + r := &istanbul.Request{ + Proposal: nil, + } + err = c.checkRequestMsg(r) + if err != errInvalidMessage { + t.Errorf("error mismatch: have %v, want %v", err, errInvalidMessage) + } + + // old request + r = &istanbul.Request{ + Proposal: makeBlock(0), + } + err = c.checkRequestMsg(r) + if err != errOldMessage { + t.Errorf("error mismatch: have %v, want %v", err, errOldMessage) + } + + // future request + r = &istanbul.Request{ + Proposal: makeBlock(2), + } + err = c.checkRequestMsg(r) + if err != errFutureMessage { + t.Errorf("error mismatch: have %v, want %v", err, errFutureMessage) + } + + // current request + r = &istanbul.Request{ + Proposal: makeBlock(1), + } + err = c.checkRequestMsg(r) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } +} + +func TestStoreRequestMsg(t *testing.T) { + backend := &testSystemBackend{ + events: new(event.TypeMux), + } + c := &core{ + logger: log.New("backend", "test", "id", 0), + backend: backend, + state: StateAcceptRequest, + current: newRoundState(&istanbul.View{ + Sequence: big.NewInt(0), + Round: big.NewInt(0), + }, newTestValidatorSet(4), common.Hash{}, nil, nil, nil), + pendingRequests: prque.New(), + pendingRequestsMu: new(sync.Mutex), + } + requests := []istanbul.Request{ + { + Proposal: makeBlock(1), + }, + { + Proposal: makeBlock(2), + }, + { + Proposal: makeBlock(3), + }, + } + + c.storeRequestMsg(&requests[1]) + c.storeRequestMsg(&requests[0]) + c.storeRequestMsg(&requests[2]) + if c.pendingRequests.Size() != len(requests) { + t.Errorf("the size of pending requests mismatch: have %v, want %v", c.pendingRequests.Size(), len(requests)) + } + + c.current.sequence = big.NewInt(3) + + c.subscribeEvents() + defer c.unsubscribeEvents() + + c.processPendingRequests() + + const timeoutDura = 2 * time.Second + timeout := time.NewTimer(timeoutDura) + select { + case ev := <-c.events.Chan(): + e, ok := ev.Data.(istanbul.RequestEvent) + if !ok { + t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data)) + } + if e.Proposal.Number().Cmp(requests[2].Proposal.Number()) != 0 { + t.Errorf("the number of proposal mismatch: have %v, want %v", e.Proposal.Number(), requests[2].Proposal.Number()) + } + case <-timeout.C: + t.Error("unexpected timeout occurs") + } +} diff --git a/consensus/istanbul/core/roundchange.go b/consensus/istanbul/core/roundchange.go new file mode 100644 index 0000000000..6c02f626ec --- /dev/null +++ b/consensus/istanbul/core/roundchange.go @@ -0,0 +1,172 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +// sendNextRoundChange sends the ROUND CHANGE message with current round + 1 +func (c *core) sendNextRoundChange() { + cv := c.currentView() + c.sendRoundChange(new(big.Int).Add(cv.Round, common.Big1)) +} + +// sendRoundChange sends the ROUND CHANGE message with the given round +func (c *core) sendRoundChange(round *big.Int) { + logger := c.logger.New("state", c.state) + + cv := c.currentView() + if cv.Round.Cmp(round) >= 0 { + logger.Error("Cannot send out the round change", "current round", cv.Round, "target round", round) + return + } + + c.catchUpRound(&istanbul.View{ + // The round number we'd like to transfer to. + Round: new(big.Int).Set(round), + Sequence: new(big.Int).Set(cv.Sequence), + }) + + // Now we have the new round number and sequence number + cv = c.currentView() + rc := &istanbul.Subject{ + View: cv, + Digest: common.Hash{}, + } + + payload, err := Encode(rc) + if err != nil { + logger.Error("Failed to encode ROUND CHANGE", "rc", rc, "err", err) + return + } + + c.broadcast(&message{ + Code: msgRoundChange, + Msg: payload, + }) +} + +func (c *core) handleRoundChange(msg *message, src istanbul.Validator) error { + logger := c.logger.New("state", c.state, "from", src.Address().Hex()) + + // Decode ROUND CHANGE message + var rc *istanbul.Subject + if err := msg.Decode(&rc); err != nil { + logger.Error("Failed to decode ROUND CHANGE", "err", err) + return errInvalidMessage + } + + if err := c.checkMessage(msgRoundChange, rc.View); err != nil { + return err + } + + cv := c.currentView() + roundView := rc.View + + // Add the ROUND CHANGE message to its message set and return how many + // messages we've got with the same round number and sequence number. + num, err := c.roundChangeSet.Add(roundView.Round, msg) + if err != nil { + logger.Warn("Failed to add round change message", "from", src, "msg", msg, "err", err) + return err + } + + // Once we received f+1 ROUND CHANGE messages, those messages form a weak certificate. + // If our round number is smaller than the certificate's round number, we would + // try to catch up the round number. + if c.waitingForRoundChange && num == c.valSet.F()+1 { + if cv.Round.Cmp(roundView.Round) < 0 { + c.sendRoundChange(roundView.Round) + } + return nil + } else if num == c.QuorumSize() && (c.waitingForRoundChange || cv.Round.Cmp(roundView.Round) < 0) { + // We've received 2f+1/Ceil(2N/3) ROUND CHANGE messages, start a new round immediately. + c.startNewRound(roundView.Round) + return nil + } else if cv.Round.Cmp(roundView.Round) < 0 { + // Only gossip the message with current round to other validators. + return errIgnored + } + return nil +} + +// ---------------------------------------------------------------------------- + +func newRoundChangeSet(valSet istanbul.ValidatorSet) *roundChangeSet { + return &roundChangeSet{ + validatorSet: valSet, + roundChanges: make(map[uint64]*messageSet), + mu: new(sync.Mutex), + } +} + +type roundChangeSet struct { + validatorSet istanbul.ValidatorSet + roundChanges map[uint64]*messageSet + mu *sync.Mutex +} + +// Add adds the round and message into round change set +func (rcs *roundChangeSet) Add(r *big.Int, msg *message) (int, error) { + rcs.mu.Lock() + defer rcs.mu.Unlock() + + round := r.Uint64() + if rcs.roundChanges[round] == nil { + rcs.roundChanges[round] = newMessageSet(rcs.validatorSet) + } + err := rcs.roundChanges[round].Add(msg) + if err != nil { + return 0, err + } + return rcs.roundChanges[round].Size(), nil +} + +// Clear deletes the messages with smaller round +func (rcs *roundChangeSet) Clear(round *big.Int) { + rcs.mu.Lock() + defer rcs.mu.Unlock() + + for k, rms := range rcs.roundChanges { + if len(rms.Values()) == 0 || k < round.Uint64() { + delete(rcs.roundChanges, k) + } + } +} + +// MaxRound returns the max round which the number of messages is equal or larger than num +func (rcs *roundChangeSet) MaxRound(num int) *big.Int { + rcs.mu.Lock() + defer rcs.mu.Unlock() + + var maxRound *big.Int + for k, rms := range rcs.roundChanges { + if rms.Size() < num { + continue + } + r := big.NewInt(int64(k)) + if maxRound == nil || maxRound.Cmp(r) < 0 { + maxRound = r + } + } + return maxRound +} diff --git a/consensus/istanbul/core/roundchange_test.go b/consensus/istanbul/core/roundchange_test.go new file mode 100644 index 0000000000..835219ae81 --- /dev/null +++ b/consensus/istanbul/core/roundchange_test.go @@ -0,0 +1,92 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" +) + +func TestRoundChangeSet(t *testing.T) { + vset := validator.NewSet(generateValidators(4), istanbul.RoundRobin) + rc := newRoundChangeSet(vset) + + view := &istanbul.View{ + Sequence: big.NewInt(1), + Round: big.NewInt(1), + } + r := &istanbul.Subject{ + View: view, + Digest: common.Hash{}, + } + m, _ := Encode(r) + + // Test Add() + // Add message from all validators + for i, v := range vset.List() { + msg := &message{ + Code: msgRoundChange, + Msg: m, + Address: v.Address(), + } + rc.Add(view.Round, msg) + if rc.roundChanges[view.Round.Uint64()].Size() != i+1 { + t.Errorf("the size of round change messages mismatch: have %v, want %v", rc.roundChanges[view.Round.Uint64()].Size(), i+1) + } + } + + // Add message again from all validators, but the size should be the same + for _, v := range vset.List() { + msg := &message{ + Code: msgRoundChange, + Msg: m, + Address: v.Address(), + } + rc.Add(view.Round, msg) + if rc.roundChanges[view.Round.Uint64()].Size() != vset.Size() { + t.Errorf("the size of round change messages mismatch: have %v, want %v", rc.roundChanges[view.Round.Uint64()].Size(), vset.Size()) + } + } + + // Test MaxRound() + for i := 0; i < 10; i++ { + maxRound := rc.MaxRound(i) + if i <= vset.Size() { + if maxRound == nil || maxRound.Cmp(view.Round) != 0 { + t.Errorf("max round mismatch: have %v, want %v", maxRound, view.Round) + } + } else if maxRound != nil { + t.Errorf("max round mismatch: have %v, want nil", maxRound) + } + } + + // Test Clear() + for i := int64(0); i < 2; i++ { + rc.Clear(big.NewInt(i)) + if rc.roundChanges[view.Round.Uint64()].Size() != vset.Size() { + t.Errorf("the size of round change messages mismatch: have %v, want %v", rc.roundChanges[view.Round.Uint64()].Size(), vset.Size()) + } + } + rc.Clear(big.NewInt(2)) + if rc.roundChanges[view.Round.Uint64()] != nil { + t.Errorf("the change messages mismatch: have %v, want nil", rc.roundChanges[view.Round.Uint64()]) + } +} diff --git a/consensus/istanbul/core/roundstate.go b/consensus/istanbul/core/roundstate.go new file mode 100644 index 0000000000..8f011bfead --- /dev/null +++ b/consensus/istanbul/core/roundstate.go @@ -0,0 +1,221 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "io" + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/rlp" +) + +// newRoundState creates a new roundState instance with the given view and validatorSet +// lockedHash and preprepare are for round change when lock exists, +// we need to keep a reference of preprepare in order to propose locked proposal when there is a lock and itself is the proposer +func newRoundState(view *istanbul.View, validatorSet istanbul.ValidatorSet, lockedHash common.Hash, preprepare *istanbul.Preprepare, pendingRequest *istanbul.Request, hasBadProposal func(hash common.Hash) bool) *roundState { + return &roundState{ + round: view.Round, + sequence: view.Sequence, + Preprepare: preprepare, + Prepares: newMessageSet(validatorSet), + Commits: newMessageSet(validatorSet), + lockedHash: lockedHash, + mu: new(sync.RWMutex), + pendingRequest: pendingRequest, + hasBadProposal: hasBadProposal, + } +} + +// roundState stores the consensus state +type roundState struct { + round *big.Int + sequence *big.Int + Preprepare *istanbul.Preprepare + Prepares *messageSet + Commits *messageSet + lockedHash common.Hash + pendingRequest *istanbul.Request + + mu *sync.RWMutex + hasBadProposal func(hash common.Hash) bool +} + +func (s *roundState) GetPrepareOrCommitSize() int { + s.mu.RLock() + defer s.mu.RUnlock() + + result := s.Prepares.Size() + s.Commits.Size() + + // find duplicate one + for _, m := range s.Prepares.Values() { + if s.Commits.Get(m.Address) != nil { + result-- + } + } + return result +} + +func (s *roundState) Subject() *istanbul.Subject { + s.mu.RLock() + defer s.mu.RUnlock() + + if s.Preprepare == nil { + return nil + } + + return &istanbul.Subject{ + View: &istanbul.View{ + Round: new(big.Int).Set(s.round), + Sequence: new(big.Int).Set(s.sequence), + }, + Digest: s.Preprepare.Proposal.Hash(), + } +} + +func (s *roundState) SetPreprepare(preprepare *istanbul.Preprepare) { + s.mu.Lock() + defer s.mu.Unlock() + + s.Preprepare = preprepare +} + +func (s *roundState) Proposal() istanbul.Proposal { + s.mu.RLock() + defer s.mu.RUnlock() + + if s.Preprepare != nil { + return s.Preprepare.Proposal + } + + return nil +} + +func (s *roundState) SetRound(r *big.Int) { + s.mu.Lock() + defer s.mu.Unlock() + + s.round = new(big.Int).Set(r) +} + +func (s *roundState) Round() *big.Int { + s.mu.RLock() + defer s.mu.RUnlock() + + return s.round +} + +func (s *roundState) SetSequence(seq *big.Int) { + s.mu.Lock() + defer s.mu.Unlock() + + s.sequence = seq +} + +func (s *roundState) Sequence() *big.Int { + s.mu.RLock() + defer s.mu.RUnlock() + + return s.sequence +} + +func (s *roundState) LockHash() { + s.mu.Lock() + defer s.mu.Unlock() + + if s.Preprepare != nil { + s.lockedHash = s.Preprepare.Proposal.Hash() + } +} + +func (s *roundState) UnlockHash() { + s.mu.Lock() + defer s.mu.Unlock() + + s.lockedHash = common.Hash{} +} + +func (s *roundState) IsHashLocked() bool { + s.mu.RLock() + defer s.mu.RUnlock() + + if common.EmptyHash(s.lockedHash) { + return false + } + return !s.hasBadProposal(s.GetLockedHash()) +} + +func (s *roundState) GetLockedHash() common.Hash { + s.mu.RLock() + defer s.mu.RUnlock() + + return s.lockedHash +} + +// The DecodeRLP method should read one value from the given +// Stream. It is not forbidden to read less or more, but it might +// be confusing. +func (s *roundState) DecodeRLP(stream *rlp.Stream) error { + var ss struct { + Round *big.Int + Sequence *big.Int + Preprepare *istanbul.Preprepare + Prepares *messageSet + Commits *messageSet + lockedHash common.Hash + pendingRequest *istanbul.Request + } + + if err := stream.Decode(&ss); err != nil { + return err + } + s.round = ss.Round + s.sequence = ss.Sequence + s.Preprepare = ss.Preprepare + s.Prepares = ss.Prepares + s.Commits = ss.Commits + s.lockedHash = ss.lockedHash + s.pendingRequest = ss.pendingRequest + s.mu = new(sync.RWMutex) + + return nil +} + +// EncodeRLP should write the RLP encoding of its receiver to w. +// If the implementation is a pointer method, it may also be +// called for nil pointers. +// +// Implementations should generate valid RLP. The data written is +// not verified at the moment, but a future version might. It is +// recommended to write only a single value but writing multiple +// values or no value at all is also permitted. +func (s *roundState) EncodeRLP(w io.Writer) error { + s.mu.RLock() + defer s.mu.RUnlock() + + return rlp.Encode(w, []interface{}{ + s.round, + s.sequence, + s.Preprepare, + s.Prepares, + s.Commits, + s.lockedHash, + s.pendingRequest, + }) +} diff --git a/consensus/istanbul/core/roundstate_test.go b/consensus/istanbul/core/roundstate_test.go new file mode 100644 index 0000000000..7cf1979c76 --- /dev/null +++ b/consensus/istanbul/core/roundstate_test.go @@ -0,0 +1,76 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func newTestRoundState(view *istanbul.View, validatorSet istanbul.ValidatorSet) *roundState { + return &roundState{ + round: view.Round, + sequence: view.Sequence, + Preprepare: newTestPreprepare(view), + Prepares: newMessageSet(validatorSet), + Commits: newMessageSet(validatorSet), + mu: new(sync.RWMutex), + hasBadProposal: func(hash common.Hash) bool { + return false + }, + } +} + +func TestLockHash(t *testing.T) { + sys := NewTestSystemWithBackend(1, 0) + rs := newTestRoundState( + &istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(0), + }, + sys.backends[0].peers, + ) + if !common.EmptyHash(rs.GetLockedHash()) { + t.Errorf("error mismatch: have %v, want empty", rs.GetLockedHash()) + } + if rs.IsHashLocked() { + t.Error("IsHashLocked should return false") + } + + // Lock + expected := rs.Proposal().Hash() + rs.LockHash() + if expected != rs.GetLockedHash() { + t.Errorf("error mismatch: have %v, want %v", rs.GetLockedHash(), expected) + } + if !rs.IsHashLocked() { + t.Error("IsHashLocked should return true") + } + + // Unlock + rs.UnlockHash() + if !common.EmptyHash(rs.GetLockedHash()) { + t.Errorf("error mismatch: have %v, want empty", rs.GetLockedHash()) + } + if rs.IsHashLocked() { + t.Error("IsHashLocked should return false") + } +} diff --git a/consensus/istanbul/core/testbackend_test.go b/consensus/istanbul/core/testbackend_test.go new file mode 100644 index 0000000000..4fe5aaa68d --- /dev/null +++ b/consensus/istanbul/core/testbackend_test.go @@ -0,0 +1,291 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "crypto/ecdsa" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/consensus/istanbul/validator" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + elog "github.com/ethereum/go-ethereum/log" +) + +var testLogger = elog.New() + +type testSystemBackend struct { + id uint64 + sys *testSystem + + engine Engine + peers istanbul.ValidatorSet + events *event.TypeMux + + committedMsgs []testCommittedMsgs + sentMsgs [][]byte // store the message when Send is called by core + + address common.Address + db ethdb.Database +} + +type testCommittedMsgs struct { + commitProposal istanbul.Proposal + committedSeals [][]byte +} + +// ============================================== +// +// define the functions that needs to be provided for Istanbul. + +func (self *testSystemBackend) Address() common.Address { + return self.address +} + +// Peers returns all connected peers +func (self *testSystemBackend) Validators(proposal istanbul.Proposal) istanbul.ValidatorSet { + return self.peers +} + +func (self *testSystemBackend) EventMux() *event.TypeMux { + return self.events +} + +func (self *testSystemBackend) Send(message []byte, target common.Address) error { + testLogger.Info("enqueuing a message...", "address", self.Address()) + self.sentMsgs = append(self.sentMsgs, message) + self.sys.queuedMessage <- istanbul.MessageEvent{ + Payload: message, + } + return nil +} + +func (self *testSystemBackend) Broadcast(valSet istanbul.ValidatorSet, message []byte) error { + testLogger.Info("enqueuing a message...", "address", self.Address()) + self.sentMsgs = append(self.sentMsgs, message) + self.sys.queuedMessage <- istanbul.MessageEvent{ + Payload: message, + } + return nil +} + +func (self *testSystemBackend) Gossip(valSet istanbul.ValidatorSet, message []byte) error { + testLogger.Warn("not sign any data") + return nil +} + +func (self *testSystemBackend) Commit(proposal istanbul.Proposal, seals [][]byte) error { + testLogger.Info("commit message", "address", self.Address()) + self.committedMsgs = append(self.committedMsgs, testCommittedMsgs{ + commitProposal: proposal, + committedSeals: seals, + }) + + // fake new head events + go self.events.Post(istanbul.FinalCommittedEvent{}) + return nil +} + +func (self *testSystemBackend) Verify(proposal istanbul.Proposal) (time.Duration, error) { + return 0, nil +} + +func (self *testSystemBackend) Sign(data []byte) ([]byte, error) { + testLogger.Info("returning current backend address so that CheckValidatorSignature returns the same value") + return self.address.Bytes(), nil +} + +func (self *testSystemBackend) CheckSignature([]byte, common.Address, []byte) error { + return nil +} + +func (self *testSystemBackend) CheckValidatorSignature(data []byte, sig []byte) (common.Address, error) { + return common.BytesToAddress(sig), nil +} + +func (self *testSystemBackend) Hash(b interface{}) common.Hash { + return common.StringToHash("Test") +} + +func (self *testSystemBackend) NewRequest(request istanbul.Proposal) { + go self.events.Post(istanbul.RequestEvent{ + Proposal: request, + }) +} + +func (self *testSystemBackend) HasBadProposal(hash common.Hash) bool { + return false +} + +func (self *testSystemBackend) LastProposal() (istanbul.Proposal, common.Address) { + l := len(self.committedMsgs) + if l > 0 { + return self.committedMsgs[l-1].commitProposal, common.Address{} + } + return makeBlock(0), common.Address{} +} + +// Only block height 5 will return true +func (self *testSystemBackend) HasPropsal(hash common.Hash, number *big.Int) bool { + return number.Cmp(big.NewInt(5)) == 0 +} + +func (self *testSystemBackend) GetProposer(number uint64) common.Address { + return common.Address{} +} + +func (self *testSystemBackend) ParentValidators(proposal istanbul.Proposal) istanbul.ValidatorSet { + return self.peers +} + +func (sb *testSystemBackend) Close() error { + return nil +} + +// ============================================== +// +// define the struct that need to be provided for integration tests. + +type testSystem struct { + backends []*testSystemBackend + + queuedMessage chan istanbul.MessageEvent + quit chan struct{} +} + +func newTestSystem(n uint64) *testSystem { + testLogger.SetHandler(elog.StdoutHandler) + return &testSystem{ + backends: make([]*testSystemBackend, n), + + queuedMessage: make(chan istanbul.MessageEvent), + quit: make(chan struct{}), + } +} + +func generateValidators(n int) []common.Address { + vals := make([]common.Address, 0) + for i := 0; i < n; i++ { + privateKey, _ := crypto.GenerateKey() + vals = append(vals, crypto.PubkeyToAddress(privateKey.PublicKey)) + } + return vals +} + +func newTestValidatorSet(n int) istanbul.ValidatorSet { + return validator.NewSet(generateValidators(n), istanbul.RoundRobin) +} + +// FIXME: int64 is needed for N and F +func NewTestSystemWithBackend(n, f uint64) *testSystem { + testLogger.SetHandler(elog.StdoutHandler) + + addrs := generateValidators(int(n)) + sys := newTestSystem(n) + config := istanbul.DefaultConfig + + for i := uint64(0); i < n; i++ { + vset := validator.NewSet(addrs, istanbul.RoundRobin) + backend := sys.NewBackend(i) + backend.peers = vset + backend.address = vset.GetByIndex(i).Address() + + core := New(backend, config).(*core) + core.state = StateAcceptRequest + core.current = newRoundState(&istanbul.View{ + Round: big.NewInt(0), + Sequence: big.NewInt(1), + }, vset, common.Hash{}, nil, nil, func(hash common.Hash) bool { + return false + }) + core.valSet = vset + core.logger = testLogger + core.validateFn = backend.CheckValidatorSignature + + backend.engine = core + } + + return sys +} + +// listen will consume messages from queue and deliver a message to core +func (t *testSystem) listen() { + for { + select { + case <-t.quit: + return + case queuedMessage := <-t.queuedMessage: + testLogger.Info("consuming a queue message...") + for _, backend := range t.backends { + go backend.EventMux().Post(queuedMessage) + } + } + } +} + +// Run will start system components based on given flag, and returns a closer +// function that caller can control lifecycle +// +// Given a true for core if you want to initialize core engine. +func (t *testSystem) Run(core bool) func() { + for _, b := range t.backends { + if core { + b.engine.Start() // start Istanbul core + } + } + + go t.listen() + closer := func() { t.stop(core) } + return closer +} + +func (t *testSystem) stop(core bool) { + close(t.quit) + + for _, b := range t.backends { + if core { + b.engine.Stop() + } + } +} + +func (t *testSystem) NewBackend(id uint64) *testSystemBackend { + // assume always success + ethDB := rawdb.NewMemoryDatabase() + backend := &testSystemBackend{ + id: id, + sys: t, + events: new(event.TypeMux), + db: ethDB, + } + + t.backends[id] = backend + return backend +} + +// ============================================== +// +// helper functions. + +func getPublicKeyAddress(privateKey *ecdsa.PrivateKey) common.Address { + return crypto.PubkeyToAddress(privateKey.PublicKey) +} diff --git a/consensus/istanbul/core/types.go b/consensus/istanbul/core/types.go new file mode 100644 index 0000000000..f8e1c81287 --- /dev/null +++ b/consensus/istanbul/core/types.go @@ -0,0 +1,180 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "bytes" + "fmt" + "io" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +type Engine interface { + Start() error + Stop() error + + IsProposer() bool + + // verify if a hash is the same as the proposed block in the current pending request + // + // this is useful when the engine is currently the proposer + // + // pending request is populated right at the preprepare stage so this would give us the earliest verification + // to avoid any race condition of coming propagated blocks + IsCurrentProposal(blockHash common.Hash) bool +} + +type State uint64 + +const ( + StateAcceptRequest State = iota + StatePreprepared + StatePrepared + StateCommitted +) + +func (s State) String() string { + if s == StateAcceptRequest { + return "Accept request" + } else if s == StatePreprepared { + return "Preprepared" + } else if s == StatePrepared { + return "Prepared" + } else if s == StateCommitted { + return "Committed" + } else { + return "Unknown" + } +} + +// Cmp compares s and y and returns: +// -1 if s is the previous state of y +// 0 if s and y are the same state +// +1 if s is the next state of y +func (s State) Cmp(y State) int { + if uint64(s) < uint64(y) { + return -1 + } + if uint64(s) > uint64(y) { + return 1 + } + return 0 +} + +const ( + msgPreprepare uint64 = iota + msgPrepare + msgCommit + msgRoundChange + // msgAll +) + +type message struct { + Code uint64 + Msg []byte + Address common.Address + Signature []byte + CommittedSeal []byte +} + +// ============================================== +// +// define the functions that needs to be provided for rlp Encoder/Decoder. + +// EncodeRLP serializes m into the Ethereum RLP format. +func (m *message) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{m.Code, m.Msg, m.Address, m.Signature, m.CommittedSeal}) +} + +// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. +func (m *message) DecodeRLP(s *rlp.Stream) error { + var msg struct { + Code uint64 + Msg []byte + Address common.Address + Signature []byte + CommittedSeal []byte + } + + if err := s.Decode(&msg); err != nil { + return err + } + m.Code, m.Msg, m.Address, m.Signature, m.CommittedSeal = msg.Code, msg.Msg, msg.Address, msg.Signature, msg.CommittedSeal + return nil +} + +// ============================================== +// +// define the functions that needs to be provided for core. + +func (m *message) FromPayload(b []byte, validateFn func([]byte, []byte) (common.Address, error)) error { + // Decode message + err := rlp.DecodeBytes(b, &m) + if err != nil { + return err + } + + // Validate message (on a message without Signature) + if validateFn != nil { + var payload []byte + payload, err = m.PayloadNoSig() + if err != nil { + return err + } + + signerAdd, err := validateFn(payload, m.Signature) + if err != nil { + return err + } + if !bytes.Equal(signerAdd.Bytes(), m.Address.Bytes()) { + return errInvalidSigner + } + } + return nil +} + +func (m *message) Payload() ([]byte, error) { + return rlp.EncodeToBytes(m) +} + +func (m *message) PayloadNoSig() ([]byte, error) { + return rlp.EncodeToBytes(&message{ + Code: m.Code, + Msg: m.Msg, + Address: m.Address, + Signature: []byte{}, + CommittedSeal: m.CommittedSeal, + }) +} + +func (m *message) Decode(val interface{}) error { + return rlp.DecodeBytes(m.Msg, val) +} + +func (m *message) String() string { + return fmt.Sprintf("{Code: %v, Address: %v}", m.Code, m.Address.String()) +} + +// ============================================== +// +// helper functions + +func Encode(val interface{}) ([]byte, error) { + return rlp.EncodeToBytes(val) +} diff --git a/consensus/istanbul/core/types_test.go b/consensus/istanbul/core/types_test.go new file mode 100644 index 0000000000..10dcaa8f1d --- /dev/null +++ b/consensus/istanbul/core/types_test.go @@ -0,0 +1,180 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func testPreprepare(t *testing.T) { + pp := &istanbul.Preprepare{ + View: &istanbul.View{ + Round: big.NewInt(1), + Sequence: big.NewInt(2), + }, + Proposal: makeBlock(1), + } + prepreparePayload, _ := Encode(pp) + + m := &message{ + Code: msgPreprepare, + Msg: prepreparePayload, + Address: common.HexToAddress("0x1234567890"), + } + + msgPayload, err := m.Payload() + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + decodedMsg := new(message) + err = decodedMsg.FromPayload(msgPayload, nil) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + var decodedPP *istanbul.Preprepare + err = decodedMsg.Decode(&decodedPP) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + // if block is encoded/decoded by rlp, we cannot to compare interface data type using reflect.DeepEqual. (like istanbul.Proposal) + // so individual comparison here. + if !reflect.DeepEqual(pp.Proposal.Hash(), decodedPP.Proposal.Hash()) { + t.Errorf("proposal hash mismatch: have %v, want %v", decodedPP.Proposal.Hash(), pp.Proposal.Hash()) + } + + if !reflect.DeepEqual(pp.View, decodedPP.View) { + t.Errorf("view mismatch: have %v, want %v", decodedPP.View, pp.View) + } + + if !reflect.DeepEqual(pp.Proposal.Number(), decodedPP.Proposal.Number()) { + t.Errorf("proposal number mismatch: have %v, want %v", decodedPP.Proposal.Number(), pp.Proposal.Number()) + } +} + +func testSubject(t *testing.T) { + s := &istanbul.Subject{ + View: &istanbul.View{ + Round: big.NewInt(1), + Sequence: big.NewInt(2), + }, + Digest: common.StringToHash("1234567890"), + } + + subjectPayload, _ := Encode(s) + + m := &message{ + Code: msgPreprepare, + Msg: subjectPayload, + Address: common.HexToAddress("0x1234567890"), + } + + msgPayload, err := m.Payload() + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + decodedMsg := new(message) + err = decodedMsg.FromPayload(msgPayload, nil) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + var decodedSub *istanbul.Subject + err = decodedMsg.Decode(&decodedSub) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + if !reflect.DeepEqual(s, decodedSub) { + t.Errorf("subject mismatch: have %v, want %v", decodedSub, s) + } +} + +func testSubjectWithSignature(t *testing.T) { + s := &istanbul.Subject{ + View: &istanbul.View{ + Round: big.NewInt(1), + Sequence: big.NewInt(2), + }, + Digest: common.StringToHash("1234567890"), + } + expectedSig := []byte{0x01} + + subjectPayload, _ := Encode(s) + // 1. Encode test + address := common.HexToAddress("0x1234567890") + m := &message{ + Code: msgPreprepare, + Msg: subjectPayload, + Address: address, + Signature: expectedSig, + CommittedSeal: []byte{}, + } + + msgPayload, err := m.Payload() + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + // 2. Decode test + // 2.1 Test normal validate func + decodedMsg := new(message) + err = decodedMsg.FromPayload(msgPayload, func(data []byte, sig []byte) (common.Address, error) { + return address, nil + }) + if err != nil { + t.Errorf("error mismatch: have %v, want nil", err) + } + + if !reflect.DeepEqual(decodedMsg, m) { + t.Errorf("error mismatch: have %v, want nil", err) + } + + // 2.2 Test nil validate func + decodedMsg = new(message) + err = decodedMsg.FromPayload(msgPayload, nil) + if err != nil { + t.Error(err) + } + + if !reflect.DeepEqual(decodedMsg, m) { + t.Errorf("message mismatch: have %v, want %v", decodedMsg, m) + } + + // 2.3 Test failed validate func + decodedMsg = new(message) + err = decodedMsg.FromPayload(msgPayload, func(data []byte, sig []byte) (common.Address, error) { + return common.Address{}, istanbul.ErrUnauthorizedAddress + }) + if err != istanbul.ErrUnauthorizedAddress { + t.Errorf("error mismatch: have %v, want %v", err, istanbul.ErrUnauthorizedAddress) + } +} + +func TestMessageEncodeDecode(t *testing.T) { + testPreprepare(t) + testSubject(t) + testSubjectWithSignature(t) +} diff --git a/consensus/istanbul/errors.go b/consensus/istanbul/errors.go new file mode 100644 index 0000000000..ed5b62342f --- /dev/null +++ b/consensus/istanbul/errors.go @@ -0,0 +1,29 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import "errors" + +var ( + // ErrUnauthorizedAddress is returned when given address cannot be found in + // current validator set. + ErrUnauthorizedAddress = errors.New("unauthorized address") + // ErrStoppedEngine is returned if the engine is stopped + ErrStoppedEngine = errors.New("stopped engine") + // ErrStartedEngine is returned if the engine is already started + ErrStartedEngine = errors.New("started engine") +) diff --git a/consensus/istanbul/events.go b/consensus/istanbul/events.go new file mode 100644 index 0000000000..fb6e5bd9c2 --- /dev/null +++ b/consensus/istanbul/events.go @@ -0,0 +1,31 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +// RequestEvent is posted to propose a proposal +type RequestEvent struct { + Proposal Proposal +} + +// MessageEvent is posted for Istanbul engine communication +type MessageEvent struct { + Payload []byte +} + +// FinalCommittedEvent is posted when a proposal is committed +type FinalCommittedEvent struct { +} diff --git a/consensus/istanbul/types.go b/consensus/istanbul/types.go new file mode 100644 index 0000000000..86b586a2d0 --- /dev/null +++ b/consensus/istanbul/types.go @@ -0,0 +1,147 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import ( + "fmt" + "io" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// Proposal supports retrieving height and serialized block to be used during Istanbul consensus. +type Proposal interface { + // Number retrieves the sequence number of this proposal. + Number() *big.Int + + // Hash retrieves the hash of this proposal. + Hash() common.Hash + + EncodeRLP(w io.Writer) error + + DecodeRLP(s *rlp.Stream) error + + String() string +} + +type Request struct { + Proposal Proposal +} + +// View includes a round number and a sequence number. +// Sequence is the block number we'd like to commit. +// Each round has a number and is composed by 3 steps: preprepare, prepare and commit. +// +// If the given block is not accepted by validators, a round change will occur +// and the validators start a new round with round+1. +type View struct { + Round *big.Int + Sequence *big.Int +} + +// EncodeRLP serializes b into the Ethereum RLP format. +func (v *View) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{v.Round, v.Sequence}) +} + +// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. +func (v *View) DecodeRLP(s *rlp.Stream) error { + var view struct { + Round *big.Int + Sequence *big.Int + } + + if err := s.Decode(&view); err != nil { + return err + } + v.Round, v.Sequence = view.Round, view.Sequence + return nil +} + +func (v *View) String() string { + return fmt.Sprintf("{Round: %d, Sequence: %d}", v.Round.Uint64(), v.Sequence.Uint64()) +} + +// Cmp compares v and y and returns: +// -1 if v < y +// 0 if v == y +// +1 if v > y +func (v *View) Cmp(y *View) int { + if v.Sequence.Cmp(y.Sequence) != 0 { + return v.Sequence.Cmp(y.Sequence) + } + if v.Round.Cmp(y.Round) != 0 { + return v.Round.Cmp(y.Round) + } + return 0 +} + +type Preprepare struct { + View *View + Proposal Proposal +} + +// EncodeRLP serializes b into the Ethereum RLP format. +func (b *Preprepare) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{b.View, b.Proposal}) +} + +// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. +func (b *Preprepare) DecodeRLP(s *rlp.Stream) error { + var preprepare struct { + View *View + Proposal *types.Block + } + + if err := s.Decode(&preprepare); err != nil { + return err + } + b.View, b.Proposal = preprepare.View, preprepare.Proposal + + return nil +} + +type Subject struct { + View *View + Digest common.Hash +} + +// EncodeRLP serializes b into the Ethereum RLP format. +func (b *Subject) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{b.View, b.Digest}) +} + +// DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. +func (b *Subject) DecodeRLP(s *rlp.Stream) error { + var subject struct { + View *View + Digest common.Hash + } + + if err := s.Decode(&subject); err != nil { + return err + } + b.View, b.Digest = subject.View, subject.Digest + return nil +} + +func (b *Subject) String() string { + return fmt.Sprintf("{View: %v, Digest: %v}", b.View, b.Digest.String()) +} diff --git a/consensus/istanbul/types_test.go b/consensus/istanbul/types_test.go new file mode 100644 index 0000000000..cc23d486f1 --- /dev/null +++ b/consensus/istanbul/types_test.go @@ -0,0 +1,71 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import ( + "math/big" + "testing" +) + +func TestViewCompare(t *testing.T) { + // test equality + srvView := &View{ + Sequence: big.NewInt(2), + Round: big.NewInt(1), + } + tarView := &View{ + Sequence: big.NewInt(2), + Round: big.NewInt(1), + } + if r := srvView.Cmp(tarView); r != 0 { + t.Errorf("source(%v) should be equal to target(%v): have %v, want %v", srvView, tarView, r, 0) + } + + // test larger Sequence + tarView = &View{ + Sequence: big.NewInt(1), + Round: big.NewInt(1), + } + if r := srvView.Cmp(tarView); r != 1 { + t.Errorf("source(%v) should be larger than target(%v): have %v, want %v", srvView, tarView, r, 1) + } + + // test larger Round + tarView = &View{ + Sequence: big.NewInt(2), + Round: big.NewInt(0), + } + if r := srvView.Cmp(tarView); r != 1 { + t.Errorf("source(%v) should be larger than target(%v): have %v, want %v", srvView, tarView, r, 1) + } + + // test smaller Sequence + tarView = &View{ + Sequence: big.NewInt(3), + Round: big.NewInt(1), + } + if r := srvView.Cmp(tarView); r != -1 { + t.Errorf("source(%v) should be smaller than target(%v): have %v, want %v", srvView, tarView, r, -1) + } + tarView = &View{ + Sequence: big.NewInt(2), + Round: big.NewInt(2), + } + if r := srvView.Cmp(tarView); r != -1 { + t.Errorf("source(%v) should be smaller than target(%v): have %v, want %v", srvView, tarView, r, -1) + } +} diff --git a/consensus/istanbul/utils.go b/consensus/istanbul/utils.go new file mode 100644 index 0000000000..1382ad03e6 --- /dev/null +++ b/consensus/istanbul/utils.go @@ -0,0 +1,60 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/crypto/sha3" +) + +func RLPHash(v interface{}) (h common.Hash) { + hw := sha3.NewLegacyKeccak256() + rlp.Encode(hw, v) + hw.Sum(h[:0]) + return h +} + +// GetSignatureAddress gets the signer address from the signature +func GetSignatureAddress(data []byte, sig []byte) (common.Address, error) { + // 1. Keccak data + hashData := crypto.Keccak256(data) + // 2. Recover public key + pubkey, err := crypto.SigToPub(hashData, sig) + if err != nil { + return common.Address{}, err + } + return crypto.PubkeyToAddress(*pubkey), nil +} + +func CheckValidatorSignature(valSet ValidatorSet, data []byte, sig []byte) (common.Address, error) { + // 1. Get signature address + signer, err := GetSignatureAddress(data, sig) + if err != nil { + log.Error("Failed to get signer address", "err", err) + return common.Address{}, err + } + + // 2. Check validator + if _, val := valSet.GetByAddress(signer); val != nil { + return val.Address(), nil + } + + return common.Address{}, ErrUnauthorizedAddress +} diff --git a/consensus/istanbul/validator.go b/consensus/istanbul/validator.go new file mode 100644 index 0000000000..e0d142866e --- /dev/null +++ b/consensus/istanbul/validator.go @@ -0,0 +1,80 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package istanbul + +import ( + "strings" + + "github.com/ethereum/go-ethereum/common" +) + +type Validator interface { + // Address returns address + Address() common.Address + + // String representation of Validator + String() string +} + +// ---------------------------------------------------------------------------- + +type Validators []Validator + +func (slice Validators) Len() int { + return len(slice) +} + +func (slice Validators) Less(i, j int) bool { + return strings.Compare(slice[i].String(), slice[j].String()) < 0 +} + +func (slice Validators) Swap(i, j int) { + slice[i], slice[j] = slice[j], slice[i] +} + +// ---------------------------------------------------------------------------- + +type ValidatorSet interface { + // Calculate the proposer + CalcProposer(lastProposer common.Address, round uint64) + // Return the validator size + Size() int + // Return the validator array + List() []Validator + // Get validator by index + GetByIndex(i uint64) Validator + // Get validator by given address + GetByAddress(addr common.Address) (int, Validator) + // Get current proposer + GetProposer() Validator + // Check whether the validator with given address is a proposer + IsProposer(address common.Address) bool + // Add validator + AddValidator(address common.Address) bool + // Remove validator + RemoveValidator(address common.Address) bool + // Copy validator set + Copy() ValidatorSet + // Get the maximum number of faulty nodes + F() int + // Get proposer policy + Policy() ProposerPolicy +} + +// ---------------------------------------------------------------------------- + +type ProposalSelector func(ValidatorSet, common.Address, uint64) Validator diff --git a/consensus/istanbul/validator/default.go b/consensus/istanbul/validator/default.go new file mode 100644 index 0000000000..17edda5521 --- /dev/null +++ b/consensus/istanbul/validator/default.go @@ -0,0 +1,201 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package validator + +import ( + "math" + "reflect" + "sort" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +type defaultValidator struct { + address common.Address +} + +func (val *defaultValidator) Address() common.Address { + return val.address +} + +func (val *defaultValidator) String() string { + return val.Address().String() +} + +// ---------------------------------------------------------------------------- + +type defaultSet struct { + validators istanbul.Validators + policy istanbul.ProposerPolicy + + proposer istanbul.Validator + validatorMu sync.RWMutex + selector istanbul.ProposalSelector +} + +func newDefaultSet(addrs []common.Address, policy istanbul.ProposerPolicy) *defaultSet { + valSet := &defaultSet{} + + valSet.policy = policy + // init validators + valSet.validators = make([]istanbul.Validator, len(addrs)) + for i, addr := range addrs { + valSet.validators[i] = New(addr) + } + // sort validator + sort.Sort(valSet.validators) + // init proposer + if valSet.Size() > 0 { + valSet.proposer = valSet.GetByIndex(0) + } + valSet.selector = roundRobinProposer + if policy == istanbul.Sticky { + valSet.selector = stickyProposer + } + + return valSet +} + +func (valSet *defaultSet) Size() int { + valSet.validatorMu.RLock() + defer valSet.validatorMu.RUnlock() + return len(valSet.validators) +} + +func (valSet *defaultSet) List() []istanbul.Validator { + valSet.validatorMu.RLock() + defer valSet.validatorMu.RUnlock() + return valSet.validators +} + +func (valSet *defaultSet) GetByIndex(i uint64) istanbul.Validator { + valSet.validatorMu.RLock() + defer valSet.validatorMu.RUnlock() + if i < uint64(valSet.Size()) { + return valSet.validators[i] + } + return nil +} + +func (valSet *defaultSet) GetByAddress(addr common.Address) (int, istanbul.Validator) { + for i, val := range valSet.List() { + if addr == val.Address() { + return i, val + } + } + return -1, nil +} + +func (valSet *defaultSet) GetProposer() istanbul.Validator { + return valSet.proposer +} + +func (valSet *defaultSet) IsProposer(address common.Address) bool { + _, val := valSet.GetByAddress(address) + return reflect.DeepEqual(valSet.GetProposer(), val) +} + +func (valSet *defaultSet) CalcProposer(lastProposer common.Address, round uint64) { + valSet.validatorMu.RLock() + defer valSet.validatorMu.RUnlock() + valSet.proposer = valSet.selector(valSet, lastProposer, round) +} + +func calcSeed(valSet istanbul.ValidatorSet, proposer common.Address, round uint64) uint64 { + offset := 0 + if idx, val := valSet.GetByAddress(proposer); val != nil { + offset = idx + } + return uint64(offset) + round +} + +func emptyAddress(addr common.Address) bool { + return addr == common.Address{} +} + +func roundRobinProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64) istanbul.Validator { + if valSet.Size() == 0 { + return nil + } + seed := uint64(0) + if emptyAddress(proposer) { + seed = round + } else { + seed = calcSeed(valSet, proposer, round) + 1 + } + pick := seed % uint64(valSet.Size()) + return valSet.GetByIndex(pick) +} + +func stickyProposer(valSet istanbul.ValidatorSet, proposer common.Address, round uint64) istanbul.Validator { + if valSet.Size() == 0 { + return nil + } + seed := uint64(0) + if emptyAddress(proposer) { + seed = round + } else { + seed = calcSeed(valSet, proposer, round) + } + pick := seed % uint64(valSet.Size()) + return valSet.GetByIndex(pick) +} + +func (valSet *defaultSet) AddValidator(address common.Address) bool { + valSet.validatorMu.Lock() + defer valSet.validatorMu.Unlock() + for _, v := range valSet.validators { + if v.Address() == address { + return false + } + } + valSet.validators = append(valSet.validators, New(address)) + // TODO: we may not need to re-sort it again + // sort validator + sort.Sort(valSet.validators) + return true +} + +func (valSet *defaultSet) RemoveValidator(address common.Address) bool { + valSet.validatorMu.Lock() + defer valSet.validatorMu.Unlock() + + for i, v := range valSet.validators { + if v.Address() == address { + valSet.validators = append(valSet.validators[:i], valSet.validators[i+1:]...) + return true + } + } + return false +} + +func (valSet *defaultSet) Copy() istanbul.ValidatorSet { + valSet.validatorMu.RLock() + defer valSet.validatorMu.RUnlock() + + addresses := make([]common.Address, 0, len(valSet.validators)) + for _, v := range valSet.validators { + addresses = append(addresses, v.Address()) + } + return NewSet(addresses, valSet.policy) +} + +func (valSet *defaultSet) F() int { return int(math.Ceil(float64(valSet.Size())/3)) - 1 } + +func (valSet *defaultSet) Policy() istanbul.ProposerPolicy { return valSet.policy } diff --git a/consensus/istanbul/validator/default_test.go b/consensus/istanbul/validator/default_test.go new file mode 100644 index 0000000000..486d4861b1 --- /dev/null +++ b/consensus/istanbul/validator/default_test.go @@ -0,0 +1,209 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package validator + +import ( + fmt "fmt" + "reflect" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" + "github.com/ethereum/go-ethereum/crypto" +) + +var ( + testAddress = "70524d664ffe731100208a0154e556f9bb679ae6" + testAddress2 = "b37866a925bccd69cfa98d43b510f1d23d78a851" +) + +func TestValidatorSet(t *testing.T) { + testNewValidatorSet(t) + testNormalValSet(t) + testEmptyValSet(t) + testStickyProposer(t) + testAddAndRemoveValidator(t) +} + +func testNewValidatorSet(t *testing.T) { + var validators []istanbul.Validator + const ValCnt = 100 + + // Create 100 validators with random addresses + b := []byte{} + for i := 0; i < ValCnt; i++ { + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + val := New(addr) + validators = append(validators, val) + b = append(b, val.Address().Bytes()...) + } + + // Create ValidatorSet + valSet := NewSet(ExtractValidators(b), istanbul.RoundRobin) + if valSet == nil { + t.Errorf("the validator byte array cannot be parsed") + t.FailNow() + } + + // Check validators sorting: should be in ascending order + for i := 0; i < ValCnt-1; i++ { + val := valSet.GetByIndex(uint64(i)) + nextVal := valSet.GetByIndex(uint64(i + 1)) + if strings.Compare(val.String(), nextVal.String()) >= 0 { + t.Errorf("validator set is not sorted in ascending order") + } + } +} + +func testNormalValSet(t *testing.T) { + b1 := common.Hex2Bytes(testAddress) + b2 := common.Hex2Bytes(testAddress2) + addr1 := common.BytesToAddress(b1) + addr2 := common.BytesToAddress(b2) + val1 := New(addr1) + val2 := New(addr2) + + valSet := newDefaultSet([]common.Address{addr1, addr2}, istanbul.RoundRobin) + if valSet == nil { + t.Errorf("the format of validator set is invalid") + t.FailNow() + } + + // check size + if size := valSet.Size(); size != 2 { + t.Errorf("the size of validator set is wrong: have %v, want 2", size) + } + // test get by index + if val := valSet.GetByIndex(uint64(0)); !reflect.DeepEqual(val, val1) { + t.Errorf("validator mismatch: have %v, want %v", val, val1) + } + // test get by invalid index + if val := valSet.GetByIndex(uint64(2)); val != nil { + t.Errorf("validator mismatch: have %v, want nil", val) + } + // test get by address + if _, val := valSet.GetByAddress(addr2); !reflect.DeepEqual(val, val2) { + t.Errorf("validator mismatch: have %v, want %v", val, val2) + } + // test get by invalid address + invalidAddr := common.HexToAddress("0x9535b2e7faaba5288511d89341d94a38063a349b") + if _, val := valSet.GetByAddress(invalidAddr); val != nil { + t.Errorf("validator mismatch: have %v, want nil", val) + } + // test get proposer + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + // test calculate proposer + lastProposer := addr1 + valSet.CalcProposer(lastProposer, uint64(0)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } + valSet.CalcProposer(lastProposer, uint64(3)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + // test empty last proposer + lastProposer = common.Address{} + valSet.CalcProposer(lastProposer, uint64(3)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } +} + +func testEmptyValSet(t *testing.T) { + valSet := NewSet(ExtractValidators([]byte{}), istanbul.RoundRobin) + if valSet == nil { + t.Errorf("validator set should not be nil") + } +} + +func testAddAndRemoveValidator(t *testing.T) { + valSet := NewSet(ExtractValidators([]byte{}), istanbul.RoundRobin) + if !valSet.AddValidator(common.StringToAddress("2")) { + t.Error("the validator should be added") + } + if valSet.AddValidator(common.StringToAddress("2")) { + t.Error("the existing validator should not be added") + } + valSet.AddValidator(common.StringToAddress("1")) + valSet.AddValidator(common.StringToAddress("0")) + if len(valSet.List()) != 3 { + t.Error("the size of validator set should be 3") + } + + for i, v := range valSet.List() { + expected := common.StringToAddress((fmt.Sprint(i))) + if v.Address() != expected { + t.Errorf("the order of validators is wrong: have %v, want %v", v.Address().Hex(), expected.Hex()) + } + } + + if !valSet.RemoveValidator(common.StringToAddress("2")) { + t.Error("the validator should be removed") + } + if valSet.RemoveValidator(common.StringToAddress("2")) { + t.Error("the non-existing validator should not be removed") + } + if len(valSet.List()) != 2 { + t.Error("the size of validator set should be 2") + } + valSet.RemoveValidator(common.StringToAddress("1")) + if len(valSet.List()) != 1 { + t.Error("the size of validator set should be 1") + } + valSet.RemoveValidator(common.StringToAddress("0")) + if len(valSet.List()) != 0 { + t.Error("the size of validator set should be 0") + } +} + +func testStickyProposer(t *testing.T) { + b1 := common.Hex2Bytes(testAddress) + b2 := common.Hex2Bytes(testAddress2) + addr1 := common.BytesToAddress(b1) + addr2 := common.BytesToAddress(b2) + val1 := New(addr1) + val2 := New(addr2) + + valSet := newDefaultSet([]common.Address{addr1, addr2}, istanbul.Sticky) + + // test get proposer + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + // test calculate proposer + lastProposer := addr1 + valSet.CalcProposer(lastProposer, uint64(0)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val1) { + t.Errorf("proposer mismatch: have %v, want %v", val, val1) + } + + valSet.CalcProposer(lastProposer, uint64(1)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } + // test empty last proposer + lastProposer = common.Address{} + valSet.CalcProposer(lastProposer, uint64(3)) + if val := valSet.GetProposer(); !reflect.DeepEqual(val, val2) { + t.Errorf("proposer mismatch: have %v, want %v", val, val2) + } +} diff --git a/consensus/istanbul/validator/validator.go b/consensus/istanbul/validator/validator.go new file mode 100644 index 0000000000..9a1e15c2d8 --- /dev/null +++ b/consensus/istanbul/validator/validator.go @@ -0,0 +1,47 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package validator + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/istanbul" +) + +func New(addr common.Address) istanbul.Validator { + return &defaultValidator{ + address: addr, + } +} + +func NewSet(addrs []common.Address, policy istanbul.ProposerPolicy) istanbul.ValidatorSet { + return newDefaultSet(addrs, policy) +} + +func ExtractValidators(extraData []byte) []common.Address { + // get the validator addresses + addrs := make([]common.Address, (len(extraData) / common.AddressLength)) + for i := 0; i < len(addrs); i++ { + copy(addrs[i][:], extraData[i*common.AddressLength:]) + } + + return addrs +} + +// Check whether the extraData is presented in prescribed form +func ValidExtraData(extraData []byte) bool { + return len(extraData)%common.AddressLength == 0 +} diff --git a/consensus/protocol.go b/consensus/protocol.go new file mode 100644 index 0000000000..6f65eebfd5 --- /dev/null +++ b/consensus/protocol.go @@ -0,0 +1,77 @@ +// Quorum +package consensus + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// Constants to match up protocol versions and messages +// istanbul/99 was added to accommodate new eth/64 handshake status data with fork id +// this is for backward compatibility which allows a mixed old/new istanbul node network +// istanbul/64 will continue using old status data as eth/63 +const ( + eth63 = 63 + eth64 = 64 + eth65 = 65 + Istanbul64 = 64 + Istanbul99 = 99 + // this istanbul subprotocol will be registered in addition to "eth" + Istanbul100 = 100 +) + +var ( + IstanbulProtocol = Protocol{ + Name: "istanbul", + Versions: []uint{Istanbul100, Istanbul99, Istanbul64}, + // istanbul/100 has to have 18 message to be backwards compatible although at the p2p layer it only has + // 1 message with msg.Code 17 + Lengths: map[uint]uint64{Istanbul100: 18, Istanbul99: 18, Istanbul64: 18}, + } + + CliqueProtocol = Protocol{ + Name: "eth", + Versions: []uint{eth65, eth64, eth63}, + Lengths: map[uint]uint64{eth65: 17, eth64: 17, eth63: 17}, + } + + // Default: Keep up-to-date with eth/protocol.go + EthProtocol = Protocol{ + Name: "eth", + Versions: []uint{eth65, eth64, eth63}, + Lengths: map[uint]uint64{eth65: 17, eth64: 17, eth63: 17}, + } + + NorewardsProtocol = Protocol{ + Name: "Norewards", + Versions: []uint{0}, + Lengths: map[uint]uint64{0: 0}, + } +) + +// Protocol defines the protocol of the consensus +type Protocol struct { + // Official short name of the protocol used during capability negotiation. + Name string + // Supported versions of the eth protocol (first is primary). + Versions []uint + // Number of implemented message corresponding to different protocol versions. + Lengths map[uint]uint64 +} + +// Broadcaster defines the interface to enqueue blocks to fetcher and find peer +type Broadcaster interface { + // Enqueue add a block into fetcher queue + Enqueue(id string, block *types.Block) + // FindPeers retrives peers by addresses + FindPeers(map[common.Address]bool) map[common.Address]Peer +} + +// Peer defines the interface to communicate with peer +type Peer interface { + // Send sends the message to this peer + Send(msgcode uint64, data interface{}) error + + // SendConsensus sends the message to this p2p peer using the consensus specific devp2p subprotocol + SendConsensus(msgcode uint64, data interface{}) error +} diff --git a/console/console.go b/console/console.go index 1dcad3065e..1200ad99eb 100644 --- a/console/console.go +++ b/console/console.go @@ -17,6 +17,7 @@ package console import ( + "context" "fmt" "io" "io/ioutil" @@ -196,6 +197,10 @@ func (c *Console) initExtensions() error { if api == "web3" { continue } + //quorum + // the @ symbol results in errors that prevent the extension from being added to the web3 object + api = strings.Replace(api, "plugin@", "plugin_", 1) + //!quorum aliases[api] = struct{}{} if file, ok := web3ext.Modules[api]; ok { if err = c.jsre.Compile(api+".js", file); err != nil { @@ -301,8 +306,26 @@ func (c *Console) AutoCompleteInput(line string, pos int) (string, []string, str func (c *Console) Welcome() { message := "Welcome to the Geth JavaScript console!\n\n" - // Print some generic Geth metadata - if res, err := c.jsre.Run(` + // Quorum: Block timestamp for Raft is in nanoseconds, so convert accordingly + consensus := c.getConsensus() + if consensus == "raft" { + // Print some generic Geth metadata + if res, err := c.jsre.Run(` + var message = "instance: " + web3.version.node + "\n"; + try { + message += "coinbase: " + eth.coinbase + "\n"; + } catch (err) {} + message += "at block: " + eth.blockNumber + " (" + new Date(eth.getBlock(eth.blockNumber).timestamp / 1000000) + ")\n"; + try { + message += " datadir: " + admin.datadir + "\n"; + } catch (err) {} + message + `); err == nil { + message += res.String() + } + } else { + // Print some generic Geth metadata + if res, err := c.jsre.Run(` var message = "instance: " + web3.version.node + "\n"; try { message += "coinbase: " + eth.coinbase + "\n"; @@ -313,7 +336,8 @@ func (c *Console) Welcome() { } catch (err) {} message `); err == nil { - message += res.String() + message += res.String() + } } // List all the supported modules for the user to call if apis, err := c.client.SupportedModules(); err == nil { @@ -327,6 +351,30 @@ func (c *Console) Welcome() { fmt.Fprintln(c.printer, message) } +// Get the consensus mechanism that is in use +func (c *Console) getConsensus() string { + + var nodeInfo struct { + Protocols struct { + Eth struct { // only partial of eth/handler.go#NodeInfo + Consensus string + } + Istanbul struct { // a bit different from others + Consensus string + } + } + } + + if err := c.client.CallContext(context.Background(), &nodeInfo, "admin_nodeInfo"); err != nil { + _, _ = fmt.Fprintf(c.printer, "WARNING: call to admin.getNodeInfo() failed, unable to determine consensus mechanism\n") + return "unknown" + } + if nodeInfo.Protocols.Istanbul.Consensus != "" { + return nodeInfo.Protocols.Istanbul.Consensus + } + return nodeInfo.Protocols.Eth.Consensus +} + // Evaluate executes code and pretty prints the result to the specified output // stream. func (c *Console) Evaluate(statement string) { diff --git a/containers/docker/develop-alpine/Dockerfile_BASE_30347 b/containers/docker/develop-alpine/Dockerfile_BASE_30347 new file mode 100644 index 0000000000..f3247d1788 --- /dev/null +++ b/containers/docker/develop-alpine/Dockerfile_BASE_30347 @@ -0,0 +1,14 @@ +FROM alpine:3.4 + +RUN \ + apk add --update go git make gcc musl-dev && \ + git clone --depth 1 --branch develop https://github.com/ethereum/go-ethereum && \ + (cd go-ethereum && make geth) && \ + cp go-ethereum/build/bin/geth /geth && \ + apk del go git make gcc musl-dev && \ + rm -rf /go-ethereum && rm -rf /var/cache/apk/* + +EXPOSE 8545 +EXPOSE 30303 + +ENTRYPOINT ["/geth"] diff --git a/containers/docker/develop-alpine/Dockerfile_LOCAL_30347 b/containers/docker/develop-alpine/Dockerfile_LOCAL_30347 new file mode 100644 index 0000000000..d239129d53 --- /dev/null +++ b/containers/docker/develop-alpine/Dockerfile_LOCAL_30347 @@ -0,0 +1,14 @@ +FROM alpine:3.5 + +RUN \ + apk add --update go git make gcc musl-dev linux-headers ca-certificates && \ + git clone --depth 1 https://github.com/ethereum/go-ethereum && \ + (cd go-ethereum && make geth) && \ + cp go-ethereum/build/bin/geth /geth && \ + apk del go git make gcc musl-dev linux-headers && \ + rm -rf /go-ethereum && rm -rf /var/cache/apk/* + +EXPOSE 8545 +EXPOSE 30303 + +ENTRYPOINT ["/geth"] diff --git a/containers/vagrant/.gitignore b/containers/vagrant/.gitignore new file mode 100644 index 0000000000..8000dd9db4 --- /dev/null +++ b/containers/vagrant/.gitignore @@ -0,0 +1 @@ +.vagrant diff --git a/containers/vagrant/provisioners/shell/centos.sh b/containers/vagrant/provisioners/shell/centos.sh new file mode 100755 index 0000000000..744da4bfd4 --- /dev/null +++ b/containers/vagrant/provisioners/shell/centos.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +sudo yum install -y git wget +sudo yum update -y + +wget --continue https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz +sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz + +GETH_PATH="~vagrant/go/src/github.com/ethereum/go-ethereum/build/bin/" + +echo "export PATH=$PATH:/usr/local/go/bin:$GETH_PATH" >> ~vagrant/.bashrc diff --git a/containers/vagrant/provisioners/shell/debian.sh b/containers/vagrant/provisioners/shell/debian.sh new file mode 100755 index 0000000000..1c1793336d --- /dev/null +++ b/containers/vagrant/provisioners/shell/debian.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +sudo apt-get install -y build-essential git-all wget +sudo apt-get update + +wget --continue https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz +sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz + +GETH_PATH="~vagrant/go/src/github.com/ethereum/go-ethereum/build/bin/" + +echo "export PATH=$PATH:/usr/local/go/bin:$GETH_PATH" >> ~vagrant/.bashrc diff --git a/containers/vagrant/provisioners/shell/ubuntu.sh b/containers/vagrant/provisioners/shell/ubuntu.sh new file mode 100755 index 0000000000..1c1793336d --- /dev/null +++ b/containers/vagrant/provisioners/shell/ubuntu.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +sudo apt-get install -y build-essential git-all wget +sudo apt-get update + +wget --continue https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz +sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz + +GETH_PATH="~vagrant/go/src/github.com/ethereum/go-ethereum/build/bin/" + +echo "export PATH=$PATH:/usr/local/go/bin:$GETH_PATH" >> ~vagrant/.bashrc diff --git a/core/bench_test.go b/core/bench_test.go index 0f4cabd837..e69ad656fc 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -94,6 +94,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) { var ( ringKeys = make([]*ecdsa.PrivateKey, 1000) ringAddrs = make([]common.Address, len(ringKeys)) + // bigTxGas = new(big.Int).SetUint64(params.TxGas) ) func init() { diff --git a/core/block_validator.go b/core/block_validator.go index b7af12ff9e..893bb20f2f 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -78,6 +78,8 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // transition, such as amount of used gas, the receipt roots and the state root // itself. ValidateState returns a database batch if the validation was a success // otherwise nil and an error is returned. +// +// For quorum it also verifies if the canonical hash in the blocks state points to a valid parent hash. func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error { header := block.Header() if block.GasUsed() != usedGas { @@ -107,10 +109,10 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD // ceil if the blocks are full. If the ceil is exceeded, it will always decrease // the gas allowance. func CalcGasLimit(parent *types.Block, gasFloor, gasCeil uint64) uint64 { - // contrib = (parentGasUsed * 3 / 2) / 1024 + // contrib = (parentGasUsed * 3 / 2) / 4096 contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor - // decay = parentGasLimit / 1024 -1 + // decay = parentGasLimit / 4096 -1 decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1 /* diff --git a/core/blockchain.go b/core/blockchain.go index 948242ed89..1bd24e7ccd 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -18,6 +18,7 @@ package core import ( + "context" "errors" "fmt" "io" @@ -29,9 +30,11 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state/snapshot" @@ -45,6 +48,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" lru "github.com/hashicorp/golang-lru" + "github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto" ) var ( @@ -207,9 +211,26 @@ type BlockChain struct { processor Processor // Block transaction processor interface vmConfig vm.Config - badBlocks *lru.Cache // Bad block cache - shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block. - terminateInsert func(common.Hash, uint64) bool // Testing hook used to terminate ancient receipt chain insertion. + badBlocks *lru.Cache // Bad block cache + shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block. + terminateInsert func(common.Hash, uint64) bool // Testing hook used to terminate ancient receipt chain insertion. + setPrivateState func([]*types.Log, *state.StateDB, types.PrivateStateIdentifier) // Function to check extension and set private state + + isMultitenant bool // if this blockchain supports multitenancy + // privateStateManager manages private state(s) for this blockchain + privateStateManager mps.PrivateStateManager +} + +// function pointer for updating private state +func (bc *BlockChain) PopulateSetPrivateState(ps func([]*types.Log, *state.StateDB, types.PrivateStateIdentifier)) { + bc.setPrivateState = ps +} + +// function to update the private state as a part contract state extension +func (bc *BlockChain) CheckAndSetPrivateState(txLogs []*types.Log, privateState *state.StateDB, psi types.PrivateStateIdentifier) { + if bc.setPrivateState != nil { + bc.setPrivateState(txLogs, privateState, psi) + } } // NewBlockChain returns a fully initialised block chain using information @@ -250,6 +271,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par bc.processor = NewStateProcessor(chainConfig, bc, engine) var err error + // Quorum: attempt to initialize PSM + if bc.privateStateManager, err = newPrivateStateManager(bc.db, chainConfig.IsMPS); err != nil { + return nil, err + } bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped) if err != nil { return nil, err @@ -286,6 +311,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par return nil, err } } + + // Quorum + if err := bc.privateStateManager.CheckAt(head.Root()); err != nil { + log.Warn("Head private state missing, resetting chain", "number", head.Number(), "hash", head.Hash()) + return nil, bc.Reset() + } + // End Quorum + // Ensure that a previous crash in SetHead doesn't leave extra ancients if frozen, err := bc.db.Ancients(); err == nil && frozen > 0 { var ( @@ -363,6 +396,27 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par return bc, nil } +// Quorum +// Decorates NewBlockChain with multitenancy flag +func NewMultitenantBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool, txLookupLimit *uint64) (*BlockChain, error) { + bc, err := NewBlockChain(db, cacheConfig, chainConfig, engine, vmConfig, shouldPreserve, txLookupLimit) + if err != nil { + return nil, err + } + bc.isMultitenant = true + return bc, err +} + +func (bc *BlockChain) PrivateStateManager() mps.PrivateStateManager { + return bc.privateStateManager +} + +func (bc *BlockChain) SetPrivateStateManager(psm mps.PrivateStateManager) { + bc.privateStateManager = psm +} + +// End Quorum + // GetVMConfig returns the block chain VM config. func (bc *BlockChain) GetVMConfig() *vm.Config { return &bc.vmConfig @@ -399,6 +453,20 @@ func (bc *BlockChain) loadLastState() error { log.Warn("Head block missing, resetting chain", "hash", head) return bc.Reset() } + + // Quorum + if privateStateRepository, err := bc.privateStateManager.StateRepository(currentBlock.Root()); err != nil { + if privateStateRepository == nil { + log.Warn("Head private state missing, resetting chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) + return bc.Reset() + } + if _, err := privateStateRepository.DefaultState(); err != nil { + log.Warn("Head private state missing, resetting chain", "number", currentBlock.Number(), "hash", currentBlock.Hash()) + return bc.Reset() + } + } + // /Quorum + // Everything seems to be fine, set as the head block bc.currentBlock.Store(currentBlock) headBlockGauge.Update(int64(currentBlock.NumberU64())) @@ -583,7 +651,14 @@ func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error { // GasLimit returns the gas limit of the current HEAD block. func (bc *BlockChain) GasLimit() uint64 { - return bc.CurrentBlock().GasLimit() + bc.chainmu.RLock() + defer bc.chainmu.RUnlock() + + if bc.Config().IsQuorum { + return math.MaxBig256.Uint64() // HACK(joel) a very large number + } else { + return bc.CurrentBlock().GasLimit() + } } // CurrentBlock retrieves the current head block of the canonical chain. The @@ -618,13 +693,51 @@ func (bc *BlockChain) Processor() Processor { } // State returns a new mutable state based on the current HEAD block. -func (bc *BlockChain) State() (*state.StateDB, error) { +func (bc *BlockChain) State() (*state.StateDB, mps.PrivateStateRepository, error) { return bc.StateAt(bc.CurrentBlock().Root()) } -// StateAt returns a new mutable state based on a particular point in time. -func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { - return state.New(root, bc.stateCache, bc.snaps) +// Quorum +// +// StatePSI returns a new mutable public state and a mutable private state for given PSI, +// based on the current HEAD block. +func (bc *BlockChain) StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, *state.StateDB, error) { + return bc.StateAtPSI(bc.CurrentBlock().Root(), psi) +} + +// Quorum +// +// StatePSI returns a new mutable public state and a mutable private state for the given PSI, +// based on a particular point in time. +func (bc *BlockChain) StateAtPSI(root common.Hash, psi types.PrivateStateIdentifier) (*state.StateDB, *state.StateDB, error) { + publicStateDb, privateStateRepo, err := bc.StateAt(root) + if err != nil { + return nil, nil, err + } + + privateStateDb, privateStateDbErr := privateStateRepo.StatePSI(psi) + if privateStateDbErr != nil { + return nil, nil, privateStateDbErr + } + + return publicStateDb, privateStateDb, nil +} + +// StateAt returns a new mutable public state and a new mutable private state repo +// based on a particular point in time. The returned private state repo can be used +// to obtain a mutable private state for a given PSI +func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, mps.PrivateStateRepository, error) { + publicStateDb, publicStateDbErr := state.New(root, bc.stateCache, bc.snaps) + if publicStateDbErr != nil { + return nil, nil, publicStateDbErr + } + + privateStateRepo, privateStateRepoErr := bc.privateStateManager.StateRepository(root) + if privateStateRepoErr != nil { + return nil, nil, privateStateRepoErr + } + + return publicStateDb, privateStateRepo, nil } // StateCache returns the caching database underpinning the blockchain instance. @@ -1421,16 +1534,44 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error { } // WriteBlockWithState writes the block and all associated state to the database. -func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { +func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, psManager mps.PrivateStateRepository, emitHeadEvent bool) (status WriteStatus, err error) { bc.chainmu.Lock() defer bc.chainmu.Unlock() - return bc.writeBlockWithState(block, receipts, logs, state, emitHeadEvent) + return bc.writeBlockWithState(block, receipts, logs, state, psManager, emitHeadEvent) +} + +// QUORUM +// checks if the consensus engine is Rfat +func (bc *BlockChain) isRaft() bool { + return bc.chainConfig.IsQuorum && bc.chainConfig.Istanbul == nil && bc.chainConfig.Clique == nil +} + +// function specifically added for Raft consensus. This is called from mintNewBlock +// to commit public and private state using bc.chainmu lock +// added to avoid concurrent map errors in high stress conditions +func (bc *BlockChain) CommitBlockWithState(deleteEmptyObjects bool, state, privateState *state.StateDB) error { + // check if consensus is not Raft + if !bc.isRaft() { + return errors.New("error function can be called only for Raft consensus") + } + + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + if _, err := state.Commit(deleteEmptyObjects); err != nil { + return fmt.Errorf("error committing public state: %v", err) + } + if _, err := privateState.Commit(deleteEmptyObjects); err != nil { + return fmt.Errorf("error committing private state: %v", err) + } + return nil } +// END QUORUM + // writeBlockWithState writes the block and all associated state to the database, // but is expects the chain mutex to be held. -func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { +func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, psManager mps.PrivateStateRepository, emitHeadEvent bool) (status WriteStatus, err error) { bc.wg.Add(1) defer bc.wg.Done() @@ -1440,6 +1581,14 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. return NonStatTy, consensus.ErrUnknownAncestor } // Make sure no inconsistent state is leaked during insertion + // Quorum + // Write private state changes to database + err = psManager.CommitAndWrite(bc.chainConfig.IsEIP158(block.Number()), block) + if err != nil { + return NonStatTy, err + } + // /Quorum + currentBlock := bc.CurrentBlock() localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64()) externTd := new(big.Int).Add(block.Difficulty(), ptd) @@ -1447,7 +1596,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // Irrelevant of the canonical status, write the block itself to the database. // // Note all the components of block(td, hash->number map, header, body, receipts) - // should be written atomically. BlockBatch is used for containing all components. + // should be written aeth/downloader/downloader.gotomically. BlockBatch is used for containing all components. blockBatch := bc.db.NewBatch() rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd) rawdb.WriteBlock(blockBatch, block) @@ -1458,6 +1607,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. } // Commit all cached state changes into underlying memory database. root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) + if err != nil { return NonStatTy, err } @@ -1468,6 +1618,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. if err := triedb.Commit(root, false, nil); err != nil { return NonStatTy, err } + } else { // Full but not archive node, do proper garbage collection triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive @@ -1634,6 +1785,12 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, error) { // If the chain is terminating, don't even bother starting up if atomic.LoadInt32(&bc.procInterrupt) == 1 { + log.Debug("Premature abort during blocks processing") + // QUORUM + if bc.isRaft() { + // Only returns an error for raft mode + return 0, ErrAbortBlocksProcessing + } return 0, nil } // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) @@ -1739,6 +1896,12 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er // If the chain is terminating, stop processing blocks if bc.insertStopped() { log.Debug("Abort during block processing") + // QUORUM + if bc.isRaft() { + // Only returns an error for raft mode + return it.index, ErrAbortBlocksProcessing + } + // END QUORUM break } // If the header is a banned one, straight out abort @@ -1791,16 +1954,27 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er if parent == nil { parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) } + statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps) if err != nil { return it.index, err } + // Quorum + privateStateRepo, err := bc.privateStateManager.StateRepository(parent.Root) + if err != nil { + return it.index, err + } + // /Quorum + // If we have a followup block, run that against the current state to pre-cache // transactions and probabilistically some of the account/storage trie nodes. var followupInterrupt uint32 if !bc.cacheConfig.TrieCleanNoPrefetch { if followup, err := it.peek(); followup != nil && err == nil { throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps) + //due to privateStateRepo changes, for now only do prefetch on the public state + //we do have an option to also do it on overall privateState but need a function in privateStateRepo to return the overall private stateCache + //this reverts the prefetch definition to the original go-ethereum definition (only takes in publicState) go func(start time.Time, followup *types.Block, throwaway *state.StateDB, interrupt *uint32) { bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt) @@ -1813,7 +1987,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er } // Process block using the parent state as reference point substart := time.Now() - receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig) + + receipts, privateReceipts, logs, usedGas, err := bc.processor.Process(block, statedb, privateStateRepo, bc.vmConfig) if err != nil { bc.reportBlock(block, receipts, err) atomic.StoreUint32(&followupInterrupt, 1) @@ -1840,8 +2015,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er atomic.StoreUint32(&followupInterrupt, 1) return it.index, err } - proctime := time.Since(start) + allReceipts := privateStateRepo.MergeReceipts(receipts, privateReceipts) + proctime := time.Since(start) // Update the metrics touched during block validation accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete, we can mark them storageHashTimer.Update(statedb.StorageHashes) // Storage hashes are complete, we can mark them @@ -1850,12 +2026,14 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er // Write the block to the chain and get the status. substart = time.Now() - status, err := bc.writeBlockWithState(block, receipts, logs, statedb, false) + status, err := bc.writeBlockWithState(block, allReceipts, logs, statedb, privateStateRepo, false) atomic.StoreUint32(&followupInterrupt, 1) if err != nil { return it.index, err } - + if err := rawdb.WritePrivateBlockBloom(bc.db, block.NumberU64(), privateReceipts); err != nil { + return it.index, err + } // Update the metrics touched during block commit accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them @@ -2311,6 +2489,11 @@ func (bc *BlockChain) BadBlocks() []*types.Block { return blocks } +// HasBadBlock returns whether the block with the hash is a bad block. dep: Istanbul +func (bc *BlockChain) HasBadBlock(hash common.Hash) bool { + return bc.badBlocks.Contains(hash) +} + // addBadBlock adds a bad block to the bad-block LRU cache func (bc *BlockChain) addBadBlock(block *types.Block) { bc.badBlocks.Add(block.Hash(), block) @@ -2481,3 +2664,7 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) } + +func (bc *BlockChain) SupportsMultitenancy(context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) { + return nil, bc.isMultitenant +} diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 7ec62b11dd..fbd68eaab1 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -148,7 +148,11 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { if err != nil { return err } - receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{}) + privateStateRepo, repoErr := blockchain.PrivateStateManager().StateRepository(block.ParentHash()) + if repoErr != nil { + return repoErr + } + receipts, _, _, usedGas, err := blockchain.processor.Process(block, statedb, privateStateRepo, vm.Config{}) if err != nil { blockchain.reportBlock(block, receipts, err) return err @@ -830,7 +834,7 @@ func TestChainTxReorgs(t *testing.T) { db = rawdb.NewMemoryDatabase() gspec = &Genesis{ Config: params.TestChainConfig, - GasLimit: 3141592, + GasLimit: 700000000, Alloc: GenesisAlloc{ addr1: {Balance: big.NewInt(1000000)}, addr2: {Balance: big.NewInt(1000000)}, @@ -1263,7 +1267,7 @@ func TestEIP155Transition(t *testing.T) { funds = big.NewInt(1000000000) deleteAddr = common.Address{1} gspec = &Genesis{ - Config: ¶ms.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, + Config: ¶ms.ChainConfig{ChainID: big.NewInt(10), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, } genesis = gspec.MustCommit(db) @@ -1367,7 +1371,7 @@ func TestEIP161AccountRemoval(t *testing.T) { theAddr = common.Address{1} gspec = &Genesis{ Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(1), + ChainID: big.NewInt(10), HomesteadBlock: new(big.Int), EIP155Block: new(big.Int), EIP150Block: new(big.Int), @@ -1403,7 +1407,7 @@ func TestEIP161AccountRemoval(t *testing.T) { if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil { t.Fatal(err) } - if st, _ := blockchain.State(); !st.Exist(theAddr) { + if st, _, _ := blockchain.State(); !st.Exist(theAddr) { t.Error("expected account to exist") } @@ -1411,7 +1415,7 @@ func TestEIP161AccountRemoval(t *testing.T) { if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil { t.Fatal(err) } - if st, _ := blockchain.State(); st.Exist(theAddr) { + if st, _, _ := blockchain.State(); st.Exist(theAddr) { t.Error("account should not exist") } @@ -1419,7 +1423,7 @@ func TestEIP161AccountRemoval(t *testing.T) { if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil { t.Fatal(err) } - if st, _ := blockchain.State(); st.Exist(theAddr) { + if st, _, _ := blockchain.State(); st.Exist(theAddr) { t.Error("account should not exist") } } @@ -2623,7 +2627,7 @@ func TestDeleteRecreateSlots(t *testing.T) { if n, err := chain.InsertChain(blocks); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", n, err) } - statedb, _ := chain.State() + statedb, _, _ := chain.State() // If all is correct, then slot 1 and 2 are zero if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp { @@ -2703,7 +2707,7 @@ func TestDeleteRecreateAccount(t *testing.T) { if n, err := chain.InsertChain(blocks); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", n, err) } - statedb, _ := chain.State() + statedb, _, _ := chain.State() // If all is correct, then both slots are zero if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp { @@ -2867,7 +2871,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) { diskdb := rawdb.NewMemoryDatabase() gspec.MustCommit(diskdb) chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{ - //Debug: true, + //Debug: true, //Tracer: vm.NewJSONLogger(nil, os.Stdout), }, nil, nil) if err != nil { @@ -2881,7 +2885,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) { if n, err := chain.InsertChain([]*types.Block{block}); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", n, err) } - statedb, _ := chain.State() + statedb, _, _ := chain.State() // If all is correct, then slot 1 and 2 are zero if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp { t.Errorf("block %d, got %x exp %x", blockNum, got, exp) @@ -3007,7 +3011,7 @@ func TestInitThenFailCreateContract(t *testing.T) { if err != nil { t.Fatalf("failed to create tester chain: %v", err) } - statedb, _ := chain.State() + statedb, _, _ := chain.State() if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 { t.Fatalf("Genesis err, got %v exp %v", got, exp) } @@ -3017,7 +3021,7 @@ func TestInitThenFailCreateContract(t *testing.T) { if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) } - statedb, _ = chain.State() + statedb, _, _ = chain.State() if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 { t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp) } diff --git a/core/call_helper.go b/core/call_helper.go new file mode 100644 index 0000000000..46532b0c10 --- /dev/null +++ b/core/call_helper.go @@ -0,0 +1,100 @@ +package core + +import ( + "crypto/ecdsa" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +// callHelper makes it easier to do proper calls and use the state transition object. +// It also manages the nonces of the caller and keeps private and public state, which +// can be freely modified outside of the helper. +type callHelper struct { + db ethdb.Database + + nonces map[common.Address]uint64 + header types.Header + gp *GasPool + + PrivateState, PublicState *state.StateDB +} + +// TxNonce returns the pending nonce +func (cg *callHelper) TxNonce(addr common.Address) uint64 { + return cg.nonces[addr] +} + +// MakeCall makes does a call to the recipient using the given input. It can switch between private and public +// by setting the private boolean flag. It returns an error if the call failed. +func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Address, input []byte) error { + var ( + from = crypto.PubkeyToAddress(key.PublicKey) + err error + ) + + // TODO(joel): these are just stubbed to the same values as in dual_state_test.go + cg.header.Number = new(big.Int) + cg.header.Time = uint64(43) + cg.header.Difficulty = new(big.Int).SetUint64(1000488) + cg.header.GasLimit = 4700000 + + signer := types.MakeSigner(params.QuorumTestChainConfig, cg.header.Number) + if private { + signer = types.QuorumPrivateTxSigner{} + } + + tx, err := types.SignTx(types.NewTransaction(cg.TxNonce(from), to, new(big.Int), 1000000, new(big.Int), input), signer, key) + + if err != nil { + return err + } + defer func() { cg.nonces[from]++ }() + msg, err := tx.AsMessage(signer) + if err != nil { + return err + } + + publicState, privateState := cg.PublicState, cg.PrivateState + if !private { + privateState = publicState + } + // TODO(joel): can we just pass nil instead of bc? + bc, _ := NewBlockChain(cg.db, nil, params.QuorumTestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil) + context := NewEVMContext(msg, &cg.header, bc, &from) + vmenv := vm.NewEVM(context, publicState, privateState, params.QuorumTestChainConfig, vm.Config{}) + sender := vm.AccountRef(msg.From()) + vmenv.Call(sender, to, msg.Data(), 100000000, new(big.Int)) + return err +} + +// MakeCallHelper returns a new callHelper +func MakeCallHelper() *callHelper { + memdb := rawdb.NewMemoryDatabase() + db := state.NewDatabase(memdb) + + publicState, err := state.New(common.Hash{}, db, nil) + if err != nil { + panic(err) + } + privateState, err := state.New(common.Hash{}, db, nil) + if err != nil { + panic(err) + } + cg := &callHelper{ + db: memdb, + nonces: make(map[common.Address]uint64), + gp: new(GasPool).AddGas(5000000), + PublicState: publicState, + PrivateState: privateState, + } + return cg +} diff --git a/core/chain_makers.go b/core/chain_makers.go index 33f253d9e8..89466f3d82 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -103,7 +103,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { b.SetCoinbase(common.Address{}) } b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) - receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}, false) if err != nil { panic(err) } diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 85a029f7c7..8ec2091c2f 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -87,7 +87,7 @@ func ExampleGenerateChain() { return } - state, _ := blockchain.State() + state, _, _ := blockchain.State() fmt.Printf("last block: #%d\n", blockchain.CurrentBlock().Number()) fmt.Println("balance of addr1:", state.GetBalance(addr1)) fmt.Println("balance of addr2:", state.GetBalance(addr2)) diff --git a/core/constellation-test-keys/tm1.key b/core/constellation-test-keys/tm1.key new file mode 100644 index 0000000000..2f8c9e6a3c --- /dev/null +++ b/core/constellation-test-keys/tm1.key @@ -0,0 +1 @@ +{"data":{"bytes":"Wl+xSyXVuuqzpvznOS7dOobhcn4C5auxkFRi7yLtgtA="},"type":"unlocked"} \ No newline at end of file diff --git a/core/constellation-test-keys/tm1.pub b/core/constellation-test-keys/tm1.pub new file mode 100644 index 0000000000..e0f51363c3 --- /dev/null +++ b/core/constellation-test-keys/tm1.pub @@ -0,0 +1 @@ +BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo= \ No newline at end of file diff --git a/core/constellation-test-keys/tm1a.key b/core/constellation-test-keys/tm1a.key new file mode 100644 index 0000000000..59e017cbeb --- /dev/null +++ b/core/constellation-test-keys/tm1a.key @@ -0,0 +1 @@ +{"data":{"bytes":"wGEar7J9G0JAgdisp61ZChyrJWeW2QPyKvecjjeVHOY="},"type":"unlocked"} \ No newline at end of file diff --git a/core/constellation-test-keys/tm1a.pub b/core/constellation-test-keys/tm1a.pub new file mode 100644 index 0000000000..eae34e2e93 --- /dev/null +++ b/core/constellation-test-keys/tm1a.pub @@ -0,0 +1 @@ +8SjRHlUBe4hAmTk3KDeJ96RhN+s10xRrHDrxEi1O5W0= \ No newline at end of file diff --git a/core/default_psm.go b/core/default_psm.go new file mode 100644 index 0000000000..7be3e27a65 --- /dev/null +++ b/core/default_psm.go @@ -0,0 +1,58 @@ +package core + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/rpc" +) + +type DefaultPrivateStateManager struct { + // Low level persistent database to store final content in + db ethdb.Database + repoCache state.Database +} + +func newDefaultPrivateStateManager(db ethdb.Database) *DefaultPrivateStateManager { + return &DefaultPrivateStateManager{ + db: db, + repoCache: state.NewDatabase(db), + } +} + +func (d *DefaultPrivateStateManager) StateRepository(blockHash common.Hash) (mps.PrivateStateRepository, error) { + return mps.NewDefaultPrivateStateRepository(d.db, d.repoCache, blockHash) +} + +func (d *DefaultPrivateStateManager) ResolveForManagedParty(_ string) (*mps.PrivateStateMetadata, error) { + return mps.DefaultPrivateStateMetadata, nil +} + +func (d *DefaultPrivateStateManager) ResolveForUserContext(ctx context.Context) (*mps.PrivateStateMetadata, error) { + psi, ok := rpc.PrivateStateIdentifierFromContext(ctx) + if !ok { + psi = types.DefaultPrivateStateIdentifier + } + return &mps.PrivateStateMetadata{ID: psi, Type: mps.Resident}, nil +} + +func (d *DefaultPrivateStateManager) PSIs() []types.PrivateStateIdentifier { + return []types.PrivateStateIdentifier{ + types.DefaultPrivateStateIdentifier, + } +} + +func (d *DefaultPrivateStateManager) NotIncludeAny(_ *mps.PrivateStateMetadata, _ ...string) bool { + // with default implementation, all managedParties are members of the psm + return false +} + +func (d *DefaultPrivateStateManager) CheckAt(root common.Hash) error { + _, err := state.New(rawdb.GetPrivateStateRoot(d.db, root), d.repoCache, nil) + return err +} diff --git a/core/default_psm_test.go b/core/default_psm_test.go new file mode 100644 index 0000000000..1a0ce82994 --- /dev/null +++ b/core/default_psm_test.go @@ -0,0 +1,106 @@ +package core + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/rpc" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" +) + +//Tests DefaultState, StatePSI, CommitAndWrite +func TestLegacyPrivateStateCreated(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockptm := private.NewMockPrivateTransactionManager(mockCtrl) + + saved := private.P + defer func() { + private.P = saved + }() + private.P = mockptm + + mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{"psi1", "psi2"}, common.FromHex(testCode), nil, nil).AnyTimes() + + blocks, blockmap, blockchain := buildTestChain(2, params.QuorumTestChainConfig) + + for _, block := range blocks { + parent := blockmap[block.ParentHash()] + statedb, _ := state.New(parent.Root(), blockchain.StateCache(), nil) + privateStateRepo, _ := blockchain.PrivateStateManager().StateRepository(parent.Root()) + + _, privateReceipts, _, _, _ := blockchain.Processor().Process(block, statedb, privateStateRepo, vm.Config{}) + + for _, privateReceipt := range privateReceipts { + expectedContractAddress := privateReceipt.ContractAddress + + assert.False(t, privateStateRepo.IsMPS()) + privateState, _ := privateStateRepo.DefaultState() + assert.True(t, privateState.Exist(expectedContractAddress)) + assert.NotEqual(t, privateState.GetCodeSize(expectedContractAddress), 0) + defaultPrivateState, _ := privateStateRepo.StatePSI(types.DefaultPrivateStateIdentifier) + assert.True(t, defaultPrivateState.Exist(expectedContractAddress)) + assert.NotEqual(t, defaultPrivateState.GetCodeSize(expectedContractAddress), 0) + _, err := privateStateRepo.StatePSI(types.PrivateStateIdentifier("empty")) + assert.Error(t, err, "only the 'private' psi is supported by the default private state manager") + + } + //CommitAndWrite to db + privateStateRepo.CommitAndWrite(false, block) + + for _, privateReceipt := range privateReceipts { + expectedContractAddress := privateReceipt.ContractAddress + latestBlockRoot := block.Root() + //contract exists on default state + _, privDb, _ := blockchain.StateAtPSI(latestBlockRoot, types.DefaultPrivateStateIdentifier) + assert.True(t, privDb.Exist(expectedContractAddress)) + assert.NotEqual(t, privDb.GetCodeSize(expectedContractAddress), 0) + //legacy psm doesnt have concept of emptystate + _, _, err := blockchain.StateAtPSI(latestBlockRoot, types.ToPrivateStateIdentifier("empty")) + assert.Error(t, err, "only the 'private' psi is supported by the default private state manager") + //legacy psm doesnt support other private states + _, _, err = blockchain.StateAtPSI(latestBlockRoot, types.ToPrivateStateIdentifier("other")) + assert.Error(t, err, "only the 'private' psi is supported by the default private state manager") + } + } +} + +func TestDefaultResolver(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockptm := private.NewMockPrivateTransactionManager(mockCtrl) + + saved := private.P + defer func() { + private.P = saved + }() + private.P = mockptm + + mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{}, common.FromHex(testCode), nil, nil).AnyTimes() + mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, common.EncryptedPayloadHash{}.Bytes(), nil, nil).AnyTimes() + + _, _, blockchain := buildTestChain(1, params.QuorumTestChainConfig) + + mpsm := newDefaultPrivateStateManager(blockchain.db) + + psm1, _ := mpsm.ResolveForManagedParty("TEST") + assert.Equal(t, psm1, mps.DefaultPrivateStateMetadata) + + ctx := rpc.WithPrivateStateIdentifier(context.Background(), types.DefaultPrivateStateIdentifier) + psm1, _ = mpsm.ResolveForUserContext(ctx) + assert.Equal(t, psm1, &mps.PrivateStateMetadata{ID: "private", Type: mps.Resident}) + psm1, _ = mpsm.ResolveForUserContext(context.Background()) + assert.Equal(t, psm1, &mps.PrivateStateMetadata{ID: "private", Type: mps.Resident}) + + assert.Equal(t, mpsm.PSIs(), []types.PrivateStateIdentifier{types.DefaultPrivateStateIdentifier}) +} diff --git a/core/dual_state_test.go b/core/dual_state_test.go new file mode 100644 index 0000000000..f5f158b04f --- /dev/null +++ b/core/dual_state_test.go @@ -0,0 +1,213 @@ +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" +) + +var dualStateTestHeader = types.Header{ + Number: new(big.Int), + Time: 43, + Difficulty: new(big.Int).SetUint64(1000488), + GasLimit: 4700000, +} + +//[1] PUSH1 0x01 (out size) +//[3] PUSH1 0x00 (out offset) +//[5] PUSH1 0x00 (in size) +//[7] PUSH1 0x00 (in offset) +//[9] PUSH1 0x00 (value) +//[30] PUSH20 0x0200000000000000000000000000000000000000 (to) +//[34] PUSH3 0x0186a0 (gas) +//[35] CALL +//[37] PUSH1 0x00 +//[38] MLOAD +//[40] PUSH1 0x00 +//[41] SSTORE +//[42] STOP + +func TestDualStatePrivateToPublicCall(t *testing.T) { + callAddr := common.Address{1} + + db := rawdb.NewMemoryDatabase() + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(common.Address{2}, common.Hex2Bytes("600a6000526001601ff300")) + + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + privateState.SetCode(callAddr, common.Hex2Bytes("60016000600060006000730200000000000000000000000000000000000000620186a0f160005160005500")) + + author := common.Address{} + msg := callmsg{ + addr: author, + to: &callAddr, + value: big.NewInt(1), + gas: 1000000, + gasPrice: new(big.Int), + data: nil, + } + + ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author) + env := vm.NewEVM(ctx, publicState, privateState, ¶ms.ChainConfig{}, vm.Config{}) + env.Call(vm.AccountRef(author), callAddr, msg.data, msg.gas, new(big.Int)) + + if value := privateState.GetState(callAddr, common.Hash{}); value != (common.Hash{10}) { + t.Errorf("expected 10 got %x", value) + } +} + +func TestDualStatePublicToPrivateCall(t *testing.T) { + callAddr := common.Address{1} + + db := rawdb.NewMemoryDatabase() + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + privateState.SetCode(common.Address{2}, common.Hex2Bytes("600a6000526001601ff300")) + + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(callAddr, common.Hex2Bytes("60016000600060006000730200000000000000000000000000000000000000620186a0f160005160005500")) + + author := common.Address{} + msg := callmsg{ + addr: author, + to: &callAddr, + value: big.NewInt(1), + gas: 1000000, + gasPrice: new(big.Int), + data: nil, + } + + ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author) + env := vm.NewEVM(ctx, publicState, publicState, ¶ms.ChainConfig{}, vm.Config{}) + env.Call(vm.AccountRef(author), callAddr, msg.data, msg.gas, new(big.Int)) + + if value := publicState.GetState(callAddr, common.Hash{}); value != (common.Hash{}) { + t.Errorf("expected 0 got %x", value) + } +} + +func TestDualStateReadOnly(t *testing.T) { + callAddr := common.Address{1} + + db := rawdb.NewMemoryDatabase() + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(common.Address{2}, common.Hex2Bytes("600a60005500")) + + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + privateState.SetCode(callAddr, common.Hex2Bytes("60016000600060006000730200000000000000000000000000000000000000620186a0f160005160005500")) + + author := common.Address{} + msg := callmsg{ + addr: author, + to: &callAddr, + value: big.NewInt(1), + gas: 1000000, + gasPrice: new(big.Int), + data: nil, + } + + ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author) + env := vm.NewEVM(ctx, publicState, privateState, ¶ms.ChainConfig{}, vm.Config{}) + env.Call(vm.AccountRef(author), callAddr, msg.data, msg.gas, new(big.Int)) + + if value := publicState.GetState(common.Address{2}, common.Hash{}); value != (common.Hash{0}) { + t.Errorf("expected 0 got %x", value) + } +} + +var ( + calleeAddress = common.Address{2} + calleeContractCode = "600a6000526001601ff300" // a function that returns 10 + callerAddress = common.Address{1} + // a functionn that calls the callee's function at its address and return the same value + //000000: PUSH1 0x01 + //000002: PUSH1 0x00 + //000004: PUSH1 0x00 + //000006: PUSH1 0x00 + //000008: PUSH20 0x0200000000000000000000000000000000000000 + //000029: PUSH3 0x0186a0 + //000033: STATICCALL + //000034: PUSH1 0x01 + //000036: PUSH1 0x00 + //000038: RETURN + //000039: STOP + callerContractCode = "6001600060006000730200000000000000000000000000000000000000620186a0fa60016000f300" +) + +func verifyStaticCall(t *testing.T, privateState *state.StateDB, publicState *state.StateDB, expectedHash common.Hash) { + author := common.Address{} + msg := callmsg{ + addr: author, + to: &callerAddress, + value: big.NewInt(1), + gas: 1000000, + gasPrice: new(big.Int), + data: nil, + } + + ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &author) + env := vm.NewEVM(ctx, publicState, privateState, ¶ms.ChainConfig{ + ByzantiumBlock: new(big.Int), + }, vm.Config{}) + + ret, _, err := env.Call(vm.AccountRef(author), callerAddress, msg.data, msg.gas, new(big.Int)) + + if err != nil { + t.Fatalf("Call error: %s", err) + } + value := common.Hash{ret[0]} + if value != expectedHash { + t.Errorf("expected %x got %x", expectedHash, value) + } +} + +func TestStaticCall_whenPublicToPublic(t *testing.T) { + db := rawdb.NewMemoryDatabase() + + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode)) + publicState.SetCode(calleeAddress, common.Hex2Bytes(calleeContractCode)) + + verifyStaticCall(t, publicState, publicState, common.Hash{10}) +} + +func TestStaticCall_whenPublicToPrivateInTheParty(t *testing.T) { + db := rawdb.NewMemoryDatabase() + + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + privateState.SetCode(calleeAddress, common.Hex2Bytes(calleeContractCode)) + + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode)) + + verifyStaticCall(t, privateState, publicState, common.Hash{10}) +} + +func TestStaticCall_whenPublicToPrivateNotInTheParty(t *testing.T) { + + db := rawdb.NewMemoryDatabase() + + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode)) + + verifyStaticCall(t, privateState, publicState, common.Hash{0}) +} + +func TestStaticCall_whenPrivateToPublic(t *testing.T) { + db := rawdb.NewMemoryDatabase() + + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + privateState.SetCode(callerAddress, common.Hex2Bytes(callerContractCode)) + + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState.SetCode(calleeAddress, common.Hex2Bytes(calleeContractCode)) + + verifyStaticCall(t, privateState, publicState, common.Hash{10}) +} diff --git a/core/error.go b/core/error.go index 5a28be7e1c..d3f55ac4d5 100644 --- a/core/error.go +++ b/core/error.go @@ -63,4 +63,21 @@ var ( // ErrIntrinsicGas is returned if the transaction is specified to use less gas // than required to start the invocation. ErrIntrinsicGas = errors.New("intrinsic gas too low") + + // Quorum + // ErrAbortBlocksProcessing is returned if bc.insertChain is interrupted under raft mode + ErrAbortBlocksProcessing = errors.New("abort during blocks processing") + + // ErrContractManagedPartiesCheckFailed is returned if managed parties check has failed for contract + ErrContractManagedPartiesCheckFailed = errors.New("managed parties check has failed for contract") + + // ErrPrivacyMetadataInvalidMerkleRoot is returned if there is an empty MR during the pmh.prepare(...) + ErrPrivacyMetadataInvalidMerkleRoot = errors.New("privacy metadata has empty MR for stateValidation flag") + + // ErrPrivacyEnhancedReceivedWhenDisabled is returned if privacy enhanced transaction received while privacy enhancements are disabled + ErrPrivacyEnhancedReceivedWhenDisabled = errors.New("privacy metadata has empty MR for stateValidation flag") + + // ErrPrivateContractInteractionVerificationFailed is returned if the verification of contract interaction differs from the one returned by Tessera (check pmh.verify(...)) + ErrPrivateContractInteractionVerificationFailed = errors.New("verification of contract interaction differs from the one returned by Tessera") + // End Quorum ) diff --git a/core/events.go b/core/events.go index ac935a137f..5b33e94f7b 100644 --- a/core/events.go +++ b/core/events.go @@ -24,6 +24,9 @@ import ( // NewTxsEvent is posted when a batch of transactions enter the transaction pool. type NewTxsEvent struct{ Txs []*types.Transaction } +// PendingStateEvent is posted pre mining and notifies of pending state changes. +type PendingStateEvent struct{} + // NewMinedBlockEvent is posted when a block has been imported. type NewMinedBlockEvent struct{ Block *types.Block } diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go index b8d670f399..0247a80176 100644 --- a/core/forkid/forkid.go +++ b/core/forkid/forkid.go @@ -229,6 +229,11 @@ func gatherForks(config *params.ChainConfig) []uint64 { if field.Type != reflect.TypeOf(new(big.Int)) { continue } + + // ignoring QIP714Block from fork check + if field.Name == "QIP714Block" { + continue + } // Extract the fork rule block number and aggregate it rule := conf.Field(i).Interface().(*big.Int) if rule != nil { diff --git a/core/genesis.go b/core/genesis.go index 4525b9c174..bfbac4b36a 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -165,10 +165,25 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig } else { log.Info("Writing custom genesis block") } + + // Quorum: Set default transaction size limit if not set in genesis + if genesis.Config.TransactionSizeLimit == 0 { + genesis.Config.TransactionSizeLimit = DefaultTxPoolConfig.TransactionSizeLimit + } + + // Check transaction size limit and max contract code size + err := genesis.Config.IsValid() + if err != nil { + return genesis.Config, common.Hash{}, err + } + + // /Quorum + block, err := genesis.Commit(db) if err != nil { return genesis.Config, common.Hash{}, err } + checkAndPrintPrivacyEnhancementsWarning(genesis.Config) return genesis.Config, block.Hash(), nil } @@ -208,6 +223,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig if storedcfg == nil { log.Warn("Found genesis block without chain config") rawdb.WriteChainConfig(db, stored, newcfg) + checkAndPrintPrivacyEnhancementsWarning(newcfg) return newcfg, stored, nil } // Special case: don't change the existing config of a non-mainnet chain if no new @@ -223,14 +239,33 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig if height == nil { return newcfg, stored, fmt.Errorf("missing block number for head header hash") } - compatErr := storedcfg.CheckCompatible(newcfg, *height) + if storedcfg.IsMPS != newcfg.IsMPS && *height > 0 { + // TODO once we implement the MPS upgrade logic the error message should be updated (to reflect the other ways of setting the IsMPS flag value) + return newcfg, stored, fmt.Errorf("the IsMPS (multiple private states support) flag once configured at block height 0 cannot be changed") + } + compatErr := storedcfg.CheckCompatible(newcfg, *height, rawdb.GetIsQuorumEIP155Activated(db)) if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { return newcfg, stored, compatErr } rawdb.WriteChainConfig(db, stored, newcfg) + + // Quorum + if storedcfg.PrivacyEnhancementsBlock == nil { + checkAndPrintPrivacyEnhancementsWarning(newcfg) + } + // End Quorum + return newcfg, stored, nil } +func checkAndPrintPrivacyEnhancementsWarning(config *params.ChainConfig) { + if config.PrivacyEnhancementsBlock != nil { + log.Warn("Privacy enhancements have been enabled from block height " + config.PrivacyEnhancementsBlock.String() + + ". Please ensure your privacy manager is upgraded and supports privacy enhancements (tessera version 1.*) " + + "otherwise your quorum node will fail to start.") + } +} + func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { switch { case g != nil: diff --git a/core/genesis_test.go b/core/genesis_test.go index 3470d0aa01..21a029fce7 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -17,15 +17,17 @@ package core import ( + "errors" "math/big" "reflect" "testing" "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/ethash" + + //"github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/vm" + //"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" ) @@ -42,10 +44,10 @@ func TestDefaultGenesisBlock(t *testing.T) { } func TestSetupGenesis(t *testing.T) { + // Quorum: customized test cases for quorum var ( - customghash = common.HexToHash("0x89c99d90b79719238d2645c7642f2c9295246e80775b38cfd162b696817fbd50") - customg = Genesis{ - Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3)}, + customg = Genesis{ + Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3), IsQuorum: true}, Alloc: GenesisAlloc{ {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, }, @@ -86,57 +88,24 @@ func TestSetupGenesis(t *testing.T) { wantConfig: params.MainnetChainConfig, }, { - name: "custom block in DB, genesis == nil", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { - customg.MustCommit(db) - return SetupGenesisBlock(db, nil) - }, - wantHash: customghash, - wantConfig: customg.Config, - }, - { - name: "custom block in DB, genesis == ropsten", + name: "genesis with incorrect SizeLimit", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { - customg.MustCommit(db) - return SetupGenesisBlock(db, DefaultRopstenGenesisBlock()) - }, - wantErr: &GenesisMismatchError{Stored: customghash, New: params.RopstenGenesisHash}, - wantHash: params.RopstenGenesisHash, - wantConfig: params.RopstenChainConfig, - }, - { - name: "compatible config in DB", - fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { - oldcustomg.MustCommit(db) + customg.Config.TransactionSizeLimit = 100000 + customg.Config.MaxCodeSize = 32 return SetupGenesisBlock(db, &customg) }, - wantHash: customghash, + wantErr: errors.New("Genesis transaction size limit must be between 32 and 128"), wantConfig: customg.Config, }, { - name: "incompatible config in DB", + name: "genesis with incorrect max code size ", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { - // Commit the 'old' genesis block with Homestead transition at #2. - // Advance to block #4, past the homestead transition block of customg. - genesis := oldcustomg.MustCommit(db) - - bc, _ := NewBlockChain(db, nil, oldcustomg.Config, ethash.NewFullFaker(), vm.Config{}, nil, nil) - defer bc.Stop() - - blocks, _ := GenerateChain(oldcustomg.Config, genesis, ethash.NewFaker(), db, 4, nil) - bc.InsertChain(blocks) - bc.CurrentBlock() - // This should return a compatibility error. + customg.Config.TransactionSizeLimit = 64 + customg.Config.MaxCodeSize = 100000 return SetupGenesisBlock(db, &customg) }, - wantHash: customghash, + wantErr: errors.New("Genesis max code size must be between 24 and 128"), wantConfig: customg.Config, - wantErr: ¶ms.ConfigCompatError{ - What: "Homestead fork block", - StoredConfig: big.NewInt(2), - NewConfig: big.NewInt(3), - RewindTo: 1, - }, }, } diff --git a/core/mps/default_psr.go b/core/mps/default_psr.go new file mode 100644 index 0000000000..9e3909f735 --- /dev/null +++ b/core/mps/default_psr.go @@ -0,0 +1,110 @@ +package mps + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" +) + +// DefaultPrivateStateRepository acts as the single private state in the original +// Quorum design. +type DefaultPrivateStateRepository struct { + db ethdb.Database + // cache of stateDB + stateCache state.Database + // stateDB gives access to the underlying state + stateDB *state.StateDB + root common.Hash +} + +func NewDefaultPrivateStateRepository(db ethdb.Database, cache state.Database, previousBlockHash common.Hash) (*DefaultPrivateStateRepository, error) { + root := rawdb.GetPrivateStateRoot(db, previousBlockHash) + + statedb, err := state.New(root, cache, nil) + if err != nil { + return nil, err + } + + return &DefaultPrivateStateRepository{ + db: db, + stateCache: cache, + stateDB: statedb, + root: root, + }, nil +} + +func (dpsr *DefaultPrivateStateRepository) DefaultState() (*state.StateDB, error) { + return dpsr.stateDB, nil +} + +func (dpsr *DefaultPrivateStateRepository) DefaultStateMetadata() *PrivateStateMetadata { + return DefaultPrivateStateMetadata +} + +func (dpsr *DefaultPrivateStateRepository) IsMPS() bool { + return false +} + +func (dpsr *DefaultPrivateStateRepository) StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, error) { + if psi != types.DefaultPrivateStateIdentifier { + return nil, fmt.Errorf("only the 'private' psi is supported by the default private state manager") + } + return dpsr.stateDB, nil +} + +func (dpsr *DefaultPrivateStateRepository) Reset() error { + // TODO - see if we need to store the original root + return dpsr.stateDB.Reset(dpsr.root) +} + +// CommitAndWrite commits the private state and writes to disk +func (dpsr *DefaultPrivateStateRepository) CommitAndWrite(isEIP158 bool, block *types.Block) error { + privateRoot, err := dpsr.stateDB.Commit(isEIP158) + if err != nil { + return err + } + + if err := rawdb.WritePrivateStateRoot(dpsr.db, block.Root(), privateRoot); err != nil { + log.Error("Failed writing private state root", "err", err) + return err + } + return dpsr.stateCache.TrieDB().Commit(privateRoot, false, nil) +} + +// Commit commits the private state only +func (dpsr *DefaultPrivateStateRepository) Commit(isEIP158 bool, block *types.Block) error { + var err error + dpsr.root, err = dpsr.stateDB.Commit(isEIP158) + return err +} + +func (dpsr *DefaultPrivateStateRepository) Copy() PrivateStateRepository { + return &DefaultPrivateStateRepository{ + db: dpsr.db, + stateCache: dpsr.stateCache, + stateDB: dpsr.stateDB.Copy(), + root: dpsr.root, + } +} + +func (dpsr *DefaultPrivateStateRepository) MergeReceipts(pub, priv types.Receipts) types.Receipts { + m := make(map[common.Hash]*types.Receipt) + for _, receipt := range pub { + m[receipt.TxHash] = receipt + } + for _, receipt := range priv { + m[receipt.TxHash] = receipt + } + + ret := make(types.Receipts, 0, len(pub)) + for _, pubReceipt := range pub { + ret = append(ret, m[pubReceipt.TxHash]) + } + + return ret +} diff --git a/core/mps/default_psr_test.go b/core/mps/default_psr_test.go new file mode 100644 index 0000000000..822c8bbef8 --- /dev/null +++ b/core/mps/default_psr_test.go @@ -0,0 +1,171 @@ +package mps + +import ( + "math/big" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +//TestDefaultPSRCopy tests that copying a the PSR object indeed makes the original and +// the copy and their states independent of each other. +func TestDefaultPSRCopy(t *testing.T) { + + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewDefaultPrivateStateRepository(testdb, testCache, common.Hash{}) + + testState, _ := psr.DefaultState() + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + } + testState.Finalise(false) + + psrCopy := psr.Copy().(*DefaultPrivateStateRepository) + + testStateCopy, _ := psrCopy.DefaultState() + + // modify all in memory + for i := byte(0); i < 255; i++ { + testState.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(2*int64(i))) + testStateCopy.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(3*int64(i))) + } + + // Finalise the changes on all concurrently + finalise := func(wg *sync.WaitGroup, db *state.StateDB) { + defer wg.Done() + db.Finalise(true) + } + + var wg sync.WaitGroup + wg.Add(2) + go finalise(&wg, testState) + go finalise(&wg, testStateCopy) + wg.Wait() + + assert.Equal(t, psr.db, psrCopy.db) + assert.Equal(t, psr.stateCache, psrCopy.stateCache) + + // Verify that the all states have been updated independently + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testObj := testState.GetOrNewStateObject(addr) + testCopyObj := testStateCopy.GetOrNewStateObject(addr) + + if want := big.NewInt(3 * int64(i)); testObj.Balance().Cmp(want) != 0 { + t.Errorf("empty obj %d: balance mismatch: have %v, want %v", i, testObj.Balance(), want) + } + if want := big.NewInt(4 * int64(i)); testCopyObj.Balance().Cmp(want) != 0 { + t.Errorf("empty copy obj %d: balance mismatch: have %v, want %v", i, testCopyObj.Balance(), want) + } + } +} + +//TestDefaultPSRReset tests that state objects are cleared from statedb after reset call +//Any updated stateObjects not committed before reset will be cleared +func TestDefaultPSRReset(t *testing.T) { + + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewDefaultPrivateStateRepository(testdb, testCache, common.Hash{}) + + testState, _ := psr.DefaultState() + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + } + testState.Finalise(false) + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + assert.True(t, testState.Exist(addr)) + } + + psr.Reset() + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + assert.False(t, testState.Exist(addr)) + } +} + +func TestOnlyPrivateStateAccessible(t *testing.T) { + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewDefaultPrivateStateRepository(testdb, testCache, common.Hash{}) + + privateState, _ := psr.DefaultState() + assert.NotEqual(t, privateState, nil) + privateState, _ = psr.StatePSI(types.DefaultPrivateStateIdentifier) + assert.NotEqual(t, privateState, nil) + _, err := psr.StatePSI(types.PrivateStateIdentifier("test")) + assert.Error(t, err, "only the 'private' psi is supported by the default private state manager") +} + +//TestDefaultPSRCommitAndWrite tests that statedb is updated but not written to db +func TestDefaultPSRCommit(t *testing.T) { + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewDefaultPrivateStateRepository(testdb, testCache, common.Hash{}) + header := &types.Header{Number: big.NewInt(int64(1)), Root: common.Hash{123}} + block := types.NewBlockWithHeader(header) + + testState, _ := psr.DefaultState() + + testRoot := testState.IntermediateRoot(false) + assert.Equal(t, testRoot, common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) + + //make updates to states + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + } + assert.Equal(t, rawdb.GetPrivateStateRoot(testdb, block.Root()), common.Hash{}) + + psr.Commit(false, block) + + //private root updated but not committed + assert.NotEqual(t, psr.root, common.Hash{}) + assert.Equal(t, rawdb.GetPrivateStateRoot(testdb, block.Root()), common.Hash{}) + + testRoot = testState.IntermediateRoot(false) + assert.NotEqual(t, testRoot, common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) +} + +//TestDefaultPSRCommitAndWrite tests that statedb is updated and written to db +func TestDefaultPSRCommitAndWrite(t *testing.T) { + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewDefaultPrivateStateRepository(testdb, testCache, common.Hash{}) + header := &types.Header{Number: big.NewInt(int64(1)), Root: common.Hash{123}} + block := types.NewBlockWithHeader(header) + + testState, _ := psr.DefaultState() + + testRoot := testState.IntermediateRoot(false) + assert.Equal(t, testRoot, common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) + + //make updates to states + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + } + assert.Equal(t, rawdb.GetPrivateStateRoot(testdb, block.Root()), common.Hash{}) + + psr.CommitAndWrite(false, block) + + //private root gets committed to db, but isn't updated on psr (only needed for commit) + assert.Equal(t, psr.root, common.Hash{}) + assert.NotEqual(t, rawdb.GetPrivateStateRoot(testdb, block.Root()), common.Hash{}) + + testRoot = testState.IntermediateRoot(false) + assert.NotEqual(t, testRoot, common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) +} diff --git a/core/mps/interface.go b/core/mps/interface.go new file mode 100644 index 0000000000..2f679f08eb --- /dev/null +++ b/core/mps/interface.go @@ -0,0 +1,44 @@ +//go:generate mockgen -source interface.go -destination=mock_interface.go -package=mps + +package mps + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" +) + +// PrivateStateManager interface separates +type PrivateStateManager interface { + PrivateStateMetadataResolver + // StateRepository returns repository corresponding to a block hash + StateRepository(blockHash common.Hash) (PrivateStateRepository, error) + // CheckAt verifies if there's a state being managed at a block hash + CheckAt(blockHash common.Hash) error +} + +type PrivateStateMetadataResolver interface { + ResolveForManagedParty(managedParty string) (*PrivateStateMetadata, error) + ResolveForUserContext(ctx context.Context) (*PrivateStateMetadata, error) + // PSIs returns list of types.PrivateStateIdentifier being managed + PSIs() []types.PrivateStateIdentifier + // NotIncludeAny returns true if NONE of the managedParties is a member + // of the given psm, otherwise returns false + NotIncludeAny(psm *PrivateStateMetadata, managedParties ...string) bool +} + +// PrivateStateRepository abstracts how we handle private state(s) including +// retrieving from and peristing private states to the underlying database +type PrivateStateRepository interface { + StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, error) + CommitAndWrite(isEIP158 bool, block *types.Block) error + Commit(isEIP158 bool, block *types.Block) error + Copy() PrivateStateRepository + Reset() error + DefaultState() (*state.StateDB, error) + DefaultStateMetadata() *PrivateStateMetadata + IsMPS() bool + MergeReceipts(pub, priv types.Receipts) types.Receipts +} diff --git a/core/mps/mock_interface.go b/core/mps/mock_interface.go new file mode 100644 index 0000000000..dd953d966a --- /dev/null +++ b/core/mps/mock_interface.go @@ -0,0 +1,367 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go + +// Package mps is a generated GoMock package. +package mps + +import ( + context "context" + reflect "reflect" + + common "github.com/ethereum/go-ethereum/common" + state "github.com/ethereum/go-ethereum/core/state" + types "github.com/ethereum/go-ethereum/core/types" + gomock "github.com/golang/mock/gomock" +) + +// MockPrivateStateManager is a mock of PrivateStateManager interface. +type MockPrivateStateManager struct { + ctrl *gomock.Controller + recorder *MockPrivateStateManagerMockRecorder +} + +// MockPrivateStateManagerMockRecorder is the mock recorder for MockPrivateStateManager. +type MockPrivateStateManagerMockRecorder struct { + mock *MockPrivateStateManager +} + +// NewMockPrivateStateManager creates a new mock instance. +func NewMockPrivateStateManager(ctrl *gomock.Controller) *MockPrivateStateManager { + mock := &MockPrivateStateManager{ctrl: ctrl} + mock.recorder = &MockPrivateStateManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPrivateStateManager) EXPECT() *MockPrivateStateManagerMockRecorder { + return m.recorder +} + +// ResolveForManagedParty mocks base method. +func (m *MockPrivateStateManager) ResolveForManagedParty(managedParty string) (*PrivateStateMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResolveForManagedParty", managedParty) + ret0, _ := ret[0].(*PrivateStateMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ResolveForManagedParty indicates an expected call of ResolveForManagedParty. +func (mr *MockPrivateStateManagerMockRecorder) ResolveForManagedParty(managedParty interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResolveForManagedParty", reflect.TypeOf((*MockPrivateStateManager)(nil).ResolveForManagedParty), managedParty) +} + +// ResolveForUserContext mocks base method. +func (m *MockPrivateStateManager) ResolveForUserContext(ctx context.Context) (*PrivateStateMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResolveForUserContext", ctx) + ret0, _ := ret[0].(*PrivateStateMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ResolveForUserContext indicates an expected call of ResolveForUserContext. +func (mr *MockPrivateStateManagerMockRecorder) ResolveForUserContext(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResolveForUserContext", reflect.TypeOf((*MockPrivateStateManager)(nil).ResolveForUserContext), ctx) +} + +// PSIs mocks base method. +func (m *MockPrivateStateManager) PSIs() []types.PrivateStateIdentifier { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PSIs") + ret0, _ := ret[0].([]types.PrivateStateIdentifier) + return ret0 +} + +// PSIs indicates an expected call of PSIs. +func (mr *MockPrivateStateManagerMockRecorder) PSIs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PSIs", reflect.TypeOf((*MockPrivateStateManager)(nil).PSIs)) +} + +// NotIncludeAny mocks base method. +func (m *MockPrivateStateManager) NotIncludeAny(psm *PrivateStateMetadata, managedParties ...string) bool { + m.ctrl.T.Helper() + varargs := []interface{}{psm} + for _, a := range managedParties { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "NotIncludeAny", varargs...) + ret0, _ := ret[0].(bool) + return ret0 +} + +// NotIncludeAny indicates an expected call of NotIncludeAny. +func (mr *MockPrivateStateManagerMockRecorder) NotIncludeAny(psm interface{}, managedParties ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{psm}, managedParties...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotIncludeAny", reflect.TypeOf((*MockPrivateStateManager)(nil).NotIncludeAny), varargs...) +} + +// StateRepository mocks base method. +func (m *MockPrivateStateManager) StateRepository(blockHash common.Hash) (PrivateStateRepository, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateRepository", blockHash) + ret0, _ := ret[0].(PrivateStateRepository) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateRepository indicates an expected call of StateRepository. +func (mr *MockPrivateStateManagerMockRecorder) StateRepository(blockHash interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateRepository", reflect.TypeOf((*MockPrivateStateManager)(nil).StateRepository), blockHash) +} + +// CheckAt mocks base method. +func (m *MockPrivateStateManager) CheckAt(blockHash common.Hash) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckAt", blockHash) + ret0, _ := ret[0].(error) + return ret0 +} + +// CheckAt indicates an expected call of CheckAt. +func (mr *MockPrivateStateManagerMockRecorder) CheckAt(blockHash interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAt", reflect.TypeOf((*MockPrivateStateManager)(nil).CheckAt), blockHash) +} + +// MockPrivateStateMetadataResolver is a mock of PrivateStateMetadataResolver interface. +type MockPrivateStateMetadataResolver struct { + ctrl *gomock.Controller + recorder *MockPrivateStateMetadataResolverMockRecorder +} + +// MockPrivateStateMetadataResolverMockRecorder is the mock recorder for MockPrivateStateMetadataResolver. +type MockPrivateStateMetadataResolverMockRecorder struct { + mock *MockPrivateStateMetadataResolver +} + +// NewMockPrivateStateMetadataResolver creates a new mock instance. +func NewMockPrivateStateMetadataResolver(ctrl *gomock.Controller) *MockPrivateStateMetadataResolver { + mock := &MockPrivateStateMetadataResolver{ctrl: ctrl} + mock.recorder = &MockPrivateStateMetadataResolverMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPrivateStateMetadataResolver) EXPECT() *MockPrivateStateMetadataResolverMockRecorder { + return m.recorder +} + +// ResolveForManagedParty mocks base method. +func (m *MockPrivateStateMetadataResolver) ResolveForManagedParty(managedParty string) (*PrivateStateMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResolveForManagedParty", managedParty) + ret0, _ := ret[0].(*PrivateStateMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ResolveForManagedParty indicates an expected call of ResolveForManagedParty. +func (mr *MockPrivateStateMetadataResolverMockRecorder) ResolveForManagedParty(managedParty interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResolveForManagedParty", reflect.TypeOf((*MockPrivateStateMetadataResolver)(nil).ResolveForManagedParty), managedParty) +} + +// ResolveForUserContext mocks base method. +func (m *MockPrivateStateMetadataResolver) ResolveForUserContext(ctx context.Context) (*PrivateStateMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ResolveForUserContext", ctx) + ret0, _ := ret[0].(*PrivateStateMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ResolveForUserContext indicates an expected call of ResolveForUserContext. +func (mr *MockPrivateStateMetadataResolverMockRecorder) ResolveForUserContext(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResolveForUserContext", reflect.TypeOf((*MockPrivateStateMetadataResolver)(nil).ResolveForUserContext), ctx) +} + +// PSIs mocks base method. +func (m *MockPrivateStateMetadataResolver) PSIs() []types.PrivateStateIdentifier { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PSIs") + ret0, _ := ret[0].([]types.PrivateStateIdentifier) + return ret0 +} + +// PSIs indicates an expected call of PSIs. +func (mr *MockPrivateStateMetadataResolverMockRecorder) PSIs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PSIs", reflect.TypeOf((*MockPrivateStateMetadataResolver)(nil).PSIs)) +} + +// NotIncludeAny mocks base method. +func (m *MockPrivateStateMetadataResolver) NotIncludeAny(psm *PrivateStateMetadata, managedParties ...string) bool { + m.ctrl.T.Helper() + varargs := []interface{}{psm} + for _, a := range managedParties { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "NotIncludeAny", varargs...) + ret0, _ := ret[0].(bool) + return ret0 +} + +// NotIncludeAny indicates an expected call of NotIncludeAny. +func (mr *MockPrivateStateMetadataResolverMockRecorder) NotIncludeAny(psm interface{}, managedParties ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{psm}, managedParties...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotIncludeAny", reflect.TypeOf((*MockPrivateStateMetadataResolver)(nil).NotIncludeAny), varargs...) +} + +// MockPrivateStateRepository is a mock of PrivateStateRepository interface. +type MockPrivateStateRepository struct { + ctrl *gomock.Controller + recorder *MockPrivateStateRepositoryMockRecorder +} + +// MockPrivateStateRepositoryMockRecorder is the mock recorder for MockPrivateStateRepository. +type MockPrivateStateRepositoryMockRecorder struct { + mock *MockPrivateStateRepository +} + +// NewMockPrivateStateRepository creates a new mock instance. +func NewMockPrivateStateRepository(ctrl *gomock.Controller) *MockPrivateStateRepository { + mock := &MockPrivateStateRepository{ctrl: ctrl} + mock.recorder = &MockPrivateStateRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPrivateStateRepository) EXPECT() *MockPrivateStateRepositoryMockRecorder { + return m.recorder +} + +// StatePSI mocks base method. +func (m *MockPrivateStateRepository) StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StatePSI", psi) + ret0, _ := ret[0].(*state.StateDB) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StatePSI indicates an expected call of StatePSI. +func (mr *MockPrivateStateRepositoryMockRecorder) StatePSI(psi interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StatePSI", reflect.TypeOf((*MockPrivateStateRepository)(nil).StatePSI), psi) +} + +// CommitAndWrite mocks base method. +func (m *MockPrivateStateRepository) CommitAndWrite(isEIP158 bool, block *types.Block) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CommitAndWrite", block) + ret0, _ := ret[0].(error) + return ret0 +} + +// CommitAndWrite indicates an expected call of CommitAndWrite. +func (mr *MockPrivateStateRepositoryMockRecorder) CommitAndWrite(block interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitAndWrite", reflect.TypeOf((*MockPrivateStateRepository)(nil).CommitAndWrite), block) +} + +// Commit mocks base method. +func (m *MockPrivateStateRepository) Commit(isEIP158 bool, block *types.Block) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Commit", block) + ret0, _ := ret[0].(error) + return ret0 +} + +// Commit indicates an expected call of Commit. +func (mr *MockPrivateStateRepositoryMockRecorder) Commit(block interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockPrivateStateRepository)(nil).Commit), block) +} + +// Copy mocks base method. +func (m *MockPrivateStateRepository) Copy() PrivateStateRepository { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Copy") + ret0, _ := ret[0].(PrivateStateRepository) + return ret0 +} + +// Copy indicates an expected call of Copy. +func (mr *MockPrivateStateRepositoryMockRecorder) Copy() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Copy", reflect.TypeOf((*MockPrivateStateRepository)(nil).Copy)) +} + +// Reset mocks base method. +func (m *MockPrivateStateRepository) Reset() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Reset") + ret0, _ := ret[0].(error) + return ret0 +} + +// Reset indicates an expected call of Reset. +func (mr *MockPrivateStateRepositoryMockRecorder) Reset() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockPrivateStateRepository)(nil).Reset)) +} + +// DefaultState mocks base method. +func (m *MockPrivateStateRepository) DefaultState() (*state.StateDB, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DefaultState") + ret0, _ := ret[0].(*state.StateDB) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DefaultState indicates an expected call of DefaultState. +func (mr *MockPrivateStateRepositoryMockRecorder) DefaultState() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultState", reflect.TypeOf((*MockPrivateStateRepository)(nil).DefaultState)) +} + +// DefaultStateMetadata mocks base method. +func (m *MockPrivateStateRepository) DefaultStateMetadata() *PrivateStateMetadata { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DefaultStateMetadata") + ret0, _ := ret[0].(*PrivateStateMetadata) + return ret0 +} + +// DefaultStateMetadata indicates an expected call of DefaultStateMetadata. +func (mr *MockPrivateStateRepositoryMockRecorder) DefaultStateMetadata() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultStateMetadata", reflect.TypeOf((*MockPrivateStateRepository)(nil).DefaultStateMetadata)) +} + +// IsMPS mocks base method. +func (m *MockPrivateStateRepository) IsMPS() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsMPS") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsMPS indicates an expected call of IsMPS. +func (mr *MockPrivateStateRepositoryMockRecorder) IsMPS() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsMPS", reflect.TypeOf((*MockPrivateStateRepository)(nil).IsMPS)) +} + +// MergeReceipts mocks base method. +func (m *MockPrivateStateRepository) MergeReceipts(pub, priv types.Receipts) types.Receipts { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MergeReceipts", pub, priv) + ret0, _ := ret[0].(types.Receipts) + return ret0 +} + +// MergeReceipts indicates an expected call of MergeReceipts. +func (mr *MockPrivateStateRepositoryMockRecorder) MergeReceipts(pub, priv interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MergeReceipts", reflect.TypeOf((*MockPrivateStateRepository)(nil).MergeReceipts), pub, priv) +} diff --git a/core/mps/multiple_psr.go b/core/mps/multiple_psr.go new file mode 100644 index 0000000000..dd27cef8bb --- /dev/null +++ b/core/mps/multiple_psr.go @@ -0,0 +1,225 @@ +package mps + +import ( + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" +) + +// MultiplePrivateStateRepository manages a number of state DB objects +// identified by their types.PrivateStateIdentifier. It also maintains a trie +// of private states whose root hash is mapped with a block hash. +type MultiplePrivateStateRepository struct { + db ethdb.Database + // trie of private states cache + repoCache state.Database + + // the trie of private states + // key - the private state identifier + // value - the root hash of the private state + trie state.Trie + + // mux protects concurrent access to managedStates map + mux sync.Mutex + // managed states map + managedStates map[types.PrivateStateIdentifier]*managedState +} + +func NewMultiplePrivateStateRepository(db ethdb.Database, cache state.Database, privateStatesTrieRoot common.Hash) (*MultiplePrivateStateRepository, error) { + tr, err := cache.OpenTrie(privateStatesTrieRoot) + if err != nil { + return nil, err + } + return &MultiplePrivateStateRepository{ + db: db, + repoCache: cache, + trie: tr, + managedStates: make(map[types.PrivateStateIdentifier]*managedState)}, nil +} + +// A managed state is a pair of stateDb and it's corresponding stateCache objects +// Although right now we may not need a separate stateCache it may be useful if we'll do multiple managed state commits in parallel +type managedState struct { + stateDb *state.StateDB + stateCache state.Database +} + +func (ms *managedState) Copy() *managedState { + return &managedState{ + stateDb: ms.stateDb.Copy(), + stateCache: ms.stateCache, + } +} + +func (mpsr *MultiplePrivateStateRepository) DefaultState() (*state.StateDB, error) { + return mpsr.StatePSI(EmptyPrivateStateMetadata.ID) +} + +func (mpsr *MultiplePrivateStateRepository) DefaultStateMetadata() *PrivateStateMetadata { + return EmptyPrivateStateMetadata +} + +func (mpsr *MultiplePrivateStateRepository) IsMPS() bool { + return true +} + +func (mpsr *MultiplePrivateStateRepository) StatePSI(psi types.PrivateStateIdentifier) (*state.StateDB, error) { + mpsr.mux.Lock() + ms, found := mpsr.managedStates[psi] + mpsr.mux.Unlock() + if found { + return ms.stateDb, nil + } + privateStateRoot, err := mpsr.trie.TryGet([]byte(psi)) + if err != nil { + return nil, err + } + var stateCache state.Database + var stateDB *state.StateDB + if privateStateRoot == nil && psi != EmptyPrivateStateMetadata.ID { + // this is the first time we are trying to use this private state so branch from the empty state + emptyState, err := mpsr.DefaultState() + if err != nil { + return nil, err + } + mpsr.mux.Lock() + ms := mpsr.managedStates[EmptyPrivateStateMetadata.ID] + mpsr.mux.Unlock() + + stateDB = emptyState.Copy() + stateCache = ms.stateCache + } else { + stateCache = state.NewDatabase(mpsr.db) + stateDB, err = state.New(common.BytesToHash(privateStateRoot), stateCache, nil) + if err != nil { + return nil, err + } + } + mpsr.mux.Lock() + defer mpsr.mux.Unlock() + mpsr.managedStates[psi] = &managedState{ + stateCache: stateCache, + stateDb: stateDB, + } + return stateDB, nil +} + +func (mpsr *MultiplePrivateStateRepository) Reset() error { + mpsr.mux.Lock() + defer mpsr.mux.Unlock() + for psi, managedState := range mpsr.managedStates { + root, err := mpsr.trie.TryGet([]byte(psi)) + if err != nil { + return err + } + // if this was a newly created private state (branched from the empty state) - remove it from the managedStates map + if root == nil { + delete(mpsr.managedStates, psi) + continue + } + err = managedState.stateDb.Reset(common.BytesToHash(root)) + if err != nil { + return err + } + } + return nil +} + +// commitAndWrite- commits all private states, updates the trie of private states, writes to disk +func (mpsr *MultiplePrivateStateRepository) CommitAndWrite(isEIP158 bool, block *types.Block) error { + mpsr.mux.Lock() + defer mpsr.mux.Unlock() + for psi, managedState := range mpsr.managedStates { + // commit each managed state + privateRoot, err := managedState.stateDb.Commit(isEIP158) + if err != nil { + return err + } + // update the managed state root in the trie of states + err = mpsr.trie.TryUpdate([]byte(psi), privateRoot.Bytes()) + if err != nil { + return err + } + err = managedState.stateCache.TrieDB().Commit(privateRoot, false, nil) + if err != nil { + return err + } + } + // commit the trie of states + mtRoot, err := mpsr.trie.Commit(nil) + if err != nil { + return err + } + err = rawdb.WritePrivateStatesTrieRoot(mpsr.db, block.Root(), mtRoot) + if err != nil { + return err + } + privateTriedb := mpsr.repoCache.TrieDB() + err = privateTriedb.Commit(mtRoot, false, nil) + return err +} + +// commit - commits all private states, updates the trie of private states only +func (mpsr *MultiplePrivateStateRepository) Commit(isEIP158 bool, block *types.Block) error { + mpsr.mux.Lock() + defer mpsr.mux.Unlock() + for psi, managedState := range mpsr.managedStates { + // commit each managed state + privateRoot, err := managedState.stateDb.Commit(isEIP158) + if err != nil { + return err + } + // update the managed state root in the trie of states + err = mpsr.trie.TryUpdate([]byte(psi), privateRoot.Bytes()) + if err != nil { + return err + } + } + // commit the trie of states + _, err := mpsr.trie.Commit(nil) + if err != nil { + return err + } + return err +} + +func (mpsr *MultiplePrivateStateRepository) Copy() PrivateStateRepository { + mpsr.mux.Lock() + defer mpsr.mux.Unlock() + managedStatesCopy := make(map[types.PrivateStateIdentifier]*managedState) + for key, value := range mpsr.managedStates { + managedStatesCopy[key] = value.Copy() + } + return &MultiplePrivateStateRepository{ + db: mpsr.db, + repoCache: mpsr.repoCache, + trie: mpsr.repoCache.CopyTrie(mpsr.trie), + managedStates: managedStatesCopy, + } +} + +func (mpsr *MultiplePrivateStateRepository) MergeReceipts(pub, priv types.Receipts) types.Receipts { + m := make(map[common.Hash]*types.Receipt) + for _, receipt := range pub { + m[receipt.TxHash] = receipt + } + for _, receipt := range priv { + publicReceipt := m[receipt.TxHash] + publicReceipt.PSReceipts = make(map[types.PrivateStateIdentifier]*types.Receipt) + publicReceipt.PSReceipts[EmptyPrivateStateMetadata.ID] = receipt + for psi, receipt := range receipt.PSReceipts { + publicReceipt.PSReceipts[psi] = receipt + } + } + + ret := make(types.Receipts, len(pub)) + for idx, pubReceipt := range pub { + ret[idx] = m[pubReceipt.TxHash] + } + + return ret +} diff --git a/core/mps/multiple_psr_test.go b/core/mps/multiple_psr_test.go new file mode 100644 index 0000000000..13d184099a --- /dev/null +++ b/core/mps/multiple_psr_test.go @@ -0,0 +1,430 @@ +package mps + +import ( + "math/big" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +// emptyRoot is the known root hash of an empty trie. Duplicate from `trie/trie.go#emptyRoot` +var emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + +//TestMultiplePSRCopy tests that copying a the PSR object indeed makes the original and +// the copy and their corresponding managed states independent of each other. +func TestMultiplePSRCopy(t *testing.T) { + + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + + testState, _ := psr.StatePSI(types.PrivateStateIdentifier("test")) + privState, _ := psr.StatePSI(types.DefaultPrivateStateIdentifier) + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + } + testState.Finalise(false) + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + privState.AddBalance(addr, big.NewInt(int64(i))) + } + privState.Finalise(false) + + psrCopy := psr.Copy().(*MultiplePrivateStateRepository) + + testStateCopy, _ := psrCopy.StatePSI(types.PrivateStateIdentifier("test")) + privStateCopy, _ := psrCopy.StatePSI(types.DefaultPrivateStateIdentifier) + addedState, _ := psrCopy.StatePSI(types.PrivateStateIdentifier("added")) + + // modify all in memory + for i := byte(0); i < 255; i++ { + testState.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(2*int64(i))) + privState.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(2*int64(i))) + + testStateCopy.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(3*int64(i))) + privStateCopy.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(3*int64(i))) + addedState.AddBalance(common.BytesToAddress([]byte{i}), big.NewInt(3*int64(i))) + } + + // Finalise the changes on all concurrently + finalise := func(wg *sync.WaitGroup, db *state.StateDB) { + defer wg.Done() + db.Finalise(true) + } + + var wg sync.WaitGroup + wg.Add(5) + go finalise(&wg, testState) + go finalise(&wg, testStateCopy) + go finalise(&wg, privState) + go finalise(&wg, privStateCopy) + go finalise(&wg, addedState) + wg.Wait() + + //copies contain correct managed states + assert.Contains(t, psr.managedStates, types.EmptyPrivateStateIdentifier) + assert.Contains(t, psr.managedStates, types.DefaultPrivateStateIdentifier) + assert.Contains(t, psr.managedStates, types.PrivateStateIdentifier("test")) + assert.NotContains(t, psr.managedStates, types.PrivateStateIdentifier("added")) + + assert.Contains(t, psrCopy.managedStates, types.EmptyPrivateStateIdentifier) + assert.Contains(t, psrCopy.managedStates, types.DefaultPrivateStateIdentifier) + assert.Contains(t, psrCopy.managedStates, types.PrivateStateIdentifier("test")) + assert.Contains(t, psrCopy.managedStates, types.PrivateStateIdentifier("added")) + + assert.Equal(t, psr.db, psrCopy.db) + assert.Equal(t, psr.repoCache, psrCopy.repoCache) + assert.NotEqual(t, psr.trie, psrCopy.trie) + + // Verify that the all states have been updated independently + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testObj := testState.GetOrNewStateObject(addr) + testCopyObj := testStateCopy.GetOrNewStateObject(addr) + privObj := privState.GetOrNewStateObject(addr) + privCopyObj := privStateCopy.GetOrNewStateObject(addr) + addedObj := addedState.GetOrNewStateObject(addr) + + if want := big.NewInt(3 * int64(i)); testObj.Balance().Cmp(want) != 0 { + t.Errorf("empty obj %d: balance mismatch: have %v, want %v", i, testObj.Balance(), want) + } + if want := big.NewInt(3 * int64(i)); privObj.Balance().Cmp(want) != 0 { + t.Errorf("priv obj %d: balance mismatch: have %v, want %v", i, privObj.Balance(), want) + } + if want := big.NewInt(4 * int64(i)); testCopyObj.Balance().Cmp(want) != 0 { + t.Errorf("empty copy obj %d: balance mismatch: have %v, want %v", i, testCopyObj.Balance(), want) + } + if want := big.NewInt(4 * int64(i)); privCopyObj.Balance().Cmp(want) != 0 { + t.Errorf("priv copy obj %d: balance mismatch: have %v, want %v", i, privCopyObj.Balance(), want) + } + if want := big.NewInt(3 * int64(i)); addedObj.Balance().Cmp(want) != 0 { + t.Errorf("added obj %d: balance mismatch: have %v, want %v", i, addedObj.Balance(), want) + } + } +} + +//TestMultiplePSRReset tests that state objects are cleared from all managedState statedbs after reset call +//Any updated stateObjects not committed to statedbs before reset will be cleared +func TestMultiplePSRReset(t *testing.T) { + + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + + testState, _ := psr.StatePSI(types.PrivateStateIdentifier("test")) + emptyState, _ := psr.StatePSI(types.EmptyPrivateStateIdentifier) + + addr := common.BytesToAddress([]byte{254}) + testState.AddBalance(addr, big.NewInt(int64(254))) + emptyState.AddBalance(addr, big.NewInt(int64(254))) + + // have something to revert to (rather than the empty trie of private states) + psr.CommitAndWrite(false, types.NewBlockWithHeader(&types.Header{Root: common.Hash{}})) + + // testState2 should branch from the emptyState - so it should contain the contract with address 254... + testState2, _ := psr.StatePSI(types.PrivateStateIdentifier("test2")) + + for i := byte(0); i < 254; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + testState2.AddBalance(addr, big.NewInt(int64(i))) + emptyState.AddBalance(addr, big.NewInt(int64(i))) + } + testState.Finalise(false) + testState2.Finalise(false) + emptyState.Finalise(false) + + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + assert.True(t, testState.Exist(addr)) + assert.True(t, testState2.Exist(addr)) + assert.True(t, emptyState.Exist(addr)) + } + + psr.Reset() + + // test2 is no longer there in the managed states after reset + assert.Contains(t, psr.managedStates, types.PrivateStateIdentifier("test")) + assert.NotContains(t, psr.managedStates, types.PrivateStateIdentifier("test2")) + assert.Contains(t, psr.managedStates, types.EmptyPrivateStateIdentifier) + + for i := byte(0); i < 254; i++ { + addr := common.BytesToAddress([]byte{i}) + assert.False(t, testState.Exist(addr)) + assert.False(t, emptyState.Exist(addr)) + } + addr = common.BytesToAddress([]byte{254}) + assert.True(t, testState.Exist(addr)) + assert.True(t, emptyState.Exist(addr)) +} + +//TestCreatingManagedStates tests that managed states are created and added to managedState map +func TestCreatingManagedStates(t *testing.T) { + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + + //create some managed states + psr.DefaultState() + psr.StatePSI(types.PrivateStateIdentifier("test")) + psr.StatePSI(types.DefaultPrivateStateIdentifier) + + //check if they exist in managedStates map + assert.Contains(t, psr.managedStates, types.EmptyPrivateStateIdentifier) + assert.Contains(t, psr.managedStates, types.DefaultPrivateStateIdentifier) + assert.Contains(t, psr.managedStates, types.PrivateStateIdentifier("test")) + assert.NotContains(t, psr.managedStates, types.PrivateStateIdentifier("added")) +} + +//TestMultiplePSRCommit tests that managedStates are updated, trie of states is updated but not written to db +func TestMultiplePSRCommit(t *testing.T) { + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + header := &types.Header{Number: big.NewInt(int64(1)), Root: common.Hash{123}} + block := types.NewBlockWithHeader(header) + + testState, _ := psr.StatePSI(types.PrivateStateIdentifier("test")) + privState, _ := psr.StatePSI(types.DefaultPrivateStateIdentifier) + + //states have empty tries first + testRoot := testState.IntermediateRoot(false) + privRoot := privState.IntermediateRoot(false) + assert.Equal(t, testRoot, emptyRoot) + assert.Equal(t, privRoot, emptyRoot) + + //make updates to states + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + privState.AddBalance(addr, big.NewInt(int64(i))) + } + + assert.Equal(t, rawdb.GetPrivateStatesTrieRoot(testdb, block.Root()), common.Hash{}) + + psr.Commit(false, block) + + //trie root updated but not committed to db + assert.NotEqual(t, psr.trie.Hash(), common.Hash{}) + assert.Equal(t, rawdb.GetPrivateStatesTrieRoot(testdb, block.Root()), common.Hash{}) + + privateKey, _ := psr.trie.TryGet([]byte(types.DefaultPrivateStateIdentifier)) + assert.NotEqual(t, len(privateKey), 0) + testKey, _ := psr.trie.TryGet([]byte(types.PrivateStateIdentifier("test"))) + assert.NotEqual(t, len(testKey), 0) + emptyKey, _ := psr.trie.TryGet([]byte(types.EmptyPrivateStateIdentifier)) + assert.NotEqual(t, len(emptyKey), 0) + notKey, _ := psr.trie.TryGet([]byte(types.PrivateStateIdentifier("notKey"))) + assert.Equal(t, len(notKey), 0) + + //managed state tries updated + testRoot = testState.IntermediateRoot(false) + privRoot = privState.IntermediateRoot(false) + assert.NotEqual(t, testRoot, emptyRoot) + assert.NotEqual(t, privRoot, emptyRoot) +} + +//TestMultiplePSRCommitAndWrite tests that managedStates are updated, trie of states is updated and written to db +func TestMultiplePSRCommitAndWrite(t *testing.T) { + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + header := &types.Header{Number: big.NewInt(int64(1)), Root: common.Hash{123}} + block := types.NewBlockWithHeader(header) + + testState, _ := psr.StatePSI(types.PrivateStateIdentifier("test")) + privState, _ := psr.StatePSI(types.DefaultPrivateStateIdentifier) + + //states have empty tries first + testRoot := testState.IntermediateRoot(false) + privRoot := privState.IntermediateRoot(false) + assert.Equal(t, testRoot, emptyRoot) + assert.Equal(t, privRoot, emptyRoot) + + //make updates to states + for i := byte(0); i < 255; i++ { + addr := common.BytesToAddress([]byte{i}) + testState.AddBalance(addr, big.NewInt(int64(i))) + privState.AddBalance(addr, big.NewInt(int64(i))) + } + + assert.Equal(t, rawdb.GetPrivateStatesTrieRoot(testdb, block.Root()), common.Hash{}) + + psr.CommitAndWrite(false, block) + + //trie root updated and committed to db + assert.NotEqual(t, psr.trie.Hash(), common.Hash{}) + assert.NotEqual(t, rawdb.GetPrivateStatesTrieRoot(testdb, block.Root()), common.Hash{}) + + privateKey, _ := psr.trie.TryGet([]byte(types.DefaultPrivateStateIdentifier)) + assert.NotEqual(t, len(privateKey), 0) + testKey, _ := psr.trie.TryGet([]byte(types.PrivateStateIdentifier("test"))) + assert.NotEqual(t, len(testKey), 0) + emptyKey, _ := psr.trie.TryGet([]byte(types.EmptyPrivateStateIdentifier)) + assert.NotEqual(t, len(emptyKey), 0) + notKey, _ := psr.trie.TryGet([]byte(types.PrivateStateIdentifier("notKey"))) + assert.Equal(t, len(notKey), 0) + + //managed state tries updated + testRoot = testState.IntermediateRoot(false) + privRoot = privState.IntermediateRoot(false) + assert.NotEqual(t, testRoot, emptyRoot) + assert.NotEqual(t, privRoot, emptyRoot) +} + +//TestMultiplePSRIntroduceNewPrivateState tests that a newly introduced private state is branched from the empty state and maintained accordingly +func TestMultiplePSRIntroduceNewPrivateState(t *testing.T) { + + testPS1 := types.PrivateStateIdentifier("PS1") + testPS2 := types.PrivateStateIdentifier("PS2") + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + header1 := &types.Header{Number: big.NewInt(int64(1)), Root: common.Hash{123}} + block1 := types.NewBlockWithHeader(header1) + + header2 := &types.Header{Number: big.NewInt(int64(2)), Root: common.Hash{124}} + block2 := types.NewBlockWithHeader(header2) + + testState1, _ := psr.StatePSI(testPS1) + emptyState, _ := psr.StatePSI(types.EmptyPrivateStateIdentifier) + + //states have empty tries first + testState1Root := testState1.IntermediateRoot(false) + emptyStateRoot := emptyState.IntermediateRoot(false) + assert.Equal(t, testState1Root, emptyRoot) + assert.Equal(t, emptyStateRoot, emptyRoot) + + //make updates to states + for i := byte(0); i < 10; i++ { + addr := common.BytesToAddress([]byte{i}) + testState1.AddBalance(addr, big.NewInt(int64(i))) + emptyState.AddBalance(addr, big.NewInt(int64(i))) + } + + assert.Equal(t, rawdb.GetPrivateStatesTrieRoot(testdb, block1.Root()), common.Hash{}) + + psr.CommitAndWrite(false, block1) + + //trie root updated and committed to db + psrRootHash1 := psr.trie.Hash() + assert.NotEqual(t, psrRootHash1, emptyRoot) + assert.Equal(t, rawdb.GetPrivateStatesTrieRoot(testdb, block1.Root()), psrRootHash1) + + emptyStateRootHash, _ := psr.trie.TryGet([]byte(types.EmptyPrivateStateIdentifier)) + assert.NotEqual(t, len(emptyStateRootHash), 0) + ps1RootHash, _ := psr.trie.TryGet([]byte(testPS1)) + assert.NotEqual(t, len(ps1RootHash), 0) + notKeyRootHash, _ := psr.trie.TryGet([]byte(types.PrivateStateIdentifier("notKey"))) + assert.Equal(t, len(notKeyRootHash), 0) + + //managed state tries updated + testState1Root = testState1.IntermediateRoot(false) + emptyStateRoot = emptyState.IntermediateRoot(false) + assert.NotEqual(t, testState1Root, emptyRoot) + assert.NotEqual(t, emptyStateRoot, emptyRoot) + + // begin adding state at block2 + psr, _ = NewMultiplePrivateStateRepository(testdb, testCache, rawdb.GetPrivateStatesTrieRoot(testdb, block1.Root())) + + testState1, _ = psr.StatePSI(testPS1) + testState2, _ := psr.StatePSI(testPS2) + emptyState, _ = psr.StatePSI(types.EmptyPrivateStateIdentifier) + + //make updates to states + for i := byte(10); i < 20; i++ { + addr := common.BytesToAddress([]byte{i}) + testState1.AddBalance(addr, big.NewInt(int64(i))) + testState2.AddBalance(addr, big.NewInt(int64(i))) + emptyState.AddBalance(addr, big.NewInt(int64(i))) + } + + psr.CommitAndWrite(false, block2) + + psr, _ = NewMultiplePrivateStateRepository(testdb, testCache, rawdb.GetPrivateStatesTrieRoot(testdb, block2.Root())) + + testState1, _ = psr.StatePSI(testPS1) + testState2, _ = psr.StatePSI(testPS2) + emptyState, _ = psr.StatePSI(types.EmptyPrivateStateIdentifier) + + // we've only added addresses from 10 to 20 to testState2 but since it branched from emptyState it should also contain addresses from 0 to 10 + for i := byte(0); i < 20; i++ { + addr := common.BytesToAddress([]byte{i}) + assert.True(t, testState1.Exist(addr)) + assert.True(t, testState2.Exist(addr)) + assert.True(t, emptyState.Exist(addr)) + } + + // check that PS2 does not exist in the PSR at block1 height + psr, _ = NewMultiplePrivateStateRepository(testdb, testCache, rawdb.GetPrivateStatesTrieRoot(testdb, block1.Root())) + + emptyStateRootHash, _ = psr.trie.TryGet([]byte(types.EmptyPrivateStateIdentifier)) + assert.NotEqual(t, len(emptyStateRootHash), 0) + ps1RootHash, _ = psr.trie.TryGet([]byte(testPS1)) + assert.NotEqual(t, len(ps1RootHash), 0) + ps2RootHash, _ := psr.trie.TryGet([]byte(testPS2)) + assert.Equal(t, len(ps2RootHash), 0) + + // check that PS2 does exist in the PSR at block2 height + psr, _ = NewMultiplePrivateStateRepository(testdb, testCache, rawdb.GetPrivateStatesTrieRoot(testdb, block2.Root())) + + emptyStateRootHash, _ = psr.trie.TryGet([]byte(types.EmptyPrivateStateIdentifier)) + assert.NotEqual(t, len(emptyStateRootHash), 0) + ps1RootHash, _ = psr.trie.TryGet([]byte(testPS1)) + assert.NotEqual(t, len(ps1RootHash), 0) + ps2RootHash, _ = psr.trie.TryGet([]byte(testPS2)) + assert.NotEqual(t, len(ps2RootHash), 0) +} + +//TestMultiplePSRRemovalFromPrivateState tests that exist no longer picks suicided accounts +func TestMultiplePSRRemovalFromPrivateState(t *testing.T) { + + testPS1 := types.PrivateStateIdentifier("PS1") + testdb := rawdb.NewMemoryDatabase() + testCache := state.NewDatabase(testdb) + psr, _ := NewMultiplePrivateStateRepository(testdb, testCache, common.Hash{}) + header1 := &types.Header{Number: big.NewInt(int64(1)), Root: common.Hash{123}} + block1 := types.NewBlockWithHeader(header1) + + header2 := &types.Header{Number: big.NewInt(int64(2)), Root: common.Hash{124}} + block2 := types.NewBlockWithHeader(header2) + + testState1, _ := psr.StatePSI(testPS1) + emptyState, _ := psr.StatePSI(types.EmptyPrivateStateIdentifier) + + //make updates to states + for i := byte(0); i < 10; i++ { + addr := common.BytesToAddress([]byte{i}) + testState1.AddBalance(addr, big.NewInt(int64(i))) + emptyState.AddBalance(addr, big.NewInt(int64(i))) + } + + assert.Equal(t, rawdb.GetPrivateStatesTrieRoot(testdb, block1.Root()), common.Hash{}) + + psr.CommitAndWrite(false, block1) + + psr, _ = NewMultiplePrivateStateRepository(testdb, testCache, rawdb.GetPrivateStatesTrieRoot(testdb, block1.Root())) + + testState1, _ = psr.StatePSI(testPS1) + emptyState, _ = psr.StatePSI(types.EmptyPrivateStateIdentifier) + + removedAddress := common.BytesToAddress([]byte{1}) + testState1.Suicide(removedAddress) + + psr.CommitAndWrite(false, block2) + + psr, _ = NewMultiplePrivateStateRepository(testdb, testCache, rawdb.GetPrivateStatesTrieRoot(testdb, block2.Root())) + testState1, _ = psr.StatePSI(testPS1) + emptyState, _ = psr.StatePSI(types.EmptyPrivateStateIdentifier) + + assert.False(t, testState1.Exist(removedAddress)) + assert.True(t, emptyState.Exist(removedAddress)) +} diff --git a/core/mps/types.go b/core/mps/types.go new file mode 100644 index 0000000000..21c8c3b829 --- /dev/null +++ b/core/mps/types.go @@ -0,0 +1,78 @@ +package mps + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/core/types" +) + +var ( + // DefaultPrivateStateMetadata is the metadata for the single private state being used + // when MPS is disabled + DefaultPrivateStateMetadata = NewPrivateStateMetadata( + types.DefaultPrivateStateIdentifier, + "private", + "legacy private state", + Resident, + nil, + ) + // EmptyPrivateStateMetadata is the metadata for the empty private state being used + // when MPS is enabled + EmptyPrivateStateMetadata = NewPrivateStateMetadata( + types.EmptyPrivateStateIdentifier, + "empty", + "empty state metadata", + Resident, + nil, + ) +) + +type PrivateStateType uint64 + +const ( + Resident PrivateStateType = iota // 0 + Legacy PrivateStateType = 1 << PrivateStateType(iota-1) // 1 + Pantheon PrivateStateType = 1 << PrivateStateType(iota-1) // 2 +) + +// PrivateStateMetadata is the domain model in Quorum which maps with +// PrivacyGroup domain in Tessera +type PrivateStateMetadata struct { + ID types.PrivateStateIdentifier + Name string + Description string + Type PrivateStateType + // Addresses stores the public keys in the SAME ORDER being configured + // in Tessera + Addresses []string + // addressIndex is to facilitate fast searching + addressIndex map[string]struct{} +} + +func (psm *PrivateStateMetadata) NotIncludeAny(addresses ...string) bool { + for _, addr := range addresses { + if _, found := psm.addressIndex[addr]; found { + return false + } + } + return true +} + +func (psm *PrivateStateMetadata) String() string { + return fmt.Sprintf("ID=%s,Name=%s,Desc=%s,Type=%d,Addresses=%v", psm.ID, psm.Name, psm.Description, psm.Type, psm.Addresses) +} + +func NewPrivateStateMetadata(id types.PrivateStateIdentifier, name, desc string, t PrivateStateType, addresses []string) *PrivateStateMetadata { + index := make(map[string]struct{}, len(addresses)) + for _, a := range addresses { + index[a] = struct{}{} + } + return &PrivateStateMetadata{ + ID: id, + Name: name, + Description: desc, + Type: t, + Addresses: addresses[:], + addressIndex: index, + } +} diff --git a/core/mps/types_test.go b/core/mps/types_test.go new file mode 100644 index 0000000000..4005405975 --- /dev/null +++ b/core/mps/types_test.go @@ -0,0 +1,48 @@ +package mps + +import ( + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +func TestNewPrivateStateMetadata_whenTypical(t *testing.T) { + psi := types.ToPrivateStateIdentifier("arbitrary") + testObject := NewPrivateStateMetadata(psi, "name", "desc", Resident, []string{"a"}) + + assert.Equal(t, psi, testObject.ID) + assert.Equal(t, "name", testObject.Name) + assert.Equal(t, "desc", testObject.Description) + assert.Equal(t, Resident, testObject.Type) + assert.Contains(t, testObject.Addresses, "a") + assert.Contains(t, testObject.addressIndex, "a") +} + +func TestNewPrivateStateMetadata_whenNoIndex(t *testing.T) { + psi := types.ToPrivateStateIdentifier("arbitrary") + testObject := NewPrivateStateMetadata(psi, "name", "desc", Resident, nil) + + assert.Equal(t, psi, testObject.ID) + assert.Equal(t, "name", testObject.Name) + assert.Equal(t, "desc", testObject.Description) + assert.Equal(t, Resident, testObject.Type) + assert.Empty(t, testObject.Addresses) + assert.Empty(t, testObject.addressIndex) +} + +func TestPrivateStateMetadata_NotIncludeAny_whenTypical(t *testing.T) { + pk1 := "arbitrary pk1" + pk2 := "arbitrary pk2" + testObject := NewPrivateStateMetadata(types.ToPrivateStateIdentifier("arbitrary"), "name", "desc", Resident, []string{pk1, pk2}) + + assert.True(t, testObject.NotIncludeAny("arbitrary pk")) +} + +func TestPrivateStateMetadata_NotIncludeAny_whenMatch(t *testing.T) { + pk1 := "arbitrary pk1" + pk2 := "arbitrary pk2" + testObject := NewPrivateStateMetadata(types.ToPrivateStateIdentifier("arbitrary"), "name", "desc", Resident, []string{pk1, pk2}) + + assert.False(t, testObject.NotIncludeAny(pk1)) +} diff --git a/core/multiple_psm.go b/core/multiple_psm.go new file mode 100644 index 0000000000..7708e7021c --- /dev/null +++ b/core/multiple_psm.go @@ -0,0 +1,74 @@ +package core + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/rpc" +) + +type MultiplePrivateStateManager struct { + // Low level persistent database to store final content in + db ethdb.Database + privateStatesTrieCache state.Database + + residentGroupByKey map[string]*mps.PrivateStateMetadata + privacyGroupById map[types.PrivateStateIdentifier]*mps.PrivateStateMetadata +} + +func newMultiplePrivateStateManager(db ethdb.Database, residentGroupByKey map[string]*mps.PrivateStateMetadata, privacyGroupById map[types.PrivateStateIdentifier]*mps.PrivateStateMetadata) (*MultiplePrivateStateManager, error) { + return &MultiplePrivateStateManager{ + db: db, + privateStatesTrieCache: state.NewDatabase(db), + residentGroupByKey: residentGroupByKey, + privacyGroupById: privacyGroupById, + }, nil +} + +func (m *MultiplePrivateStateManager) StateRepository(blockHash common.Hash) (mps.PrivateStateRepository, error) { + privateStatesTrieRoot := rawdb.GetPrivateStatesTrieRoot(m.db, blockHash) + return mps.NewMultiplePrivateStateRepository(m.db, m.privateStatesTrieCache, privateStatesTrieRoot) +} + +func (m *MultiplePrivateStateManager) ResolveForManagedParty(managedParty string) (*mps.PrivateStateMetadata, error) { + psm, found := m.residentGroupByKey[managedParty] + if !found { + return nil, fmt.Errorf("unable to find private state metadata for managed party %s", managedParty) + } + return psm, nil +} + +func (m *MultiplePrivateStateManager) ResolveForUserContext(ctx context.Context) (*mps.PrivateStateMetadata, error) { + psi, ok := rpc.PrivateStateIdentifierFromContext(ctx) + if !ok { + psi = types.DefaultPrivateStateIdentifier + } + psm, found := m.privacyGroupById[psi] + if !found { + return nil, fmt.Errorf("unable to find private state for context psi %s", psi) + } + return psm, nil +} + +func (m *MultiplePrivateStateManager) PSIs() []types.PrivateStateIdentifier { + psis := make([]types.PrivateStateIdentifier, 0, len(m.privacyGroupById)) + for psi := range m.privacyGroupById { + psis = append(psis, psi) + } + return psis +} + +func (m *MultiplePrivateStateManager) NotIncludeAny(psm *mps.PrivateStateMetadata, managedParties ...string) bool { + return psm.NotIncludeAny(managedParties...) +} + +func (m *MultiplePrivateStateManager) CheckAt(root common.Hash) error { + _, err := state.New(rawdb.GetPrivateStatesTrieRoot(m.db, root), m.privateStatesTrieCache, nil) + return err +} diff --git a/core/multiple_psm_test.go b/core/multiple_psm_test.go new file mode 100644 index 0000000000..2f57206ac9 --- /dev/null +++ b/core/multiple_psm_test.go @@ -0,0 +1,331 @@ +package core + +import ( + "context" + "encoding/base64" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" + "github.com/ethereum/go-ethereum/rpc" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" +) + +const ( + // testCode is the testing contract binary code which will initialises some + // variables in constructor + testCode = "0x60806040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060005534801561003457600080fd5b5060fc806100436000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80630c4dae8814603757806398a213cf146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506084565b005b60005481565b806000819055507fe9e44f9f7da8c559de847a3232b57364adc0354f15a2cd8dc636d54396f9587a6000546040518082815260200191505060405180910390a15056fea265627a7a723058208ae31d9424f2d0bc2a3da1a5dd659db2d71ec322a17db8f87e19e209e3a1ff4a64736f6c634300050a0032" + + // testGas is the gas required for contract deployment. + testGas = 144109 +) + +var ( + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + testAddress = crypto.PubkeyToAddress(testKey.PublicKey) +) + +func buildTestChain(n int, config *params.ChainConfig) ([]*types.Block, map[common.Hash]*types.Block, *BlockChain) { + testdb := rawdb.NewMemoryDatabase() + genesis := GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000)) + blocks, _ := GenerateChain(params.QuorumMPSTestChainConfig, genesis, ethash.NewFaker(), testdb, n, func(i int, block *BlockGen) { + block.SetCoinbase(common.Address{0}) + + signer := types.QuorumPrivateTxSigner{} + tx, err := types.SignTx(types.NewContractCreation(block.TxNonce(testAddress), big.NewInt(0), testGas, nil, common.FromHex(testCode)), signer, testKey) + if err != nil { + panic(err) + } + block.AddTx(tx) + }) + + hashes := make([]common.Hash, n+1) + hashes[len(hashes)-1] = genesis.Hash() + blockm := make(map[common.Hash]*types.Block, n+1) + blockm[genesis.Hash()] = genesis + for i, b := range blocks { + hashes[len(hashes)-i-2] = b.Hash() + blockm[b.Hash()] = b + } + + blockchain, _ := NewBlockChain(testdb, nil, config, ethash.NewFaker(), vm.Config{}, nil, nil) + return blocks, blockm, blockchain +} + +func TestMultiplePSMRStateCreated(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockptm := private.NewMockPrivateTransactionManager(mockCtrl) + + saved := private.P + defer func() { + private.P = saved + }() + private.P = mockptm + + mockpsm := mps.NewMockPrivateStateManager(mockCtrl) + + mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{"psi1", "psi2"}, common.FromHex(testCode), nil, nil).AnyTimes() + mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, common.EncryptedPayloadHash{}.Bytes(), nil, nil).AnyTimes() + mockptm.EXPECT().HasFeature(engine.MultiplePrivateStates).Return(true) + mockptm.EXPECT().Groups().Return(PrivacyGroups, nil).AnyTimes() + + mockpsm.EXPECT().ResolveForManagedParty("psi1").Return(&PSI1PSM, nil).AnyTimes() + mockpsm.EXPECT().ResolveForManagedParty("psi2").Return(&PSI2PSM, nil).AnyTimes() + mockpsm.EXPECT().PSIs().Return([]types.PrivateStateIdentifier{PSI1PSM.ID, PSI2PSM.ID, types.DefaultPrivateStateIdentifier, types.ToPrivateStateIdentifier("other")}).AnyTimes() + + blocks, blockmap, blockchain := buildTestChain(2, params.QuorumMPSTestChainConfig) + cache := state.NewDatabase(blockchain.db) + blockchain.privateStateManager = mockpsm + + for _, block := range blocks { + parent := blockmap[block.ParentHash()] + statedb, _ := state.New(parent.Root(), blockchain.StateCache(), nil) + mockpsm.EXPECT().StateRepository(gomock.Any()).Return(mps.NewMultiplePrivateStateRepository(blockchain.db, cache, common.Hash{})).AnyTimes() + + privateStateRepo, err := blockchain.PrivateStateManager().StateRepository(parent.Root()) + assert.NoError(t, err) + + publicReceipts, privateReceipts, _, _, _ := blockchain.Processor().Process(block, statedb, privateStateRepo, vm.Config{}) + + //managed states tests + for _, privateReceipt := range privateReceipts { + expectedContractAddress := privateReceipt.ContractAddress + + emptyState, _ := privateStateRepo.DefaultState() + assert.True(t, emptyState.Exist(expectedContractAddress)) + assert.Equal(t, emptyState.GetCodeSize(expectedContractAddress), 0) + ps1, _ := privateStateRepo.StatePSI(types.PrivateStateIdentifier("psi1")) + assert.True(t, ps1.Exist(expectedContractAddress)) + assert.NotEqual(t, ps1.GetCodeSize(expectedContractAddress), 0) + ps2, _ := privateStateRepo.StatePSI(types.PrivateStateIdentifier("psi2")) + assert.True(t, ps2.Exist(expectedContractAddress)) + assert.NotEqual(t, ps2.GetCodeSize(expectedContractAddress), 0) + + } + //CommitAndWrite to db + privateStateRepo.CommitAndWrite(false, block) + + //managed states test + for _, privateReceipt := range privateReceipts { + expectedContractAddress := privateReceipt.ContractAddress + latestBlockRoot := block.Root() + _, privDb, _ := blockchain.StateAtPSI(latestBlockRoot, types.ToPrivateStateIdentifier("empty")) + assert.True(t, privDb.Exist(expectedContractAddress)) + assert.Equal(t, privDb.GetCodeSize(expectedContractAddress), 0) + //contract exists on both psi states + _, privDb, _ = blockchain.StateAtPSI(latestBlockRoot, types.PrivateStateIdentifier("psi1")) + assert.True(t, privDb.Exist(expectedContractAddress)) + assert.NotEqual(t, privDb.GetCodeSize(expectedContractAddress), 0) + _, privDb, _ = blockchain.StateAtPSI(latestBlockRoot, types.PrivateStateIdentifier("psi2")) + assert.True(t, privDb.Exist(expectedContractAddress)) + assert.NotEqual(t, privDb.GetCodeSize(expectedContractAddress), 0) + //contract should exist on default private state but no contract code + _, privDb, _ = blockchain.StateAtPSI(latestBlockRoot, types.DefaultPrivateStateIdentifier) + assert.True(t, privDb.Exist(expectedContractAddress)) + assert.Equal(t, privDb.GetCodeSize(expectedContractAddress), 0) + //contract should exist on random state but no contract code + _, privDb, _ = blockchain.StateAtPSI(latestBlockRoot, types.ToPrivateStateIdentifier("other")) + assert.True(t, privDb.Exist(expectedContractAddress)) + assert.Equal(t, privDb.GetCodeSize(expectedContractAddress), 0) + } + + //mergeReceipts test + for _, pubReceipt := range publicReceipts { + assert.Equal(t, 0, len(pubReceipt.PSReceipts)) + } + for _, privReceipt := range privateReceipts { + assert.Equal(t, 2, len(privReceipt.PSReceipts)) + assert.NotEqual(t, nil, privReceipt.PSReceipts["psi1"]) + assert.NotEqual(t, nil, privReceipt.PSReceipts["psi2"]) + } + + allReceipts := privateStateRepo.MergeReceipts(publicReceipts, privateReceipts) + for _, receipt := range allReceipts { + assert.Equal(t, 3, len(receipt.PSReceipts)) + assert.NotEqual(t, nil, receipt.PSReceipts["empty"]) + assert.NotEqual(t, nil, receipt.PSReceipts["psi1"]) + assert.NotEqual(t, nil, receipt.PSReceipts["psi2"]) + } + } +} + +func TestMPSReset(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockptm := private.NewMockPrivateTransactionManager(mockCtrl) + + saved := private.P + defer func() { + private.P = saved + }() + private.P = mockptm + + mockpsm := mps.NewMockPrivateStateManager(mockCtrl) + + mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{"psi1", "psi2"}, common.FromHex(testCode), nil, nil).AnyTimes() + mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, common.EncryptedPayloadHash{}.Bytes(), nil, nil).AnyTimes() + mockptm.EXPECT().HasFeature(engine.MultiplePrivateStates).Return(true) + mockptm.EXPECT().Groups().Return(PrivacyGroups, nil).AnyTimes() + + mockpsm.EXPECT().ResolveForManagedParty("psi1").Return(&PSI1PSM, nil).AnyTimes() + mockpsm.EXPECT().ResolveForManagedParty("psi2").Return(&PSI2PSM, nil).AnyTimes() + mockpsm.EXPECT().PSIs().Return([]types.PrivateStateIdentifier{PSI1PSM.ID, PSI2PSM.ID}).AnyTimes() + + blocks, blockmap, blockchain := buildTestChain(2, params.QuorumMPSTestChainConfig) + blockchain.privateStateManager = mockpsm + cache := state.NewDatabase(blockchain.db) + + for _, block := range blocks { + parent := blockmap[block.ParentHash()] + statedb, _ := state.New(parent.Root(), blockchain.StateCache(), nil) + mockpsm.EXPECT().StateRepository(gomock.Any()).Return(mps.NewMultiplePrivateStateRepository(blockchain.db, cache, common.Hash{})).AnyTimes() + + privateStateRepo, err := blockchain.PrivateStateManager().StateRepository(parent.Root()) + assert.NoError(t, err) + + _, privateReceipts, _, _, _ := blockchain.Processor().Process(block, statedb, privateStateRepo, vm.Config{}) + + for _, privateReceipt := range privateReceipts { + expectedContractAddress := privateReceipt.ContractAddress + + emptyState, _ := privateStateRepo.DefaultState() + assert.True(t, emptyState.Exist(expectedContractAddress)) + assert.Equal(t, emptyState.GetCodeSize(expectedContractAddress), 0) + ps1, _ := privateStateRepo.StatePSI(types.PrivateStateIdentifier("psi1")) + assert.True(t, ps1.Exist(expectedContractAddress)) + assert.NotEqual(t, ps1.GetCodeSize(expectedContractAddress), 0) + ps2, _ := privateStateRepo.StatePSI(types.PrivateStateIdentifier("psi2")) + assert.True(t, ps2.Exist(expectedContractAddress)) + assert.NotEqual(t, ps2.GetCodeSize(expectedContractAddress), 0) + + privateStateRepo.Reset() + + emptyState, _ = privateStateRepo.DefaultState() + assert.False(t, emptyState.Exist(expectedContractAddress)) + assert.Equal(t, emptyState.GetCodeSize(expectedContractAddress), 0) + ps1, _ = privateStateRepo.StatePSI(types.PrivateStateIdentifier("psi1")) + assert.False(t, ps1.Exist(expectedContractAddress)) + assert.Equal(t, ps1.GetCodeSize(expectedContractAddress), 0) + ps2, _ = privateStateRepo.StatePSI(types.PrivateStateIdentifier("psi2")) + assert.False(t, ps2.Exist(expectedContractAddress)) + assert.Equal(t, ps2.GetCodeSize(expectedContractAddress), 0) + } + } +} + +func TestPrivateStateMetadataResolver(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockptm := private.NewMockPrivateTransactionManager(mockCtrl) + + saved := private.P + defer func() { + private.P = saved + }() + private.P = mockptm + + mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{"AAA", "CCC"}, common.FromHex(testCode), nil, nil).AnyTimes() + mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, common.EncryptedPayloadHash{}.Bytes(), nil, nil).AnyTimes() + mockptm.EXPECT().HasFeature(engine.MultiplePrivateStates).Return(true) + mockptm.EXPECT().Groups().Return(PrivacyGroups, nil).AnyTimes() + + _, _, blockchain := buildTestChain(1, params.QuorumMPSTestChainConfig) + + mpsm := blockchain.privateStateManager + + psm1, _ := mpsm.ResolveForManagedParty("AAA") + psm2, _ := mpsm.ResolveForManagedParty("CCC") + _, err := mpsm.ResolveForManagedParty("TEST") + assert.Equal(t, psm1, privacyGroupToPrivateStateMetadata(PG1)) + assert.Equal(t, psm2, privacyGroupToPrivateStateMetadata(PG2)) + assert.Error(t, err, "unable to find private state metadata for managed party TEST") + + ctx := rpc.WithPrivateStateIdentifier(context.Background(), types.ToPrivateStateIdentifier("RG1")) + psm1, _ = mpsm.ResolveForUserContext(ctx) + assert.Equal(t, psm1, privacyGroupToPrivateStateMetadata(PG1)) + ctx = rpc.WithPrivateStateIdentifier(context.Background(), types.ToPrivateStateIdentifier("OTHER")) + _, err = mpsm.ResolveForUserContext(ctx) + assert.Error(t, err, "unable to find private state for context psi OTHER") + _, err = mpsm.ResolveForUserContext(context.Background()) + assert.Error(t, err, "unable to find private state for context psi private") + + assert.Contains(t, mpsm.PSIs(), types.PrivateStateIdentifier("RG1")) + assert.Contains(t, mpsm.PSIs(), types.PrivateStateIdentifier("RG2")) + assert.Contains(t, mpsm.PSIs(), types.PrivateStateIdentifier("LEGACY1")) +} + +var PSI1PSM = mps.PrivateStateMetadata{ + ID: "psi1", + Name: "psi1", + Description: "private state 1", + Type: mps.Resident, + Addresses: nil, +} + +var PSI2PSM = mps.PrivateStateMetadata{ + ID: "psi2", + Name: "psi2", + Description: "private state 2", + Type: mps.Resident, + Addresses: nil, +} + +var PG1 = engine.PrivacyGroup{ + Type: "RESIDENT", + Name: "RG1", + PrivacyGroupId: "RG1", + Description: "Resident Group 1", + From: "", + Members: []string{"AAA", "BBB"}, +} + +var PG2 = engine.PrivacyGroup{ + Type: "RESIDENT", + Name: "RG2", + PrivacyGroupId: "RG2", + Description: "Resident Group 2", + From: "", + Members: []string{"CCC", "DDD"}, +} + +var PrivacyGroups = []engine.PrivacyGroup{ + { + Type: "RESIDENT", + Name: "RG1", + PrivacyGroupId: base64.StdEncoding.EncodeToString([]byte("RG1")), + Description: "Resident Group 1", + From: "", + Members: []string{"AAA", "BBB"}, + }, + { + Type: "RESIDENT", + Name: "RG2", + PrivacyGroupId: base64.StdEncoding.EncodeToString([]byte("RG2")), + Description: "Resident Group 2", + From: "", + Members: []string{"CCC", "DDD"}, + }, + { + Type: "LEGACY", + Name: "LEGACY1", + PrivacyGroupId: "LEGACY1", + Description: "Legacy Group 1", + From: "", + Members: []string{"LEG1", "LEG2"}, + }, +} diff --git a/core/private_state_manager.go b/core/private_state_manager.go new file mode 100644 index 0000000000..9b0f535077 --- /dev/null +++ b/core/private_state_manager.go @@ -0,0 +1,83 @@ +package core + +import ( + "encoding/base64" + "fmt" + + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" +) + +// newPrivateStateManager instantiates an instance of mps.PrivateStateManager based on +// the given isMPS flag. +// +// If isMPS is true, it also does the validation to make sure +// the target private.PrivateTransactionManager supports MPS +func newPrivateStateManager(db ethdb.Database, isMPS bool) (mps.PrivateStateManager, error) { + if isMPS { + // validation + if !private.P.HasFeature(engine.MultiplePrivateStates) { + return nil, fmt.Errorf("cannot instantiate MultiplePrivateStateManager while the transaction manager does not support multiple private states") + } + groups, err := private.P.Groups() + if err != nil { + return nil, err + } + residentGroupByKey := make(map[string]*mps.PrivateStateMetadata) + privacyGroupById := make(map[types.PrivateStateIdentifier]*mps.PrivateStateMetadata) + convertedGroups := make([]engine.PrivacyGroup, 0) + for _, group := range groups { + if group.Type == engine.PrivacyGroupResident { + // Resident group IDs come in base64 encoded, so revert to original ID + decoded, err := base64.StdEncoding.DecodeString(group.PrivacyGroupId) + if err != nil { + return nil, err + } + group.PrivacyGroupId = string(decoded) + } + psi := types.ToPrivateStateIdentifier(group.PrivacyGroupId) + existing, found := privacyGroupById[psi] + if found { + return nil, fmt.Errorf("privacy groups id clash id=%s existing.Name=%s duplicate.Name=%s", existing.ID, existing.Name, group.Name) + } + privacyGroupById[psi] = privacyGroupToPrivateStateMetadata(group) + if group.Type == engine.PrivacyGroupResident { + for _, address := range group.Members { + existing, found := residentGroupByKey[address] + if found { + return nil, fmt.Errorf("same address is part of two different groups: address=%s existing.Name=%s duplicate.Name=%s", address, existing.Name, group.Name) + } + residentGroupByKey[address] = privacyGroupToPrivateStateMetadata(group) + } + } + convertedGroups = append(convertedGroups, group) + } + return newMultiplePrivateStateManager(db, residentGroupByKey, privacyGroupById) + } else { + return newDefaultPrivateStateManager(db), nil + } +} + +func privacyGroupToPrivateStateMetadata(group engine.PrivacyGroup) *mps.PrivateStateMetadata { + return mps.NewPrivateStateMetadata( + types.ToPrivateStateIdentifier(group.PrivacyGroupId), + group.Name, + group.Description, + strTypeToPrivateStateType(group.Type), + group.Members, + ) +} + +func strTypeToPrivateStateType(strType string) mps.PrivateStateType { + switch strType { + case engine.PrivacyGroupLegacy: + return mps.Legacy + case engine.PrivacyGroupPantheon: + return mps.Pantheon + default: + return mps.Resident + } +} diff --git a/core/private_state_test.go b/core/private_state_test.go new file mode 100644 index 0000000000..f766c366da --- /dev/null +++ b/core/private_state_test.go @@ -0,0 +1,146 @@ +package core + +import ( + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +// callmsg is the message type used for call transactions in the private state test +type callmsg struct { + addr common.Address + to *common.Address + gas uint64 + gasPrice *big.Int + value *big.Int + data []byte +} + +// accessor boilerplate to implement core.Message +func (m callmsg) From() common.Address { return m.addr } +func (m callmsg) FromFrontier() common.Address { return m.addr } +func (m callmsg) Nonce() uint64 { return 0 } +func (m callmsg) To() *common.Address { return m.to } +func (m callmsg) GasPrice() *big.Int { return m.gasPrice } +func (m callmsg) Gas() uint64 { return m.gas } +func (m callmsg) Value() *big.Int { return m.value } +func (m callmsg) Data() []byte { return m.data } +func (m callmsg) CheckNonce() bool { return true } + +func ExampleMakeCallHelper() { + var ( + // setup new pair of keys for the calls + key, _ = crypto.GenerateKey() + // create a new helper + helper = MakeCallHelper() + ) + // Private contract address + prvContractAddr := common.Address{1} + // Initialise custom code for private contract + helper.PrivateState.SetCode(prvContractAddr, common.Hex2Bytes("600a60005500")) + // Public contract address + pubContractAddr := common.Address{2} + // Initialise custom code for public contract + helper.PublicState.SetCode(pubContractAddr, common.Hex2Bytes("601460005500")) + + // Make a call to the private contract + err := helper.MakeCall(true, key, prvContractAddr, nil) + if err != nil { + fmt.Println(err) + } + // Make a call to the public contract + err = helper.MakeCall(false, key, pubContractAddr, nil) + if err != nil { + fmt.Println(err) + } + + // Output: + // Private: 10 + // Public: 20 + fmt.Println("Private:", helper.PrivateState.GetState(prvContractAddr, common.Hash{}).Big()) + fmt.Println("Public:", helper.PublicState.GetState(pubContractAddr, common.Hash{}).Big()) +} + +// 600a600055600060006001a1 +// 60 0a, 60 00, 55, 60 00, 60 00, 60 01, a1 +// [1] (0x60) PUSH1 0x0a (store value) +// [3] (0x60) PUSH1 0x00 (store addr) +// [4] (0x55) SSTORE (Store (k-00,v-a)) + +// [6] (0x60) PUSH1 0x00 +// [8] (0x60) PUSH1 0x00 +// [10](0x60) PUSH1 0x01 +// [11](0xa1) LOG1 offset(0x01), len(0x00), topic(0x00) +// +// Store then log +func TestPrivateTransaction(t *testing.T) { + var ( + key, _ = crypto.GenerateKey() + helper = MakeCallHelper() + privateState = helper.PrivateState + publicState = helper.PublicState + ) + + prvContractAddr := common.Address{1} + pubContractAddr := common.Address{2} + // SSTORE (K,V) SSTORE(0, 10): 600a600055 + // + + // LOG1 OFFSET LEN TOPIC, LOG1 (a1) 01, 00, 00: 600060006001a1 + privateState.SetCode(prvContractAddr, common.Hex2Bytes("600a600055600060006001a1")) + // SSTORE (K,V) SSTORE(0, 14): 6014600055 + publicState.SetCode(pubContractAddr, common.Hex2Bytes("6014600055")) + + if publicState.Exist(prvContractAddr) { + t.Error("didn't expect private contract address to exist on public state") + } + + // Private transaction 1 + err := helper.MakeCall(true, key, prvContractAddr, nil) + + if err != nil { + t.Fatal(err) + } + stateEntry := privateState.GetState(prvContractAddr, common.Hash{}).Big() + if stateEntry.Cmp(big.NewInt(10)) != 0 { + t.Error("expected state to have 10, got", stateEntry) + } + if len(privateState.Logs()) != 1 { + t.Error("expected private state to have 1 log, got", len(privateState.Logs())) + } + if len(publicState.Logs()) != 0 { + t.Error("expected public state to have 0 logs, got", len(publicState.Logs())) + } + if publicState.Exist(prvContractAddr) { + t.Error("didn't expect private contract address to exist on public state") + } + if !privateState.Exist(prvContractAddr) { + t.Error("expected private contract address to exist on private state") + } + + // Public transaction 1 + err = helper.MakeCall(false, key, pubContractAddr, nil) + if err != nil { + t.Fatal(err) + } + stateEntry = publicState.GetState(pubContractAddr, common.Hash{}).Big() + if stateEntry.Cmp(big.NewInt(20)) != 0 { + t.Error("expected state to have 20, got", stateEntry) + } + + // Private transaction 2 + helper.MakeCall(true, key, prvContractAddr, nil) + stateEntry = privateState.GetState(prvContractAddr, common.Hash{}).Big() + if stateEntry.Cmp(big.NewInt(10)) != 0 { + t.Error("expected state to have 10, got", stateEntry) + } + + if publicState.Exist(prvContractAddr) { + t.Error("didn't expect private contract address to exist on public state") + } + if privateState.Exist(pubContractAddr) { + t.Error("didn't expect public contract address to exist on private state") + } +} diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index c948cdc7c6..5842f3ea1e 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -23,7 +23,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -268,29 +267,61 @@ func WriteFastTxLookupLimit(db ethdb.KeyValueWriter, number uint64) { } } +// Quorum // ReadHeaderRLP retrieves a block header in its raw RLP database encoding. -func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { +func readHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) (rlp.RawValue, *types.Header) { // First try to look up the data in ancient database. Extra hash // comparison is necessary since ancient database only maintains // the canonical data. data, _ := db.Ancient(freezerHeaderTable, number) - if len(data) > 0 && crypto.Keccak256Hash(data) == hash { - return data + + // Quorum: parse header to make sure we compare using the right hash (IBFT hash is based on a filtered header) + if len(data) > 0 { + header := decodeHeaderRLP(data) + if header.Hash() == hash { + return data, header + } } + // End Quorum + // Then try to look up the data in leveldb. data, _ = db.Get(headerKey(number, hash)) if len(data) > 0 { - return data + return data, decodeHeaderRLP(data) // Quorum: return decodeHeaderRLP(data) } // In the background freezer is moving data from leveldb to flatten files. // So during the first check for ancient db, the data is not yet in there, // but when we reach into leveldb, the data was already moved. That would // result in a not found error. data, _ = db.Ancient(freezerHeaderTable, number) - if len(data) > 0 && crypto.Keccak256Hash(data) == hash { - return data + + // Quorum: parse header to make sure we compare using the right hash (IBFT hash is based on a filtered header) + if len(data) > 0 { + header := decodeHeaderRLP(data) + if header.Hash() == hash { + return data, header + } } - return nil // Can't find the data anywhere. + // End Quorum + + return nil, nil // Can't find the data anywhere. +} + +// Quorum +func decodeHeaderRLP(data rlp.RawValue) *types.Header { + header := new(types.Header) + if err := rlp.Decode(bytes.NewReader(data), header); err != nil { + log.Error("Invalid block header RLP", "err", err) + return nil + } + return header +} + +// ReadHeaderRLP retrieves a block header in its raw RLP database encoding. +func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { + // Quorum: original code implemented inside `readHeaderRLP(...)` with some modifications from Quorum + data, _ := readHeaderRLP(db, hash, number) + return data } // HasHeader verifies the existence of a block header corresponding to the hash. @@ -306,13 +337,13 @@ func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { // ReadHeader retrieves the block header corresponding to the hash. func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { - data := ReadHeaderRLP(db, hash, number) - if len(data) == 0 { + data, header := readHeaderRLP(db, hash, number) + if data == nil { + log.Trace("header data not found in ancient or level db", "hash", hash) return nil } - header := new(types.Header) - if err := rlp.Decode(bytes.NewReader(data), header); err != nil { - log.Error("Invalid block header RLP", "hash", hash, "err", err) + if header == nil { + log.Error("Invalid block header RLP", "hash", hash) return nil } return header diff --git a/core/rawdb/database_quorum.go b/core/rawdb/database_quorum.go new file mode 100644 index 0000000000..d1115eeabc --- /dev/null +++ b/core/rawdb/database_quorum.go @@ -0,0 +1,134 @@ +/* + + +// Copyright 2015 The go-ethereum Authors + +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +*/ +package rawdb + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" +) + +var ( + privateRootPrefix = []byte("P") + privateStatesTrieRootPrefix = []byte("PSTP") + privateBloomPrefix = []byte("Pb") + quorumEIP155ActivatedPrefix = []byte("quorum155active") + // Quorum + // we introduce a generic approach to store extra data for an account. PrivacyMetadata is wrapped. + // However, this value is kept as-is to support backward compatibility + stateRootToExtraDataRootPrefix = []byte("PSR2PMDR") + // emptyRoot is the known root hash of an empty trie. Duplicate from `trie/trie.go#emptyRoot` + emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") +) + +//returns whether we have a chain configuration that can't be updated +//after the EIP155 HF has happened +func GetIsQuorumEIP155Activated(db ethdb.KeyValueReader) bool { + data, _ := db.Get(quorumEIP155ActivatedPrefix) + return len(data) == 1 +} + +// WriteQuorumEIP155Activation writes a flag to the database saying EIP155 HF is enforced +func WriteQuorumEIP155Activation(db ethdb.KeyValueWriter) error { + return db.Put(quorumEIP155ActivatedPrefix, []byte{1}) +} + +func GetPrivateStateRoot(db ethdb.Database, blockRoot common.Hash) common.Hash { + root, _ := db.Get(append(privateRootPrefix, blockRoot[:]...)) + return common.BytesToHash(root) +} + +func GetPrivateStatesTrieRoot(db ethdb.Database, blockRoot common.Hash) common.Hash { + root, _ := db.Get(append(privateStatesTrieRootPrefix, blockRoot[:]...)) + return common.BytesToHash(root) +} + +func GetAccountExtraDataRoot(db ethdb.KeyValueReader, stateRoot common.Hash) common.Hash { + root, _ := db.Get(append(stateRootToExtraDataRootPrefix, stateRoot[:]...)) + return common.BytesToHash(root) +} + +func WritePrivateStateRoot(db ethdb.Database, blockRoot, root common.Hash) error { + return db.Put(append(privateRootPrefix, blockRoot[:]...), root[:]) +} + +func WritePrivateStatesTrieRoot(db ethdb.Database, blockRoot, root common.Hash) error { + return db.Put(append(privateStatesTrieRootPrefix, blockRoot[:]...), root[:]) +} + +// WriteRootHashMapping stores the mapping between root hash of state trie and +// root hash of state.AccountExtraData trie to persistent storage +func WriteRootHashMapping(db ethdb.KeyValueWriter, stateRoot, extraDataRoot common.Hash) error { + return db.Put(append(stateRootToExtraDataRootPrefix, stateRoot[:]...), extraDataRoot[:]) +} + +// WritePrivateBlockBloom creates a bloom filter for the given receipts and saves it to the database +// with the number given as identifier (i.e. block number). +func WritePrivateBlockBloom(db ethdb.Database, number uint64, receipts types.Receipts) error { + rbloom := types.CreateBloom(receipts.Flatten()) + return db.Put(append(privateBloomPrefix, encodeBlockNumber(number)...), rbloom[:]) +} + +// GetPrivateBlockBloom retrieves the private bloom associated with the given number. +func GetPrivateBlockBloom(db ethdb.Database, number uint64) (bloom types.Bloom) { + data, _ := db.Get(append(privateBloomPrefix, encodeBlockNumber(number)...)) + if len(data) > 0 { + bloom = types.BytesToBloom(data) + } + return bloom +} + +// AccountExtraDataLinker maintains mapping between root hash of the state trie +// and root hash of state.AccountExtraData trie +type AccountExtraDataLinker interface { + // GetAccountExtraDataRoot returns the root hash of the state.AccountExtraData trie from + // the given root hash of the state trie. + // + // It returns an empty hash if not found. + GetAccountExtraDataRoot(stateRoot common.Hash) common.Hash + // Link saves the mapping between root hash of the state trie and + // root hash of state.AccountExtraData trie to the persistent storage. + // Don't write the mapping if extraDataRoot is an emptyRoot + Link(stateRoot, extraDataRoot common.Hash) error +} + +// ethdbAccountExtraDataLinker implements AccountExtraDataLinker using ethdb.Database +// as the persistence storage +type ethdbAccountExtraDataLinker struct { + db ethdb.Database +} + +func NewAccountExtraDataLinker(db ethdb.Database) AccountExtraDataLinker { + return ðdbAccountExtraDataLinker{ + db: db, + } +} + +func (pml *ethdbAccountExtraDataLinker) GetAccountExtraDataRoot(stateRoot common.Hash) common.Hash { + return GetAccountExtraDataRoot(pml.db, stateRoot) +} + +func (pml *ethdbAccountExtraDataLinker) Link(stateRoot, extraDataRoot common.Hash) error { + if extraDataRoot != emptyRoot { + return WriteRootHashMapping(pml.db, stateRoot, extraDataRoot) + } + return nil +} diff --git a/core/rawdb/database_quorum_test.go b/core/rawdb/database_quorum_test.go new file mode 100644 index 0000000000..ed6dc0b8ef --- /dev/null +++ b/core/rawdb/database_quorum_test.go @@ -0,0 +1,184 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "errors" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/stretchr/testify/assert" +) + +// Tests that setting the flag for Quorum EIP155 activation read values correctly +func TestIsQuorumEIP155Active(t *testing.T) { + db := NewMemoryDatabase() + + isQuorumEIP155Active := GetIsQuorumEIP155Activated(db) + if isQuorumEIP155Active { + t.Fatal("Quorum EIP155 active read to be set, but wasn't set beforehand") + } + + dbSet := NewMemoryDatabase() + err := WriteQuorumEIP155Activation(dbSet) + + if err != nil { + t.Fatal("unable to write quorum EIP155 activation") + } + + isQuorumEIP155ActiveAfterSetting := GetIsQuorumEIP155Activated(dbSet) + if !isQuorumEIP155ActiveAfterSetting { + t.Fatal("Quorum EIP155 active read to be unset, but was set beforehand") + } +} + +func TestAccountExtraDataLinker_whenLinkingEmptyRoot(t *testing.T) { + db := NewMemoryDatabase() + psr := common.Hash{1} + + linker := NewAccountExtraDataLinker(db) + + err := linker.Link(psr, emptyRoot) + + if err != nil { + t.Fatal("unable to store the link") + } + + value, _ := db.Get(append(stateRootToExtraDataRootPrefix, psr[:]...)) + + if value != nil { + t.Fatal("the mapping should not have been stored") + } +} + +func TestAccountExtraDataLinker_whenLinkingRoots(t *testing.T) { + db := NewMemoryDatabase() + psr := common.Hash{1} + pmr := common.Hash{2} + + linker := NewAccountExtraDataLinker(db) + + err := linker.Link(psr, pmr) + + if err != nil { + t.Fatal("unable to store the link") + } + + value, _ := db.Get(append(stateRootToExtraDataRootPrefix, psr[:]...)) + + if value == nil { + t.Fatal("the mapping should have been stored") + } + + valueHash := common.BytesToHash(value) + + if pmr != valueHash { + t.Fatal("the privacy metadata root does not have the expected value") + } +} + +var errReadOnly = errors.New("unable to write") + +type ReadOnlyDB struct { + memorydb.Database +} + +func (t *ReadOnlyDB) Put(key []byte, value []byte) error { + return errReadOnly +} + +func TestAccountExtraDataLinker_whenError(t *testing.T) { + db := NewDatabase(&ReadOnlyDB{}) + psr := common.Hash{1} + pmr := common.Hash{2} + + linker := NewAccountExtraDataLinker(db) + + err := linker.Link(psr, pmr) + + if err == nil { + t.Fatal("expecting a read only error to be returned") + } + + if err != errReadOnly { + t.Fatal("expecting the read only error to be returned") + } +} + +func TestAccountExtraDataLinker_whenFinding(t *testing.T) { + db := NewMemoryDatabase() + psr := common.Hash{1} + pmr := common.Hash{2} + + err := db.Put(append(stateRootToExtraDataRootPrefix, psr[:]...), pmr[:]) + + if err != nil { + t.Fatal("unable to write to db") + } + + pml := NewAccountExtraDataLinker(db) + + pmrRetrieved := pml.GetAccountExtraDataRoot(psr) + + if pmrRetrieved != pmr { + t.Fatal("the mapping should have been retrieved") + } +} + +func TestAccountExtraDataLinker_whenNotFound(t *testing.T) { + db := NewMemoryDatabase() + psr := common.Hash{1} + + pml := NewAccountExtraDataLinker(db) + + pmrRetrieved := pml.GetAccountExtraDataRoot(psr) + + if !common.EmptyHash(pmrRetrieved) { + t.Fatal("the retrieved privacy metadata root should be the empty hash") + } +} + +func TestPrivateStatesTrieRoot(t *testing.T) { + db := NewMemoryDatabase() + blockRoot := common.HexToHash("0x4c50c7d11e58e5c6f40fa1a630ffcb3a017453e7f9d0ec8ccb01033fcf9f2210") + pstRoot := common.HexToHash("0x5c46375b6b333983077e152d1b6ca101d0586a6565fa75750deb1b07154bbdca") + + err := WritePrivateStatesTrieRoot(db, blockRoot, pstRoot) + assert.Nil(t, err) + + retrievedRoot := GetPrivateStatesTrieRoot(db, blockRoot) + assert.Equal(t, pstRoot, retrievedRoot) + + retrievedEmptyRoot := GetPrivateStatesTrieRoot(db, common.Hash{}) + assert.Equal(t, common.Hash{}, retrievedEmptyRoot) +} + +func TestPrivateStateRoot(t *testing.T) { + db := NewMemoryDatabase() + blockRoot := common.HexToHash("0x4c50c7d11e58e5c6f40fa1a630ffcb3a017453e7f9d0ec8ccb01033fcf9f2210") + psRoot := common.HexToHash("0x5c46375b6b333983077e152d1b6ca101d0586a6565fa75750deb1b07154bbdca") + + err := WritePrivateStateRoot(db, blockRoot, psRoot) + assert.Nil(t, err) + + retrievedRoot := GetPrivateStateRoot(db, blockRoot) + assert.Equal(t, psRoot, retrievedRoot) + + retrievedEmptyRoot := GetPrivateStateRoot(db, common.Hash{}) + assert.Equal(t, common.Hash{}, retrievedEmptyRoot) +} diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index 5744b0cbb3..28715f3125 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -301,7 +301,7 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) { continue } number := ReadHeaderNumber(nfdb, hash) - threshold := atomic.LoadUint64(&f.threshold) + threshold := int(atomic.LoadUint64(&f.threshold)) switch { case number == nil: @@ -309,12 +309,12 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) { backoff = true continue - case *number < threshold: - log.Debug("Current full block not old enough", "number", *number, "hash", hash, "delay", threshold) + case *number < uint64(params.GetImmutabilityThresholdWithDefault(threshold)): + log.Debug("Current full block not old enough", "number", *number, "hash", hash, "delay", params.GetImmutabilityThresholdWithDefault(threshold)) backoff = true continue - case *number-threshold <= f.frozen: + case *number-uint64(params.GetImmutabilityThresholdWithDefault(threshold)) <= f.frozen: log.Debug("Ancient blocks frozen already", "number", *number, "hash", hash, "frozen", f.frozen) backoff = true continue @@ -326,7 +326,7 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) { continue } // Seems we have data ready to be frozen, process in usable batches - limit := *number - threshold + limit := *number - uint64(params.GetImmutabilityThresholdWithDefault(threshold)) if limit-f.frozen > freezerBatchLimit { limit = f.frozen + freezerBatchLimit } diff --git a/core/rawdb/freezer_test.go b/core/rawdb/freezer_test.go new file mode 100644 index 0000000000..b3f9c2cb39 --- /dev/null +++ b/core/rawdb/freezer_test.go @@ -0,0 +1,73 @@ +package rawdb + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +// Quorum + +func Test_freezer_Close(t *testing.T) { + // Close first time + mockFreezer := newFreezerMock(t) + err := mockFreezer.Close() + assert.Nil(t, err) + + // Close second time should return error but do not hang sending data to freeze.quit channel + timeout := time.After(1 * time.Second) + errCh := make(chan error) + + go func() { + errCh <- mockFreezer.Close() + }() + + select { + case <-timeout: + t.Fatal("freezer.Close() timed out") + case err := <-errCh: + assert.Nil(t, err) + } +} + +// Releaser is an autogenerated mock type for the Releaser type +type releaserMock struct { + mock.Mock +} + +// Release provides a mock function with given fields: +func (_m *releaserMock) Release() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +func newFreezerMock(t *testing.T) *freezer { + mockLock := new(releaserMock) + mockFreezer := &freezer{ + tables: make(map[string]*freezerTable), + instanceLock: mockLock, + quit: make(chan struct{}), + } + mockLock.On("Release").Return(nil) + + started := make(chan bool) + go func() { + started <- true + <-mockFreezer.quit + }() + <-started + + return mockFreezer +} + +// End Quorum diff --git a/core/state/account_extra_data.go b/core/state/account_extra_data.go new file mode 100644 index 0000000000..8e05e8c974 --- /dev/null +++ b/core/state/account_extra_data.go @@ -0,0 +1,160 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "fmt" + "io" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/private/engine" + "github.com/ethereum/go-ethereum/rlp" +) + +// Quorum +// AccountExtraData is to contain extra data that supplements existing Account data. +// It is also maintained in a trie to support rollback. +// Note: +// - update copy() method +// - update DecodeRLP and EncodeRLP when adding new field +type AccountExtraData struct { + // for privacy enhancements + PrivacyMetadata *PrivacyMetadata + // list of public keys managed by the corresponding Tessera. + // This is for multitenancy + ManagedParties []string +} + +func (qmd *AccountExtraData) DecodeRLP(stream *rlp.Stream) error { + var dataRLP struct { + // from state.PrivacyMetadata, this is required to support + // backward compatibility with RLP-encoded state.PrivacyMetadata. + // Refer to rlp/doc.go for decoding rules. + CreationTxHash *common.EncryptedPayloadHash `rlp:"nil"` + // from state.PrivacyMetadata, this is required to support + // backward compatibility with RLP-encoded state.PrivacyMetadata. + // Refer to rlp/doc.go for decoding rules. + PrivacyFlag *engine.PrivacyFlagType `rlp:"nil"` + + Rest []rlp.RawValue `rlp:"tail"` // to maintain forward compatibility + } + if err := stream.Decode(&dataRLP); err != nil { + return err + } + if dataRLP.CreationTxHash != nil && dataRLP.PrivacyFlag != nil { + qmd.PrivacyMetadata = &PrivacyMetadata{ + CreationTxHash: *dataRLP.CreationTxHash, + PrivacyFlag: *dataRLP.PrivacyFlag, + } + } + if len(dataRLP.Rest) > 0 { + var managedParties []string + if err := rlp.DecodeBytes(dataRLP.Rest[0], &managedParties); err != nil { + return fmt.Errorf("fail to decode managedParties with error %v", err) + } + // As RLP encodes empty slice or nil slice as an empty string (192) + // we won't be able to determine when decoding. So we use pragmatic approach + // to default to nil value. Downstream usage would deal with it easier. + if len(managedParties) == 0 { + qmd.ManagedParties = nil + } else { + qmd.ManagedParties = managedParties + } + } + return nil +} + +func (qmd *AccountExtraData) EncodeRLP(writer io.Writer) error { + var ( + hash *common.EncryptedPayloadHash + flag *engine.PrivacyFlagType + ) + if qmd.PrivacyMetadata != nil { + hash = &qmd.PrivacyMetadata.CreationTxHash + flag = &qmd.PrivacyMetadata.PrivacyFlag + } + return rlp.Encode(writer, struct { + CreationTxHash *common.EncryptedPayloadHash `rlp:"nil"` + PrivacyFlag *engine.PrivacyFlagType `rlp:"nil"` + ManagedParties []string + }{ + CreationTxHash: hash, + PrivacyFlag: flag, + ManagedParties: qmd.ManagedParties, + }) +} + +func (qmd *AccountExtraData) copy() *AccountExtraData { + if qmd == nil { + return nil + } + var copyPM *PrivacyMetadata + if qmd.PrivacyMetadata != nil { + copyPM = &PrivacyMetadata{ + CreationTxHash: qmd.PrivacyMetadata.CreationTxHash, + PrivacyFlag: qmd.PrivacyMetadata.PrivacyFlag, + } + } + copyManagedParties := make([]string, len(qmd.ManagedParties)) + copy(copyManagedParties, qmd.ManagedParties) + return &AccountExtraData{ + PrivacyMetadata: copyPM, + ManagedParties: copyManagedParties, + } +} + +// attached to every private contract account +type PrivacyMetadata struct { + CreationTxHash common.EncryptedPayloadHash `json:"creationTxHash"` + PrivacyFlag engine.PrivacyFlagType `json:"privacyFlag"` +} + +// Quorum +// privacyMetadataRLP struct is to make sure +// field order is preserved regardless changes in the PrivacyMetadata and its internal +// +// Edit this struct with care to make sure forward and backward compatibility +type privacyMetadataRLP struct { + CreationTxHash common.EncryptedPayloadHash + PrivacyFlag engine.PrivacyFlagType + + Rest []rlp.RawValue `rlp:"tail"` // to maintain forward compatibility +} + +func (p *PrivacyMetadata) DecodeRLP(stream *rlp.Stream) error { + var dataRLP privacyMetadataRLP + if err := stream.Decode(&dataRLP); err != nil { + return err + } + p.CreationTxHash = dataRLP.CreationTxHash + p.PrivacyFlag = dataRLP.PrivacyFlag + return nil +} + +func (p *PrivacyMetadata) EncodeRLP(writer io.Writer) error { + return rlp.Encode(writer, privacyMetadataRLP{ + CreationTxHash: p.CreationTxHash, + PrivacyFlag: p.PrivacyFlag, + }) +} + +func NewStatePrivacyMetadata(creationTxHash common.EncryptedPayloadHash, privacyFlag engine.PrivacyFlagType) *PrivacyMetadata { + return &PrivacyMetadata{ + CreationTxHash: creationTxHash, + PrivacyFlag: privacyFlag, + } +} diff --git a/core/state/account_extra_data_test.go b/core/state/account_extra_data_test.go new file mode 100644 index 0000000000..f158a1c805 --- /dev/null +++ b/core/state/account_extra_data_test.go @@ -0,0 +1,193 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/private/engine" + "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/assert" +) + +type privacyMetadataOld struct { + CreationTxHash common.EncryptedPayloadHash + PrivacyFlag engine.PrivacyFlagType +} + +// privacyMetadataToBytes is the utility function under test from previous implementation +func privacyMetadataToBytes(pm *privacyMetadataOld) ([]byte, error) { + return rlp.EncodeToBytes(pm) +} + +// bytesToPrivacyMetadata is the utility function under test from previous implementation +func bytesToPrivacyMetadata(b []byte) (*privacyMetadataOld, error) { + var data *privacyMetadataOld + if err := rlp.DecodeBytes(b, &data); err != nil { + return nil, fmt.Errorf("unable to decode privacy metadata. Cause: %v", err) + } + return data, nil +} + +func TestRLP_PrivacyMetadata_DecodeBackwardCompatibility(t *testing.T) { + existingPM := &privacyMetadataOld{ + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("arbitrary-hash")), + PrivacyFlag: engine.PrivacyFlagStateValidation, + } + existing, err := privacyMetadataToBytes(existingPM) + assert.NoError(t, err) + + var actual PrivacyMetadata + err = rlp.DecodeBytes(existing, &actual) + + assert.NoError(t, err, "Must decode PrivacyMetadata successfully") + assert.Equal(t, existingPM.CreationTxHash, actual.CreationTxHash) + assert.Equal(t, existingPM.PrivacyFlag, actual.PrivacyFlag) +} + +func TestRLP_PrivacyMetadata_DecodeForwardCompatibility(t *testing.T) { + pm := &PrivacyMetadata{ + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("arbitrary-hash")), + PrivacyFlag: engine.PrivacyFlagStateValidation, + } + existing, err := rlp.EncodeToBytes(pm) + assert.NoError(t, err) + + var actual *privacyMetadataOld + actual, err = bytesToPrivacyMetadata(existing) + + assert.NoError(t, err, "Must encode PrivacyMetadata successfully") + assert.Equal(t, pm.CreationTxHash, actual.CreationTxHash) + assert.Equal(t, pm.PrivacyFlag, actual.PrivacyFlag) +} + +// From initial privacy enhancements, the privacy metadata is RLP encoded +// we now wrap PrivacyMetadata in a more generic struct. This test is to make sure +// we support backward compatibility. +func TestRLP_AccountExtraData_BackwardCompatibility(t *testing.T) { + // prepare existing RLP bytes + arbitraryExistingMetadata := &PrivacyMetadata{ + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("arbitrary-existing-privacy-metadata-creation-hash")), + PrivacyFlag: engine.PrivacyFlagPartyProtection, + } + existing, err := rlp.EncodeToBytes(arbitraryExistingMetadata) + assert.NoError(t, err) + + // now try to decode with the new struct + var actual AccountExtraData + err = rlp.DecodeBytes(existing, &actual) + + assert.NoError(t, err, "Must decode successfully") + assert.Equal(t, arbitraryExistingMetadata.CreationTxHash, actual.PrivacyMetadata.CreationTxHash) + assert.Equal(t, arbitraryExistingMetadata.PrivacyFlag, actual.PrivacyMetadata.PrivacyFlag) +} + +func TestRLP_AccountExtraData_withField_ManagedParties(t *testing.T) { + // prepare existing RLP bytes + arbitraryExtraData := &AccountExtraData{ + PrivacyMetadata: &PrivacyMetadata{ + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("arbitrary-existing-privacy-metadata-creation-hash")), + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, + ManagedParties: []string{"Arbitrary PK1", "Arbitrary PK2"}, + } + existing, err := rlp.EncodeToBytes(arbitraryExtraData) + assert.NoError(t, err) + + // now try to decode with the new struct + var actual AccountExtraData + err = rlp.DecodeBytes(existing, &actual) + + assert.NoError(t, err, "Must decode successfully") + assert.Equal(t, arbitraryExtraData.PrivacyMetadata.CreationTxHash, actual.PrivacyMetadata.CreationTxHash) + assert.Equal(t, arbitraryExtraData.PrivacyMetadata.PrivacyFlag, actual.PrivacyMetadata.PrivacyFlag) + assert.Equal(t, arbitraryExtraData.ManagedParties, actual.ManagedParties) +} + +func TestRLP_AccountExtraData_whenTypical(t *testing.T) { + expected := AccountExtraData{ + PrivacyMetadata: &PrivacyMetadata{ + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("arbitrary-payload-hash")), + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, + ManagedParties: []string{"XYZ"}, + } + + data, err := rlp.EncodeToBytes(&expected) + assert.NoError(t, err) + + var actual AccountExtraData + assert.NoError(t, rlp.DecodeBytes(data, &actual)) + assert.Equal(t, expected.PrivacyMetadata.CreationTxHash, actual.PrivacyMetadata.CreationTxHash) + assert.Equal(t, expected.PrivacyMetadata.PrivacyFlag, actual.PrivacyMetadata.PrivacyFlag) + assert.Equal(t, expected.ManagedParties, actual.ManagedParties) +} + +func TestRLP_AccountExtraData_whenHavingPrivacyMetadataOnly(t *testing.T) { + expected := AccountExtraData{ + PrivacyMetadata: &PrivacyMetadata{ + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("arbitrary-payload-hash")), + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, + } + + data, err := rlp.EncodeToBytes(&expected) + assert.NoError(t, err) + + var actual AccountExtraData + assert.NoError(t, rlp.DecodeBytes(data, &actual)) + assert.Equal(t, expected.PrivacyMetadata.CreationTxHash, actual.PrivacyMetadata.CreationTxHash) + assert.Equal(t, expected.PrivacyMetadata.PrivacyFlag, actual.PrivacyMetadata.PrivacyFlag) +} + +func TestRLP_AccountExtraData_whenHavingNilManagedParties(t *testing.T) { + expected := AccountExtraData{ + PrivacyMetadata: nil, + ManagedParties: nil, + } + + data, err := rlp.EncodeToBytes(&expected) + assert.NoError(t, err) + + var actual AccountExtraData + assert.NoError(t, rlp.DecodeBytes(data, &actual)) + assert.Nil(t, actual.ManagedParties) + assert.Nil(t, actual.PrivacyMetadata) +} + +func TestRLP_AccountExtraData_whenHavingEmptyManagedParties(t *testing.T) { + expected := AccountExtraData{ + PrivacyMetadata: nil, + ManagedParties: []string{}, + } + + data, err := rlp.EncodeToBytes(&expected) + assert.NoError(t, err) + + var actual AccountExtraData + assert.NoError(t, rlp.DecodeBytes(data, &actual)) + assert.Nil(t, actual.ManagedParties) + assert.Nil(t, actual.PrivacyMetadata) +} + +func TestCopy_whenNil(t *testing.T) { + var testObj *AccountExtraData = nil + + assert.Nil(t, testObj.copy()) +} diff --git a/core/state/database.go b/core/state/database.go index a9342f5179..5159f92e65 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -55,6 +55,12 @@ type Database interface { // TrieDB retrieves the low level trie database used for data storage. TrieDB() *trie.Database + + // Quorum + // + // accountExtraDataLinker maintains mapping between root hash of the state trie + // and root hash of state.AccountExtraData trie. + AccountExtraDataLinker() rawdb.AccountExtraDataLinker } // Trie is a Ethereum Merkle Patricia trie. @@ -115,9 +121,10 @@ func NewDatabase(db ethdb.Database) Database { func NewDatabaseWithCache(db ethdb.Database, cache int, journal string) Database { csc, _ := lru.New(codeSizeCacheSize) return &cachingDB{ - db: trie.NewDatabaseWithCache(db, cache, journal), - codeSizeCache: csc, - codeCache: fastcache.New(codeCacheSize), + db: trie.NewDatabaseWithCache(db, cache, journal), + codeSizeCache: csc, + codeCache: fastcache.New(codeCacheSize), + accountExtraDataLinker: rawdb.NewAccountExtraDataLinker(db), // Quorum } } @@ -125,6 +132,16 @@ type cachingDB struct { db *trie.Database codeSizeCache *lru.Cache codeCache *fastcache.Cache + + // Quorum + // + // accountExtraDataLinker maintains mapping between state root and state.AccountExtraData root. + // As this struct is the backing store for state, this gives the reference to the linker when needed. + accountExtraDataLinker rawdb.AccountExtraDataLinker +} + +func (db *cachingDB) AccountExtraDataLinker() rawdb.AccountExtraDataLinker { + return db.accountExtraDataLinker } // OpenTrie opens the main account trie at a specific root hash. diff --git a/core/state/dump.go b/core/state/dump.go index 9bb946d14b..911b8cf1d4 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -189,6 +189,36 @@ func (s *StateDB) Dump(excludeCode, excludeStorage, excludeMissingPreimages bool return json } +func (self *StateDB) DumpAddress(address common.Address) (DumpAccount, bool) { + if !self.Exist(address) { + return DumpAccount{}, false + } + + obj := self.getStateObject(address) + account := DumpAccount{ + Balance: obj.data.Balance.String(), + Nonce: obj.data.Nonce, + Root: common.Bytes2Hex(obj.data.Root[:]), + CodeHash: common.Bytes2Hex(obj.data.CodeHash), + Code: common.Bytes2Hex(obj.Code(self.db)), + Storage: make(map[common.Hash]string), + } + + noDataIssue := true + storageIt := trie.NewIterator(obj.getTrie(self.db).NodeIterator(nil)) + for storageIt.Next() { + _, content, _, err := rlp.Split(storageIt.Value) + if err != nil { + noDataIssue = false + log.Error("Failed to decode the value returned by iterator", "error", err) + break + } + account.Storage[common.BytesToHash(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(content) + } + + return account, noDataIssue +} + // IterativeDump dumps out accounts as json-objects, delimited by linebreaks on stdout func (s *StateDB) IterativeDump(excludeCode, excludeStorage, excludeMissingPreimages bool, output *json.Encoder) { s.DumpToCollector(iterativeDump{output}, excludeCode, excludeStorage, excludeMissingPreimages, nil, 0) diff --git a/core/state/journal.go b/core/state/journal.go index f242dac5af..142954788e 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -116,7 +116,11 @@ type ( account *common.Address prevcode, prevhash []byte } - + // Quorum - changes to AccountExtraData + accountExtraDataChange struct { + account *common.Address + prev *AccountExtraData + } // Changes to other state values. refundChange struct { prev uint64 @@ -197,6 +201,17 @@ func (ch codeChange) dirtied() *common.Address { return ch.account } +// Quorum +func (ch accountExtraDataChange) revert(s *StateDB) { + s.getStateObject(*ch.account).setAccountExtraData(ch.prev) +} + +func (ch accountExtraDataChange) dirtied() *common.Address { + return ch.account +} + +// End Quorum - Privacy Enhancements + func (ch storageChange) revert(s *StateDB) { s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) } diff --git a/core/state/state_object.go b/core/state/state_object.go index 26ab67e1ad..16e8d93cf5 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -18,9 +18,11 @@ package state import ( "bytes" + "errors" "fmt" "io" "math/big" + "sync" "time" "github.com/ethereum/go-ethereum/common" @@ -79,6 +81,13 @@ type stateObject struct { trie Trie // storage trie, which becomes non-nil on first access code Code // contract bytecode, which gets set when code is loaded + // Quorum + // contains extra data that is linked to the account + accountExtraData *AccountExtraData + // as there are many fields in accountExtraData which might be concurrently changed + // this is to make sure we can keep track of changes individually. + accountExtraDataMutex sync.Mutex + originStorage Storage // Storage cache of original entries to dedup rewrites, reset for every transaction pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block dirtyStorage Storage // Storage entries that have been modified in the current transaction execution @@ -90,6 +99,9 @@ type stateObject struct { dirtyCode bool // true if the code was updated suicided bool deleted bool + // Quorum + // flag to track changes in AccountExtraData + dirtyAccountExtraData bool } // empty returns whether the account is considered empty. @@ -167,6 +179,10 @@ func (s *stateObject) getTrie(db Database) Trie { return s.trie } +func (so *stateObject) storageRoot(db Database) common.Hash { + return so.getTrie(db).Hash() +} + // GetState retrieves a value from the account storage trie. func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { // If the fake storage is set, only lookup the state here(in the debugging mode) @@ -425,6 +441,10 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject { stateObject.suicided = s.suicided stateObject.dirtyCode = s.dirtyCode stateObject.deleted = s.deleted + // Quorum - copy AccountExtraData + stateObject.accountExtraData = s.accountExtraData + stateObject.dirtyAccountExtraData = s.dirtyAccountExtraData + return stateObject } @@ -498,6 +518,60 @@ func (s *stateObject) setNonce(nonce uint64) { s.data.Nonce = nonce } +// Quorum +// SetAccountExtraData modifies the AccountExtraData reference and journals it +func (s *stateObject) SetAccountExtraData(extraData *AccountExtraData) { + current, _ := s.AccountExtraData() + s.db.journal.append(accountExtraDataChange{ + account: &s.address, + prev: current, + }) + s.setAccountExtraData(extraData) +} + +// A new AccountExtraData will be created if not exists. +// This must be called after successfully acquiring accountExtraDataMutex lock +func (s *stateObject) journalAccountExtraData() *AccountExtraData { + current, _ := s.AccountExtraData() + s.db.journal.append(accountExtraDataChange{ + account: &s.address, + prev: current.copy(), + }) + if current == nil { + current = &AccountExtraData{} + } + return current +} + +// Quorum +// SetStatePrivacyMetadata updates the PrivacyMetadata in AccountExtraData and journals it. +func (s *stateObject) SetStatePrivacyMetadata(pm *PrivacyMetadata) { + s.accountExtraDataMutex.Lock() + defer s.accountExtraDataMutex.Unlock() + + newExtraData := s.journalAccountExtraData() + newExtraData.PrivacyMetadata = pm + s.setAccountExtraData(newExtraData) +} + +// Quorum +// SetStatePrivacyMetadata updates the PrivacyMetadata in AccountExtraData and journals it. +func (s *stateObject) SetManagedParties(managedParties []string) { + s.accountExtraDataMutex.Lock() + defer s.accountExtraDataMutex.Unlock() + + newExtraData := s.journalAccountExtraData() + newExtraData.ManagedParties = managedParties + s.setAccountExtraData(newExtraData) +} + +// Quorum +// setAccountExtraData modifies the AccountExtraData reference in this state object +func (s *stateObject) setAccountExtraData(extraData *AccountExtraData) { + s.accountExtraData = extraData + s.dirtyAccountExtraData = true +} + func (s *stateObject) CodeHash() []byte { return s.data.CodeHash } @@ -510,6 +584,83 @@ func (s *stateObject) Nonce() uint64 { return s.data.Nonce } +// Quorum +// AccountExtraData returns the extra data in this state object. +// It will also update the reference by searching the accountExtraDataTrie. +// +// This method enforces on returning error and never returns (nil, nil). +func (s *stateObject) AccountExtraData() (*AccountExtraData, error) { + if s.accountExtraData != nil { + return s.accountExtraData, nil + } + val, err := s.getCommittedAccountExtraData() + if err != nil { + return nil, err + } + s.accountExtraData = val + return val, nil +} + +// Quorum +// getCommittedAccountExtraData looks for an entry in accountExtraDataTrie. +// +// This method enforces on returning error and never returns (nil, nil). +func (s *stateObject) getCommittedAccountExtraData() (*AccountExtraData, error) { + val, err := s.db.accountExtraDataTrie.TryGet(s.address.Bytes()) + if err != nil { + return nil, fmt.Errorf("unable to retrieve data from the accountExtraDataTrie. Cause: %v", err) + } + if len(val) == 0 { + return nil, fmt.Errorf("%s: %w", s.address.Hex(), common.ErrNoAccountExtraData) + } + var extraData AccountExtraData + if err := rlp.DecodeBytes(val, &extraData); err != nil { + return nil, fmt.Errorf("unable to decode to AccountExtraData. Cause: %v", err) + } + return &extraData, nil +} + +// Quorum - Privacy Enhancements +// PrivacyMetadata returns the reference to PrivacyMetadata. +// It will returrn an error if no PrivacyMetadata is in the AccountExtraData. +func (s *stateObject) PrivacyMetadata() (*PrivacyMetadata, error) { + extraData, err := s.AccountExtraData() + if err != nil { + return nil, err + } + // extraData can't be nil. Refer to s.AccountExtraData() + if extraData.PrivacyMetadata == nil { + return nil, fmt.Errorf("no privacy metadata data for contract %s", s.address.Hex()) + } + return extraData.PrivacyMetadata, nil +} + +func (s *stateObject) GetCommittedPrivacyMetadata() (*PrivacyMetadata, error) { + extraData, err := s.getCommittedAccountExtraData() + if err != nil { + return nil, err + } + if extraData == nil || extraData.PrivacyMetadata == nil { + return nil, fmt.Errorf("The provided contract does not have privacy metadata: %x", s.address) + } + return extraData.PrivacyMetadata, nil +} + +// End Quorum - Privacy Enhancements + +// ManagedParties will return empty if no account extra data found +func (s *stateObject) ManagedParties() ([]string, error) { + extraData, err := s.AccountExtraData() + if errors.Is(err, common.ErrNoAccountExtraData) { + return []string{}, nil + } + if err != nil { + return nil, err + } + // extraData can't be nil. Refer to s.AccountExtraData() + return extraData.ManagedParties, nil +} + // Never called, but must be present to allow stateObject to be used // as a vm.Account interface that also satisfies the vm.ContractRef // interface. Interfaces are awesome. diff --git a/core/state/state_test.go b/core/state/state_test.go index 0dc4c0ad63..cc912bfde4 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -18,6 +18,7 @@ package state import ( "bytes" + "encoding/json" "math/big" "testing" @@ -25,6 +26,8 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + + checker "gopkg.in/check.v1" ) var toAddr = common.BytesToAddress @@ -87,6 +90,61 @@ func TestDump(t *testing.T) { } } +func (s *stateTest) TestDumpAddress(c *checker.C) { + // generate a few entries + obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) + obj1.AddBalance(big.NewInt(22)) + obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) + obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) + obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) + obj3.SetBalance(big.NewInt(44)) + + // write some of them to the trie + s.state.updateStateObject(obj1) + s.state.updateStateObject(obj2) + s.state.Commit(false) + + addressToDump := toAddr([]byte{0x01}) + // check that dump contains the state objects that are in trie + got, _ := s.state.DumpAddress(addressToDump) + out, _ := json.Marshal(got) + + want := `{"balance":"22","nonce":0,"root":"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"}` + + if string(out) != want { + c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", string(out), want) + } +} + +func (s *stateTest) TestDumpAddressNotFound(c *checker.C) { + // generate a few entries + obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) + obj1.AddBalance(big.NewInt(22)) + obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) + obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) + obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) + obj3.SetBalance(big.NewInt(44)) + + // write some of them to the trie + s.state.updateStateObject(obj1) + s.state.updateStateObject(obj2) + s.state.Commit(false) + + addressToDump := toAddr([]byte{0x09}) + + // check that dump contains the state objects that are in trie + _, found := s.state.DumpAddress(addressToDump) + + if found { + c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", found, false) + } +} + +func (s *stateTest) SetUpTest(c *checker.C) { + s.db = rawdb.NewMemoryDatabase() + s.state, _ = New(common.Hash{}, NewDatabase(s.db), nil) +} + func TestNull(t *testing.T) { s := newStateTest() address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") diff --git a/core/state/statedb.go b/core/state/statedb.go index 36f7d863af..fd0521e972 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -71,6 +71,9 @@ type StateDB struct { snapAccounts map[common.Hash][]byte snapStorage map[common.Hash]map[common.Hash][]byte + // Quorum - a trie to hold extra account information that cannot be stored in the accounts trie + accountExtraDataTrie Trie + // This map holds 'live' objects, which will get modified while processing a state transition. stateObjects map[common.Address]*stateObject stateObjectsPending map[common.Address]struct{} // State objects finalized but not yet written to the trie @@ -119,17 +122,30 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) if err != nil { return nil, err } + + // Quorum - Privacy Enhancements - retrieve the privacy metadata root corresponding to the account state root + extraDataRoot := db.AccountExtraDataLinker().GetAccountExtraDataRoot(root) + log.Debug("Account Extra Data root", "hash", extraDataRoot) + accountExtraDataTrie, err := db.OpenTrie(extraDataRoot) + if err != nil { + return nil, fmt.Errorf("Unable to open privacy metadata trie: %v", err) + } + // End Quorum - Privacy Enhancements + sdb := &StateDB{ - db: db, - trie: tr, - snaps: snaps, - stateObjects: make(map[common.Address]*stateObject), - stateObjectsPending: make(map[common.Address]struct{}), - stateObjectsDirty: make(map[common.Address]struct{}), - logs: make(map[common.Hash][]*types.Log), - preimages: make(map[common.Hash][]byte), - journal: newJournal(), + db: db, + trie: tr, + snaps: snaps, + // Quorum - Privacy Enhancements + accountExtraDataTrie: accountExtraDataTrie, + stateObjects: make(map[common.Address]*stateObject), + stateObjectsPending: make(map[common.Address]struct{}), + stateObjectsDirty: make(map[common.Address]struct{}), + logs: make(map[common.Hash][]*types.Log), + preimages: make(map[common.Hash][]byte), + journal: newJournal(), } + if sdb.snaps != nil { if sdb.snap = sdb.snaps.Snapshot(root); sdb.snap != nil { sdb.snapDestructs = make(map[common.Hash]struct{}) @@ -245,7 +261,10 @@ func (s *StateDB) Exist(addr common.Address) bool { // or empty according to the EIP161 specification (balance = nonce = code = 0) func (s *StateDB) Empty(addr common.Address) bool { so := s.getStateObject(addr) - return so == nil || so.empty() + if so != nil { + return so.empty() + } + return true } // GetBalance retrieves the balance from the given address or 0 if object not found @@ -262,10 +281,51 @@ func (s *StateDB) GetNonce(addr common.Address) uint64 { if stateObject != nil { return stateObject.Nonce() } - return 0 } +// Quorum +func (s *StateDB) GetPrivacyMetadata(addr common.Address) (*PrivacyMetadata, error) { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.PrivacyMetadata() + } + return nil, nil +} + +// Quorum +func (s *StateDB) GetCommittedStatePrivacyMetadata(addr common.Address) (*PrivacyMetadata, error) { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.GetCommittedPrivacyMetadata() + } + return nil, nil +} + +// Quorum +func (self *StateDB) GetManagedParties(addr common.Address) ([]string, error) { + stateObject := self.getStateObject(addr) + if stateObject != nil { + return stateObject.ManagedParties() + } + return nil, nil +} + +func (s *StateDB) GetRLPEncodedStateObject(addr common.Address) ([]byte, error) { + stateObject := s.getStateObject(addr) + if stateObject == nil { + return nil, fmt.Errorf("no state found for %s", addr.Hex()) + } + // When calculating the execution hash or simulating the transaction the stateOject state is not committed/updated + // In order to reflect the updated state invoke stateObject.updateRoot on a copy of the state object. + if len(stateObject.pendingStorage) > 0 || len(stateObject.dirtyStorage) > 0 || stateObject.dirtyCode { + cpy := stateObject.deepCopy(s) + cpy.updateRoot(s.db) + return rlp.EncodeToBytes(cpy) + } + return rlp.EncodeToBytes(stateObject) +} + // TxIndex returns the current transaction index set by Prepare. func (s *StateDB) TxIndex() int { return s.txIndex @@ -361,6 +421,16 @@ func (s *StateDB) HasSuicided(addr common.Address) bool { return false } +// Quorum +// GetStorageRoot returns the root of the storage associated with the given address. +func (s *StateDB) GetStorageRoot(addr common.Address) (common.Hash, error) { + so := s.getStateObject(addr) + if so == nil { + return common.Hash{}, fmt.Errorf("can't find state object") + } + return so.storageRoot(s.db), nil +} + /* * SETTERS */ @@ -395,6 +465,20 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { } } +func (s *StateDB) SetPrivacyMetadata(addr common.Address, metadata *PrivacyMetadata) { + stateObject := s.GetOrNewStateObject(addr) + if stateObject != nil { + stateObject.SetStatePrivacyMetadata(metadata) + } +} + +func (self *StateDB) SetManagedParties(addr common.Address, managedParties []string) { + stateObject := self.GetOrNewStateObject(addr) + if stateObject != nil && len(managedParties) > 0 { + stateObject.SetManagedParties(managedParties) + } +} + func (s *StateDB) SetCode(addr common.Address, code []byte) { stateObject := s.GetOrNewStateObject(addr) if stateObject != nil { @@ -444,6 +528,8 @@ func (s *StateDB) Suicide(addr common.Address) bool { // // updateStateObject writes the given object to the trie. +// Quorum: +// - update AccountExtraData trie func (s *StateDB) updateStateObject(obj *stateObject) { // Track the amount of time wasted on updating the account from the trie if metrics.EnabledExpensive { @@ -467,9 +553,29 @@ func (s *StateDB) updateStateObject(obj *stateObject) { if s.snap != nil { s.snapAccounts[obj.addrHash] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash) } + + // Quorum - Privacy Enhancements - update the privacy metadata trie in case the privacy metadata is dirty + if err != nil { + return + } + + if obj.dirtyAccountExtraData && obj.accountExtraData != nil { + extraDataBytes, err := rlp.EncodeToBytes(obj.accountExtraData) + if err != nil { + panic(fmt.Errorf("can't encode privacy metadata at %x: %v", addr[:], err)) + } + err = s.accountExtraDataTrie.TryUpdate(addr[:], extraDataBytes) + if err != nil { + s.setError(err) + return + } + } + } // deleteStateObject removes the given object from the state trie. +// Quorum: +// - delete the data from the extra data trie corresponding to the account address func (s *StateDB) deleteStateObject(obj *stateObject) { // Track the amount of time wasted on deleting the account from the trie if metrics.EnabledExpensive { @@ -479,7 +585,9 @@ func (s *StateDB) deleteStateObject(obj *stateObject) { addr := obj.Address() if err := s.trie.TryDelete(addr[:]); err != nil { s.setError(fmt.Errorf("deleteStateObject (%x) error: %v", addr[:], err)) + return } + s.setError(s.accountExtraDataTrie.TryDelete(addr[:])) } // getStateObject retrieves a state object given by the address, returning nil if @@ -644,16 +752,18 @@ func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common func (s *StateDB) Copy() *StateDB { // Copy all the basic fields, initialize the memory ones state := &StateDB{ - db: s.db, - trie: s.db.CopyTrie(s.trie), - stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)), - stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), - stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)), - refund: s.refund, - logs: make(map[common.Hash][]*types.Log, len(s.logs)), - logSize: s.logSize, - preimages: make(map[common.Hash][]byte, len(s.preimages)), - journal: newJournal(), + db: s.db, + trie: s.db.CopyTrie(s.trie), + // Quorum - Privacy Enhancements + accountExtraDataTrie: s.db.CopyTrie(s.accountExtraDataTrie), + stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)), + stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), + stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)), + refund: s.refund, + logs: make(map[common.Hash][]*types.Log, len(s.logs)), + logSize: s.logSize, + preimages: make(map[common.Hash][]byte, len(s.preimages)), + journal: newJournal(), } // Copy the dirty states, logs, and preimages for addr := range s.journal.dirties { @@ -809,6 +919,8 @@ func (s *StateDB) clearJournalAndRefund() { } // Commit writes the state to the underlying in-memory trie database. +// Quorum: +// - linking state root and the AccountExtraData root func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { if s.dbErr != nil { return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) @@ -844,8 +956,6 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { if metrics.EnabledExpensive { start = time.Now() } - // The onleaf func is called _serially_, so we can reuse the same account - // for unmarshalling every time. var account Account root, err := s.trie.Commit(func(path []byte, leaf []byte, parent common.Hash) error { if err := rlp.DecodeBytes(leaf, &account); err != nil { @@ -875,5 +985,24 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { } s.snap, s.snapDestructs, s.snapAccounts, s.snapStorage = nil, nil, nil, nil } + + // Quorum + // linking the state root and the AccountExtraData root + if err == nil { + // commit the AccountExtraData trie + extraDataRoot, err := s.accountExtraDataTrie.Commit(nil) + if err != nil { + return common.Hash{}, fmt.Errorf("unable to commit the AccountExtraData trie: %v", err) + } + log.Debug("AccountExtraData root after trie commit", "root", extraDataRoot) + // link the new state root to the AccountExtraData root + err = s.db.AccountExtraDataLinker().Link(root, extraDataRoot) + if err != nil { + return common.Hash{}, fmt.Errorf("Unable to link the state root to the privacy metadata root: %v", err) + } + // add a reference from the AccountExtraData root to the state root so that when the state root is written + // to the DB the the AccountExtraData root is also written + s.db.TrieDB().Reference(extraDataRoot, root) + } return root, err } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 36ff271331..825521a32b 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/private/engine" ) // Tests that updating a state trie does not leak any database writes prior to @@ -290,6 +291,22 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { }, args: make([]int64, 2), }, + { + name: "SetPrivacyMetadata", + fn: func(a testAction, s *StateDB) { + + privFlag := engine.PrivacyFlagType((uint64(a.args[0])%2)*2 + 1) // the only possible values should be 1 and 3 + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, uint64(a.args[1])) + hash := common.BytesToEncryptedPayloadHash(b) + + s.SetPrivacyMetadata(addr, &PrivacyMetadata{ + CreationTxHash: hash, + PrivacyFlag: privFlag, + }) + }, + args: make([]int64, 2), + }, { name: "CreateAccount", fn: func(a testAction, s *StateDB) { @@ -431,6 +448,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr)) checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr)) + statePM, _ := state.GetPrivacyMetadata(addr) + checkStatePM, _ := checkstate.GetPrivacyMetadata(addr) + checkeq("GetPrivacyMetadata", statePM, checkStatePM) // Check storage. if obj := state.getStateObject(addr); obj != nil { state.ForEachStorage(addr, func(key, value common.Hash) bool { @@ -727,3 +747,188 @@ func TestMissingTrieNodes(t *testing.T) { t.Fatalf("expected error, got root :%x", root) } } + +// Quorum + +func TestStorageRoot(t *testing.T) { + var ( + mem = rawdb.NewMemoryDatabase() + db = NewDatabase(mem) + state, _ = New(common.Hash{}, db, nil) + addr = common.Address{1} + key = common.Hash{1} + value = common.Hash{42} + + empty = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + ) + + so := state.GetOrNewStateObject(addr) + + emptyRoot := so.storageRoot(db) + if emptyRoot != empty { + t.Errorf("Invalid empty storage root, expected %x, got %x", empty, emptyRoot) + } + + // add a bit of state + so.SetState(db, key, value) + state.Commit(false) + + root := so.storageRoot(db) + expected := common.HexToHash("63511abd258fa907afa30cb118b53744a4f49055bb3f531da512c6b866fc2ffb") + + if expected != root { + t.Errorf("Invalid storage root, expected %x, got %x", expected, root) + } +} + +// End Quorum + +// Quorum - Privacy Enhancements +func TestPrivacyMetadataIsSavedOnStateDbCommit(t *testing.T) { + ethDb := rawdb.NewMemoryDatabase() + stateDb := NewDatabase(ethDb) + state, _ := New(common.Hash{}, stateDb, nil) + + addr := common.Address{1} + state.CreateAccount(addr) + + state.SetNonce(addr, uint64(1)) + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagPartyProtection, + CreationTxHash: common.EncryptedPayloadHash{1}, + }) + + privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData != nil { + t.Errorf("privacy metadata should not have been stored before commit") + } + + state.Commit(false) + + privMetaData, _ = state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData == nil { + t.Errorf("privacy metadata should have been stored during commit") + } +} + +func TestPrivacyMetadataIsUpdatedOnAccountReCreateWithDifferentPrivacyMetadata(t *testing.T) { + ethDb := rawdb.NewMemoryDatabase() + stateDb := NewDatabase(ethDb) + state, _ := New(common.Hash{}, stateDb, nil) + + addr := common.Address{1} + state.CreateAccount(addr) + + state.SetNonce(addr, uint64(1)) + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagPartyProtection, + CreationTxHash: common.EncryptedPayloadHash{1}, + }) + state.Commit(false) + + privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData == nil { + t.Errorf("privacy metadata should have been stored during commit") + } + + state.CreateAccount(addr) + state.SetNonce(addr, uint64(1)) + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagStateValidation, + CreationTxHash: common.EncryptedPayloadHash{1}, + }) + + state.Commit(false) + + privMetaData, _ = state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData == nil { + t.Errorf("privacy metadata should have been updated during commit") + } else if privMetaData.PrivacyFlag != engine.PrivacyFlagStateValidation { + t.Errorf("privacy metadata should have StateValidation as the the privacy flag") + } +} + +func TestPrivacyMetadataIsRemovedOnAccountSuicide(t *testing.T) { + ethDb := rawdb.NewMemoryDatabase() + stateDb := NewDatabase(ethDb) + state, _ := New(common.Hash{}, stateDb, nil) + + addr := common.Address{1} + state.CreateAccount(addr) + + state.SetNonce(addr, uint64(1)) + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagPartyProtection, + CreationTxHash: common.EncryptedPayloadHash{1}, + }) + state.Commit(false) + + privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData == nil { + t.Errorf("privacy metadata should have been stored during commit") + } + + state.Suicide(addr) + state.Commit(false) + + privMetaData, _ = state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData != nil { + t.Errorf("privacy metadata should have been deleted during account suicide") + } +} + +func TestPrivacyMetadataChangesAreRolledBackOnRevert(t *testing.T) { + ethDb := rawdb.NewMemoryDatabase() + stateDb := NewDatabase(ethDb) + state, _ := New(common.Hash{}, stateDb, nil) + + addr := common.Address{1} + state.CreateAccount(addr) + + state.SetNonce(addr, uint64(1)) + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagPartyProtection, + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("one")), + }) + state.Commit(false) + + privMetaData, _ := state.GetCommittedStatePrivacyMetadata(addr) + if privMetaData == nil { + t.Errorf("privacy metadata should have been stored during commit") + } + + // update privacy metadata + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagStateValidation, + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("two")), + }) + + // record the snapshot + snapshot := state.Snapshot() + + privMetaData, _ = state.GetPrivacyMetadata(addr) + if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("two")) { + t.Errorf("current privacy metadata creation tx hash does not match the expected value") + } + + // update the metadata + state.SetPrivacyMetadata(addr, &PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagStateValidation, + CreationTxHash: common.BytesToEncryptedPayloadHash([]byte("three")), + }) + + privMetaData, _ = state.GetPrivacyMetadata(addr) + if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("three")) { + t.Errorf("current privacy metadata creation tx hash does not match the expected value") + } + + // revert to snapshot + state.RevertToSnapshot(snapshot) + + privMetaData, _ = state.GetPrivacyMetadata(addr) + if privMetaData.CreationTxHash != common.BytesToEncryptedPayloadHash([]byte("two")) { + t.Errorf("current privacy metadata creation tx hash does not match the expected value") + } +} + +// End Quorum - Privacy Enhancements diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 1c550fa8bc..701cc32805 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -87,7 +87,11 @@ func precacheTransaction(config *params.ChainConfig, bc ChainContext, author *co } // Create the EVM and execute the transaction context := NewEVMContext(msg, header, bc, author) - vm := vm.NewEVM(context, statedb, config, cfg) + + //only precaching public txs + vm := vm.NewEVM(context, statedb, statedb, config, cfg) + vm.SetCurrentTX(tx) + // /Quorum _, err = ApplyMessage(vm, msg, gaspool) return err diff --git a/core/state_processor.go b/core/state_processor.go index e655d8f3bf..1592ea4ea1 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -20,11 +20,14 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/permission/core" + "github.com/ethereum/go-ethereum/private" ) // StateProcessor is a basic Processor, which takes care of transitioning @@ -53,13 +56,22 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen // Process returns the receipts and logs accumulated during the process and // returns the amount of gas that was used in the process. If any of the // transactions failed to execute due to insufficient gas it will return an error. -func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { +// +// Quorum: Private transactions are handled for the following: +// +// 1. On original single private state (SPS) design +// 2. On multiple private states (MPS) design +// 3. Contract extension callback (p.bc.CheckAndSetPrivateState) +func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, privateStateRepo mps.PrivateStateRepository, cfg vm.Config) (types.Receipts, types.Receipts, []*types.Log, uint64, error) { + var ( receipts types.Receipts usedGas = new(uint64) header = block.Header() allLogs []*types.Log gp = new(GasPool).AddGas(block.GasLimit()) + + privateReceipts types.Receipts ) // Mutate the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { @@ -67,38 +79,183 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } // Iterate over and process the individual transactions for i, tx := range block.Transactions() { + mpsReceipt, err := p.handleMPS(i, tx, block, gp, usedGas, cfg, statedb, privateStateRepo) + if err != nil { + return nil, nil, nil, 0, err + } + // handling transaction in 2 scenarios: + // 1. For MPS, the target private state being applied would be the EmptyPrivateState. + // This must be last to avoid contract address collisions. + // 2. For orignal SPS design, the target private state is the single private state + // + // in both cases, privateStateRepo is responsible to return the appropriate + // private state for execution and a bool flag to enable the privacy execution + privateStateDB, err := privateStateRepo.DefaultState() + if err != nil { + return nil, nil, nil, 0, err + } + privateStateDB.Prepare(tx.Hash(), block.Hash(), i) statedb.Prepare(tx.Hash(), block.Hash(), i) - receipt, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg) + + receipt, privateReceipt, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, privateStateDB, header, tx, usedGas, cfg, privateStateRepo.IsMPS()) if err != nil { - return nil, nil, 0, err + return nil, nil, nil, 0, err } + receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) + + // if the private receipt is nil this means the tx was public + // and we do not need to apply the additional logic. + if privateReceipt != nil { + privateReceipts = append(privateReceipts, privateReceipt) + allLogs = append(allLogs, privateReceipt.Logs...) + p.bc.CheckAndSetPrivateState(privateReceipt.Logs, privateStateDB, privateStateRepo.DefaultStateMetadata().ID) + // handling the auxiliary receipt from MPS execution + if mpsReceipt != nil { + privateReceipt.PSReceipts = mpsReceipt.PSReceipts + allLogs = append(allLogs, mpsReceipt.Logs...) + } + } } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles()) - return receipts, allLogs, *usedGas, nil + return receipts, privateReceipts, allLogs, *usedGas, nil +} + +// Quorum +// returns the privateStateDB to be used for a transaction +func PrivateStateDBForTxn(isQuorum, isPrivate bool, stateDb, privateStateDB *state.StateDB) *state.StateDB { + if !isQuorum || !isPrivate { + return stateDb + } + return privateStateDB +} + +// handling MPS scenario for a private transaction +// +// handleMPS returns the auxiliary receipt and not the standard receipt +func (p *StateProcessor) handleMPS(ti int, tx *types.Transaction, block *types.Block, gp *GasPool, usedGas *uint64, cfg vm.Config, statedb *state.StateDB, privateStateRepo mps.PrivateStateRepository) (mpsReceipt *types.Receipt, err error) { + if tx.IsPrivate() && privateStateRepo.IsMPS() { + publicStateDBFactory := func() *state.StateDB { + db := statedb.Copy() + db.Prepare(tx.Hash(), block.Hash(), ti) + return db + } + privateStateDBFactory := func(psi types.PrivateStateIdentifier) (*state.StateDB, error) { + db, err := privateStateRepo.StatePSI(psi) + if err != nil { + return nil, err + } + db.Prepare(tx.Hash(), block.Hash(), ti) + return db, nil + } + mpsReceipt, err = ApplyTransactionOnMPS(p.config, p.bc, nil, gp, publicStateDBFactory, privateStateDBFactory, block.Header(), tx, usedGas, cfg) + } + return +} + +// ApplyTransactionOnMPS runs the transaction on multiple private states which +// the transaction is designated to. +// +// For each designated private state, the transaction is ran only ONCE. +// +// ApplyTransactionOnMPS returns the auxiliary receipt which is mainly used to capture +// multiple private receipts and logs array. Logs are decorated with types.PrivateStateIdentifier +// +// The originalGP gas pool will not be modified +func ApplyTransactionOnMPS(config *params.ChainConfig, bc *BlockChain, author *common.Address, originalGP *GasPool, + publicStateDBFactory func() *state.StateDB, privateStateDBFactory func(psi types.PrivateStateIdentifier) (*state.StateDB, error), + header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { + // clone the gas pool (as we don't want to keep consuming intrinsic gas multiple times for each MPS execution) + gp := new(GasPool).AddGas(originalGP.Gas()) + mpsReceipt := &types.Receipt{ + PSReceipts: make(map[types.PrivateStateIdentifier]*types.Receipt), + Logs: make([]*types.Log, 0), + } + _, managedParties, _, _, err := private.P.Receive(common.BytesToEncryptedPayloadHash(tx.Data())) + if err != nil { + return nil, err + } + targetPsi := make(map[types.PrivateStateIdentifier]struct{}) + for _, managedParty := range managedParties { + psMetadata, err := bc.PrivateStateManager().ResolveForManagedParty(managedParty) + if err != nil { + return nil, err + } + targetPsi[psMetadata.ID] = struct{}{} + } + // execute in all the managed private states + // TODO this could be enhanced to run in parallel + for _, psi := range bc.PrivateStateManager().PSIs() { + _, applyAsParty := targetPsi[psi] + privateStateDB, err := privateStateDBFactory(psi) + if err != nil { + return nil, err + } + publicStateDB := publicStateDBFactory() + _, receipt, err := ApplyTransaction(config, bc, author, gp, publicStateDB, privateStateDB, header, tx, usedGas, cfg, !applyAsParty) + if err != nil { + return nil, err + } + // set the PSI for each log (so that the filter system knows for what private state they are) + // we don't care about the empty receipt (as we'll execute the transaction on the empty state anyway) + if applyAsParty { + for _, log := range receipt.Logs { + log.PSI = psi + mpsReceipt.Logs = append(mpsReceipt.Logs, log) + } + mpsReceipt.PSReceipts[psi] = receipt + + bc.CheckAndSetPrivateState(receipt.Logs, privateStateDB, psi) + } + } + return mpsReceipt, nil } +// /Quorum + // ApplyTransaction attempts to apply a transaction to the given state database // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) { +func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb, privateStateDB *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, forceNonParty bool) (*types.Receipt, *types.Receipt, error) { + // Quorum - decide the privateStateDB to use + privateStateDbToUse := PrivateStateDBForTxn(config.IsQuorum, tx.IsPrivate(), statedb, privateStateDB) + // /Quorum + + // Quorum - check for account permissions to execute the transaction + if core.IsV2Permission() { + if err := core.CheckAccountPermission(tx.From(), tx.To(), tx.Value(), tx.Data(), tx.Gas(), tx.GasPrice()); err != nil { + return nil, nil, err + } + } + + if config.IsQuorum && tx.GasPrice() != nil && tx.GasPrice().Cmp(common.Big0) > 0 { + return nil, nil, ErrInvalidGasPrice + } + msg, err := tx.AsMessage(types.MakeSigner(config, header.Number)) if err != nil { - return nil, err + return nil, nil, err } + // Quorum: this tx needs to be applied as if we were not a party + msg = msg.WithEmptyPrivateData(forceNonParty && tx.IsPrivate()) // Create a new context to be used in the EVM environment context := NewEVMContext(msg, header, bc, author) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmenv := vm.NewEVM(context, statedb, config, cfg) + vmenv := vm.NewEVM(context, statedb, privateStateDbToUse, config, cfg) + // the same transaction object is used for multiple executions (clear the privacy metadata - it should be updated after privacyManager.receive) + // when running in parallel for multiple private states is implemented - a copy of the tx may be used + tx.SetTxPrivacyMetadata(nil) + vmenv.SetCurrentTX(tx) + // Apply the transaction to the current state (included in the env) result, err := ApplyMessage(vmenv, msg, gp) if err != nil { - return nil, err + return nil, nil, err } // Update the state with pending changes var root []byte @@ -109,9 +266,13 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo } *usedGas += result.UsedGas + // If this is a private transaction, the public receipt should always + // indicate success. + publicFailed := !(config.IsQuorum && tx.IsPrivate()) && result.Failed() + // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx - // based on the eip phase, we're passing whether the root touch-delete accounts. - receipt := types.NewReceipt(root, result.Failed(), *usedGas) + // based on the eip phase, we're passing wether the root touch-delete accounts. + receipt := types.NewReceipt(root, publicFailed, *usedGas) receipt.TxHash = tx.Hash() receipt.GasUsed = result.UsedGas // if the transaction created a contract, store the creation address in the receipt. @@ -125,5 +286,24 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo receipt.BlockNumber = header.Number receipt.TransactionIndex = uint(statedb.TxIndex()) - return receipt, err + var privateReceipt *types.Receipt + if config.IsQuorum && tx.IsPrivate() { + var privateRoot []byte + if config.IsByzantium(header.Number) { + privateStateDB.Finalise(true) + } else { + privateRoot = privateStateDB.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() + } + privateReceipt = types.NewReceipt(privateRoot, result.Failed(), *usedGas) + privateReceipt.TxHash = tx.Hash() + privateReceipt.GasUsed = result.UsedGas + if msg.To() == nil { + privateReceipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) + } + + privateReceipt.Logs = privateStateDB.GetLogs(tx.Hash()) + privateReceipt.Bloom = types.CreateBloom(types.Receipts{privateReceipt}) + } + + return receipt, privateReceipt, err } diff --git a/core/state_transition.go b/core/state_transition.go index 9a9bf475e9..93a78d6ac0 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -17,12 +17,18 @@ package core import ( + "errors" "math" "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/multitenancy" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/private" ) /* @@ -103,6 +109,12 @@ func (result *ExecutionResult) Revert() []byte { return common.CopyBytes(result.ReturnData) } +// PrivateMessage implements a private message +type PrivateMessage interface { + Message + IsPrivate() bool +} + // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. func IntrinsicGas(data []byte, contractCreation, isHomestead bool, isEIP2028 bool) (uint64, error) { // Set the starting gas for the raw transaction @@ -149,7 +161,7 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition gasPrice: msg.GasPrice(), value: msg.Value(), data: msg.Data(), - state: evm.StateDB, + state: evm.PublicState(), } } @@ -160,6 +172,7 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition // the gas used (which includes gas refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. + func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (*ExecutionResult, error) { return NewStateTransition(evm, msg, gp).TransitionDb() } @@ -213,6 +226,15 @@ func (st *StateTransition) preCheck() error { // // However if any consensus issue encountered, return the error directly with // nil evm execution result. +// +// Quorum: +// 1. Intrinsic gas is calculated based on the encrypted payload hash +// and NOT the actual private payload +// 2. For private transactions, we only deduct intrinsic gas from the gas pool +// regardless the current node is party to the transaction or not +// 3. With multitenancy support, we enforce the party set in the contract index must contain all +// parties from the transaction. This is to detect unauthorized access from a legit proxy contract +// to an unauthorized contract. func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { // First check this message satisfies all consensus rules before // applying the message. The rules include these clauses @@ -225,7 +247,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { // 6. caller has enough balance to cover asset transfer for **topmost** call // Check clauses 1-3, buy gas if everything is correct - if err := st.preCheck(); err != nil { + var err error + if err = st.preCheck(); err != nil { return nil, err } msg := st.msg @@ -233,7 +256,49 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber) istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.BlockNumber) contractCreation := msg.To() == nil + isQuorum := st.evm.ChainConfig().IsQuorum + snapshot := st.evm.StateDB.Snapshot() + + var data []byte + isPrivate := false + publicState := st.state + pmh := newPMH(st) + if msg, ok := msg.(PrivateMessage); ok && isQuorum && msg.IsPrivate() { + isPrivate = true + pmh.snapshot = snapshot + pmh.eph = common.BytesToEncryptedPayloadHash(st.data) + _, _, data, pmh.receivedPrivacyMetadata, err = private.P.Receive(pmh.eph) + // Increment the public account nonce if: + // 1. Tx is private and *not* a participant of the group and either call or create + // 2. Tx is private we are part of the group and is a call + if err != nil || !contractCreation { + publicState.SetNonce(sender.Address(), publicState.GetNonce(sender.Address())+1) + } + if err != nil { + return &ExecutionResult{ + UsedGas: 0, + Err: nil, + ReturnData: nil, + }, nil + } + + pmh.hasPrivatePayload = data != nil + + vmErr, consensusErr := pmh.prepare() + if consensusErr != nil || vmErr != nil { + return &ExecutionResult{ + UsedGas: 0, + Err: vmErr, + ReturnData: nil, + }, consensusErr + } + } else { + data = st.data + } + // Pay intrinsic gas. For a private contract this is done using the public hash passed in, + // not the private data retrieved above. This is because we need any (participant) validator + // node to get the same result as a (non-participant) minter node, to avoid out-of-gas issues. // Check clauses 4-5, subtract intrinsic gas if everything is correct gas, err := IntrinsicGas(st.data, contractCreation, homestead, istanbul) if err != nil { @@ -249,19 +314,91 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { return nil, ErrInsufficientFundsForTransfer } var ( - ret []byte - vmerr error // vm errors do not effect consensus and are therefore not assigned to err + leftoverGas uint64 + evm = st.evm + ret []byte + // vm errors do not effect consensus and are therefor + // not assigned to err, except for insufficient balance + // error. + vmerr error ) if contractCreation { - ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value) + ret, _, leftoverGas, vmerr = evm.Create(sender, data, st.gas, st.value) } else { - // Increment the nonce for the next transaction - st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) - ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value) + // Increment the account nonce only if the transaction isn't private. + // If the transaction is private it has already been incremented on + // the public state. + if !isPrivate { + publicState.SetNonce(msg.From(), publicState.GetNonce(sender.Address())+1) + } + var to common.Address + if isQuorum { + to = *st.msg.To() + } else { + to = st.to() + } + //if input is empty for the smart contract call, return + if len(data) == 0 && isPrivate { + st.refundGas() + st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) + return &ExecutionResult{ + UsedGas: 0, + Err: nil, + ReturnData: nil, + }, nil + } + + ret, leftoverGas, vmerr = evm.Call(sender, to, data, st.gas, st.value) } + if vmerr != nil { + log.Info("VM returned with error", "err", vmerr) + // The only possible consensus-error would be if there wasn't + // sufficient balance to make the transfer happen. The first + // balance transfer may never fail. + if vmerr == vm.ErrInsufficientBalance { + return nil, vmerr + } + if errors.Is(vmerr, multitenancy.ErrNotAuthorized) { + return nil, vmerr + } + } + + // Quorum - Privacy Enhancements + // perform privacy enhancements checks + if pmh.mustVerify() { + var exitEarly bool + exitEarly, err = pmh.verify(vmerr) + if exitEarly { + return &ExecutionResult{ + UsedGas: 0, + Err: ErrPrivateContractInteractionVerificationFailed, + ReturnData: nil, + }, err + } + } + // End Quorum - Privacy Enhancements + + // Pay gas used during contract creation or execution (st.gas tracks remaining gas) + // However, if private contract then we don't want to do this else we can get + // a mismatch between a (non-participant) minter and (participant) validator, + // which can cause a 'BAD BLOCK' crash. + if !isPrivate { + st.gas = leftoverGas + } + // End Quorum + st.refundGas() st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice)) + if isPrivate { + return &ExecutionResult{ + UsedGas: 0, + Err: vmerr, + ReturnData: ret, + }, err + } + // End Quorum + return &ExecutionResult{ UsedGas: st.gasUsed(), Err: vmerr, @@ -290,3 +427,25 @@ func (st *StateTransition) refundGas() { func (st *StateTransition) gasUsed() uint64 { return st.initialGas - st.gas } + +// Quorum - Privacy Enhancements - implement the pmcStateTransitionAPI interface +func (st *StateTransition) SetTxPrivacyMetadata(pm *types.PrivacyMetadata) { + st.evm.SetTxPrivacyMetadata(pm) +} +func (st *StateTransition) IsPrivacyEnhancementsEnabled() bool { + return st.evm.ChainConfig().IsPrivacyEnhancementsEnabled(st.evm.BlockNumber) +} +func (st *StateTransition) RevertToSnapshot(snapshot int) { + st.evm.StateDB.RevertToSnapshot(snapshot) +} +func (st *StateTransition) GetStatePrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { + return st.evm.StateDB.GetPrivacyMetadata(addr) +} +func (st *StateTransition) CalculateMerkleRoot() (common.Hash, error) { + return st.evm.CalculateMerkleRoot() +} +func (st *StateTransition) AffectedContracts() []common.Address { + return st.evm.AffectedContracts() +} + +// End Quorum - Privacy Enhancements diff --git a/core/state_transition_pmh.go b/core/state_transition_pmh.go new file mode 100644 index 0000000000..d7a0079ba4 --- /dev/null +++ b/core/state_transition_pmh.go @@ -0,0 +1,136 @@ +package core + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private/engine" +) + +type pmcStateTransitionAPI interface { + SetTxPrivacyMetadata(pm *types.PrivacyMetadata) + IsPrivacyEnhancementsEnabled() bool + RevertToSnapshot(int) + GetStatePrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) + CalculateMerkleRoot() (common.Hash, error) + AffectedContracts() []common.Address +} + +func newPMH(st pmcStateTransitionAPI) *privateMessageHandler { + return &privateMessageHandler{stAPI: st} +} + +type privateMessageHandler struct { + stAPI pmcStateTransitionAPI + + hasPrivatePayload bool + + snapshot int + receivedPrivacyMetadata *engine.ExtraMetadata + eph common.EncryptedPayloadHash +} + +func (pmh *privateMessageHandler) mustVerify() bool { + return pmh.hasPrivatePayload && pmh.receivedPrivacyMetadata != nil && pmh.stAPI.IsPrivacyEnhancementsEnabled() +} + +// checks the privacy metadata in the state transition context +// returns vmError if there is an error in the EVM execution +// returns consensusErr if there is an error in the consensus execution +func (pmh *privateMessageHandler) prepare() (vmError, consensusErr error) { + if pmh.receivedPrivacyMetadata != nil { + if !pmh.stAPI.IsPrivacyEnhancementsEnabled() && pmh.receivedPrivacyMetadata.PrivacyFlag.IsNotStandardPrivate() { + // This situation is only possible if the current node has been upgraded (both quorum and tessera) yet the + // node did not apply the privacyEnhancementsBlock configuration (with a network agreed block height). + // Since this would be considered node misconfiguration the behavior should be changed to return an error + // which would then cause the node not to apply the block (and potentially get stuck and not be able to + // continue to apply new blocks). The resolution should then be to revert to an appropriate block height and + // run geth init with the network agreed privacyEnhancementsBlock. + // The prepare method signature has been changed to allow returning the relevant error. + return ErrPrivacyEnhancedReceivedWhenDisabled, fmt.Errorf("Privacy enhanced transaction received while privacy enhancements are disabled."+ + " Please check your node configuration. EPH=%s", pmh.eph.ToBase64()) + } + + if pmh.receivedPrivacyMetadata.PrivacyFlag == engine.PrivacyFlagStateValidation && common.EmptyHash(pmh.receivedPrivacyMetadata.ACMerkleRoot) { + log.Error(ErrPrivacyMetadataInvalidMerkleRoot.Error()) + return ErrPrivacyMetadataInvalidMerkleRoot, nil + } + privMetadata := types.NewTxPrivacyMetadata(pmh.receivedPrivacyMetadata.PrivacyFlag) + pmh.stAPI.SetTxPrivacyMetadata(privMetadata) + } + return nil, nil +} + +//If the list of affected CA Transactions by the time evm executes is different from the list of affected contract transactions returned from Tessera +//an Error should be thrown and the state should not be updated +//This validation is to prevent cases where the list of affected contract will have changed by the time the evm actually executes transaction +// failed = true will make sure receipt is marked as "failure" +// return error will crash the node and only use when that's the case +func (pmh *privateMessageHandler) verify(vmerr error) (bool, error) { + // convenient function to return error. It has the same signature as the main function + returnErrorFunc := func(anError error, logMsg string, ctx ...interface{}) (exitEarly bool, err error) { + if logMsg != "" { + log.Debug(logMsg, ctx...) + } + pmh.stAPI.RevertToSnapshot(pmh.snapshot) + exitEarly = true + if anError != nil { + err = fmt.Errorf("vmerr=%s, err=%s", vmerr, anError) + } + return + } + actualACAddresses := pmh.stAPI.AffectedContracts() + log.Trace("Verify hashes of affected contracts", "expectedHashes", pmh.receivedPrivacyMetadata.ACHashes, "numberOfAffectedAddresses", len(actualACAddresses)) + privacyFlag := pmh.receivedPrivacyMetadata.PrivacyFlag + for _, addr := range actualACAddresses { + // GetPrivacyMetadata is invoked on the privateState (as the tx is private) and it returns: + // 1. public contacts: privacyMetadata = nil, err = nil + // 2. private contracts of type: + // 2.1. StandardPrivate: privacyMetadata = nil, err = "The provided contract does not have privacy metadata" + // 2.2. PartyProtection/PSV: privacyMetadata = , err = nil + actualPrivacyMetadata, err := pmh.stAPI.GetStatePrivacyMetadata(addr) + //when privacyMetadata should have been recovered but wasnt (includes non-party) + //non party will only be caught here if sender provides privacyFlag + if err != nil && privacyFlag.IsNotStandardPrivate() { + return returnErrorFunc(nil, "Unable to find PrivacyMetadata for affected contract", "err", err, "addr", addr.Hex()) + } + log.Trace("Privacy metadata", "affectedAddress", addr.Hex(), "metadata", actualPrivacyMetadata) + // both public and standard private contracts will be nil and can be skipped in acoth check + // public contracts - evm error for write, no error for reads + // standard private - only error if privacyFlag sent with tx or if no flag sent but other affecteds have privacyFlag + if actualPrivacyMetadata == nil { + continue + } + // Check that the affected contracts privacy flag matches the transaction privacy flag. + // I know that this is also checked by tessera, but it only checks for non standard private transactions. + if actualPrivacyMetadata.PrivacyFlag != pmh.receivedPrivacyMetadata.PrivacyFlag { + return returnErrorFunc(nil, "Mismatched privacy flags", + "affectedContract.Address", addr.Hex(), + "affectedContract.PrivacyFlag", actualPrivacyMetadata.PrivacyFlag, + "received.PrivacyFlag", pmh.receivedPrivacyMetadata.PrivacyFlag) + } + // acoth check - case where node isn't privy to one of actual affecteds + if pmh.receivedPrivacyMetadata.ACHashes.NotExist(actualPrivacyMetadata.CreationTxHash) { + return returnErrorFunc(nil, "Participation check failed", + "affectedContractAddress", addr.Hex(), + "missingCreationTxHash", actualPrivacyMetadata.CreationTxHash.Hex()) + } + } + + // check the psv merkle root comparison - for both creation and msg calls + if !common.EmptyHash(pmh.receivedPrivacyMetadata.ACMerkleRoot) { + log.Trace("Verify merkle root", "merkleRoot", pmh.receivedPrivacyMetadata.ACMerkleRoot) + actualACMerkleRoot, err := pmh.stAPI.CalculateMerkleRoot() + if err != nil { + return returnErrorFunc(err, "") + } + if actualACMerkleRoot != pmh.receivedPrivacyMetadata.ACMerkleRoot { + return returnErrorFunc(nil, "Merkle Root check failed", "actual", actualACMerkleRoot, + "expect", pmh.receivedPrivacyMetadata.ACMerkleRoot) + } + } + return false, nil +} diff --git a/core/state_transition_pmh_test.go b/core/state_transition_pmh_test.go new file mode 100644 index 0000000000..34cfd2e164 --- /dev/null +++ b/core/state_transition_pmh_test.go @@ -0,0 +1,53 @@ +package core + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/private/engine" + testifyassert "github.com/stretchr/testify/assert" +) + +type stubPmhStateTransition struct { + snapshot int +} + +func (s *stubPmhStateTransition) SetTxPrivacyMetadata(pm *types.PrivacyMetadata) { +} + +func (s *stubPmhStateTransition) IsPrivacyEnhancementsEnabled() bool { + return true +} + +func (s *stubPmhStateTransition) RevertToSnapshot(val int) { + s.snapshot = val +} + +func (s *stubPmhStateTransition) GetStatePrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { + return &state.PrivacyMetadata{PrivacyFlag: engine.PrivacyFlagStateValidation, CreationTxHash: common.EncryptedPayloadHash{1}}, nil +} + +func (s *stubPmhStateTransition) CalculateMerkleRoot() (common.Hash, error) { + return common.Hash{}, fmt.Errorf("Unable to calculate MerkleRoot") +} + +func (s *stubPmhStateTransition) AffectedContracts() []common.Address { + return make([]common.Address, 0) +} + +func TestPrivateMessageContextVerify_WithMerkleRootCreationError(t *testing.T) { + assert := testifyassert.New(t) + stateTransitionAPI := &stubPmhStateTransition{} + + pmc := newPMH(stateTransitionAPI) + pmc.receivedPrivacyMetadata = &engine.ExtraMetadata{ACMerkleRoot: common.Hash{1}, PrivacyFlag: engine.PrivacyFlagStateValidation} + pmc.snapshot = 10 + exitEarly, err := pmc.verify(nil) + + assert.Error(err, "verify must return an error due to the MerkleRoot calculation error") + assert.Equal(pmc.snapshot, stateTransitionAPI.snapshot, "Revert should have been called") + assert.True(exitEarly, "Exit early should be true") +} diff --git a/core/state_transition_test.go b/core/state_transition_test.go new file mode 100644 index 0000000000..8c8e9a89f2 --- /dev/null +++ b/core/state_transition_test.go @@ -0,0 +1,1363 @@ +package core + +import ( + "fmt" + "math/big" + "os" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" + "github.com/ethereum/go-ethereum/private/engine/notinuse" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + testifyassert "github.com/stretchr/testify/assert" +) + +var ( + c1 = &contract{ + name: "c1", + abi: mustParse(c1AbiDefinition), + bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806105a88339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610550806100586000396000f3fe608060405260043610610051576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100565780636d4ce63c146100a5578063d7139463146100d0575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b810190808035906020019092919050505061010b565b6040518082815260200191505060405180910390f35b3480156100b157600080fd5b506100ba61011e565b6040518082815260200191505060405180910390f35b3480156100dc57600080fd5b50610109600480360360208110156100f357600080fd5b8101908080359060200190929190505050610127565b005b6000816000819055506000549050919050565b60008054905090565b600030610132610212565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015610184573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff166360fe47b1836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156101f657600080fd5b505af115801561020a573d6000803e3d6000fd5b505050505050565b604051610302806102238339019056fe608060405234801561001057600080fd5b506040516020806103028339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610271806100916000396000f3fe608060405260043610610046576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b11461004b5780636d4ce63c14610086575b600080fd5b34801561005757600080fd5b506100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100b1565b005b34801561009257600080fd5b5061009b610180565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561014157600080fd5b505af1158015610155573d6000803e3d6000fd5b505050506040513d602081101561016b57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561020557600080fd5b505afa158015610219573d6000803e3d6000fd5b505050506040513d602081101561022f57600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820a537f4c360ce5c6f55523298e314e6456e5c3e02c170563751dfda37d3aeddb30029a165627a7a7230582060396bfff29d2dfc5a9f4216bfba5e24d031d54fd4b26ebebde1a26c59df0c1e0029"), + } + c2 = &contract{ + name: "c2", + abi: mustParse(c2AbiDefinition), + bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806102f58339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610264806100916000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100585780636d4ce63c14610086575b600080fd5b6100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100a4565b005b61008e610173565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561013457600080fd5b505af1158015610148573d6000803e3d6000fd5b505050506040513d602081101561015e57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156101f857600080fd5b505afa15801561020c573d6000803e3d6000fd5b505050506040513d602081101561022257600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820dd8a5dcf693e1969289c444a282d0684a9760bac26f1e4e0139d46821ec1979b0029"), + } + + // exec hash helper vars (accounts/tries) + signingAddress = common.StringToAddress("contract") + + c1AccAddress = crypto.CreateAddress(signingAddress, 0) + c2AccAddress = crypto.CreateAddress(signingAddress, 1) + + // this is used as the field key in account storage (which is the index/sequence of the field in the contract) + // both contracts have only one field (c1 - has the value while c2 has c1's address) + // For more info please see: https://solidity.readthedocs.io/en/v0.6.8/internals/layout_in_storage.html + firstFieldKey = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") + + val42 = common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000002A") + val53 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000035") + valC1Address = append(common.Hex2Bytes("000000000000000000000000"), c1AccAddress.Bytes()...) + + // this is the contract storage trie after storing value 42 + c1StorageTrieWithValue42 = secureTrieWithStoredValue(firstFieldKey, val42) + c1StorageTrieWithValue53 = secureTrieWithStoredValue(firstFieldKey, val53) + c2StorageTrieWithC1Address = secureTrieWithStoredValue(firstFieldKey, valC1Address) + + // The contract bytecode above includes the constructor bytecode (which is removed by the EVM before storing the + // contract bytecode) thus it can't be used to calculate the code hash for the contract. + // Below we deploy both of them as public contracts and extract the resulting codeHashes from the public state. + c1CodeHash, c2CodeHash = contractCodeHashes() + + c1AccountWithValue42Stored = &state.Account{Nonce: 1, Balance: big.NewInt(0), Root: c1StorageTrieWithValue42.Hash(), CodeHash: c1CodeHash.Bytes()} + c1AccountWithValue53Stored = &state.Account{Nonce: 1, Balance: big.NewInt(0), Root: c1StorageTrieWithValue53.Hash(), CodeHash: c1CodeHash.Bytes()} + c2AccountWithC1AddressStored = &state.Account{Nonce: 1, Balance: big.NewInt(0), Root: c2StorageTrieWithC1Address.Hash(), CodeHash: c2CodeHash.Bytes()} +) + +type contract struct { + abi abi.ABI + bytecode []byte + name string +} + +func (c *contract) create(args ...interface{}) []byte { + bytes, err := c.abi.Pack("", args...) + if err != nil { + panic("can't pack: " + err.Error()) + } + return append(c.bytecode, bytes...) +} + +func (c *contract) set(value int64) []byte { + bytes, err := c.abi.Pack("set", big.NewInt(value)) + if err != nil { + panic("can't pack: " + err.Error()) + } + return bytes +} + +func (c *contract) get() []byte { + bytes, err := c.abi.Pack("get") + if err != nil { + panic("can't pack: " + err.Error()) + } + return bytes +} + +func init() { + log.PrintOrigins(true) + log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) +} + +func secureTrieWithStoredValue(key []byte, value []byte) *trie.SecureTrie { + res, _ := trie.NewSecure(common.Hash{}, trie.NewDatabase(rawdb.NewMemoryDatabase())) + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(value[:])) + res.Update(key, v) + return res +} + +func contractCodeHashes() (c1CodeHash common.Hash, c2CodeHash common.Hash) { + assert := testifyassert.New(nil) + cfg := newConfig() + + // create public c1 + cfg.setData(c1.create(big.NewInt(42))) + c1Address := createPublicContract(cfg, assert, c1) + c1CodeHash = cfg.publicState.GetCodeHash(c1Address) + + // create public c2 + cfg.setNonce(1) + cfg.setData(c2.create(c1Address)) + c2Address := createPublicContract(cfg, assert, c2) + c2CodeHash = cfg.publicState.GetCodeHash(c2Address) + + return +} + +func TestApplyMessage_Private_whenTypicalCreate_Success(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + + // calling C1.Create standard private + cfg := newConfig(). + setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData([]byte("arbitrary encrypted payload hash")) + gp := new(GasPool).AddGas(math.MaxUint64) + privateMsg := newTypicalPrivateMessage(cfg) + + //since standard private create only get back PrivacyFlag + mockPM.When("Receive").Return(c1.create(big.NewInt(42)), &engine.ExtraMetadata{ + PrivacyFlag: engine.PrivacyFlagStandardPrivate, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, gp) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenCreatePartyProtectionC1_Success(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + + // calling C1.Create party protection + cfg := newConfig(). + setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary encrypted payload hash")) + gp := new(GasPool).AddGas(math.MaxUint64) + privateMsg := newTypicalPrivateMessage(cfg) + + //since party protection create only get back privacyFlag + mockPM.When("Receive").Return(c1.create(big.NewInt(42)), &engine.ExtraMetadata{ + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, gp) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenCreatePartyProtectionC1WithPrivacyEnhancementsDisabledReturnsError(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + + // calling C1.Create party protection + cfg := newConfig(). + setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary encrypted payload hash")) + + gp := new(GasPool).AddGas(math.MaxUint64) + privateMsg := newTypicalPrivateMessage(cfg) + + //since party protection create only get back privacyFlag + mockPM.When("Receive").Return(c1.create(big.NewInt(42)), &engine.ExtraMetadata{ + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + evm := newEVM(cfg) + evm.ChainConfig().PrivacyEnhancementsBlock = nil + result, err := ApplyMessage(evm, privateMsg, gp) + + assert.Error(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + // check that there is no privacy metadata for the newly created contract + assert.Len(evm.CreatedContracts(), 0, "no contracts created") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenInteractWithPartyProtectionC1_Success(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + //create party protection c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // calling C1.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(1). + setTo(c1Address) + privateMsg := newTypicalPrivateMessage(cfg) + //since party protection need ACHashes and PrivacyFlag + mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenInteractWithStateValidationC1_Success(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + //create state validation c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData(c1EncPayloadHash) + cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored}) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // calling C1.Set() state validation + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData([]byte("arbitrary enc payload hash")). + setNonce(1). + setTo(c1Address) + privateMsg := newTypicalPrivateMessage(cfg) + mr, _ := calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue53Stored}) + //since state validation need ACHashes, MerkleRoot and PrivacyFlag + mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagStateValidation, + ACMerkleRoot: mr, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenInteractWithStateValidationC1WithEmptyMRFromTessera_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create state validation c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData(c1EncPayloadHash) + cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored}) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // calling C1.Set() state validation + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData([]byte("arbitrary enc payload hash")). + setNonce(1). + setTo(c1Address) + privateMsg := newTypicalPrivateMessage(cfg) + // since state validation need ACHashes, privacyFlag, MerkleRoot + mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagStateValidation, + ACMerkleRoot: common.Hash{}, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenInteractWithStateValidationC1WithWrongMRFromTessera_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + //create state validation c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData(c1EncPayloadHash) + cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored}) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // calling C1.Set() state validation + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData([]byte("arbitrary enc payload hash")). + setNonce(1). + setTo(c1Address) + privateMsg := newTypicalPrivateMessage(cfg) + //since state validation need ACHashes, PrivacyFlag, MerkleRoot + mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagStateValidation, + ACMerkleRoot: common.Hash{123}, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +//Limitation of design --if don't send privacyFlag can't be guaranteed to catch non-party +//review this... +func TestApplyMessage_Private_whenNonPartyTriesInteractingWithPartyProtectionC1_NoFlag_Succeed(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + //act like doesnt exist on non-party node + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // calling C1.Set() + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData([]byte("arbitrary enc payload hash")). + setNonce(1). + setTo(c1Address) + privateMsg := newTypicalPrivateMessage(cfg) + //will have no ACHashes because when non-party sends tx, because no flag it doesn't generate privacyMetadata info + //actual execution will find affected contract, but non-party won't have info + mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{}, + PrivacyFlag: engine.PrivacyFlagStandardPrivate, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenNonPartyTriesInteractingWithPartyProtectionC1_WithFlag_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + //act like doesnt exist on non-party node + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // calling C1.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData([]byte("arbitrary enc payload hash")). + setNonce(1). + setTo(c1Address) + privateMsg := newTypicalPrivateMessage(cfg) + mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +// C1 is a existing contract before privacy enhancements implementation +func TestApplyMessage_Private_whenPartyProtectionC2InteractsExistingStandardPrivateC1_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create c1 like c1 already exist before privacy enhancements + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(math.MaxUint64). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create party protection c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + // since party protection need ACHashes (only private non standard) and PrivacyFlag + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenPartyProtectionC2InteractsNewStandardPrivateC1_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create default standard private c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create party protection c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + // since party protection need ACHashes (only private non standard) and PrivacyFlag + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenPartyProtectionC2InteractsWithPartyProtectionC1_Succeed(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create party protection c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create party protection c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + // since party protection need ACHashes and PrivacyFlag + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +//scenario where sender Q1 runs simulation which affects c2 and c1 privy for Q3 and Q7 +//Q3 receives block but wasn't privy to C1 so doesn't have creation info in tessera +func TestApplyMessage_Private_whenPartyProtectionC2AndC1ButMissingC1CreationInTessera_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create c1 as a party protection + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create party protection c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + // since party protection need ACHashes and PrivacyFlag + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +//scenario where the simulation is run on the Q1 (privatefor Q3 and Q7) and 3 contracts are affected (C2,C1,C0) +//but now Q3 receives block and should be privy to all 3 given tessera response +//but doesn't have C0 privacyMetadata stored in its db +// UPDATE - after relaxing the ACOTH checks this is a valid scenario where C0 acoth is ignored if it isn't detected as an +// affected contract during transaction execution +func TestApplyMessage_Private_whenPartyProtectionC2AndC1AndC0ButMissingC0InStateDB_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create party protection c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create party protection c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + c3EncPayloadHash := []byte("c3") + // calling C2.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + // since party protection need ACHashes and PrivacyFlag + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + common.BytesToEncryptedPayloadHash(c3EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + // after ACOTH check updates this is a successful scenario + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenStateValidationC2InteractsWithStateValidationC1_Succeed(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create party protection c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData(c1EncPayloadHash) + cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored}) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create state validation c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData(c2EncPayloadHash). + setNonce(1) + cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored}) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() state validation + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + + stuff := crypto.Keccak256Hash(c2.bytecode) + log.Trace("stuff", "c2code", stuff[:]) + + privateMsg := newTypicalPrivateMessage(cfg) + mr, _ := calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue53Stored}, accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored}) + //since state validation need ACHashes, PrivacyFlag & MerkleRoot + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagStateValidation, + ACMerkleRoot: mr, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenStateValidationC2InteractsWithPartyProtectionC1_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create party protection c1 + c1EncPayloadHash := []byte("c1") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c1EncPayloadHash) + c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42)) + + // create state validation c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData(c2EncPayloadHash). + setNonce(1) + cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored}) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() state validation + cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + // use the correctly calculated MR so that it can't be a source of false positives + mr, _ := calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue53Stored}, accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored}) + //since state validation need ACHashes, PrivacyFlag & MerkleRoot + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagStateValidation, + ACMerkleRoot: mr, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenStandardPrivateC2InteractsWithPublicC1_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create public c1 + cfg.setData(c1.create(big.NewInt(42))) + c1Address := createPublicContract(cfg, assert, c1) + + // create standard private c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() standard private + cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + //since standard private call no ACHashes, no MerkleRoot + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{}, + PrivacyFlag: engine.PrivacyFlagStandardPrivate, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenPartyProtectionC2InteractsWithPublicC1_Fail(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + cfg := newConfig() + + // create public c1 + cfg.setData(c1.create(big.NewInt(42))) + c1Address := createPublicContract(cfg, assert, c1) + + // create party protection c2 + c2EncPayloadHash := []byte("c2") + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData(c2EncPayloadHash). + setNonce(1) + c2Address := createContract(cfg, mockPM, assert, c2, c1Address) + + // calling C2.Set() party protection + cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection). + setData([]byte("arbitrary enc payload hash")). + setNonce(2). + setTo(c2Address) + privateMsg := newTypicalPrivateMessage(cfg) + mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{ + ACHashes: common.EncryptedPayloadHashes{ + common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{}, + }, + PrivacyFlag: engine.PrivacyFlagPartyProtection, + }, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "EVM execution") + assert.True(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenTxManagerReturnsError_Success(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + + // calling C1.Create standard private + cfg := newConfig(). + setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData([]byte("arbitrary encrypted payload hash")) + gp := new(GasPool).AddGas(math.MaxUint64) + privateMsg := newTypicalPrivateMessage(cfg) + + //since standard private create only get back PrivacyFlag + mockPM.When("Receive").Return(nil, nil, fmt.Errorf("Error during receive")) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, gp) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func TestApplyMessage_Private_whenTxManagerReturnsEmptyResult_Success(t *testing.T) { + originalP := private.P + defer func() { private.P = originalP }() + mockPM := newMockPrivateTransactionManager() + private.P = mockPM + assert := testifyassert.New(t) + + // calling C1.Create standard private + cfg := newConfig(). + setPrivacyFlag(engine.PrivacyFlagStandardPrivate). + setData([]byte("arbitrary encrypted payload hash")) + gp := new(GasPool).AddGas(math.MaxUint64) + privateMsg := newTypicalPrivateMessage(cfg) + + //since standard private create only get back PrivacyFlag + mockPM.When("Receive").Return(nil, nil, nil) + + result, err := ApplyMessage(newEVM(cfg), privateMsg, gp) + + assert.NoError(err, "EVM execution") + assert.False(result.Failed(), "Transaction receipt status") + mockPM.Verify(assert) +} + +func createContract(cfg *config, mockPM *mockPrivateTransactionManager, assert *testifyassert.Assertions, c *contract, args ...interface{}) common.Address { + defer mockPM.reset() + + privateMsg := newTypicalPrivateMessage(cfg) + metadata := &engine.ExtraMetadata{} + if cfg.privacyFlag < math.MaxUint64 { + metadata.PrivacyFlag = cfg.privacyFlag + if metadata.PrivacyFlag == engine.PrivacyFlagStateValidation { + metadata.ACMerkleRoot = cfg.acMerkleRoot + } + } + mockPM.When("Receive").Return(c.create(args...), metadata, nil) + + evm := newEVM(cfg) + result, err := ApplyMessage(evm, privateMsg, new(GasPool).AddGas(math.MaxUint64)) + + assert.NoError(err, "%s: EVM execution", c.name) + assert.False(result.Failed(), "%s: Transaction receipt status", c.name) + mockPM.Verify(assert) + createdContracts := evm.CreatedContracts() + log.Trace("priv statedb", "evmstatedb", evm.StateDB) + assert.Len(createdContracts, 1, "%s: Number of created contracts", c.name) + address := createdContracts[0] + log.Debug("Created "+c.name, "address", address) + return address +} + +func createPublicContract(cfg *config, assert *testifyassert.Assertions, c *contract) common.Address { + pubcfg := cfg.setPublicToPrivateState() + msg := newTypicalPublicMessage(pubcfg) + + evm := newEVM(pubcfg) + result, err := ApplyMessage(evm, msg, new(GasPool).AddGas(math.MaxUint64)) + assert.NoError(err, "%s: EVM execution", c.name) + assert.False(result.Failed(), "%s: Transaction receipt status", c.name) + createdContracts := evm.CreatedContracts() + log.Trace("pub statedb", "evmstatedb", evm.StateDB) + assert.Len(createdContracts, 1, "%s: Number of created contracts", c.name) + address := createdContracts[0] + log.Debug("Created "+c.name, "address", address) + return address +} + +func newTypicalPrivateMessage(cfg *config) PrivateMessage { + var tx *types.Transaction + if cfg.to == nil { + tx = types.NewContractCreation(cfg.nonce, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data) + } else { + tx = types.NewTransaction(cfg.nonce, *cfg.to, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data) + } + tx.SetPrivate() + if cfg.privacyFlag < math.MaxUint64 { + tx.SetTxPrivacyMetadata(&types.PrivacyMetadata{ + PrivacyFlag: cfg.privacyFlag, + }) + } else { + tx.SetTxPrivacyMetadata(nil) // simulate standard private transaction + } + msg, err := tx.AsMessage(&stubSigner{}) + if err != nil { + panic(fmt.Sprintf("can't create a new private message: %s", err)) + } + cfg.currentTx = tx + return PrivateMessage(msg) +} + +func newTypicalPublicMessage(cfg *config) Message { + var tx *types.Transaction + if cfg.to == nil { + tx = types.NewContractCreation(cfg.nonce, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data) + } else { + tx = types.NewTransaction(cfg.nonce, *cfg.to, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data) + } + tx.SetTxPrivacyMetadata(nil) + msg, err := tx.AsMessage(&stubSigner{}) + if err != nil { + panic(fmt.Sprintf("can't create a new private message: %s", err)) + } + cfg.currentTx = tx + return msg +} + +type accEntry struct { + address common.Address + account *state.Account +} + +func calcAccMR(entries ...accEntry) (common.Hash, error) { + combined := new(trie.Trie) + for _, entry := range entries { + data, err := rlp.EncodeToBytes(entry.account) + if err != nil { + return common.Hash{}, err + } + if err = combined.TryUpdate(entry.address.Bytes(), data); err != nil { + return common.Hash{}, err + } + } + return combined.Hash(), nil +} + +type config struct { + from common.Address + to *common.Address + data []byte + nonce uint64 + + privacyFlag engine.PrivacyFlagType + acMerkleRoot common.Hash + + currentTx *types.Transaction + + publicState, privateState *state.StateDB +} + +func newConfig() *config { + pubDatabase := rawdb.NewMemoryDatabase() + privDatabase := rawdb.NewMemoryDatabase() + publicState, _ := state.New(common.Hash{}, state.NewDatabase(pubDatabase), nil) + privateState, _ := state.New(common.Hash{}, state.NewDatabase(privDatabase), nil) + return &config{ + privateState: privateState, + publicState: publicState, + } +} + +func (cfg config) setPublicToPrivateState() *config { + cfg.privateState = cfg.publicState + return &cfg +} + +func (cfg *config) setPrivacyFlag(f engine.PrivacyFlagType) *config { + cfg.privacyFlag = f + return cfg +} + +func (cfg *config) setData(bytes []byte) *config { + cfg.data = bytes + return cfg +} + +func (cfg *config) setNonce(n uint64) *config { + cfg.nonce = n + return cfg +} + +func (cfg *config) setTo(address common.Address) *config { + cfg.to = &address + return cfg +} + +func newEVM(cfg *config) *vm.EVM { + context := vm.Context{ + CanTransfer: CanTransfer, + Transfer: Transfer, + GetHash: func(uint64) common.Hash { return common.Hash{} }, + + Origin: common.Address{}, + Coinbase: common.Address{}, + BlockNumber: new(big.Int), + Time: big.NewInt(time.Now().Unix()), + Difficulty: new(big.Int), + GasLimit: uint64(3450366), + GasPrice: big.NewInt(0), + } + evm := vm.NewEVM(context, cfg.publicState, cfg.privateState, ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + ByzantiumBlock: new(big.Int), + HomesteadBlock: new(big.Int), + DAOForkBlock: new(big.Int), + DAOForkSupport: false, + EIP150Block: new(big.Int), + EIP155Block: new(big.Int), + EIP158Block: new(big.Int), + IsQuorum: true, + PrivacyEnhancementsBlock: new(big.Int), + }, vm.Config{}) + evm.SetCurrentTX(cfg.currentTx) + return evm +} + +func mustParse(def string) abi.ABI { + ret, err := abi.JSON(strings.NewReader(def)) + if err != nil { + panic(fmt.Sprintf("Can't parse ABI def %s", err)) + } + return ret +} + +type stubSigner struct { +} + +func (ss *stubSigner) Sender(tx *types.Transaction) (common.Address, error) { + return signingAddress, nil +} + +func (ss *stubSigner) SignatureValues(tx *types.Transaction, sig []byte) (r, s, v *big.Int, err error) { + panic("implement me") +} + +func (ss *stubSigner) Hash(tx *types.Transaction) common.Hash { + panic("implement me") +} + +func (ss *stubSigner) Equal(types.Signer) bool { + panic("implement me") +} + +type mockPrivateTransactionManager struct { + notinuse.PrivateTransactionManager + returns map[string][]interface{} + currentMethod string + count map[string]int +} + +func (mpm *mockPrivateTransactionManager) HasFeature(f engine.PrivateTransactionManagerFeature) bool { + return true +} + +func (mpm *mockPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) { + mpm.count["Receive"]++ + values := mpm.returns["Receive"] + var ( + r1 []byte + r2 *engine.ExtraMetadata + r3 error + ) + if values[0] != nil { + r1 = values[0].([]byte) + } + if values[1] != nil { + r2 = values[1].(*engine.ExtraMetadata) + } + if values[2] != nil { + r3 = values[2].(error) + } + return "", nil, r1, r2, r3 +} + +func (mpm *mockPrivateTransactionManager) When(name string) *mockPrivateTransactionManager { + mpm.currentMethod = name + mpm.count[name] = -1 + return mpm +} + +func (mpm *mockPrivateTransactionManager) Return(values ...interface{}) { + mpm.returns[mpm.currentMethod] = values +} + +func (mpm *mockPrivateTransactionManager) Verify(assert *testifyassert.Assertions) { + for m, c := range mpm.count { + assert.True(c > -1, "%s has not been called", m) + } +} + +func (mpm *mockPrivateTransactionManager) reset() { + mpm.count = make(map[string]int) + mpm.currentMethod = "" + mpm.returns = make(map[string][]interface{}) +} + +func newMockPrivateTransactionManager() *mockPrivateTransactionManager { + return &mockPrivateTransactionManager{ + returns: make(map[string][]interface{}), + count: make(map[string]int), + } +} + +const ( + c1AbiDefinition = ` +[ + { + "constant": false, + "inputs": [ + { + "name": "newValue", + "type": "uint256" + } + ], + "name": "set", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "get", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newValue", + "type": "uint256" + } + ], + "name": "newContractC2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "initVal", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } +] +` + c2AbiDefinition = ` +[ + { + "constant": false, + "inputs": [ + { + "name": "_val", + "type": "uint256" + } + ], + "name": "set", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "get", + "outputs": [ + { + "name": "result", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_t", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } +] +` +) + +func verifyGasPoolCalculation(t *testing.T, pm private.PrivateTransactionManager) { + assert := testifyassert.New(t) + saved := private.P + defer func() { + private.P = saved + }() + private.P = pm + + txGasLimit := uint64(100000) + gasPool := new(GasPool).AddGas(200000) + // this payload would give us 25288 intrinsic gas + arbitraryEncryptedPayload := "4ab80888354582b92ab442a317828386e4bf21ea4a38d1a9183fbb715f199475269d7686939017f4a6b28310d5003ebd8e012eade530b79e157657ce8dd9692a" + expectedGasPool := new(GasPool).AddGas(177988) // only intrinsic gas is deducted + + db := rawdb.NewMemoryDatabase() + privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + msg := privateCallMsg{ + callmsg: callmsg{ + addr: common.Address{2}, + to: &common.Address{}, + value: new(big.Int), + gas: txGasLimit, + gasPrice: big.NewInt(0), + data: common.Hex2Bytes(arbitraryEncryptedPayload), + }, + } + ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &common.Address{}) + evm := vm.NewEVM(ctx, publicState, privateState, params.QuorumTestChainConfig, vm.Config{}) + + tx := types.NewTransaction( + 0, + common.Address{}, + big.NewInt(0), + txGasLimit, + big.NewInt(0), + common.Hex2Bytes(arbitraryEncryptedPayload)) + evm.SetCurrentTX(tx) + + arbitraryBalance := big.NewInt(100000000) + publicState.SetBalance(evm.Coinbase, arbitraryBalance) + publicState.SetBalance(msg.From(), arbitraryBalance) + + testObject := NewStateTransition(evm, msg, gasPool) + + result, err := testObject.TransitionDb() + + assert.NoError(err) + assert.False(result.Failed()) + + assert.Equal(new(big.Int).SetUint64(expectedGasPool.Gas()), new(big.Int).SetUint64(gasPool.Gas()), "gas pool must be calculated correctly") + assert.Equal(arbitraryBalance, publicState.GetBalance(evm.Coinbase), "balance must not be changed") + assert.Equal(arbitraryBalance, publicState.GetBalance(msg.From()), "balance must not be changed") +} + +func TestStateTransition_TransitionDb_GasPoolCalculation_whenNonPartyNodeProcessingPrivateTransactions(t *testing.T) { + stubPTM := &StubPrivateTransactionManager{ + responses: map[string][]interface{}{ + "Receive": { + []byte{}, + nil, + }, + }, + } + verifyGasPoolCalculation(t, stubPTM) +} + +func TestStateTransition_TransitionDb_GasPoolCalculation_whenPartyNodeProcessingPrivateTransactions(t *testing.T) { + stubPTM := &StubPrivateTransactionManager{ + responses: map[string][]interface{}{ + "Receive": { + common.Hex2Bytes("600a6000526001601ff300"), + nil, + }, + }, + } + verifyGasPoolCalculation(t, stubPTM) +} + +type privateCallMsg struct { + callmsg +} + +func (pm privateCallMsg) IsPrivate() bool { return true } + +type StubPrivateTransactionManager struct { + notinuse.PrivateTransactionManager + responses map[string][]interface{} +} + +func (spm *StubPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) { + res := spm.responses["Receive"] + if err, ok := res[1].(error); ok { + return "", nil, nil, nil, err + } + if ret, ok := res[0].([]byte); ok { + return "", nil, ret, &engine.ExtraMetadata{ + PrivacyFlag: engine.PrivacyFlagStandardPrivate, + }, nil + } + return "", nil, nil, nil, nil +} + +func (spm *StubPrivateTransactionManager) ReceiveRaw(hash common.EncryptedPayloadHash) ([]byte, string, *engine.ExtraMetadata, error) { + _, sender, data, metadata, err := spm.Receive(hash) + return data, sender[0], metadata, err +} + +func (spm *StubPrivateTransactionManager) HasFeature(f engine.PrivateTransactionManagerFeature) bool { + return true +} diff --git a/core/tx_pool.go b/core/tx_pool.go index 0fe1d3db5b..9c2a6a77bb 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -26,12 +26,14 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" + pcore "github.com/ethereum/go-ethereum/permission/core" ) const ( @@ -48,7 +50,8 @@ const ( // non-trivial consequences: larger transactions are significantly harder and // more expensive to propagate; larger transactions also take more resources // to validate whether they fit into the pool or not. - txMaxSize = 4 * txSlotSize // 128KB + // txMaxSize = 4 * txSlotSize // 128KB + // Quorum - value above is not used. instead, ChainConfig.TransactionSizeLimit is used ) var ( @@ -79,6 +82,12 @@ var ( // than some meaningful limit a user might use. This is not a consensus error // making the transaction invalid, rather a DOS protection. ErrOversizedData = errors.New("oversized data") + + ErrInvalidGasPrice = errors.New("Gas price not 0") + + // ErrEtherValueUnsupported is returned if a transaction specifies an Ether Value + // for a private Quorum transaction. + ErrEtherValueUnsupported = errors.New("ether value is not supported for private transactions") ) var ( @@ -127,7 +136,7 @@ const ( type blockChain interface { CurrentBlock() *types.Block GetBlock(hash common.Hash, number uint64) *types.Block - StateAt(root common.Hash) (*state.StateDB, error) + StateAt(root common.Hash) (*state.StateDB, mps.PrivateStateRepository, error) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription } @@ -148,6 +157,10 @@ type TxPoolConfig struct { GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts Lifetime time.Duration // Maximum amount of time non-executable transaction are queued + + // Quorum + TransactionSizeLimit uint64 // Maximum size allowed for valid transaction (in KB) + MaxCodeSize uint64 // Maximum size allowed of contract code that can be deployed (in KB) } // DefaultTxPoolConfig contains the default configurations for the transaction @@ -165,6 +178,10 @@ var DefaultTxPoolConfig = TxPoolConfig{ GlobalQueue: 1024, Lifetime: 3 * time.Hour, + + // Quorum + TransactionSizeLimit: 64, + MaxCodeSize: 24, } // sanitize checks the provided user configurations and changes anything that's @@ -517,10 +534,17 @@ func (pool *TxPool) local() map[common.Address]types.Transactions { // validateTx checks whether a transaction is valid according to the consensus // rules and adheres to some heuristic limits of the local node (price and size). func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { - // Reject transactions over defined size to prevent DOS attacks - if uint64(tx.Size()) > txMaxSize { + // Quorum + sizeLimit := pool.chainconfig.TransactionSizeLimit + if sizeLimit == 0 { + sizeLimit = DefaultTxPoolConfig.TransactionSizeLimit + } + // Reject transactions over 64KB (or manually set limit) to prevent DOS attacks + if float64(tx.Size()) > float64(sizeLimit*1024) { return ErrOversizedData } + // /Quorum + // Transactions can't be negative. This may never happen using RLP decoded // transactions but may occur if you create a transaction using the RPC. if tx.Value().Sign() < 0 { @@ -535,10 +559,26 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if err != nil { return ErrInvalidSender } - // Drop non-local transactions under our own minimal accepted gas price - local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network - if !local && tx.GasPriceIntCmp(pool.gasPrice) < 0 { - return ErrUnderpriced + if pool.chainconfig.IsQuorum { + // Quorum + // Gas price must be zero for Quorum transaction + if tx.GasPriceIntCmp(common.Big0) != 0 { + return ErrInvalidGasPrice + } + // Ether value is not currently supported on private transactions + if tx.IsPrivate() && (len(tx.Data()) == 0 || tx.Value().Sign() != 0) { + return ErrEtherValueUnsupported + } + // Quorum - check if the sender account is authorized to perform the transaction + if err := pcore.CheckAccountPermission(tx.From(), tx.To(), tx.Value(), tx.Data(), tx.Gas(), tx.GasPrice()); err != nil { + return err + } + } else { + // Drop non-local transactions under our own minimal accepted gas price + local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network + if !local && tx.GasPriceIntCmp(pool.gasPrice) < 0 { + return ErrUnderpriced + } } // Ensure the transaction adheres to nonce ordering if pool.currentState.GetNonce(from) > tx.Nonce() { @@ -584,7 +624,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e // If the transaction pool is full, discard underpriced transactions if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue { // If the new transaction is underpriced, don't accept it - if !local && pool.priced.Underpriced(tx, pool.locals) { + if !pool.chainconfig.IsQuorum && !local && pool.priced.Underpriced(tx, pool.locals) { log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice()) underpricedTxMeter.Mark(1) return false, ErrUnderpriced @@ -1162,7 +1202,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { if newHead == nil { newHead = pool.chain.CurrentBlock().Header() // Special case during testing } - statedb, err := pool.chain.StateAt(newHead.Root) + statedb, _, err := pool.chain.StateAt(newHead.Root) if err != nil { log.Error("Failed to reset txpool state", "err", err) return @@ -1185,6 +1225,11 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Transaction { + isQuorum := pool.chainconfig.IsQuorum + // Init delayed since tx pool could have been started before any state sync + if isQuorum && pool.pendingNonces == nil { + pool.reset(nil, nil) + } // Track the promoted transactions to broadcast them at once var promoted []*types.Transaction @@ -1200,20 +1245,24 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans hash := tx.Hash() pool.all.Remove(hash) } - log.Trace("Removed old queued transactions", "count", len(forwards)) - // Drop all transactions that are too costly (low balance or out of gas) - drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) - for _, tx := range drops { - hash := tx.Hash() - pool.all.Remove(hash) + var drops types.Transactions + if !isQuorum { + log.Trace("Removed old queued transactions", "count", len(forwards)) + // Drop all transactions that are too costly (low balance or out of gas) + drops, _ := list.Filter(pool.currentState.GetBalance(addr), pool.currentMaxGas) + for _, tx := range drops { + hash := tx.Hash() + pool.all.Remove(hash) + } + log.Trace("Removed unpayable queued transactions", "count", len(drops)) + queuedNofundsMeter.Mark(int64(len(drops))) } - log.Trace("Removed unpayable queued transactions", "count", len(drops)) - queuedNofundsMeter.Mark(int64(len(drops))) // Gather all executable transactions and promote them readies := list.Ready(pool.pendingNonces.get(addr)) for _, tx := range readies { hash := tx.Hash() + log.Trace("Promoting queued transaction", "hash", hash) if pool.promoteTx(addr, hash, tx) { promoted = append(promoted, tx) } @@ -1598,6 +1647,11 @@ func (t *txLookup) Remove(hash common.Hash) { delete(t.all, hash) } +// helper function to return chainHeadChannel size +func GetChainHeadChannleSize() int { + return chainHeadChanSize +} + // numSlots calculates the number of slots needed for a single transaction. func numSlots(tx *types.Transaction) int { return int((tx.Size() + txSlotSize - 1) / txSlotSize) diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 4fca734e65..1021ad27b6 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -24,10 +24,12 @@ import ( "math/big" "math/rand" "os" + "reflect" "testing" "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -48,6 +50,7 @@ func init() { type testBlockChain struct { statedb *state.StateDB + psManager mps.PrivateStateRepository gasLimit uint64 chainHeadFeed *event.Feed } @@ -62,8 +65,8 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block return bc.CurrentBlock() } -func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { - return bc.statedb, nil +func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, mps.PrivateStateRepository, error) { + return bc.statedb, bc.psManager, nil } func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { @@ -87,16 +90,25 @@ func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key return tx } -func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { +// Quorum - created setupTxPoolWithConfig(...) from original setupTxPool() to allow passing a ChainConfig as argument +func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 10000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 10000000, new(event.Feed)} key, _ := crypto.GenerateKey() - pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) + pool := NewTxPool(testTxPoolConfig, config, blockchain) return pool, key } +func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { + return setupTxPoolWithConfig(params.TestChainConfig) +} + +func setupQuorumTxPool() (*TxPool, *ecdsa.PrivateKey) { + return setupTxPoolWithConfig(params.QuorumTestChainConfig) +} + // validateTxPoolInternals checks various consistency invariants within the pool. func validateTxPoolInternals(pool *TxPool) error { pool.mu.RLock() @@ -168,7 +180,7 @@ type testChain struct { // testChain.State() is used multiple times to reset the pending state. // when simulate is true it will create a state that indicates // that tx0 and tx1 are included in the chain. -func (c *testChain) State() (*state.StateDB, error) { +func (c *testChain) State() (*state.StateDB, mps.PrivateStateRepository, error) { // delay "state change" by one. The tx pool fetches the // state multiple times and by delaying it a bit we simulate // a state change between those fetches. @@ -180,7 +192,7 @@ func (c *testChain) State() (*state.StateDB, error) { c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether)) *c.trigger = false } - return stdb, nil + return stdb, nil, nil } // This test simulates a scenario where a new block is imported during a @@ -198,7 +210,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { // setup pool with 2 transaction in it statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether)) - blockchain := &testChain{&testBlockChain{statedb, 1000000000, new(event.Feed)}, address, &trigger} + blockchain := &testChain{&testBlockChain{statedb, nil, 1000000000, new(event.Feed)}, address, &trigger} tx0 := transaction(0, 100000, key) tx1 := transaction(1, 100000, key) @@ -232,6 +244,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { } } +// Test for transactions that are invalid on Ethereum & Quorum func TestInvalidTransactions(t *testing.T) { t.Parallel() @@ -243,29 +256,131 @@ func TestInvalidTransactions(t *testing.T) { pool.currentState.AddBalance(from, big.NewInt(1)) if err := pool.AddRemote(tx); err != ErrInsufficientFunds { - t.Error("expected", ErrInsufficientFunds) + t.Error("expected", ErrInsufficientFunds, "; got", err) } balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice())) pool.currentState.AddBalance(from, balance) if err := pool.AddRemote(tx); !errors.Is(err, ErrIntrinsicGas) { - t.Error("expected", ErrIntrinsicGas, "got", err) + t.Error("expected", ErrIntrinsicGas, "; got", err) } pool.currentState.SetNonce(from, 1) pool.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) tx = transaction(0, 100000, key) if err := pool.AddRemote(tx); err != ErrNonceTooLow { - t.Error("expected", ErrNonceTooLow) + t.Error("expected", ErrNonceTooLow, "; got", err) } tx = transaction(1, 100000, key) pool.gasPrice = big.NewInt(1000) if err := pool.AddRemote(tx); err != ErrUnderpriced { - t.Error("expected", ErrUnderpriced, "got", err) + t.Error("expected", ErrUnderpriced, "; got", err) } if err := pool.AddLocal(tx); err != nil { - t.Error("expected", nil, "got", err) + t.Error("expected", nil, "; got", err) + } + + tooMuchGas := pool.currentMaxGas + 1 + tx1 := transaction(2, tooMuchGas, key) + if err := pool.AddRemote(tx1); err != ErrGasLimit { + t.Error("expected", ErrGasLimit, "; got", err) + } + + data := make([]byte, (64*1024)+1) + tx2, _ := types.SignTx(types.NewTransaction(2, common.Address{}, big.NewInt(100), 100000, big.NewInt(1), data), types.HomesteadSigner{}, key) + if err := pool.AddRemote(tx2); err != ErrOversizedData { + t.Error("expected", ErrOversizedData, "; got", err) + } + + // Quorum + statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} + params.QuorumTestChainConfig.TransactionSizeLimit = 128 + pool2 := NewTxPool(testTxPoolConfig, params.QuorumTestChainConfig, blockchain) + + pool2.currentState.AddBalance(from, big.NewInt(0xffffffffffffff)) + data2 := make([]byte, (127 * 1024)) + + tx3, _ := types.SignTx(types.NewTransaction(2, common.Address{}, big.NewInt(100), 100000, big.NewInt(0), data2), types.HomesteadSigner{}, key) + if err := pool2.AddRemote(tx3); err != ErrIntrinsicGas { + t.Error("expected", ErrIntrinsicGas, "; got", err) + } + + data3 := make([]byte, (128*1024)+1) + tx4, _ := types.SignTx(types.NewTransaction(2, common.Address{}, big.NewInt(100), 100000, big.NewInt(0), data3), types.HomesteadSigner{}, key) + if err := pool2.AddRemote(tx4); err != ErrOversizedData { + t.Error("expected", ErrOversizedData, "; got", err) + } + + tx5, _ := types.SignTx(types.NewTransaction(1, common.Address{}, big.NewInt(100), 0, big.NewInt(0), nil), types.HomesteadSigner{}, key) + balance = new(big.Int).Add(tx5.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx5.Gas()), tx5.GasPrice())) + + from, _ = deriveSender(tx5) + pool2.currentState.AddBalance(from, balance) + tx5.SetPrivate() + if err := pool2.AddRemote(tx5); err != ErrEtherValueUnsupported { + t.Error("expected", ErrEtherValueUnsupported, "; got", err) + } +} + +//Test for transactions that are only invalid on Quorum +func TestQuorumInvalidTransactions(t *testing.T) { + pool, key := setupQuorumTxPool() + defer pool.Stop() + + tx := transaction(0, 0, key) + if err := pool.AddRemote(tx); err != ErrInvalidGasPrice { + t.Error("expected", ErrInvalidGasPrice, "; got", err) + } + +} + +func TestValidateTx_whenValueZeroTransferForPrivateTransaction(t *testing.T) { + pool, key := setupQuorumTxPool() + defer pool.Stop() + zeroValue := common.Big0 + zeroGasPrice := common.Big0 + defaultTxPoolGasLimit := uint64(1000000) + arbitraryTx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, zeroValue, defaultTxPoolGasLimit, zeroGasPrice, nil), types.HomesteadSigner{}, key) + arbitraryTx.SetPrivate() + + if err := pool.AddRemote(arbitraryTx); err != ErrEtherValueUnsupported { + t.Error("expected:", ErrEtherValueUnsupported, "; got:", err) + } +} + +func TestValidateTx_whenValueNonZeroTransferForPrivateTransaction(t *testing.T) { + pool, key := setupQuorumTxPool() + defer pool.Stop() + arbitraryValue := common.Big3 + arbitraryTx, balance, from := newPrivateTransaction(arbitraryValue, nil, key) + pool.currentState.AddBalance(from, balance) + + if err := pool.AddRemote(arbitraryTx); err != ErrEtherValueUnsupported { + t.Error("expected: ", ErrEtherValueUnsupported, "; got:", err) + } +} + +func newPrivateTransaction(value *big.Int, data []byte, key *ecdsa.PrivateKey) (*types.Transaction, *big.Int, common.Address) { + zeroGasPrice := common.Big0 + defaultTxPoolGasLimit := uint64(1000000) + arbitraryTx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, value, defaultTxPoolGasLimit, zeroGasPrice, data), types.HomesteadSigner{}, key) + arbitraryTx.SetPrivate() + balance := new(big.Int).Add(arbitraryTx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(arbitraryTx.Gas()), arbitraryTx.GasPrice())) + from, _ := deriveSender(arbitraryTx) + return arbitraryTx, balance, from +} + +func TestValidateTx_whenValueNonZeroWithSmartContractForPrivateTransaction(t *testing.T) { + pool, key := setupQuorumTxPool() + defer pool.Stop() + arbitraryValue := common.Big3 + arbitraryTx, balance, from := newPrivateTransaction(arbitraryValue, []byte("arbitrary bytecode"), key) + pool.currentState.AddBalance(from, balance) + + if err := pool.AddRemote(arbitraryTx); err != ErrEtherValueUnsupported { + t.Error("expected: ", ErrEtherValueUnsupported, "; got:", err) } } @@ -351,7 +466,7 @@ func TestTransactionChainFork(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) statedb.AddBalance(addr, big.NewInt(100000000000000)) - pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} + pool.chain = &testBlockChain{statedb, nil, 1000000, new(event.Feed)} <-pool.requestReset(nil, nil) } resetState() @@ -380,7 +495,7 @@ func TestTransactionDoubleNonce(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) statedb.AddBalance(addr, big.NewInt(100000000000000)) - pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} + pool.chain = &testBlockChain{statedb, nil, 1000000, new(event.Feed)} <-pool.requestReset(nil, nil) } resetState() @@ -569,7 +684,7 @@ func TestTransactionPostponing(t *testing.T) { // Create the pool to test the postponing with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -782,7 +897,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { // Create the pool to test the limit enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.NoLocals = nolocals @@ -874,7 +989,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { // Create the pool to test the non-expiration enforcement statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.Lifetime = time.Second @@ -1059,7 +1174,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { // Create the pool to test the limit enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = config.AccountSlots * 10 @@ -1106,7 +1221,7 @@ func TestTransactionAllowedTxSize(t *testing.T) { t.Parallel() // Create a test account and fund it - pool, key := setupTxPool() + pool, key := setupQuorumTxPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -1123,23 +1238,25 @@ func TestTransactionAllowedTxSize(t *testing.T) { // - signature == 65 bytes // All those fields are summed up to at most 213 bytes. baseSize := uint64(213) + txMaxSize := params.QuorumTestChainConfig.TransactionSizeLimit * 1024 dataSize := txMaxSize - baseSize // Try adding a transaction with maximal allowed size - tx := pricedDataTransaction(0, pool.currentMaxGas, big.NewInt(1), key, dataSize) + gasPrice := big.NewInt(0) + tx := pricedDataTransaction(0, pool.currentMaxGas, gasPrice, key, dataSize) if err := pool.addRemoteSync(tx); err != nil { t.Fatalf("failed to add transaction of size %d, close to maximal: %v", int(tx.Size()), err) } // Try adding a transaction with random allowed size - if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentMaxGas, big.NewInt(1), key, uint64(rand.Intn(int(dataSize))))); err != nil { + if err := pool.addRemoteSync(pricedDataTransaction(1, pool.currentMaxGas, gasPrice, key, uint64(rand.Intn(int(dataSize))))); err != nil { t.Fatalf("failed to add transaction of random allowed size: %v", err) } // Try adding a transaction of minimal not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, big.NewInt(1), key, txMaxSize)); err == nil { + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, gasPrice, key, txMaxSize)); err == nil { t.Fatalf("expected rejection on slightly oversize transaction") } // Try adding a transaction of random not allowed size - if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, big.NewInt(1), key, dataSize+1+uint64(rand.Intn(int(10*txMaxSize))))); err == nil { + if err := pool.addRemoteSync(pricedDataTransaction(2, pool.currentMaxGas, gasPrice, key, dataSize+1+uint64(rand.Intn(int(10*txMaxSize))))); err == nil { t.Fatalf("expected rejection on oversize transaction") } // Run some sanity checks on the pool internals @@ -1161,7 +1278,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { // Create the pool to test the limit enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.AccountSlots = 2 @@ -1195,7 +1312,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { // Create the pool to test the limit enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = 1 @@ -1243,7 +1360,7 @@ func TestTransactionPoolRepricing(t *testing.T) { // Create the pool to test the pricing enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1364,7 +1481,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { // Create the pool to test the pricing enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1426,7 +1543,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { // Create the pool to test the pricing enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = 2 @@ -1532,7 +1649,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { // Create the pool to test the pricing enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.GlobalSlots = 128 @@ -1597,7 +1714,7 @@ func TestTransactionDeduplication(t *testing.T) { // Create the pool to test the pricing enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1663,7 +1780,7 @@ func TestTransactionReplacement(t *testing.T) { // Create the pool to test the pricing enforcement with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -1758,7 +1875,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { // Create the original pool to inject transaction into the journal statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} config := testTxPoolConfig config.NoLocals = nolocals @@ -1800,7 +1917,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive pool.Stop() statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain = &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool = NewTxPool(config, params.TestChainConfig, blockchain) @@ -1827,7 +1944,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { pool.Stop() statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1) - blockchain = &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain = &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool = NewTxPool(config, params.TestChainConfig, blockchain) pending, queued = pool.Stats() @@ -1856,7 +1973,7 @@ func TestTransactionStatusCheck(t *testing.T) { // Create the pool to test the status retrievals with statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() @@ -2007,3 +2124,47 @@ func benchmarkPoolBatchInsert(b *testing.B, size int, local bool) { } } } + +//Checks that the EIP155 signer is assigned to the TxPool no matter the configuration, even invalid config +func TestEIP155SignerOnTxPool(t *testing.T) { + var flagtests = []struct { + name string + homesteadBlock *big.Int + eip155Block *big.Int + }{ + {"hsnileip155nil", nil, nil}, + {"hsnileip1550", nil, big.NewInt(0)}, + {"hsnileip155100", nil, big.NewInt(100)}, + {"hs0eip155nil", big.NewInt(0), nil}, + {"hs0eip1550", big.NewInt(0), big.NewInt(0)}, + {"hs0eip155100", big.NewInt(0), big.NewInt(100)}, + {"hs100eip155nil", big.NewInt(100), nil}, + {"hs100eip1550", big.NewInt(100), big.NewInt(0)}, + {"hs100eip155100", big.NewInt(100), big.NewInt(100)}, + } + + for _, tt := range flagtests { + t.Run("", func(t *testing.T) { + db := rawdb.NewMemoryDatabase() + statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + blockchain := &testBlockChain{statedb, nil, 1000000, new(event.Feed)} + + chainconfig := ¶ms.ChainConfig{ + ChainID: big.NewInt(10), + HomesteadBlock: tt.homesteadBlock, + EIP150Block: big.NewInt(0), + EIP155Block: tt.eip155Block, + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + Ethash: new(params.EthashConfig), + } + + pool := NewTxPool(testTxPoolConfig, chainconfig, blockchain) + + if reflect.TypeOf(types.EIP155Signer{}) != reflect.TypeOf(pool.signer) { + t.Fail() + } + }) + } + +} diff --git a/core/types.go b/core/types.go index 4c5b74a498..77827a3136 100644 --- a/core/types.go +++ b/core/types.go @@ -17,6 +17,7 @@ package core import ( + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -47,5 +48,5 @@ type Processor interface { // Process processes the state changes according to the Ethereum rules by running // the transaction messages using the statedb and applying any rewards to both // the processor (coinbase) and any included uncles. - Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) + Process(block *types.Block, statedb *state.StateDB, privateStateManager mps.PrivateStateRepository, cfg vm.Config) (types.Receipts, types.Receipts, []*types.Log, uint64, error) } diff --git a/core/types/block.go b/core/types/block.go index 8096ebb755..dca10e75a6 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -101,6 +101,14 @@ type headerMarshaling struct { // Hash returns the block hash of the header, which is simply the keccak256 hash of its // RLP encoding. func (h *Header) Hash() common.Hash { + // If the mix digest is equivalent to the predefined Istanbul digest, use Istanbul + // specific hash calculation. + if h.MixDigest == IstanbulDigest { + // Seal is reserved in extra-data. To prove block is signed by the proposer. + if istanbulHeader := IstanbulFilteredHeader(h, true); istanbulHeader != nil { + return rlpHash(istanbulHeader) + } + } return rlpHash(h) } @@ -185,6 +193,10 @@ type Block struct { ReceivedFrom interface{} } +func (b *Block) String() string { + return fmt.Sprintf("{Header: %v}", b.header) +} + // DeprecatedTd is an old relic for extracting the TD of a block. It is in the // code solely to facilitate upgrading the database from the old format to the // new, after which it should be deleted. Do not use! diff --git a/core/types/bloom9.go b/core/types/bloom9.go index d045c9e667..4970477d4d 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -63,6 +63,15 @@ func (b *Bloom) Add(d *big.Int) { b.SetBytes(bin.Bytes()) } +// Quorum +// OrBloom executes an Or operation on the bloom +func (b *Bloom) OrBloom(bl []byte) { + bin := new(big.Int).SetBytes(b[:]) + input := new(big.Int).SetBytes(bl[:]) + bin.Or(bin, input) + b.SetBytes(bin.Bytes()) +} + // Big converts b to a big integer. func (b Bloom) Big() *big.Int { return new(big.Int).SetBytes(b[:]) diff --git a/core/types/istanbul.go b/core/types/istanbul.go new file mode 100644 index 0000000000..3375dbbda3 --- /dev/null +++ b/core/types/istanbul.go @@ -0,0 +1,107 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "errors" + "io" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + // IstanbulDigest represents a hash of "Istanbul practical byzantine fault tolerance" + // to identify whether the block is from Istanbul consensus engine + IstanbulDigest = common.HexToHash("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365") + + IstanbulExtraVanity = 32 // Fixed number of extra-data bytes reserved for validator vanity + IstanbulExtraSeal = 65 // Fixed number of extra-data bytes reserved for validator seal + + // ErrInvalidIstanbulHeaderExtra is returned if the length of extra-data is less than 32 bytes + ErrInvalidIstanbulHeaderExtra = errors.New("invalid istanbul header extra-data") +) + +type IstanbulExtra struct { + Validators []common.Address + Seal []byte + CommittedSeal [][]byte +} + +// EncodeRLP serializes ist into the Ethereum RLP format. +func (ist *IstanbulExtra) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{ + ist.Validators, + ist.Seal, + ist.CommittedSeal, + }) +} + +// DecodeRLP implements rlp.Decoder, and load the istanbul fields from a RLP stream. +func (ist *IstanbulExtra) DecodeRLP(s *rlp.Stream) error { + var istanbulExtra struct { + Validators []common.Address + Seal []byte + CommittedSeal [][]byte + } + if err := s.Decode(&istanbulExtra); err != nil { + return err + } + ist.Validators, ist.Seal, ist.CommittedSeal = istanbulExtra.Validators, istanbulExtra.Seal, istanbulExtra.CommittedSeal + return nil +} + +// ExtractIstanbulExtra extracts all values of the IstanbulExtra from the header. It returns an +// error if the length of the given extra-data is less than 32 bytes or the extra-data can not +// be decoded. +func ExtractIstanbulExtra(h *Header) (*IstanbulExtra, error) { + if len(h.Extra) < IstanbulExtraVanity { + return nil, ErrInvalidIstanbulHeaderExtra + } + + var istanbulExtra *IstanbulExtra + err := rlp.DecodeBytes(h.Extra[IstanbulExtraVanity:], &istanbulExtra) + if err != nil { + return nil, err + } + return istanbulExtra, nil +} + +// IstanbulFilteredHeader returns a filtered header which some information (like seal, committed seals) +// are clean to fulfill the Istanbul hash rules. It returns nil if the extra-data cannot be +// decoded/encoded by rlp. +func IstanbulFilteredHeader(h *Header, keepSeal bool) *Header { + newHeader := CopyHeader(h) + istanbulExtra, err := ExtractIstanbulExtra(newHeader) + if err != nil { + return nil + } + + if !keepSeal { + istanbulExtra.Seal = []byte{} + } + istanbulExtra.CommittedSeal = [][]byte{} + + payload, err := rlp.EncodeToBytes(&istanbulExtra) + if err != nil { + return nil + } + + newHeader.Extra = append(newHeader.Extra[:IstanbulExtraVanity], payload...) + + return newHeader +} diff --git a/core/types/istanbul_test.go b/core/types/istanbul_test.go new file mode 100644 index 0000000000..db5453b53a --- /dev/null +++ b/core/types/istanbul_test.go @@ -0,0 +1,88 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "bytes" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +func TestHeaderHash(t *testing.T) { + // 0xcefefd3ade63a5955bca4562ed840b67f39e74df217f7e5f7241a6e9552cca70 + expectedExtra := common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000f89af8549444add0ec310f115a0e603b2d7db9f067778eaf8a94294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212946beaaed781d2d2ab6350f5c4566a2c6eaac407a6948be76812f765c24641ec63dc2852b378aba2b440b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0") + expectedHash := common.HexToHash("0xcefefd3ade63a5955bca4562ed840b67f39e74df217f7e5f7241a6e9552cca70") + + // for istanbul consensus + header := &Header{MixDigest: IstanbulDigest, Extra: expectedExtra} + if !reflect.DeepEqual(header.Hash(), expectedHash) { + t.Errorf("expected: %v, but got: %v", expectedHash.Hex(), header.Hash().Hex()) + } + + // append useless information to extra-data + unexpectedExtra := append(expectedExtra, []byte{1, 2, 3}...) + header.Extra = unexpectedExtra + if !reflect.DeepEqual(header.Hash(), rlpHash(header)) { + t.Errorf("expected: %v, but got: %v", rlpHash(header).Hex(), header.Hash().Hex()) + } +} + +func TestExtractToIstanbul(t *testing.T) { + testCases := []struct { + vanity []byte + istRawData []byte + expectedResult *IstanbulExtra + expectedErr error + }{ + { + // normal case + bytes.Repeat([]byte{0x00}, IstanbulExtraVanity), + hexutil.MustDecode("0xf858f8549444add0ec310f115a0e603b2d7db9f067778eaf8a94294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212946beaaed781d2d2ab6350f5c4566a2c6eaac407a6948be76812f765c24641ec63dc2852b378aba2b44080c0"), + &IstanbulExtra{ + Validators: []common.Address{ + common.BytesToAddress(hexutil.MustDecode("0x44add0ec310f115a0e603b2d7db9f067778eaf8a")), + common.BytesToAddress(hexutil.MustDecode("0x294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212")), + common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")), + common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")), + }, + Seal: []byte{}, + CommittedSeal: [][]byte{}, + }, + nil, + }, + { + // insufficient vanity + bytes.Repeat([]byte{0x00}, IstanbulExtraVanity-1), + nil, + nil, + ErrInvalidIstanbulHeaderExtra, + }, + } + for _, test := range testCases { + h := &Header{Extra: append(test.vanity, test.istRawData...)} + istanbulExtra, err := ExtractIstanbulExtra(h) + if err != test.expectedErr { + t.Errorf("expected: %v, but got: %v", test.expectedErr, err) + } + if !reflect.DeepEqual(istanbulExtra, test.expectedResult) { + t.Errorf("expected: %v, but got: %v", test.expectedResult, istanbulExtra) + } + } +} diff --git a/core/types/log.go b/core/types/log.go index 88274e39da..1d7c582029 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -53,6 +53,9 @@ type Log struct { // The Removed field is true if this log was reverted due to a chain reorganisation. // You must pay attention to this field if you receive logs through a filter query. Removed bool `json:"removed"` + + // multi tenancy + PSI PrivateStateIdentifier } type logMarshaling struct { diff --git a/core/types/mps.go b/core/types/mps.go new file mode 100644 index 0000000000..68171ab04b --- /dev/null +++ b/core/types/mps.go @@ -0,0 +1,23 @@ +package types + +var ( + // DefaultPrivateStateIdentifier is the default privacy group name created when + // no privacy group has been configured in Tessera + DefaultPrivateStateIdentifier = ToPrivateStateIdentifier("private") + // EmptyPrivateStateIdentifier is the identifier for the empty private state + // which is to hold state of transactions "as if" to which the node is not party + EmptyPrivateStateIdentifier = ToPrivateStateIdentifier("empty") +) + +// PrivateStateIdentifier is an unique identifier of a private state. +// The value comes from Tessera privacy group detail, +// it could be a privacy group name or ID +type PrivateStateIdentifier string + +func (psi PrivateStateIdentifier) String() string { + return string(psi) +} + +func ToPrivateStateIdentifier(s string) PrivateStateIdentifier { + return PrivateStateIdentifier(s) +} diff --git a/core/types/receipt.go b/core/types/receipt.go index a96c7525ef..22ce7751c0 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -66,6 +66,14 @@ type Receipt struct { BlockHash common.Hash `json:"blockHash,omitempty"` BlockNumber *big.Int `json:"blockNumber,omitempty"` TransactionIndex uint `json:"transactionIndex"` + + // Quorum + // + // this is to support execution of a private transaction on multiple private states + // in which receipts are produced per PSI. + // + // This nested structure would not have more than 2 levels. + PSReceipts map[PrivateStateIdentifier]*Receipt `json:"-"` } type receiptMarshaling struct { @@ -85,6 +93,20 @@ type receiptRLP struct { Logs []*Log } +// storedMPSReceiptRLP is the storage encoding of a receipt which contains +// receipts per PSI +type storedMPSReceiptRLP struct { + PostStateOrStatus []byte + CumulativeGasUsed uint64 + Logs []*LogForStorage + PSReceipts []storedPSIToReceiptMapEntry +} + +type storedPSIToReceiptMapEntry struct { + Key PrivateStateIdentifier + Value storedReceiptRLP +} + // storedReceiptRLP is the storage encoding of a receipt. type storedReceiptRLP struct { PostStateOrStatus []byte @@ -186,7 +208,40 @@ type ReceiptForStorage Receipt // EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt // into an RLP stream. +// Quorum: +// - added logic to support multiple private state +// - original EncodeRLP is now encodeRLPOrig func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { + if r.PSReceipts == nil { + return r.encodeRLPOrig(w) + } + enc := &storedMPSReceiptRLP{ + PostStateOrStatus: (*Receipt)(r).statusEncoding(), + CumulativeGasUsed: r.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(r.Logs)), + PSReceipts: make([]storedPSIToReceiptMapEntry, len(r.PSReceipts)), + } + for i, log := range r.Logs { + enc.Logs[i] = (*LogForStorage)(log) + } + idx := 0 + for key, val := range r.PSReceipts { + rec := storedReceiptRLP{ + PostStateOrStatus: val.statusEncoding(), + CumulativeGasUsed: val.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(val.Logs)), + } + for i, log := range val.Logs { + rec.Logs[i] = (*LogForStorage)(log) + } + enc.PSReceipts[idx] = storedPSIToReceiptMapEntry{Key: key, Value: rec} + idx++ + } + return rlp.Encode(w, enc) +} + +// encodeRLPOrig is the original from upstream +func (r *ReceiptForStorage) encodeRLPOrig(w io.Writer) error { enc := &storedReceiptRLP{ PostStateOrStatus: (*Receipt)(r).statusEncoding(), CumulativeGasUsed: r.CumulativeGasUsed, @@ -209,6 +264,9 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { // Try decoding from the newest format for future proofness, then the older one // for old nodes that just upgraded. V4 was an intermediate unreleased format so // we do need to decode it, but it's not common (try last). + if err := decodeStoredMPSReceiptRLP(r, blob); err == nil { + return nil + } if err := decodeStoredReceiptRLP(r, blob); err == nil { return nil } @@ -218,6 +276,42 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { return decodeV4StoredReceiptRLP(r, blob) } +func decodeStoredMPSReceiptRLP(r *ReceiptForStorage, blob []byte) error { + var stored storedMPSReceiptRLP + if err := rlp.DecodeBytes(blob, &stored); err != nil { + return err + } + if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { + return err + } + r.CumulativeGasUsed = stored.CumulativeGasUsed + r.Logs = make([]*Log, len(stored.Logs)) + for i, log := range stored.Logs { + r.Logs[i] = (*Log)(log) + } + r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) + + if len(stored.PSReceipts) > 0 { + r.PSReceipts = make(map[PrivateStateIdentifier]*Receipt) + for _, entry := range stored.PSReceipts { + rec := &Receipt{} + if err := rec.setStatus(entry.Value.PostStateOrStatus); err != nil { + return err + } + rec.CumulativeGasUsed = entry.Value.CumulativeGasUsed + rec.Logs = make([]*Log, len(entry.Value.Logs)) + for i, log := range entry.Value.Logs { + rec.Logs[i] = (*Log)(log) + rec.Logs[i].PSI = entry.Key + } + rec.Bloom = CreateBloom(Receipts{rec}) + r.PSReceipts[entry.Key] = rec + } + } + + return nil +} + func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { var stored storedReceiptRLP if err := rlp.DecodeBytes(blob, &stored); err != nil { @@ -294,7 +388,85 @@ func (r Receipts) GetRlp(i int) []byte { // DeriveFields fills the receipts with their computed fields based on consensus // data and contextual infos like containing block and transactions. +// Quorum: +// - Provide additional support for Multiple Private State +// - Original DeriveFields func is now deriveFieldsOrig func (r Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, txs Transactions) error { + //flatten all the receipts + + allReceipts := make(map[PrivateStateIdentifier][]*Receipt) + allPublic := make([]*Receipt, 0) + + for i := 0; i < len(r); i++ { + receipt := r[i] + tx := txs[i] + + // if receipt is public, append to all known PSIs + // if private, append to all attached PSIs + // if new PSI, attach public version of all previous receipts + // append public to all other PSIs + + if !tx.IsPrivate() { + for psi := range allReceipts { + allReceipts[psi] = append(allReceipts[psi], receipt) + } + allPublic = append(allPublic, receipt) + continue + } + + // this is a private tx + // add the PSI version of the receipt to all the relevant PSI arrays + for psi, privateReceipt := range receipt.PSReceipts { + //does it exist + if _, ok := allReceipts[psi]; !ok { + allReceipts[psi] = append(make([]*Receipt, 0), allPublic...) + } + allReceipts[psi] = append(allReceipts[psi], privateReceipt) + } + // add the empty receipt to all the currently tracked PSIs + emptyReceipt := receipt.PSReceipts[EmptyPrivateStateIdentifier] + for psi := range allReceipts { + if len(allReceipts[psi]) < i+1 { + allReceipts[psi] = append(allReceipts[psi], emptyReceipt) + } + } + + allPublic = append(allPublic, receipt) + } + + // now we have all the receipts, so derive all their fields + for _, receipts := range allReceipts { + casted := Receipts(receipts) + if err := casted.deriveFieldsOrig(config, hash, number, txs); err != nil { + return err + } + } + if err := Receipts(allPublic).deriveFieldsOrig(config, hash, number, txs); err != nil { + return err + } + + // fields now derived, put back into correct order + tmp := make([]*Receipt, len(r)) + for i := 0; i < len(r); i++ { + tmp[i] = allPublic[i] + oldPsis := tmp[i].PSReceipts + tmp[i].PSReceipts = nil + if txs[i].IsPrivate() { + tmp[i].PSReceipts = make(map[PrivateStateIdentifier]*Receipt) + } + for psi := range oldPsis { + tmp[i].PSReceipts[psi] = allReceipts[psi][i] + } + } + + for i := 0; i < len(r); i++ { + r[i] = tmp[i] + } + return nil +} + +// deriveFieldsOrig is the original DeriveFields from upstream +func (r Receipts) deriveFieldsOrig(config *params.ChainConfig, hash common.Hash, number uint64, txs Transactions) error { signer := MakeSigner(config, new(big.Int).SetUint64(number)) logIndex := uint(0) @@ -334,3 +506,18 @@ func (r Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, num } return nil } + +// Quorum +// +// Flatten takes a list of private receipts, which will be the "private" PSI receipt, +// and flatten all the MPS receipts into a single list, which the bloom can work with +func (r Receipts) Flatten() []*Receipt { + var flattenedReceipts []*Receipt + for _, privReceipt := range r { + flattenedReceipts = append(flattenedReceipts, privReceipt) + for _, psReceipt := range privReceipt.PSReceipts { + flattenedReceipts = append(flattenedReceipts, psReceipt) + } + } + return flattenedReceipts +} diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index 806b3dd2ab..13826ee2cc 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -21,12 +21,14 @@ import ( "math" "math/big" "reflect" + "strconv" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/stretchr/testify/assert" ) func TestLegacyReceiptDecoding(t *testing.T) { @@ -81,32 +83,108 @@ func TestLegacyReceiptDecoding(t *testing.T) { t.Fatalf("Error decoding RLP receipt: %v", err) } // Check whether all consensus fields are correct. - if dec.Status != receipt.Status { - t.Fatalf("Receipt status mismatch, want %v, have %v", receipt.Status, dec.Status) - } - if dec.CumulativeGasUsed != receipt.CumulativeGasUsed { - t.Fatalf("Receipt CumulativeGasUsed mismatch, want %v, have %v", receipt.CumulativeGasUsed, dec.CumulativeGasUsed) - } - if dec.Bloom != receipt.Bloom { - t.Fatalf("Bloom data mismatch, want %v, have %v", receipt.Bloom, dec.Bloom) - } - if len(dec.Logs) != len(receipt.Logs) { - t.Fatalf("Receipt log number mismatch, want %v, have %v", len(receipt.Logs), len(dec.Logs)) - } - for i := 0; i < len(dec.Logs); i++ { - if dec.Logs[i].Address != receipt.Logs[i].Address { - t.Fatalf("Receipt log %d address mismatch, want %v, have %v", i, receipt.Logs[i].Address, dec.Logs[i].Address) - } - if !reflect.DeepEqual(dec.Logs[i].Topics, receipt.Logs[i].Topics) { - t.Fatalf("Receipt log %d topics mismatch, want %v, have %v", i, receipt.Logs[i].Topics, dec.Logs[i].Topics) - } - if !bytes.Equal(dec.Logs[i].Data, receipt.Logs[i].Data) { - t.Fatalf("Receipt log %d data mismatch, want %v, have %v", i, receipt.Logs[i].Data, dec.Logs[i].Data) - } - } + testConsensusFields(t, dec, receipt) }) } } +func TestMPSReceiptDecoding(t *testing.T) { + tx := NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil) + psiReceipt := &Receipt{ + PostState: common.Hash{2}.Bytes(), + CumulativeGasUsed: 3, + Logs: []*Log{ + {Address: common.BytesToAddress([]byte{0x22})}, + {Address: common.BytesToAddress([]byte{0x02, 0x22})}, + }, + TxHash: tx.Hash(), + ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), + GasUsed: 2, + } + psiReceipt.Bloom = CreateBloom(Receipts{psiReceipt}) + receipt := &Receipt{ + Status: ReceiptStatusFailed, + CumulativeGasUsed: 1, + Logs: []*Log{ + { + Address: common.BytesToAddress([]byte{0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + { + Address: common.BytesToAddress([]byte{0x01, 0x11}), + Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, + Data: []byte{0x01, 0x00, 0xff}, + }, + }, + TxHash: tx.Hash(), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + } + receipt.Bloom = CreateBloom(Receipts{receipt}) + receipt.PSReceipts = make(map[PrivateStateIdentifier]*Receipt) + receipt.PSReceipts["psi1"] = psiReceipt + + enc, err := encodeAsStoredMPSReceiptRLP(receipt) + if err != nil { + t.Fatalf("Error encoding receipt: %v", err) + } + var dec ReceiptForStorage + if err := rlp.DecodeBytes(enc, &dec); err != nil { + t.Fatalf("Error decoding RLP receipt: %v", err) + } + + // Check whether all consensus fields are correct for top level receipt + testConsensusFields(t, dec, receipt) + + //check number of psi receipts is correct + if len(dec.PSReceipts) != len(receipt.PSReceipts) { + t.Fatalf("Receipt psi number mismatch, want %v, have %v", len(receipt.PSReceipts), len(dec.PSReceipts)) + } + + //test psi receipt + for psi, decPsiReceipt := range dec.PSReceipts { + wantedPsiReceipt := receipt.PSReceipts[psi] + // Check whether all consensus fields are correct for psi receipt + if decPsiReceipt.Status != wantedPsiReceipt.Status { + t.Fatalf("%s Receipt status mismatch, want %v, have %v", psi.String(), wantedPsiReceipt.Status, decPsiReceipt.Status) + } + if decPsiReceipt.CumulativeGasUsed != wantedPsiReceipt.CumulativeGasUsed { + t.Fatalf("%s Receipt CumulativeGasUsed mismatch, want %v, have %v", psi.String(), wantedPsiReceipt.CumulativeGasUsed, decPsiReceipt.CumulativeGasUsed) + } + if decPsiReceipt.Bloom != wantedPsiReceipt.Bloom { + t.Fatalf("%s Receipt Bloom data mismatch, want %v, have %v", psi.String(), wantedPsiReceipt.Bloom, decPsiReceipt.Bloom) + } + if len(decPsiReceipt.Logs) != len(wantedPsiReceipt.Logs) { + t.Fatalf("%s Receipt log number mismatch, want %v, have %v", psi.String(), len(wantedPsiReceipt.Logs), len(decPsiReceipt.Logs)) + } + } +} + +func testConsensusFields(t *testing.T, dec ReceiptForStorage, receipt *Receipt) { + if dec.Status != receipt.Status { + t.Fatalf("Receipt status mismatch, want %v, have %v", receipt.Status, dec.Status) + } + if dec.CumulativeGasUsed != receipt.CumulativeGasUsed { + t.Fatalf("Receipt CumulativeGasUsed mismatch, want %v, have %v", receipt.CumulativeGasUsed, dec.CumulativeGasUsed) + } + if dec.Bloom != receipt.Bloom { + t.Fatalf("Bloom data mismatch, want %v, have %v", receipt.Bloom, dec.Bloom) + } + if len(dec.Logs) != len(receipt.Logs) { + t.Fatalf("Receipt log number mismatch, want %v, have %v", len(receipt.Logs), len(dec.Logs)) + } + for i := 0; i < len(dec.Logs); i++ { + if dec.Logs[i].Address != receipt.Logs[i].Address { + t.Fatalf("Receipt log %d address mismatch, want %v, have %v", i, receipt.Logs[i].Address, dec.Logs[i].Address) + } + if !reflect.DeepEqual(dec.Logs[i].Topics, receipt.Logs[i].Topics) { + t.Fatalf("Receipt log %d topics mismatch, want %v, have %v", i, receipt.Logs[i].Topics, dec.Logs[i].Topics) + } + if !bytes.Equal(dec.Logs[i].Data, receipt.Logs[i].Data) { + t.Fatalf("Receipt log %d data mismatch, want %v, have %v", i, receipt.Logs[i].Data, dec.Logs[i].Data) + } + } +} func encodeAsStoredReceiptRLP(want *Receipt) ([]byte, error) { stored := &storedReceiptRLP{ @@ -120,6 +198,32 @@ func encodeAsStoredReceiptRLP(want *Receipt) ([]byte, error) { return rlp.EncodeToBytes(stored) } +func encodeAsStoredMPSReceiptRLP(want *Receipt) ([]byte, error) { + stored := &storedMPSReceiptRLP{ + PostStateOrStatus: want.statusEncoding(), + CumulativeGasUsed: want.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(want.Logs)), + PSReceipts: make([]storedPSIToReceiptMapEntry, len(want.PSReceipts)), + } + for i, log := range want.Logs { + stored.Logs[i] = (*LogForStorage)(log) + } + idx := 0 + for key, val := range want.PSReceipts { + rec := storedReceiptRLP{ + PostStateOrStatus: val.statusEncoding(), + CumulativeGasUsed: val.CumulativeGasUsed, + Logs: make([]*LogForStorage, len(val.Logs)), + } + for i, log := range val.Logs { + rec.Logs[i] = (*LogForStorage)(log) + } + stored.PSReceipts[idx] = storedPSIToReceiptMapEntry{Key: key, Value: rec} + idx++ + } + return rlp.EncodeToBytes(stored) +} + func encodeAsV4StoredReceiptRLP(want *Receipt) ([]byte, error) { stored := &v4StoredReceiptRLP{ PostStateOrStatus: want.statusEncoding(), @@ -194,51 +298,145 @@ func TestDeriveFields(t *testing.T) { // Iterate over all the computed fields and check that they're correct signer := MakeSigner(params.TestChainConfig, number) - logIndex := uint(0) for i := range receipts { - if receipts[i].TxHash != txs[i].Hash() { - t.Errorf("receipts[%d].TxHash = %s, want %s", i, receipts[i].TxHash.String(), txs[i].Hash().String()) - } - if receipts[i].BlockHash != hash { - t.Errorf("receipts[%d].BlockHash = %s, want %s", i, receipts[i].BlockHash.String(), hash.String()) - } - if receipts[i].BlockNumber.Cmp(number) != 0 { - t.Errorf("receipts[%c].BlockNumber = %s, want %s", i, receipts[i].BlockNumber.String(), number.String()) - } - if receipts[i].TransactionIndex != uint(i) { - t.Errorf("receipts[%d].TransactionIndex = %d, want %d", i, receipts[i].TransactionIndex, i) + testReceiptFields(t, receipts[i], txs, i, "receipt"+strconv.Itoa(i), hash, number, signer) + } +} + +// Tests that receipt data can be correctly derived from the contextual infos +// Tests public, private, and private mps txs/receipts +func TestDeriveFieldsMPS(t *testing.T) { + // Create a public tx, private tx, psi tx + pubT := NewContractCreation(1, big.NewInt(1), 1, big.NewInt(1), nil) + privT := NewContractCreation(2, big.NewInt(2), 2, big.NewInt(2), nil) + privT.SetPrivate() + psiT := NewTransaction(3, common.HexToAddress("0x3"), big.NewInt(3), 3, big.NewInt(3), nil) + psiT.SetPrivate() + //3 transactions: public, private, and private with mps + txs := Transactions{ + pubT, + privT, + psiT, + } + publicReceipt := &Receipt{ + Status: ReceiptStatusFailed, + CumulativeGasUsed: 1, + Logs: []*Log{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: txs[0].Hash(), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 1, + } + innerPrivateReceipt := &Receipt{ + PostState: common.Hash{2}.Bytes(), + CumulativeGasUsed: 3, + Logs: []*Log{ + {Address: common.BytesToAddress([]byte{0x22})}, + {Address: common.BytesToAddress([]byte{0x02, 0x22})}, + }, + TxHash: txs[1].Hash(), + ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), + GasUsed: 2, + } + innerPSIReceipt := &Receipt{ + PostState: common.Hash{3}.Bytes(), + CumulativeGasUsed: 6, + Logs: []*Log{ + {Address: common.BytesToAddress([]byte{0x33})}, + {Address: common.BytesToAddress([]byte{0x03, 0x33})}, + }, + TxHash: txs[2].Hash(), + ContractAddress: common.BytesToAddress([]byte{0x03, 0x33, 0x33}), + GasUsed: 1, + } + psiReceipt := innerPSIReceipt + psiReceipt.PSReceipts = make(map[PrivateStateIdentifier]*Receipt) + psiReceipt.PSReceipts[PrivateStateIdentifier("psi1")] = innerPSIReceipt + psiReceipt.PSReceipts[EmptyPrivateStateIdentifier] = innerPSIReceipt + + privateReceipt := innerPrivateReceipt + privateReceipt.PSReceipts = make(map[PrivateStateIdentifier]*Receipt) + privateReceipt.PSReceipts[EmptyPrivateStateIdentifier] = innerPrivateReceipt + // Create the corresponding receipts: public, private, psi + receipts := Receipts{ + publicReceipt, + privateReceipt, + psiReceipt, + } + // Clear all the computed fields and re-derive them + number := big.NewInt(1) + hash := common.BytesToHash([]byte{0x03, 0x14}) + + clearComputedFieldsOnReceipts(t, receipts) + if err := receipts.DeriveFields(params.QuorumMPSTestChainConfig, hash, number.Uint64(), txs); err != nil { + t.Fatalf("DeriveFields(...) = %v, want ", err) + } + // Iterate over all the computed fields and check that they're correct + signer := MakeSigner(params.QuorumMPSTestChainConfig, number) + + for i := range receipts { + testReceiptFields(t, receipts[i], txs, i, "receipt"+strconv.Itoa(i), hash, number, signer) + } + //check psi info on public and private receipt + assert.Empty(t, receipts[0].PSReceipts) + privRec := receipts[1] + assert.Equal(t, 1, len(privRec.PSReceipts)) + assert.Contains(t, privRec.PSReceipts, EmptyPrivateStateIdentifier) + for _, pR := range privRec.PSReceipts { + testReceiptFields(t, pR, txs, 1, "privateReceipt", hash, number, signer) + } + + //check psi info on private mps receipt + psiRec := receipts[2] + assert.Equal(t, 2, len(psiRec.PSReceipts)) + assert.Contains(t, psiRec.PSReceipts, EmptyPrivateStateIdentifier) + assert.Contains(t, psiRec.PSReceipts, PrivateStateIdentifier("psi1")) + for _, pR := range psiRec.PSReceipts { + testReceiptFields(t, pR, txs, 2, "psiReceipt", hash, number, signer) + } +} + +func testReceiptFields(t *testing.T, receipt *Receipt, txs Transactions, txIndex int, receiptName string, hash common.Hash, number *big.Int, signer Signer) { + if receipt.TxHash != txs[txIndex].Hash() { + t.Errorf("%s.TxHash = %s, want %s", receiptName, receipt.TxHash.String(), txs[1].Hash().String()) + } + if receipt.BlockHash != hash { + t.Errorf("%s.BlockHash = %s, want %s", receiptName, receipt.BlockHash.String(), hash.String()) + } + if receipt.BlockNumber.Cmp(number) != 0 { + t.Errorf("%s.BlockNumber = %s, want %s", receiptName, receipt.BlockNumber.String(), number.String()) + } + if receipt.TransactionIndex != uint(txIndex) { + t.Errorf("%s.TransactionIndex = %d, want %d", receiptName, receipt.TransactionIndex, txIndex) + } + if receipt.GasUsed != txs[txIndex].Gas() { + t.Errorf("%s.GasUsed = %d, want %d", receiptName, receipt.GasUsed, txs[txIndex].Gas()) + } + if txs[txIndex].To() != nil && receipt.ContractAddress != (common.Address{}) { + t.Errorf("%s.ContractAddress = %s, want %s", receiptName, receipt.ContractAddress.String(), (common.Address{}).String()) + } + from, _ := Sender(signer, txs[txIndex]) + contractAddress := crypto.CreateAddress(from, txs[txIndex].Nonce()) + if txs[txIndex].To() == nil && receipt.ContractAddress != contractAddress { + t.Errorf("%s.ContractAddress = %s, want %s", receiptName, receipt.ContractAddress.String(), contractAddress.String()) + } + for j := range receipt.Logs { + if receipt.Logs[j].BlockNumber != number.Uint64() { + t.Errorf("%s.Logs[%d].BlockNumber = %d, want %d", receiptName, j, receipt.Logs[j].BlockNumber, number.Uint64()) } - if receipts[i].GasUsed != txs[i].Gas() { - t.Errorf("receipts[%d].GasUsed = %d, want %d", i, receipts[i].GasUsed, txs[i].Gas()) + if receipt.Logs[j].BlockHash != hash { + t.Errorf("%s.Logs[%d].BlockHash = %s, want %s", receiptName, j, receipt.Logs[j].BlockHash.String(), hash.String()) } - if txs[i].To() != nil && receipts[i].ContractAddress != (common.Address{}) { - t.Errorf("receipts[%d].ContractAddress = %s, want %s", i, receipts[i].ContractAddress.String(), (common.Address{}).String()) + if receipt.Logs[j].TxHash != txs[txIndex].Hash() { + t.Errorf("%s.Logs[%d].TxHash = %s, want %s", receiptName, j, receipt.Logs[j].TxHash.String(), txs[txIndex].Hash().String()) } - from, _ := Sender(signer, txs[i]) - contractAddress := crypto.CreateAddress(from, txs[i].Nonce()) - if txs[i].To() == nil && receipts[i].ContractAddress != contractAddress { - t.Errorf("receipts[%d].ContractAddress = %s, want %s", i, receipts[i].ContractAddress.String(), contractAddress.String()) + if receipt.Logs[j].TxHash != txs[txIndex].Hash() { + t.Errorf("%s.Logs[%d].TxHash = %s, want %s", receiptName, j, receipt.Logs[j].TxHash.String(), txs[txIndex].Hash().String()) } - for j := range receipts[i].Logs { - if receipts[i].Logs[j].BlockNumber != number.Uint64() { - t.Errorf("receipts[%d].Logs[%d].BlockNumber = %d, want %d", i, j, receipts[i].Logs[j].BlockNumber, number.Uint64()) - } - if receipts[i].Logs[j].BlockHash != hash { - t.Errorf("receipts[%d].Logs[%d].BlockHash = %s, want %s", i, j, receipts[i].Logs[j].BlockHash.String(), hash.String()) - } - if receipts[i].Logs[j].TxHash != txs[i].Hash() { - t.Errorf("receipts[%d].Logs[%d].TxHash = %s, want %s", i, j, receipts[i].Logs[j].TxHash.String(), txs[i].Hash().String()) - } - if receipts[i].Logs[j].TxHash != txs[i].Hash() { - t.Errorf("receipts[%d].Logs[%d].TxHash = %s, want %s", i, j, receipts[i].Logs[j].TxHash.String(), txs[i].Hash().String()) - } - if receipts[i].Logs[j].TxIndex != uint(i) { - t.Errorf("receipts[%d].Logs[%d].TransactionIndex = %d, want %d", i, j, receipts[i].Logs[j].TxIndex, i) - } - if receipts[i].Logs[j].Index != logIndex { - t.Errorf("receipts[%d].Logs[%d].Index = %d, want %d", i, j, receipts[i].Logs[j].Index, logIndex) - } - logIndex++ + if receipt.Logs[j].TxIndex != uint(txIndex) { + t.Errorf("%s.Logs[%d].TransactionIndex = %d, want %d", receiptName, j, receipt.Logs[j].TxIndex, txIndex) } } } diff --git a/core/types/transaction.go b/core/types/transaction.go index ec19744881..81f560c1d2 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -19,6 +19,7 @@ package types import ( "container/heap" "errors" + "fmt" "io" "math/big" "sync/atomic" @@ -27,6 +28,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private/engine" "github.com/ethereum/go-ethereum/rlp" ) @@ -36,6 +39,21 @@ var ( ErrInvalidSig = errors.New("invalid transaction v, r, s values") ) +// Quorum +// deriveSigner makes a *best* guess about which signer to use. +func deriveSigner(V *big.Int) Signer { + // joel: this is one of the two places we used a wrong signer to print txes + if V.Sign() != 0 && isProtectedV(V) { + return NewEIP155Signer(deriveChainId(V)) + } else if isPrivate(V) { + return QuorumPrivateTxSigner{} + } else { + return HomesteadSigner{} + } +} + +// End Quorum + type Transaction struct { data txdata // Consensus contents of a transaction time time.Time // Time first seen locally (spam avoidance) @@ -44,6 +62,8 @@ type Transaction struct { hash atomic.Value size atomic.Value from atomic.Value + + privacyMetadata *PrivacyMetadata } type txdata struct { @@ -109,6 +129,19 @@ func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit } } +// Quorum +func NewTxPrivacyMetadata(privacyFlag engine.PrivacyFlagType) *PrivacyMetadata { + return &PrivacyMetadata{ + PrivacyFlag: privacyFlag, + } +} + +func (tx *Transaction) SetTxPrivacyMetadata(pm *PrivacyMetadata) { + tx.privacyMetadata = pm +} + +// End Quorum + // ChainId returns which chain id this transaction was signed for (if at all) func (tx *Transaction) ChainId() *big.Int { return deriveChainId(tx.data.V) @@ -122,7 +155,8 @@ func (tx *Transaction) Protected() bool { func isProtectedV(V *big.Int) bool { if V.BitLen() <= 8 { v := V.Uint64() - return v != 27 && v != 28 + // 27 / 28 are pre eip 155 -- ie unprotected. + return !(v == 27 || v == 28) } // anything not 27 or 28 is considered protected return true @@ -187,9 +221,10 @@ func (tx *Transaction) GasPriceCmp(other *Transaction) int { func (tx *Transaction) GasPriceIntCmp(other *big.Int) int { return tx.data.Price.Cmp(other) } -func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } -func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } -func (tx *Transaction) CheckNonce() bool { return true } +func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } +func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } +func (tx *Transaction) CheckNonce() bool { return true } +func (tx *Transaction) PrivacyMetadata() *PrivacyMetadata { return tx.privacyMetadata } // To returns the recipient address of the transaction. // It returns nil if the transaction is a contract creation. @@ -201,6 +236,14 @@ func (tx *Transaction) To() *common.Address { return &to } +func (tx *Transaction) From() common.Address { + signer := deriveSigner(tx.data.V) + if from, err := Sender(signer, tx); err == nil { + return from + } + return common.Address{} +} + // Hash hashes the RLP encoding of tx. // It uniquely identifies the transaction. func (tx *Transaction) Hash() common.Hash { @@ -238,6 +281,7 @@ func (tx *Transaction) AsMessage(s Signer) (Message, error) { amount: tx.data.Amount, data: tx.data.Payload, checkNonce: true, + isPrivate: tx.IsPrivate(), } var err error @@ -273,6 +317,58 @@ func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) { return tx.data.V, tx.data.R, tx.data.S } +func (tx *Transaction) String() string { + var from, to string + if tx.data.V != nil { + // make a best guess about the signer and use that to derive + // the sender. + signer := deriveSigner(tx.data.V) + if f, err := Sender(signer, tx); err != nil { // derive but don't cache + from = "[invalid sender: invalid sig]" + } else { + from = fmt.Sprintf("%x", f[:]) + } + } else { + from = "[invalid sender: nil V field]" + } + + if tx.data.Recipient == nil { + to = "[contract creation]" + } else { + to = fmt.Sprintf("%x", tx.data.Recipient[:]) + } + enc, _ := rlp.EncodeToBytes(&tx.data) + return fmt.Sprintf(` + TX(%x) + Contract: %v + From: %s + To: %s + Nonce: %v + GasPrice: %#x + GasLimit %#x + Value: %#x + Data: 0x%x + V: %#x + R: %#x + S: %#x + Hex: %x +`, + tx.Hash(), + tx.data.Recipient == nil, + from, + to, + tx.data.AccountNonce, + tx.data.Price, + tx.data.GasLimit, + tx.data.Amount, + tx.data.Payload, + tx.data.V, + tx.data.R, + tx.data.S, + enc, + ) +} + // Transactions is a Transaction slice type for basic sorting. type Transactions []*Transaction @@ -361,10 +457,14 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa // Initialize a price and received time based heap with the head transactions heads := make(TxByPriceAndTime, 0, len(txs)) for from, accTxs := range txs { - heads = append(heads, accTxs[0]) // Ensure the sender address is from the signer - acc, _ := Sender(signer, accTxs[0]) - txs[acc] = accTxs[1:] + acc, err := Sender(signer, accTxs[0]) + if err == nil { + heads = append(heads, accTxs[0]) + txs[acc] = accTxs[1:] + } else { + log.Info("Failed to recovered sender address, this transaction is skipped", "from", from, "nonce", accTxs[0].data.AccountNonce, "err", err) + } if from != acc { delete(txs, from) } @@ -417,6 +517,7 @@ type Message struct { gasPrice *big.Int data []byte checkNonce bool + isPrivate bool } func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message { @@ -440,3 +541,50 @@ func (m Message) Gas() uint64 { return m.gasLimit } func (m Message) Nonce() uint64 { return m.nonce } func (m Message) Data() []byte { return m.data } func (m Message) CheckNonce() bool { return m.checkNonce } + +// Quorum +func (m Message) IsPrivate() bool { + return m.isPrivate +} + +// overriding msg.data so that when tesseera.receive is invoked we get nothing back +func (m Message) WithEmptyPrivateData(b bool) Message { + if b { + m.data = common.EncryptedPayloadHash{}.Bytes() + } + return m +} + +func (tx *Transaction) IsPrivate() bool { + if tx.data.V == nil { + return false + } + return tx.data.V.Uint64() == 37 || tx.data.V.Uint64() == 38 +} + +/* + * Indicates that a transaction is private, but doesn't necessarily set the correct v value, as it can be called on + * an unsigned transaction. + * pre homestead signer, all v values were v=27 or v=28, with EIP155Signer that change, + * but SetPrivate() is also used on unsigned transactions to temporarily set the v value to indicate + * the transaction is intended to be private, and so that the correct signer can be selected. The signer will correctly + * set the valid v value (37 or 38): This helps minimize changes vs upstream go-ethereum code. + */ +func (tx *Transaction) SetPrivate() { + if tx.IsPrivate() { + return + } + if tx.data.V.Int64() == 28 { + tx.data.V.SetUint64(38) + } else { + tx.data.V.SetUint64(37) + } +} + +// PrivacyMetadata encapsulates privacy information to be attached +// to a transaction being processed +type PrivacyMetadata struct { + PrivacyFlag engine.PrivacyFlagType +} + +// End Quorum diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 842fedbd03..41ae8f53a0 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -125,6 +125,9 @@ func (s EIP155Signer) Equal(s2 Signer) bool { var big8 = big.NewInt(8) func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { + if tx.IsPrivate() { + return QuorumPrivateTxSigner{}.Sender(tx) + } if !tx.Protected() { return HomesteadSigner{}.Sender(tx) } @@ -223,7 +226,14 @@ func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (commo if Vb.BitLen() > 8 { return common.Address{}, ErrInvalidSig } - V := byte(Vb.Uint64() - 27) + var offset uint64 + // private transaction has a v value of 37 or 38 + if isPrivate(Vb) { + offset = 37 + } else { + offset = 27 + } + V := byte(Vb.Uint64() - offset) if !crypto.ValidateSignatureValues(V, R, S, homestead) { return common.Address{}, ErrInvalidSig } @@ -253,6 +263,7 @@ func deriveChainId(v *big.Int) *big.Int { if v == 27 || v == 28 { return new(big.Int) } + // TODO(joel): this given v = 37 / 38 this constrains us to chain id 1 return new(big.Int).SetUint64((v - 35) / 2) } v = new(big.Int).Sub(v, big.NewInt(35)) diff --git a/core/types/transaction_signing_private.go b/core/types/transaction_signing_private.go new file mode 100644 index 0000000000..a3130664d9 --- /dev/null +++ b/core/types/transaction_signing_private.go @@ -0,0 +1,61 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +// Signs with Homestead +// obtains sender from EIP55Signer +type QuorumPrivateTxSigner struct{ HomesteadSigner } + +func (s QuorumPrivateTxSigner) Sender(tx *Transaction) (common.Address, error) { + return HomesteadSigner{}.Sender(tx) +} + +// SignatureValues returns signature values. This signature +// needs to be in the [R || S || V] format where V is 0 or 1. +func (qs QuorumPrivateTxSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { + r, s, _, err := HomesteadSigner{}.SignatureValues(tx, sig) + // update v for private transaction marker: needs to be 37 (0+37) or 38 (1+37) for a private transaction. + v := new(big.Int).SetBytes([]byte{sig[64] + 37}) + return r, s, v, nil +} + +// Hash returns the hash to be signed by the sender. +// It does not uniquely identify the transaction. +func (s QuorumPrivateTxSigner) Hash(tx *Transaction) common.Hash { + return s.HomesteadSigner.Hash(tx) +} + +func (s QuorumPrivateTxSigner) Equal(s2 Signer) bool { + _, ok := s2.(QuorumPrivateTxSigner) + return ok +} + +/* + * If v is `37` or `38` that marks the transaction as private in Quorum. + * Note: this means quorum chains cannot have a public ethereum chainId == 1, as the EIP155 v + * param is `37` and `38` for the public Ethereum chain. Having a private chain with a chainId ==1 + * is discouraged in the general Ethereum ecosystem. + */ +func isPrivate(v *big.Int) bool { + return v.Cmp(big.NewInt(37)) == 0 || v.Cmp(big.NewInt(38)) == 0 +} diff --git a/core/types/transaction_signing_quorum_private_test.go b/core/types/transaction_signing_quorum_private_test.go new file mode 100644 index 0000000000..694a3fd29d --- /dev/null +++ b/core/types/transaction_signing_quorum_private_test.go @@ -0,0 +1,62 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "crypto/ecdsa" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + testifyassert "github.com/stretchr/testify/assert" +) + +func signTxWithSigner(signer Signer, key *ecdsa.PrivateKey) (*Transaction, common.Address, error) { + addr := crypto.PubkeyToAddress(key.PublicKey) + tx := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) + signedTx, err := SignTx(tx, signer, key) + return signedTx, addr, err +} + +// run all the tests in this file +// $> go test $(go list ./...) -run QuorumSignPrivate + +// test with QuorumPrivateSigner +/* +* $> go test -run TestQuorumSignPrivateQuorum + */ +func TestQuorumSignPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + keys := []*big.Int{k0v, k1v} + + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + qpPrivateSigner := QuorumPrivateTxSigner{HomesteadSigner{}} + + signedTx, addr, err := signTxWithSigner(qpPrivateSigner, key) + assert.Nil(err, err) + assert.True(signedTx.IsPrivate(), + fmt.Sprintf("The signed transaction is not private, signedTx.data.V is [%v]", signedTx.data.V)) + from, err := Sender(qpPrivateSigner, signedTx) + assert.Nil(err, err) + assert.True(from == addr, fmt.Sprintf("Expected from == address, [%x] == [%x]", from, addr)) + } + +} diff --git a/core/types/transaction_signing_quorum_test.go b/core/types/transaction_signing_quorum_test.go new file mode 100644 index 0000000000..8cce908526 --- /dev/null +++ b/core/types/transaction_signing_quorum_test.go @@ -0,0 +1,354 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + testifyassert "github.com/stretchr/testify/assert" +) + +// run all the tests in this file +// $> go test $(go list ./...) -run TestSignQuorum + +// private key material to test both 0 and 1 bit for the recoveryId (v). +// key with v sign == 28 (Homestead) +var k0v, _ = new(big.Int).SetString("25807260602402504536675820444142779248993100028628438487502323668296269534891", 10) + +// key with v sign == 27 (Homestead) +var k1v, _ = new(big.Int).SetString("10148397294747000913768625849546502595195728826990639993137198410557736548965", 10) + +// helper to deterministically create an ECDSA key from an int. +func createKey(c elliptic.Curve, k *big.Int) (*ecdsa.PrivateKey, error) { + sk := new(ecdsa.PrivateKey) + sk.PublicKey.Curve = c + sk.D = k + sk.PublicKey.X, sk.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) + return sk, nil +} + +func signTx(key *ecdsa.PrivateKey, signer Signer) (*Transaction, common.Address, error) { + addr := crypto.PubkeyToAddress(key.PublicKey) + tx := NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) + signedTx, err := SignTx(tx, signer, key) + //fmt.Printf("\ntx.data.V signTx after sign [%v] \n", signedTx.data.V) + return signedTx, addr, err +} + +/** + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * Test public transactions signed by homestead Signer. Homestead sets the v param on a signed transaction to + * either 27 or 28. The v parameter is used for recovering the sender of the signed transaction. + * + * 1. Homestead: should be 27, 28 + * $> go test -run TestSignQuorumHomesteadPublic + */ +func TestSignQuorumHomesteadPublic(t *testing.T) { + + assert := testifyassert.New(t) + + k0, _ := createKey(crypto.S256(), k0v) + k1, _ := createKey(crypto.S256(), k1v) + + homeSinger := HomesteadSigner{} + + // odd parity should be 27 for Homestead + signedTx, addr, _ := signTx(k1, homeSinger) + + assert.True(signedTx.data.V.Cmp(big.NewInt(27)) == 0, fmt.Sprintf("v wasn't 27 it was [%v]", signedTx.data.V)) + + // recover address from signed TX + from, _ := Sender(homeSinger, signedTx) + //fmt.Printf("from [%v] == addr [%v]\n\n", from, from == addr) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + + // even parity should be 28 for Homestead + signedTx, addr, _ = signTx(k0, homeSinger) + assert.True(signedTx.data.V.Cmp(big.NewInt(28)) == 0, fmt.Sprintf("v wasn't 28 it was [%v]\n", signedTx.data.V)) + + // recover address from signed TX + from, _ = Sender(homeSinger, signedTx) + //fmt.Printf("from [%v] == addr [%v]\n", from, from == addr) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + +} + +/** + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * Test the public transactions signed by the EIP155Signer. + * The EIP155Signer was introduced to protect against replay + * attacks https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md and stores + * the CHAINID in the signed transaction's `v` parameter as `v = chainId * 2 + 35`. + * + * The EthEIP155Signer change breaks private quorum transactions when the chainId == 1 (mainnet chainId), + * as the v parameter on a public transaction and on a private transaction will both be 37, 38. + * + * $> go test -run TestSignQuorumEIP155Public + */ +func TestSignQuorumEIP155Public(t *testing.T) { + + assert := testifyassert.New(t) + + k0, _ := createKey(crypto.S256(), k0v) + k1, _ := createKey(crypto.S256(), k1v) + + // chainId 1 even EIP155Signer should be 37 conflicts with private transaction + var chainId int64 = 2 // 7 2 10 + + v0 := chainId*2 + 35 // sig[64] + 35 .. where sig[64] == 0 + v1 := chainId*2 + 36 // sig[64] + 35 .. where sig[64] == 1 + + // Will calculate v to be `v = CHAINID * 2 + 35` + // To compute V: + // 2 * 2 + 35 == 39 + // 2 * 2 + 36 == 40 + // To retrieve Sender, pull out 27, 28 Eth Frontier / Homestead values. + // 39 - (2 * 2) - 8 == 27 + // 40 - (2 * 2) - 8 == 28 + EIPsigner := NewEIP155Signer(big.NewInt(chainId)) + + signedTx, addr, _ := signTx(k0, EIPsigner) + + //fmt.Printf("After signing V is [%v] \n", signedTx.data.V) + assert.True(signedTx.data.V.Cmp(big.NewInt(v0)) == 0, fmt.Sprintf("v wasn't [%v] it was [%v]\n", v0, signedTx.data.V)) + from, _ := Sender(EIPsigner, signedTx) + + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + + // chainId 1 even EIP155Signer should be 38 conflicts with private transaction + assert.False(signedTx.IsPrivate(), fmt.Sprintf("Public transaction is set to a private transition v == [%v]", signedTx.data.V)) + + signedTx, addr, _ = signTx(k1, EIPsigner) + + assert.True(signedTx.data.V.Cmp(big.NewInt(v1)) == 0, fmt.Sprintf("v wasn't [%v], it was [%v]\n", v1, signedTx.data.V)) + from, _ = Sender(EIPsigner, signedTx) + + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + +} + +/** + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * When the signer is EIP155Signer, chainId == 1 cannot be used because the EIP155 computed `v` value conflicts + * with the private `v` value that quorum uses to indicate a private transaction: v == 37 and v == 38. + * + * $> go test -run TestSignQuorumEIP155FailPublicChain1 + */ +func TestSignQuorumEIP155FailPublicChain1(t *testing.T) { + + assert := testifyassert.New(t) + + k0, _ := createKey(crypto.S256(), k0v) + k1, _ := createKey(crypto.S256(), k1v) + + // chainId 1 even EIP155Signer should be 37.38 which conflicts with private transaction + var chainId int64 = 1 + + v0 := chainId*2 + 35 // sig[64] + 35 .. where sig[64] == 0 + v1 := chainId*2 + 36 // sig[64] + 35 .. where sig[64] == 1 + + // Will calculate v to be `v = CHAINID * 2 + 35` + // To compute V: + // 2 * 1 + 35 == 37 + // 2 * 1 + 36 == 38 + // To retrieve Sender, pull out 27, 28 Eth Frontier / Homestead values. + // 37 - (1 * 2) - 8 == 27 + // 38 - (1 * 2) - 8 == 28 + EIPsigner := NewEIP155Signer(big.NewInt(chainId)) + + signedTx, addr, _ := signTx(k0, EIPsigner) + + // the calculated v value should equal `chainId * 2 + 35 ` + assert.True(signedTx.data.V.Cmp(big.NewInt(v0)) == 0, fmt.Sprintf("v wasn't [%v] it was "+ + "[%v]\n", v0, signedTx.data.V)) + // the sender will not be equal as HomesteadSigner{}.Sender(tx) is used because IsPrivate() will be true + // although it is a public tx. + // This is test to catch when / if this behavior changes. + assert.True(signedTx.IsPrivate(), "A public transaction with EIP155 and chainID 1 is expected to be "+ + "considered private, as its v param conflict with a private transaction. signedTx.IsPrivate() == [%v]", signedTx.IsPrivate()) + from, _ := Sender(EIPsigner, signedTx) + + assert.False(from == addr, fmt.Sprintf("Expected the sender of a public TX from chainId 1, \n "+ + "should not be recoverable from [%x] addr [%v] ", from, addr)) + + signedTx, addr, _ = signTx(k1, EIPsigner) + + // the calculated v value should equal `chainId * 2 + 35` + assert.True(signedTx.data.V.Cmp(big.NewInt(v1)) == 0, + fmt.Sprintf("v wasn't [%v] it was [%v]", v1, signedTx.data.V)) + + // the sender will not be equal as HomesteadSigner{}.Sender(tx) is used because IsPrivate() will be true + // although it is a public tx. + // This is test to catch when / if this behavior changes. + // we are signing the data with EIPsigner and chainID 1, so this would be considered a private tx. + assert.True(signedTx.IsPrivate(), "A public transaction with EIP155 and chainID 1 is expected to "+ + "to be considered private, as its v param conflict with a private transaction. "+ + "signedTx.IsPrivate() == [%v]", signedTx.IsPrivate()) + from, _ = Sender(EIPsigner, signedTx) + + assert.False(from == addr, fmt.Sprintf("Expected the sender of a public TX from chainId 1, "+ + "should not be recoverable from [%x] addr [%v] ", from, addr)) + +} + +/** +* As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior +* +* Use Homestead to sign and EIPSigner to recover. +* +* SendTransaction creates a transaction for the given argument, signs it and submit it to the transaction pool. +* func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { +* Current implementation in `internal/ethapi/api.go` +* +* accounts/keystore/keystore.SignTx(): would hash and sign with homestead +* +* When a private tx (obtained from json params PrivateFor) is submitted `internal/ethapi/api.go`: +* +* 1. sign with HomesteadSigner, this will set the v parameter to +* 27 or 28. // there is no indication that this is a private tx yet. +* +* 2. when submitting a transaction `submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, isPrivate bool)` + check isPrivate param, and call `tx.SetPrivate()`, this will update the `v` signature param (recoveryID) +* from 27 -> 37, 28 -> 38. // this is now considered a private tx. +* +* $> go test -run TestSignQuorumHomesteadEIP155SigningPrivateQuorum +*/ +func TestSignQuorumHomesteadEIP155SigningPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + + keys := []*big.Int{k0v, k1v} + + homeSinger := HomesteadSigner{} + recoverySigner := NewEIP155Signer(big.NewInt(18)) + + // check for both sig[64] == 0, and sig[64] == 1 + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + signedTx, addr, err := signTx(key, homeSinger) + + assert.Nil(err, err) + // set to privateTX after the initial signing, this explicitly sets the v param. + // Note: only works when the tx was signed with the homesteadSinger (v==27 | 28). + signedTx.SetPrivate() + + assert.True(signedTx.IsPrivate(), fmt.Sprintf("Expected the transaction to be private [%v]", signedTx.IsPrivate())) + // Try to recover Sender + from, err := Sender(recoverySigner, signedTx) + + assert.Nil(err, err) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. Got %x want %x", from, addr)) + } + +} + +/* + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * Use Homestead to sign and Homestead to recover. + * + * Signing private transactions with HomesteadSigner, and recovering a private transaction with + * HomesteadSigner works, but the transaction has to be set to private `signedTx.SetPrivate()` after + * the signature and before recovering the address. + * + * $> go test -run TestSignQuorumHomesteadOnlyPrivateQuorum + */ +func TestSignQuorumHomesteadOnlyPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + + // check even and odd parity + keys := []*big.Int{k0v, k1v} + + homeSinger := HomesteadSigner{} + recoverySigner := HomesteadSigner{} + + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + signedTx, addr, err := signTx(key, homeSinger) + + assert.Nil(err, err) + + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + // set to privateTX after the initial signing. + signedTx.SetPrivate() + assert.True(signedTx.IsPrivate(), fmt.Sprintf("Expected the transaction to be "+ + "private [%v]", signedTx.IsPrivate())) + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + + // Try to recover Sender + from, err := Sender(recoverySigner, signedTx) + + assert.Nil(err, err) + assert.True(from == addr, fmt.Sprintf("Expected from and address to be equal. "+ + " Got %x want %x", from, addr)) + } + +} + +/* + * As of quorum v2.2.3 commit be7cc31ce208525ea1822e7d0fee88bf7f14500b 30 April 2019 behavior + * + * Use EIP155 to sign and EIP155 to recover (This is not a valid combination and does **not** work). + * + * Signing private transactions with EIP155Signer, and recovering a private transaction with + * EIP155Signer does **not** work. + * note: deriveChainId only checks for 27, 28 when using EIP155 + * note: In the case where the v param is not 27 or 28 when setting private it will always be set to 37 + * + * $> go test -run TestSignQuorumEIP155OnlyPrivateQuorum + */ +func TestSignQuorumEIP155OnlyPrivateQuorum(t *testing.T) { + + assert := testifyassert.New(t) + + // check even and odd parity + keys := []*big.Int{k0v, k1v} + + EIP155Signer := NewEIP155Signer(big.NewInt(0)) + + for i := 0; i < len(keys); i++ { + key, _ := createKey(crypto.S256(), keys[i]) + signedTx, addr, err := signTx(key, EIP155Signer) + + assert.Nil(err, err) + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + + // set to privateTX after the initial signing. + signedTx.SetPrivate() + + assert.True(signedTx.IsPrivate(), fmt.Sprintf("Expected the transaction to be private [%v]", signedTx.IsPrivate())) + //fmt.Printf("Private tx.data.V Home [%v] \n", signedTx.data.V) + + // Try to recover Sender + from, err := Sender(EIP155Signer, signedTx) + + assert.Nil(err, err) + assert.False(from == addr, fmt.Sprintf("Expected recovery to fail. from [%x] should not equal "+ + "addr [%x]", from, addr)) + + } + +} diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go index 689fc38a9b..0e02bdf796 100644 --- a/core/types/transaction_signing_test.go +++ b/core/types/transaction_signing_test.go @@ -77,22 +77,25 @@ func TestEIP155ChainId(t *testing.T) { } func TestEIP155SigningVitalik(t *testing.T) { - // Test vectors come from http://vitalik.ca/files/eip155_testvec.txt + // Test vectors come from http://vitalik.ca/files/eip155_testvec.txt is not available + // Since we cannot use chainId of 1, new raw transaction and address paris are create as below rule. + // gasPrice: 20 * 10**9, gas: 21000, data: "", to: 0x3535353535353535353535353535353535353535, value: 10**18, nonce: 9, chainid: 10, + // privateKeys used are 0x4646464646464646464646464646464646464646464646464646464646464640 to 0x4646464646464646464646464646464646464646464646464646464646464649 for i, test := range []struct { txRlp, addr string }{ - {"f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce"}, - {"f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112"}, - {"f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be"}, - {"f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0"}, - {"f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554"}, - {"f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4"}, - {"f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35"}, - {"f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332"}, - {"f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029"}, - {"f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008037a024692193af7d2c93f2b105d8d79f91106c4e44bed054b8056e0cb13d1f48c598a01126dbf7c80423fbd2c8b062812d15ad3144caea7f599eed86a17d17da5e9d5d", "0x5fAA510EB3f838aC398a293b5714ad279f9cECF4"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008038a0262959a9f060bf3e205e28e046a3331036d7824487c21f9c9a234da7bf8d947da078c0623a89396c1e49eb24c53e38c2cb44d39e82b66d3e5c3216f55883eaa18f", "0xDe6AB723c23bba740410129F9edc952fD6fbced4"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008038a0ed95916ac3f361c77d91504f7fd9e582926b96f786669356efc5027c96ea59c1a04f8c52b39d3303df7f577b2087f7a550de117f07c3d7eac8d24b2e58fd2cb722", "0x4107c605Be9cFc6C8c625bCB3f762E963472457E"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008038a0e15270bbd1f981aa17b41dba76c6e244439eab3766ac535cfd914fbe7bd45e56a05cd6920d3ad53c16fbe659450b9ff1e52bb3983998d769db5b10b6d42320e0c1", "0x68B48A376F3158362443Ee0DF16f5C30b4aCE9B7"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008038a04007e77c19387f9d59d3d9e64f2f1c961d89e76a4478e000bbba436b03605d58a00edc33fe0f5a8598cc70f8ac7c24d9d22580f51a1fe6e52872819c35df6cc955", "0x14Fe11894410453c01485a7e337c3F63fC512d14"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008037a0a45e844857928b7309f5607180680887fd98940aadd4cc21126ecbe55c4f363fa07c67cab2c7a53b09fdea0f07bce9a7cacb5edfacf19539472e17fd286af2dcf4", "0xAa9b8181391561bCe5199c5b1762aa26832EE548"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008037a0745aa5ba54d4b1cf6d264556c75abce97bfd2d07b9864a298ebcb6dc5268667fa04d6224e1036d4820ac36dfe768c3230b0450f657a2b8b459689da069f2c1a383", "0x9d8A62f656a8d1615C1294fd71e9CFb3E4855A4F"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008038a007d494d57c46ffb9a7d560497751e4f75c10083b1f703b57f155193c34837a07a006f58ebd3d8df59b8d2d8ea484a861592b5c18dc9652075a080758787d2db7ae", "0x5a17650BE84F28Ed583e93E6ed0C99b1D1FC1b34"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008038a0878b3ea61b8135c5f6c6907ea6669fc0f9eb9c90e4b648923498627c4cb8b5b6a02e8de6963a8649f16cadfebf23def96cafd89072ad19ed04c29e5f880e5ede98", "0x0EfbD0bEC0dA8dCc0Ad442A7D337E9CDc2dd6a54"}, + {"f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008037a0fa0fd46b84c9d488558da70103960f1c43400b4d92cc9ca37737bd508635acefa01b2b01c2667ce7b48cc3fcfdba75181d097134ae6e57af4b691ba6d5c118d0c1", "0x0E8E18e1A11E6196f6B82426196027d042Fd6812"}, } { - signer := NewEIP155Signer(big.NewInt(1)) + signer := NewEIP155Signer(big.NewInt(10)) var tx *Transaction err := rlp.DecodeBytes(common.Hex2Bytes(test.txRlp), &tx) @@ -121,17 +124,17 @@ func TestChainId(t *testing.T) { tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) var err error - tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key) + tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(10)), key) if err != nil { t.Fatal(err) } - _, err = Sender(NewEIP155Signer(big.NewInt(2)), tx) + _, err = Sender(NewEIP155Signer(big.NewInt(11)), tx) if err != ErrInvalidChainId { t.Error("expected error:", ErrInvalidChainId) } - _, err = Sender(NewEIP155Signer(big.NewInt(1)), tx) + _, err = Sender(NewEIP155Signer(big.NewInt(10)), tx) if err != nil { t.Error("expected no error") } diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 159cb0c4c4..a35d5860bc 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -50,6 +50,18 @@ var ( HomesteadSigner{}, common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"), ) + + rightvrsTx2, _ = NewTransaction( + 3, + common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), + big.NewInt(10), + 2000, + big.NewInt(0), + common.FromHex("5544"), + ).WithSignature( + HomesteadSigner{}, + common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"), + ) ) func TestTransactionSigHash(t *testing.T) { @@ -73,6 +85,18 @@ func TestTransactionEncode(t *testing.T) { } } +// Test from the original quorum implementation +func TestTransactionEncode2(t *testing.T) { + txb, err := rlp.EncodeToBytes(rightvrsTx2) + if err != nil { + t.Fatalf("encode error: %v", err) + } + should := common.FromHex("f86103808207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3") + if !bytes.Equal(txb, should) { + t.Errorf("encoded RLP mismatch, got %x", txb) + } +} + func decodeTx(data []byte) (*Transaction, error) { var tx Transaction t, err := &tx, rlp.Decode(bytes.NewReader(data), &tx) diff --git a/core/vm/errors.go b/core/vm/errors.go index f6b156a02e..a58b236248 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -39,6 +39,9 @@ var ( ErrGasUintOverflow = errors.New("gas uint64 overflow") ErrInvalidRetsub = errors.New("invalid retsub") ErrReturnStackExceeded = errors.New("return stack limit reached") + + ErrReadOnlyValueTransfer = errors.New("VM in read-only mode. Value transfer prohibited.") + ErrNoCompatibleInterpreter = errors.New("no compatible interpreter") ) // ErrStackUnderflow wraps an evm error when the items on the stack less diff --git a/core/vm/evm.go b/core/vm/evm.go index f5469c500c..a815ef6172 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -23,11 +23,26 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie" "github.com/holiman/uint256" ) +// note: Quorum, States, and Value Transfer +// +// In Quorum there is a tricky issue in one specific case when there is call from private state to public state: +// * The state db is selected based on the callee (public) +// * With every call there is an associated value transfer -- in our case this is 0 +// * Thus, there is an implicit transfer of 0 value from the caller to callee on the public state +// * However in our scenario the caller is private +// * Thus, the transfer creates a ghost of the private account on the public state with no value, code, or storage +// +// The solution is to skip this transfer of 0 value under Quorum + // emptyCodeHash is used by create to ensure deployment is disallowed to already // deployed contract addresses (relevant after the account abstraction). var emptyCodeHash = crypto.Keccak256Hash(nil) @@ -60,6 +75,16 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) { + // Quorum + if contract.CodeAddr != nil { + // Using CodeAddr is favour over contract.Address() + // During DelegateCall() CodeAddr is the address of the delegated account + address := *contract.CodeAddr + if _, ok := evm.affectedContracts[address]; !ok { + evm.affectedContracts[address] = MessageCall + } + } + // End Quorum for _, interpreter := range evm.interpreters { if interpreter.CanRun(contract.Code) { if evm.interpreter != interpreter { @@ -99,6 +124,9 @@ type Context struct { Difficulty *big.Int // Provides information for DIFFICULTY } +type PublicState StateDB +type PrivateState StateDB + // EVM is the Ethereum Virtual Machine base object and provides // the necessary tools to run a contract on the given state with // the provided context. It should be noted that any error @@ -134,11 +162,35 @@ type EVM struct { // available gas is calculated in gasCall* according to the 63/64 rule and later // applied in opCall*. callGasTemp uint64 + + // Quorum additions: + publicState PublicState + privateState PrivateState + states [1027]*state.StateDB // TODO(joel) we should be able to get away with 1024 or maybe 1025 + currentStateDepth uint + + // This flag has different semantics from the `Interpreter:readOnly` flag (though they interact and could maybe + // be simplified). This is set by Quorum when it's inside a Private State -> Public State read. + quorumReadOnly bool + readOnlyDepth uint + + // these are for privacy enhancements and multitenancy + affectedContracts map[common.Address]AffectedReason // affected contract account address -> type + currentTx *types.Transaction // transaction currently being applied on this EVM } +// AffectedReason defines a type of operation that was applied to a contract. +type AffectedReason byte + +const ( + _ AffectedReason = iota + Creation AffectedReason = iota + MessageCall +) + // NewEVM returns a new EVM. The returned EVM is not thread safe and should // only ever be used *once*. -func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { +func NewEVM(ctx Context, statedb, privateState StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { evm := &EVM{ Context: ctx, StateDB: statedb, @@ -146,6 +198,11 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon chainConfig: chainConfig, chainRules: chainConfig.Rules(ctx.BlockNumber), interpreters: make([]Interpreter, 0, 1), + + publicState: statedb, + privateState: privateState, + + affectedContracts: make(map[common.Address]AffectedReason), } if chainConfig.IsEWASM(ctx.BlockNumber) { @@ -164,6 +221,8 @@ func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmCon panic("No supported ewasm interpreter yet.") } + evm.Push(privateState) + // vmConfig.EVMInterpreter will be used by EVM-C, it won't be checked here // as we always want to have the built-in EVM as the failover option. evm.interpreters = append(evm.interpreters, NewEVMInterpreter(evm, vmConfig)) @@ -196,6 +255,10 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if evm.vmConfig.NoRecursion && evm.depth > 0 { return nil, gas, nil } + + evm.Push(getDualState(evm, addr)) + defer func() { evm.Pop() }() + // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -218,7 +281,20 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas } evm.StateDB.CreateAccount(addr) } - evm.Transfer(evm.StateDB, caller.Address(), addr, value) + + // Quorum + if evm.ChainConfig().IsQuorum { + // skip transfer if value /= 0 (see note: Quorum, States, and Value Transfer) + if value.Sign() != 0 { + if evm.quorumReadOnly { + return nil, gas, ErrReadOnlyValueTransfer + } + evm.Transfer(evm.StateDB, caller.Address(), addr, value) + } + // End Quorum + } else { + evm.Transfer(evm.StateDB, caller.Address(), addr, value) + } // Capture the tracer start/end events in debug mode if evm.vmConfig.Debug && evm.depth == 0 { @@ -234,17 +310,13 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. code := evm.StateDB.GetCode(addr) - if len(code) == 0 { - ret, err = nil, nil // gas is unchanged - } else { - addrCopy := addr - // If the account has no code, we can abort here - // The depth-check is already done, and precompiles handled above - contract := NewContract(caller, AccountRef(addrCopy), value, gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) - ret, err = run(evm, contract, input, false) - gas = contract.Gas - } + addrCopy := addr + // If the account has no code, we can abort here + // The depth-check is already done, and precompiles handled above + contract := NewContract(caller, AccountRef(addrCopy), value, gas) + contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) + ret, err = run(evm, contract, input, false) + gas = contract.Gas } // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally @@ -272,6 +344,12 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, if evm.vmConfig.NoRecursion && evm.depth > 0 { return nil, gas, nil } + + // Quorum + evm.Push(getDualState(evm, addr)) + defer func() { evm.Pop() }() + // End Quorum + // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -315,6 +393,12 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by if evm.vmConfig.NoRecursion && evm.depth > 0 { return nil, gas, nil } + + // Quorum + evm.Push(getDualState(evm, addr)) + defer func() { evm.Pop() }() + // End Quorum + // Fail if we're trying to execute above the call depth limit if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth @@ -353,18 +437,23 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth } + // Quorum + // use the right state (public or private) + stateDb := getDualState(evm, addr) + // End Quorum + // We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped. // However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced // after all empty accounts were deleted, so this is not required. However, if we omit this, // then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json. // We could change this, but for now it's left for legacy reasons - var snapshot = evm.StateDB.Snapshot() + var snapshot = stateDb.Snapshot() // We do an AddBalance of zero here, just in order to trigger a touch. // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, // but is the correct thing to do and matters on other networks, in tests, and potential // future scenarios - evm.StateDB.AddBalance(addr, big0) + stateDb.AddBalance(addr, big0) if p, isPrecompile := evm.precompile(addr); isPrecompile { ret, gas, err = RunPrecompiledContract(p, input, gas) @@ -376,7 +465,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. contract := NewContract(caller, AccountRef(addrCopy), new(big.Int), gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) + contract.SetCallCode(&addrCopy, stateDb.GetCodeHash(addrCopy), stateDb.GetCode(addrCopy)) // When an error was returned by the EVM or when setting the creation code // above we revert to the snapshot and consume any gas remaining. Additionally // when we're in Homestead this also counts for code storage gas errors. @@ -384,7 +473,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte gas = contract.Gas } if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) + stateDb.RevertToSnapshot(snapshot) if err != ErrExecutionReverted { gas = 0 } @@ -414,8 +503,25 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } - nonce := evm.StateDB.GetNonce(caller.Address()) - evm.StateDB.SetNonce(caller.Address(), nonce+1) + + // Quorum + // Get the right state in case of a dual state environment. If a sender + // is a transaction (depth == 0) use the public state to derive the address + // and increment the nonce of the public state. If the sender is a contract + // (depth > 0) use the private state to derive the nonce and increment the + // nonce on the private state only. + // + // If the transaction went to a public contract the private and public state + // are the same. + var creatorStateDb StateDB + if evm.depth > 0 { + creatorStateDb = evm.privateState + } else { + creatorStateDb = evm.publicState + } + + nonce := creatorStateDb.GetNonce(caller.Address()) + creatorStateDb.SetNonce(caller.Address(), nonce+1) // Ensure there's no existing contract already at the designated address contractHash := evm.StateDB.GetCodeHash(address) @@ -425,10 +531,31 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Create a new account on the state snapshot := evm.StateDB.Snapshot() evm.StateDB.CreateAccount(address) + // Quorum + evm.affectedContracts[address] = Creation + // End Quorum if evm.chainRules.IsEIP158 { evm.StateDB.SetNonce(address, 1) } - evm.Transfer(evm.StateDB, caller.Address(), address, value) + if nil != evm.currentTx && evm.currentTx.IsPrivate() && evm.currentTx.PrivacyMetadata() != nil { + // for calls (reading contract state) or finding the affected contracts there is no transaction + if evm.currentTx.PrivacyMetadata().PrivacyFlag.IsNotStandardPrivate() { + pm := state.NewStatePrivacyMetadata(common.BytesToEncryptedPayloadHash(evm.currentTx.Data()), evm.currentTx.PrivacyMetadata().PrivacyFlag) + evm.StateDB.SetPrivacyMetadata(address, pm) + log.Trace("Set Privacy Metadata", "key", address, "privacyMetadata", pm) + } + } + if evm.ChainConfig().IsQuorum { + // skip transfer if value /= 0 (see note: Quorum, States, and Value Transfer) + if value.Sign() != 0 { + if evm.quorumReadOnly { + return nil, common.Address{}, gas, ErrReadOnlyValueTransfer + } + evm.Transfer(evm.StateDB, caller.Address(), address, value) + } + } else { + evm.Transfer(evm.StateDB, caller.Address(), address, value) + } // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. @@ -446,8 +573,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, ret, err := run(evm, contract, nil, false) - // check whether the max code size has been exceeded - maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize + maxCodeSize := evm.ChainConfig().GetMaxCodeSize(evm.BlockNumber) + // check whether the max code size has been exceeded, check maxcode size from chain config + maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > maxCodeSize // if the contract creation ran successfully and no errors were returned // calculate the gas required to store the code. If the code could not // be stored due to not enough gas set an error and let it be handled @@ -483,7 +611,25 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Create creates a new contract using code as deployment code. func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) + // Quorum + // Get the right state in case of a dual state environment. If a sender + // is a transaction (depth == 0) use the public state to derive the address + // and increment the nonce of the public state. If the sender is a contract + // (depth > 0) use the private state to derive the nonce and increment the + // nonce on the private state only. + // + // If the transaction went to a public contract the private and public state + // are the same. + var creatorStateDb StateDB + if evm.depth > 0 { + creatorStateDb = evm.privateState + } else { + creatorStateDb = evm.publicState + } + + // Ensure there's no existing contract already at the designated address + nonce := creatorStateDb.GetNonce(caller.Address()) + contractAddr = crypto.CreateAddress(caller.Address(), nonce) return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr) } @@ -499,3 +645,105 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment * // ChainConfig returns the environment's chain configuration func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } + +// Quorum functions for dual state +func getDualState(evm *EVM, addr common.Address) StateDB { + // priv: (a) -> (b) (private) + // pub: a -> [b] (private -> public) + // priv: (a) -> b (public) + state := evm.StateDB + + if evm.PrivateState().Exist(addr) { + state = evm.PrivateState() + } else if evm.PublicState().Exist(addr) { + state = evm.PublicState() + } + + return state +} + +func (evm *EVM) PublicState() PublicState { return evm.publicState } +func (evm *EVM) PrivateState() PrivateState { return evm.privateState } +func (evm *EVM) SetCurrentTX(tx *types.Transaction) { evm.currentTx = tx } +func (evm *EVM) SetTxPrivacyMetadata(pm *types.PrivacyMetadata) { + evm.currentTx.SetTxPrivacyMetadata(pm) +} +func (evm *EVM) Push(statedb StateDB) { + // Quorum : the read only depth to be set up only once for the entire + // op code execution. This will be set first time transition from + // private state to public state happens + // statedb will be the state of the contract being called. + // if a private contract is calling a public contract make it readonly. + if !evm.quorumReadOnly && evm.privateState != statedb { + evm.quorumReadOnly = true + evm.readOnlyDepth = evm.currentStateDepth + } + + if castedStateDb, ok := statedb.(*state.StateDB); ok { + evm.states[evm.currentStateDepth] = castedStateDb + evm.currentStateDepth++ + } + + evm.StateDB = statedb +} +func (evm *EVM) Pop() { + evm.currentStateDepth-- + if evm.quorumReadOnly && evm.currentStateDepth == evm.readOnlyDepth { + evm.quorumReadOnly = false + } + evm.StateDB = evm.states[evm.currentStateDepth-1] +} + +func (evm *EVM) Depth() int { return evm.depth } + +// We only need to revert the current state because when we call from private +// public state it's read only, there wouldn't be anything to reset. +// (A)->(B)->C->(B): A failure in (B) wouldn't need to reset C, as C was flagged +// read only. +func (evm *EVM) RevertToSnapshot(snapshot int) { + evm.StateDB.RevertToSnapshot(snapshot) +} + +// Quorum +// +// Returns addresses of contracts which are newly created +func (evm *EVM) CreatedContracts() []common.Address { + addr := make([]common.Address, 0, len(evm.affectedContracts)) + for a, t := range evm.affectedContracts { + if t == Creation { + addr = append(addr, a) + } + } + return addr[:] +} + +// Quorum +// +// AffectedContracts returns all affected contracts that are the results of +// MessageCall transaction +func (evm *EVM) AffectedContracts() []common.Address { + addr := make([]common.Address, 0, len(evm.affectedContracts)) + for a, t := range evm.affectedContracts { + if t == MessageCall { + addr = append(addr, a) + } + } + return addr[:] +} + +// Quorum +// +// Return MerkleRoot of all affected contracts (due to both creation and message call) +func (evm *EVM) CalculateMerkleRoot() (common.Hash, error) { + combined := new(trie.Trie) + for addr := range evm.affectedContracts { + data, err := getDualState(evm, addr).GetRLPEncodedStateObject(addr) + if err != nil { + return common.Hash{}, err + } + if err := combined.TryUpdate(addr.Bytes(), data); err != nil { + return common.Hash{}, err + } + } + return combined.Hash(), nil +} diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 6655f9bf42..b8cc5e5a14 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -95,8 +95,9 @@ var ( func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( + db = getDualState(evm, contract.Address()) y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), common.Hash(x.Bytes32())) + current = db.GetState(contract.Address(), common.Hash(x.Bytes32())) ) // The legacy gas metering only takes into consideration the current state // Legacy rules should be applied if we are in Petersburg (removal of EIP-1283) @@ -332,10 +333,10 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize address = common.Address(stack.Back(1).Bytes20()) ) if evm.chainRules.IsEIP158 { - if transfersValue && evm.StateDB.Empty(address) { + if transfersValue && getDualState(evm, address).Empty(address) { gas += params.CallNewAccountGas } - } else if !evm.StateDB.Exist(address) { + } else if !getDualState(evm, address).Exist(address) { gas += params.CallNewAccountGas } if transfersValue { diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index 419c903062..6a273c9584 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -91,7 +91,7 @@ func TestEIP2200(t *testing.T) { CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true }, Transfer: func(StateDB, common.Address, common.Address, *big.Int) {}, } - vmenv := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) + vmenv := NewEVM(vmctx, statedb, statedb, params.AllEthashProtocolChanges, Config{ExtraEips: []int{2200}}) _, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(big.Int)) if err != tt.failure { diff --git a/core/vm/instructions.go b/core/vm/instructions.go index adf44b7f48..00460d60cc 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -258,8 +258,10 @@ func opAddress(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([ func opBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { slot := callContext.stack.peek() - address := common.Address(slot.Bytes20()) - slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address)) + addr := common.Address(slot.Bytes20()) + // Quorum: get public/private state db based on addr + balance := getDualState(interpreter.evm, addr).GetBalance(addr) + slot.SetFromBig(balance) return nil, nil } @@ -341,7 +343,10 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *call func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { slot := callContext.stack.peek() - slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.Address(slot.Bytes20())))) + addr := common.Address(slot.Bytes20()) + // Quorum: get public/private state db based on addr + slot.SetUint64(uint64(getDualState(interpreter.evm, addr).GetCodeSize(addr))) + return nil, nil } @@ -381,7 +386,8 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx uint64CodeOffset = 0xffffffffffffffff } addr := common.Address(a.Bytes20()) - codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64()) + codeCopy := getData(getDualState(interpreter.evm, addr).GetCode(addr), uint64CodeOffset, length.Uint64()) + // Quorum: get public/private state db based on addr callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) return nil, nil @@ -416,10 +422,11 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { slot := callContext.stack.peek() address := common.Address(slot.Bytes20()) - if interpreter.evm.StateDB.Empty(address) { + stateDB := getDualState(interpreter.evm, address) + if stateDB.Empty(address) { slot.Clear() } else { - slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) + slot.SetBytes(stateDB.GetCodeHash(address).Bytes()) } return nil, nil } @@ -508,7 +515,8 @@ func opMstore8(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([ func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { loc := callContext.stack.peek() hash := common.Hash(loc.Bytes32()) - val := interpreter.evm.StateDB.GetState(callContext.contract.Address(), hash) + // Quorum: get public/private state db based on addr + val := getDualState(interpreter.evm, callContext.contract.Address()).GetState(callContext.contract.Address(), hash) loc.SetBytes(val.Bytes()) return nil, nil } @@ -516,7 +524,8 @@ func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]b func opSstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { loc := callContext.stack.pop() val := callContext.stack.pop() - interpreter.evm.StateDB.SetState(callContext.contract.Address(), + // Quorum: get public/private state db based on addr + getDualState(interpreter.evm, callContext.contract.Address()).SetState(callContext.contract.Address(), common.Hash(loc.Bytes32()), common.Hash(val.Bytes32())) return nil, nil } @@ -816,9 +825,11 @@ func opStop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { beneficiary := callContext.stack.pop() - balance := interpreter.evm.StateDB.GetBalance(callContext.contract.Address()) - interpreter.evm.StateDB.AddBalance(common.Address(beneficiary.Bytes20()), balance) - interpreter.evm.StateDB.Suicide(callContext.contract.Address()) + // Quorum: get public/private state db based on addr + db := getDualState(interpreter.evm, callContext.contract.Address()) + balance := db.GetBalance(callContext.contract.Address()) + db.AddBalance(common.Address(beneficiary.Bytes20()), balance) + db.Suicide(callContext.contract.Address()) return nil, nil } diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 0b6fb1f486..ec6c3fd4c2 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -92,7 +92,7 @@ func init() { func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack = newstack() rstack = newReturnStack() pc = uint64(0) @@ -192,7 +192,7 @@ func TestSAR(t *testing.T) { func TestAddMod(t *testing.T) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack = newstack() evmInterpreter = NewEVMInterpreter(env, env.vmConfig) pc = uint64(0) @@ -231,7 +231,7 @@ func TestAddMod(t *testing.T) { // getResult is a convenience function to generate the expected values func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack, rstack = newstack(), newReturnStack() pc = uint64(0) interpreter = env.interpreter.(*EVMInterpreter) @@ -281,7 +281,7 @@ func TestJsonTestcases(t *testing.T) { func opBenchmark(bench *testing.B, op executionFunc, args ...string) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack, rstack = newstack(), newReturnStack() evmInterpreter = NewEVMInterpreter(env, env.vmConfig) ) @@ -515,7 +515,7 @@ func BenchmarkOpIsZero(b *testing.B) { func TestOpMstore(t *testing.T) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack, rstack = newstack(), newReturnStack() mem = NewMemory() evmInterpreter = NewEVMInterpreter(env, env.vmConfig) @@ -539,7 +539,7 @@ func TestOpMstore(t *testing.T) { func BenchmarkOpMstore(bench *testing.B) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack, rstack = newstack(), newReturnStack() mem = NewMemory() evmInterpreter = NewEVMInterpreter(env, env.vmConfig) @@ -560,7 +560,7 @@ func BenchmarkOpMstore(bench *testing.B) { func BenchmarkOpSHA3(bench *testing.B) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + env = NewEVM(Context{}, nil, nil, params.TestChainConfig, Config{}) stack, rstack = newstack(), newReturnStack() mem = NewMemory() evmInterpreter = NewEVMInterpreter(env, env.vmConfig) diff --git a/core/vm/interface.go b/core/vm/interface.go index dd401466ad..af0c373fbe 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -14,29 +14,71 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:generate mockgen -source interface.go -destination mock_interface.go -package vm + package vm import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" ) +type AccountExtraDataStateGetter interface { + // Return nil for public contract + GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) + GetManagedParties(addr common.Address) ([]string, error) +} + +type AccountExtraDataStateSetter interface { + SetPrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) + SetManagedParties(addr common.Address, managedParties []string) +} + +// Quorum uses a cut-down StateDB, MinimalApiState. We leave the methods in StateDB commented out so they'll produce a +// conflict when upstream changes. +type MinimalApiState interface { + AccountExtraDataStateGetter + + GetBalance(addr common.Address) *big.Int + SetBalance(addr common.Address, balance *big.Int) + GetCode(addr common.Address) []byte + GetState(a common.Address, b common.Hash) common.Hash + GetNonce(addr common.Address) uint64 + SetNonce(addr common.Address, nonce uint64) + SetCode(common.Address, []byte) + + // RLP-encoded of the state object in a given address + // Throw error if no state object is found + GetRLPEncodedStateObject(addr common.Address) ([]byte, error) + GetProof(common.Address) ([][]byte, error) + GetStorageProof(common.Address, common.Hash) ([][]byte, error) + StorageTrie(addr common.Address) state.Trie + Error() error + GetCodeHash(common.Address) common.Hash + SetState(common.Address, common.Hash, common.Hash) + SetStorage(addr common.Address, storage map[common.Hash]common.Hash) +} + // StateDB is an EVM database for full state querying. type StateDB interface { + MinimalApiState + AccountExtraDataStateSetter + CreateAccount(common.Address) SubBalance(common.Address, *big.Int) AddBalance(common.Address, *big.Int) - GetBalance(common.Address) *big.Int + //GetBalance(common.Address) *big.Int - GetNonce(common.Address) uint64 - SetNonce(common.Address, uint64) + //GetNonce(common.Address) uint64 + //SetNonce(common.Address, uint64) - GetCodeHash(common.Address) common.Hash - GetCode(common.Address) []byte - SetCode(common.Address, []byte) + //GetCodeHash(common.Address) common.Hash + //GetCode(common.Address) []byte + //SetCode(common.Address, []byte) GetCodeSize(common.Address) int AddRefund(uint64) @@ -44,8 +86,8 @@ type StateDB interface { GetRefund() uint64 GetCommittedState(common.Address, common.Hash) common.Hash - GetState(common.Address, common.Hash) common.Hash - SetState(common.Address, common.Hash, common.Hash) + //GetState(common.Address, common.Hash) common.Hash + //SetState(common.Address, common.Hash, common.Hash) Suicide(common.Address) bool HasSuicided(common.Address) bool diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 1e2a661deb..1b42397eba 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -17,6 +17,7 @@ package vm import ( + "fmt" "hash" "sync/atomic" @@ -230,6 +231,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( } else if sLen > operation.maxStack { return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack} } + + if in.evm.quorumReadOnly && operation.writes { + return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited") + } // If the operation is valid, enforce and write restrictions if in.readOnly && in.evm.chainRules.IsByzantium { // If the interpreter is operating in readonly mode, make sure no diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go index e287f0c7aa..e390b8903c 100644 --- a/core/vm/logger_test.go +++ b/core/vm/logger_test.go @@ -51,7 +51,8 @@ func (*dummyStatedb) GetRefund() uint64 { return 1337 } func TestStoreCapture(t *testing.T) { var ( - env = NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{}) + db = &dummyStatedb{} + env = NewEVM(Context{}, db, db, params.TestChainConfig, Config{}) logger = NewStructLogger(nil) mem = NewMemory() stack = newstack() diff --git a/core/vm/mock_interface.go b/core/vm/mock_interface.go new file mode 100644 index 0000000000..5060315167 --- /dev/null +++ b/core/vm/mock_interface.go @@ -0,0 +1,957 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interface.go + +// Package vm is a generated GoMock package. +package vm + +import ( + big "math/big" + reflect "reflect" + + common "github.com/ethereum/go-ethereum/common" + state "github.com/ethereum/go-ethereum/core/state" + types "github.com/ethereum/go-ethereum/core/types" + gomock "github.com/golang/mock/gomock" +) + +// MockAccountExtraDataStateGetter is a mock of AccountExtraDataStateGetter interface. +type MockAccountExtraDataStateGetter struct { + ctrl *gomock.Controller + recorder *MockAccountExtraDataStateGetterMockRecorder +} + +// MockAccountExtraDataStateGetterMockRecorder is the mock recorder for MockAccountExtraDataStateGetter. +type MockAccountExtraDataStateGetterMockRecorder struct { + mock *MockAccountExtraDataStateGetter +} + +// NewMockAccountExtraDataStateGetter creates a new mock instance. +func NewMockAccountExtraDataStateGetter(ctrl *gomock.Controller) *MockAccountExtraDataStateGetter { + mock := &MockAccountExtraDataStateGetter{ctrl: ctrl} + mock.recorder = &MockAccountExtraDataStateGetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAccountExtraDataStateGetter) EXPECT() *MockAccountExtraDataStateGetterMockRecorder { + return m.recorder +} + +// GetPrivacyMetadata mocks base method. +func (m *MockAccountExtraDataStateGetter) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPrivacyMetadata", addr) + ret0, _ := ret[0].(*state.PrivacyMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPrivacyMetadata indicates an expected call of GetPrivacyMetadata. +func (mr *MockAccountExtraDataStateGetterMockRecorder) GetPrivacyMetadata(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivacyMetadata", reflect.TypeOf((*MockAccountExtraDataStateGetter)(nil).GetPrivacyMetadata), addr) +} + +// GetManagedParties mocks base method. +func (m *MockAccountExtraDataStateGetter) GetManagedParties(addr common.Address) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetManagedParties", addr) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetManagedParties indicates an expected call of GetManagedParties. +func (mr *MockAccountExtraDataStateGetterMockRecorder) GetManagedParties(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetManagedParties", reflect.TypeOf((*MockAccountExtraDataStateGetter)(nil).GetManagedParties), addr) +} + +// MockAccountExtraDataStateSetter is a mock of AccountExtraDataStateSetter interface. +type MockAccountExtraDataStateSetter struct { + ctrl *gomock.Controller + recorder *MockAccountExtraDataStateSetterMockRecorder +} + +// MockAccountExtraDataStateSetterMockRecorder is the mock recorder for MockAccountExtraDataStateSetter. +type MockAccountExtraDataStateSetterMockRecorder struct { + mock *MockAccountExtraDataStateSetter +} + +// NewMockAccountExtraDataStateSetter creates a new mock instance. +func NewMockAccountExtraDataStateSetter(ctrl *gomock.Controller) *MockAccountExtraDataStateSetter { + mock := &MockAccountExtraDataStateSetter{ctrl: ctrl} + mock.recorder = &MockAccountExtraDataStateSetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAccountExtraDataStateSetter) EXPECT() *MockAccountExtraDataStateSetterMockRecorder { + return m.recorder +} + +// SetPrivacyMetadata mocks base method. +func (m *MockAccountExtraDataStateSetter) SetPrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetPrivacyMetadata", addr, pm) +} + +// SetPrivacyMetadata indicates an expected call of SetPrivacyMetadata. +func (mr *MockAccountExtraDataStateSetterMockRecorder) SetPrivacyMetadata(addr, pm interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrivacyMetadata", reflect.TypeOf((*MockAccountExtraDataStateSetter)(nil).SetPrivacyMetadata), addr, pm) +} + +// SetManagedParties mocks base method. +func (m *MockAccountExtraDataStateSetter) SetManagedParties(addr common.Address, managedParties []string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetManagedParties", addr, managedParties) +} + +// SetManagedParties indicates an expected call of SetManagedParties. +func (mr *MockAccountExtraDataStateSetterMockRecorder) SetManagedParties(addr, managedParties interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetManagedParties", reflect.TypeOf((*MockAccountExtraDataStateSetter)(nil).SetManagedParties), addr, managedParties) +} + +// MockMinimalApiState is a mock of MinimalApiState interface. +type MockMinimalApiState struct { + ctrl *gomock.Controller + recorder *MockMinimalApiStateMockRecorder +} + +// MockMinimalApiStateMockRecorder is the mock recorder for MockMinimalApiState. +type MockMinimalApiStateMockRecorder struct { + mock *MockMinimalApiState +} + +// NewMockMinimalApiState creates a new mock instance. +func NewMockMinimalApiState(ctrl *gomock.Controller) *MockMinimalApiState { + mock := &MockMinimalApiState{ctrl: ctrl} + mock.recorder = &MockMinimalApiStateMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockMinimalApiState) EXPECT() *MockMinimalApiStateMockRecorder { + return m.recorder +} + +// GetPrivacyMetadata mocks base method. +func (m *MockMinimalApiState) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPrivacyMetadata", addr) + ret0, _ := ret[0].(*state.PrivacyMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPrivacyMetadata indicates an expected call of GetPrivacyMetadata. +func (mr *MockMinimalApiStateMockRecorder) GetPrivacyMetadata(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivacyMetadata", reflect.TypeOf((*MockMinimalApiState)(nil).GetPrivacyMetadata), addr) +} + +// GetManagedParties mocks base method. +func (m *MockMinimalApiState) GetManagedParties(addr common.Address) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetManagedParties", addr) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetManagedParties indicates an expected call of GetManagedParties. +func (mr *MockMinimalApiStateMockRecorder) GetManagedParties(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetManagedParties", reflect.TypeOf((*MockMinimalApiState)(nil).GetManagedParties), addr) +} + +// GetBalance mocks base method. +func (m *MockMinimalApiState) GetBalance(addr common.Address) *big.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBalance", addr) + ret0, _ := ret[0].(*big.Int) + return ret0 +} + +// GetBalance indicates an expected call of GetBalance. +func (mr *MockMinimalApiStateMockRecorder) GetBalance(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockMinimalApiState)(nil).GetBalance), addr) +} + +// SetBalance mocks base method. +func (m *MockMinimalApiState) SetBalance(addr common.Address, balance *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetBalance", addr, balance) +} + +// SetBalance indicates an expected call of SetBalance. +func (mr *MockMinimalApiStateMockRecorder) SetBalance(addr, balance interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBalance", reflect.TypeOf((*MockMinimalApiState)(nil).SetBalance), addr, balance) +} + +// GetCode mocks base method. +func (m *MockMinimalApiState) GetCode(addr common.Address) []byte { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCode", addr) + ret0, _ := ret[0].([]byte) + return ret0 +} + +// GetCode indicates an expected call of GetCode. +func (mr *MockMinimalApiStateMockRecorder) GetCode(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCode", reflect.TypeOf((*MockMinimalApiState)(nil).GetCode), addr) +} + +// GetState mocks base method. +func (m *MockMinimalApiState) GetState(a common.Address, b common.Hash) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetState", a, b) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetState indicates an expected call of GetState. +func (mr *MockMinimalApiStateMockRecorder) GetState(a, b interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockMinimalApiState)(nil).GetState), a, b) +} + +// GetNonce mocks base method. +func (m *MockMinimalApiState) GetNonce(addr common.Address) uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNonce", addr) + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetNonce indicates an expected call of GetNonce. +func (mr *MockMinimalApiStateMockRecorder) GetNonce(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNonce", reflect.TypeOf((*MockMinimalApiState)(nil).GetNonce), addr) +} + +// SetNonce mocks base method. +func (m *MockMinimalApiState) SetNonce(addr common.Address, nonce uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetNonce", addr, nonce) +} + +// SetNonce indicates an expected call of SetNonce. +func (mr *MockMinimalApiStateMockRecorder) SetNonce(addr, nonce interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNonce", reflect.TypeOf((*MockMinimalApiState)(nil).SetNonce), addr, nonce) +} + +// SetCode mocks base method. +func (m *MockMinimalApiState) SetCode(arg0 common.Address, arg1 []byte) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCode", arg0, arg1) +} + +// SetCode indicates an expected call of SetCode. +func (mr *MockMinimalApiStateMockRecorder) SetCode(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCode", reflect.TypeOf((*MockMinimalApiState)(nil).SetCode), arg0, arg1) +} + +// GetRLPEncodedStateObject mocks base method. +func (m *MockMinimalApiState) GetRLPEncodedStateObject(addr common.Address) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRLPEncodedStateObject", addr) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRLPEncodedStateObject indicates an expected call of GetRLPEncodedStateObject. +func (mr *MockMinimalApiStateMockRecorder) GetRLPEncodedStateObject(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRLPEncodedStateObject", reflect.TypeOf((*MockMinimalApiState)(nil).GetRLPEncodedStateObject), addr) +} + +// GetProof mocks base method. +func (m *MockMinimalApiState) GetProof(arg0 common.Address) ([][]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProof", arg0) + ret0, _ := ret[0].([][]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetProof indicates an expected call of GetProof. +func (mr *MockMinimalApiStateMockRecorder) GetProof(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMinimalApiState)(nil).GetProof), arg0) +} + +// GetStorageProof mocks base method. +func (m *MockMinimalApiState) GetStorageProof(arg0 common.Address, arg1 common.Hash) ([][]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStorageProof", arg0, arg1) + ret0, _ := ret[0].([][]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStorageProof indicates an expected call of GetStorageProof. +func (mr *MockMinimalApiStateMockRecorder) GetStorageProof(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageProof", reflect.TypeOf((*MockMinimalApiState)(nil).GetStorageProof), arg0, arg1) +} + +// StorageTrie mocks base method. +func (m *MockMinimalApiState) StorageTrie(addr common.Address) state.Trie { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageTrie", addr) + ret0, _ := ret[0].(state.Trie) + return ret0 +} + +// StorageTrie indicates an expected call of StorageTrie. +func (mr *MockMinimalApiStateMockRecorder) StorageTrie(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageTrie", reflect.TypeOf((*MockMinimalApiState)(nil).StorageTrie), addr) +} + +// Error mocks base method. +func (m *MockMinimalApiState) Error() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Error") + ret0, _ := ret[0].(error) + return ret0 +} + +// Error indicates an expected call of Error. +func (mr *MockMinimalApiStateMockRecorder) Error() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockMinimalApiState)(nil).Error)) +} + +// GetCodeHash mocks base method. +func (m *MockMinimalApiState) GetCodeHash(arg0 common.Address) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCodeHash", arg0) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetCodeHash indicates an expected call of GetCodeHash. +func (mr *MockMinimalApiStateMockRecorder) GetCodeHash(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCodeHash", reflect.TypeOf((*MockMinimalApiState)(nil).GetCodeHash), arg0) +} + +// SetState mocks base method. +func (m *MockMinimalApiState) SetState(arg0 common.Address, arg1, arg2 common.Hash) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetState", arg0, arg1, arg2) +} + +// SetState indicates an expected call of SetState. +func (mr *MockMinimalApiStateMockRecorder) SetState(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*MockMinimalApiState)(nil).SetState), arg0, arg1, arg2) +} + +// SetStorage mocks base method. +func (m *MockMinimalApiState) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetStorage", addr, storage) +} + +// SetStorage indicates an expected call of SetStorage. +func (mr *MockMinimalApiStateMockRecorder) SetStorage(addr, storage interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStorage", reflect.TypeOf((*MockMinimalApiState)(nil).SetStorage), addr, storage) +} + +// MockStateDB is a mock of StateDB interface. +type MockStateDB struct { + ctrl *gomock.Controller + recorder *MockStateDBMockRecorder +} + +// MockStateDBMockRecorder is the mock recorder for MockStateDB. +type MockStateDBMockRecorder struct { + mock *MockStateDB +} + +// NewMockStateDB creates a new mock instance. +func NewMockStateDB(ctrl *gomock.Controller) *MockStateDB { + mock := &MockStateDB{ctrl: ctrl} + mock.recorder = &MockStateDBMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStateDB) EXPECT() *MockStateDBMockRecorder { + return m.recorder +} + +// GetPrivacyMetadata mocks base method. +func (m *MockStateDB) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPrivacyMetadata", addr) + ret0, _ := ret[0].(*state.PrivacyMetadata) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPrivacyMetadata indicates an expected call of GetPrivacyMetadata. +func (mr *MockStateDBMockRecorder) GetPrivacyMetadata(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivacyMetadata", reflect.TypeOf((*MockStateDB)(nil).GetPrivacyMetadata), addr) +} + +// GetManagedParties mocks base method. +func (m *MockStateDB) GetManagedParties(addr common.Address) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetManagedParties", addr) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetManagedParties indicates an expected call of GetManagedParties. +func (mr *MockStateDBMockRecorder) GetManagedParties(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetManagedParties", reflect.TypeOf((*MockStateDB)(nil).GetManagedParties), addr) +} + +// GetBalance mocks base method. +func (m *MockStateDB) GetBalance(addr common.Address) *big.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBalance", addr) + ret0, _ := ret[0].(*big.Int) + return ret0 +} + +// GetBalance indicates an expected call of GetBalance. +func (mr *MockStateDBMockRecorder) GetBalance(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockStateDB)(nil).GetBalance), addr) +} + +// SetBalance mocks base method. +func (m *MockStateDB) SetBalance(addr common.Address, balance *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetBalance", addr, balance) +} + +// SetBalance indicates an expected call of SetBalance. +func (mr *MockStateDBMockRecorder) SetBalance(addr, balance interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBalance", reflect.TypeOf((*MockStateDB)(nil).SetBalance), addr, balance) +} + +// GetCode mocks base method. +func (m *MockStateDB) GetCode(addr common.Address) []byte { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCode", addr) + ret0, _ := ret[0].([]byte) + return ret0 +} + +// GetCode indicates an expected call of GetCode. +func (mr *MockStateDBMockRecorder) GetCode(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCode", reflect.TypeOf((*MockStateDB)(nil).GetCode), addr) +} + +// GetState mocks base method. +func (m *MockStateDB) GetState(a common.Address, b common.Hash) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetState", a, b) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetState indicates an expected call of GetState. +func (mr *MockStateDBMockRecorder) GetState(a, b interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockStateDB)(nil).GetState), a, b) +} + +// GetNonce mocks base method. +func (m *MockStateDB) GetNonce(addr common.Address) uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNonce", addr) + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetNonce indicates an expected call of GetNonce. +func (mr *MockStateDBMockRecorder) GetNonce(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNonce", reflect.TypeOf((*MockStateDB)(nil).GetNonce), addr) +} + +// SetNonce mocks base method. +func (m *MockStateDB) SetNonce(addr common.Address, nonce uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetNonce", addr, nonce) +} + +// SetNonce indicates an expected call of SetNonce. +func (mr *MockStateDBMockRecorder) SetNonce(addr, nonce interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNonce", reflect.TypeOf((*MockStateDB)(nil).SetNonce), addr, nonce) +} + +// SetCode mocks base method. +func (m *MockStateDB) SetCode(arg0 common.Address, arg1 []byte) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCode", arg0, arg1) +} + +// SetCode indicates an expected call of SetCode. +func (mr *MockStateDBMockRecorder) SetCode(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCode", reflect.TypeOf((*MockStateDB)(nil).SetCode), arg0, arg1) +} + +// GetRLPEncodedStateObject mocks base method. +func (m *MockStateDB) GetRLPEncodedStateObject(addr common.Address) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRLPEncodedStateObject", addr) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRLPEncodedStateObject indicates an expected call of GetRLPEncodedStateObject. +func (mr *MockStateDBMockRecorder) GetRLPEncodedStateObject(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRLPEncodedStateObject", reflect.TypeOf((*MockStateDB)(nil).GetRLPEncodedStateObject), addr) +} + +// GetProof mocks base method. +func (m *MockStateDB) GetProof(arg0 common.Address) ([][]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProof", arg0) + ret0, _ := ret[0].([][]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetProof indicates an expected call of GetProof. +func (mr *MockStateDBMockRecorder) GetProof(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockStateDB)(nil).GetProof), arg0) +} + +// GetStorageProof mocks base method. +func (m *MockStateDB) GetStorageProof(arg0 common.Address, arg1 common.Hash) ([][]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStorageProof", arg0, arg1) + ret0, _ := ret[0].([][]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetStorageProof indicates an expected call of GetStorageProof. +func (mr *MockStateDBMockRecorder) GetStorageProof(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStorageProof", reflect.TypeOf((*MockStateDB)(nil).GetStorageProof), arg0, arg1) +} + +// StorageTrie mocks base method. +func (m *MockStateDB) StorageTrie(addr common.Address) state.Trie { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StorageTrie", addr) + ret0, _ := ret[0].(state.Trie) + return ret0 +} + +// StorageTrie indicates an expected call of StorageTrie. +func (mr *MockStateDBMockRecorder) StorageTrie(addr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageTrie", reflect.TypeOf((*MockStateDB)(nil).StorageTrie), addr) +} + +// Error mocks base method. +func (m *MockStateDB) Error() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Error") + ret0, _ := ret[0].(error) + return ret0 +} + +// Error indicates an expected call of Error. +func (mr *MockStateDBMockRecorder) Error() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockStateDB)(nil).Error)) +} + +// GetCodeHash mocks base method. +func (m *MockStateDB) GetCodeHash(arg0 common.Address) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCodeHash", arg0) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetCodeHash indicates an expected call of GetCodeHash. +func (mr *MockStateDBMockRecorder) GetCodeHash(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCodeHash", reflect.TypeOf((*MockStateDB)(nil).GetCodeHash), arg0) +} + +// SetState mocks base method. +func (m *MockStateDB) SetState(arg0 common.Address, arg1, arg2 common.Hash) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetState", arg0, arg1, arg2) +} + +// SetState indicates an expected call of SetState. +func (mr *MockStateDBMockRecorder) SetState(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*MockStateDB)(nil).SetState), arg0, arg1, arg2) +} + +// SetStorage mocks base method. +func (m *MockStateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetStorage", addr, storage) +} + +// SetStorage indicates an expected call of SetStorage. +func (mr *MockStateDBMockRecorder) SetStorage(addr, storage interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStorage", reflect.TypeOf((*MockStateDB)(nil).SetStorage), addr, storage) +} + +// SetPrivacyMetadata mocks base method. +func (m *MockStateDB) SetPrivacyMetadata(addr common.Address, pm *state.PrivacyMetadata) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetPrivacyMetadata", addr, pm) +} + +// SetPrivacyMetadata indicates an expected call of SetPrivacyMetadata. +func (mr *MockStateDBMockRecorder) SetPrivacyMetadata(addr, pm interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrivacyMetadata", reflect.TypeOf((*MockStateDB)(nil).SetPrivacyMetadata), addr, pm) +} + +// SetManagedParties mocks base method. +func (m *MockStateDB) SetManagedParties(addr common.Address, managedParties []string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetManagedParties", addr, managedParties) +} + +// SetManagedParties indicates an expected call of SetManagedParties. +func (mr *MockStateDBMockRecorder) SetManagedParties(addr, managedParties interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetManagedParties", reflect.TypeOf((*MockStateDB)(nil).SetManagedParties), addr, managedParties) +} + +// CreateAccount mocks base method. +func (m *MockStateDB) CreateAccount(arg0 common.Address) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "CreateAccount", arg0) +} + +// CreateAccount indicates an expected call of CreateAccount. +func (mr *MockStateDBMockRecorder) CreateAccount(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAccount", reflect.TypeOf((*MockStateDB)(nil).CreateAccount), arg0) +} + +// SubBalance mocks base method. +func (m *MockStateDB) SubBalance(arg0 common.Address, arg1 *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SubBalance", arg0, arg1) +} + +// SubBalance indicates an expected call of SubBalance. +func (mr *MockStateDBMockRecorder) SubBalance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubBalance", reflect.TypeOf((*MockStateDB)(nil).SubBalance), arg0, arg1) +} + +// AddBalance mocks base method. +func (m *MockStateDB) AddBalance(arg0 common.Address, arg1 *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddBalance", arg0, arg1) +} + +// AddBalance indicates an expected call of AddBalance. +func (mr *MockStateDBMockRecorder) AddBalance(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBalance", reflect.TypeOf((*MockStateDB)(nil).AddBalance), arg0, arg1) +} + +// GetCodeSize mocks base method. +func (m *MockStateDB) GetCodeSize(arg0 common.Address) int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCodeSize", arg0) + ret0, _ := ret[0].(int) + return ret0 +} + +// GetCodeSize indicates an expected call of GetCodeSize. +func (mr *MockStateDBMockRecorder) GetCodeSize(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCodeSize", reflect.TypeOf((*MockStateDB)(nil).GetCodeSize), arg0) +} + +// AddRefund mocks base method. +func (m *MockStateDB) AddRefund(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddRefund", arg0) +} + +// AddRefund indicates an expected call of AddRefund. +func (mr *MockStateDBMockRecorder) AddRefund(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRefund", reflect.TypeOf((*MockStateDB)(nil).AddRefund), arg0) +} + +// SubRefund mocks base method. +func (m *MockStateDB) SubRefund(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SubRefund", arg0) +} + +// SubRefund indicates an expected call of SubRefund. +func (mr *MockStateDBMockRecorder) SubRefund(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubRefund", reflect.TypeOf((*MockStateDB)(nil).SubRefund), arg0) +} + +// GetRefund mocks base method. +func (m *MockStateDB) GetRefund() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRefund") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetRefund indicates an expected call of GetRefund. +func (mr *MockStateDBMockRecorder) GetRefund() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRefund", reflect.TypeOf((*MockStateDB)(nil).GetRefund)) +} + +// GetCommittedState mocks base method. +func (m *MockStateDB) GetCommittedState(arg0 common.Address, arg1 common.Hash) common.Hash { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCommittedState", arg0, arg1) + ret0, _ := ret[0].(common.Hash) + return ret0 +} + +// GetCommittedState indicates an expected call of GetCommittedState. +func (mr *MockStateDBMockRecorder) GetCommittedState(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommittedState", reflect.TypeOf((*MockStateDB)(nil).GetCommittedState), arg0, arg1) +} + +// Suicide mocks base method. +func (m *MockStateDB) Suicide(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Suicide", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Suicide indicates an expected call of Suicide. +func (mr *MockStateDBMockRecorder) Suicide(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Suicide", reflect.TypeOf((*MockStateDB)(nil).Suicide), arg0) +} + +// HasSuicided mocks base method. +func (m *MockStateDB) HasSuicided(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasSuicided", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// HasSuicided indicates an expected call of HasSuicided. +func (mr *MockStateDBMockRecorder) HasSuicided(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasSuicided", reflect.TypeOf((*MockStateDB)(nil).HasSuicided), arg0) +} + +// Exist mocks base method. +func (m *MockStateDB) Exist(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Exist", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Exist indicates an expected call of Exist. +func (mr *MockStateDBMockRecorder) Exist(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exist", reflect.TypeOf((*MockStateDB)(nil).Exist), arg0) +} + +// Empty mocks base method. +func (m *MockStateDB) Empty(arg0 common.Address) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Empty", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// Empty indicates an expected call of Empty. +func (mr *MockStateDBMockRecorder) Empty(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Empty", reflect.TypeOf((*MockStateDB)(nil).Empty), arg0) +} + +// RevertToSnapshot mocks base method. +func (m *MockStateDB) RevertToSnapshot(arg0 int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RevertToSnapshot", arg0) +} + +// RevertToSnapshot indicates an expected call of RevertToSnapshot. +func (mr *MockStateDBMockRecorder) RevertToSnapshot(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertToSnapshot", reflect.TypeOf((*MockStateDB)(nil).RevertToSnapshot), arg0) +} + +// Snapshot mocks base method. +func (m *MockStateDB) Snapshot() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Snapshot") + ret0, _ := ret[0].(int) + return ret0 +} + +// Snapshot indicates an expected call of Snapshot. +func (mr *MockStateDBMockRecorder) Snapshot() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Snapshot", reflect.TypeOf((*MockStateDB)(nil).Snapshot)) +} + +// AddLog mocks base method. +func (m *MockStateDB) AddLog(arg0 *types.Log) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddLog", arg0) +} + +// AddLog indicates an expected call of AddLog. +func (mr *MockStateDBMockRecorder) AddLog(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLog", reflect.TypeOf((*MockStateDB)(nil).AddLog), arg0) +} + +// AddPreimage mocks base method. +func (m *MockStateDB) AddPreimage(arg0 common.Hash, arg1 []byte) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddPreimage", arg0, arg1) +} + +// AddPreimage indicates an expected call of AddPreimage. +func (mr *MockStateDBMockRecorder) AddPreimage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPreimage", reflect.TypeOf((*MockStateDB)(nil).AddPreimage), arg0, arg1) +} + +// ForEachStorage mocks base method. +func (m *MockStateDB) ForEachStorage(arg0 common.Address, arg1 func(common.Hash, common.Hash) bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ForEachStorage", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ForEachStorage indicates an expected call of ForEachStorage. +func (mr *MockStateDBMockRecorder) ForEachStorage(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForEachStorage", reflect.TypeOf((*MockStateDB)(nil).ForEachStorage), arg0, arg1) +} + +// MockCallContext is a mock of CallContext interface. +type MockCallContext struct { + ctrl *gomock.Controller + recorder *MockCallContextMockRecorder +} + +// MockCallContextMockRecorder is the mock recorder for MockCallContext. +type MockCallContextMockRecorder struct { + mock *MockCallContext +} + +// NewMockCallContext creates a new mock instance. +func NewMockCallContext(ctrl *gomock.Controller) *MockCallContext { + mock := &MockCallContext{ctrl: ctrl} + mock.recorder = &MockCallContextMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCallContext) EXPECT() *MockCallContextMockRecorder { + return m.recorder +} + +// Call mocks base method. +func (m *MockCallContext) Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Call", env, me, addr, data, gas, value) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Call indicates an expected call of Call. +func (mr *MockCallContextMockRecorder) Call(env, me, addr, data, gas, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockCallContext)(nil).Call), env, me, addr, data, gas, value) +} + +// CallCode mocks base method. +func (m *MockCallContext) CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CallCode", env, me, addr, data, gas, value) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CallCode indicates an expected call of CallCode. +func (mr *MockCallContextMockRecorder) CallCode(env, me, addr, data, gas, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CallCode", reflect.TypeOf((*MockCallContext)(nil).CallCode), env, me, addr, data, gas, value) +} + +// DelegateCall mocks base method. +func (m *MockCallContext) DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DelegateCall", env, me, addr, data, gas) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DelegateCall indicates an expected call of DelegateCall. +func (mr *MockCallContextMockRecorder) DelegateCall(env, me, addr, data, gas interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelegateCall", reflect.TypeOf((*MockCallContext)(nil).DelegateCall), env, me, addr, data, gas) +} + +// Create mocks base method. +func (m *MockCallContext) Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", env, me, data, gas, value) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(common.Address) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// Create indicates an expected call of Create. +func (mr *MockCallContextMockRecorder) Create(env, me, data, gas, value interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockCallContext)(nil).Create), env, me, data, gas, value) +} diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index 38ee448904..30bd23e9fe 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -35,5 +35,5 @@ func NewEnv(cfg *Config) *vm.EVM { GasPrice: cfg.GasPrice, } - return vm.NewEVM(context, cfg.State, cfg.ChainConfig, cfg.EVMConfig) + return vm.NewEVM(context, cfg.State, cfg.State, cfg.ChainConfig, cfg.EVMConfig) } diff --git a/core/vm/runtime/evm_privacy_test.go b/core/vm/runtime/evm_privacy_test.go new file mode 100644 index 0000000000..c1be7e5cb9 --- /dev/null +++ b/core/vm/runtime/evm_privacy_test.go @@ -0,0 +1,448 @@ +package runtime + +import ( + "fmt" + "math/big" + "os" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private/engine" + testifyassert "github.com/stretchr/testify/assert" +) + +/* +The following contracts are used as the samples. Bytecodes are compiled using solc 0.5.4 + +import "./C2.sol"; + +contract C1 { + + uint x; + + constructor(uint initVal) public { + x = initVal; + } + + function set(uint newValue) public returns (uint) { + x = newValue; + return x; + } + + function get() public view returns (uint) { + return x; + } + + function newContractC2(uint newValue) public { + C2 c = new C2(address(this)); + c.set(newValue); + } +} + +import "./C1.sol"; + +contract C2 { + + C1 c1; + + constructor(address _t) public { + c1 = C1(_t); + } + + function get() public view returns (uint result) { + return c1.get(); + } + + function set(uint _val) public { + c1.set(_val); + } + +} +*/ + +type contract struct { + abi abi.ABI + bytecode []byte + name string +} + +var ( + c1, c2 *contract + stubPrivateTx *types.Transaction +) + +func init() { + c1 = &contract{ + name: "c1", + abi: mustParse(c1AbiDefinition), + bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806105a88339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610550806100586000396000f3fe608060405260043610610051576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100565780636d4ce63c146100a5578063d7139463146100d0575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b810190808035906020019092919050505061010b565b6040518082815260200191505060405180910390f35b3480156100b157600080fd5b506100ba61011e565b6040518082815260200191505060405180910390f35b3480156100dc57600080fd5b50610109600480360360208110156100f357600080fd5b8101908080359060200190929190505050610127565b005b6000816000819055506000549050919050565b60008054905090565b600030610132610212565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015610184573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff166360fe47b1836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156101f657600080fd5b505af115801561020a573d6000803e3d6000fd5b505050505050565b604051610302806102238339019056fe608060405234801561001057600080fd5b506040516020806103028339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610271806100916000396000f3fe608060405260043610610046576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b11461004b5780636d4ce63c14610086575b600080fd5b34801561005757600080fd5b506100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100b1565b005b34801561009257600080fd5b5061009b610180565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561014157600080fd5b505af1158015610155573d6000803e3d6000fd5b505050506040513d602081101561016b57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561020557600080fd5b505afa158015610219573d6000803e3d6000fd5b505050506040513d602081101561022f57600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820a537f4c360ce5c6f55523298e314e6456e5c3e02c170563751dfda37d3aeddb30029a165627a7a7230582060396bfff29d2dfc5a9f4216bfba5e24d031d54fd4b26ebebde1a26c59df0c1e0029"), + } + c2 = &contract{ + name: "c2", + abi: mustParse(c2AbiDefinition), + bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806102f58339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610264806100916000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100585780636d4ce63c14610086575b600080fd5b6100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100a4565b005b61008e610173565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561013457600080fd5b505af1158015610148573d6000803e3d6000fd5b505050506040513d602081101561015e57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156101f857600080fd5b505afa15801561020c573d6000803e3d6000fd5b505050506040513d602081101561022257600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820dd8a5dcf693e1969289c444a282d0684a9760bac26f1e4e0139d46821ec1979b0029"), + } + log.PrintOrigins(true) + log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) +} + +func TestPrivacyEnhancements_CreateC1(t *testing.T) { + assert := testifyassert.New(t) + cfg := newConfig() + initialValue := int64(42) + var affectedContracts []common.Address + var getPrivacyMetadataFunc func(common.Address) (*state.PrivacyMetadata, error) + cfg.onAfterEVM = func(evm *vm.EVM) { + affectedContracts = evm.AffectedContracts() + getPrivacyMetadataFunc = evm.StateDB.GetPrivacyMetadata + } + stubPrivateTx = newTypicalPrivateTx(cfg) + stubPrivateTx.SetTxPrivacyMetadata(&types.PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagStateValidation, + }) + + c1Address := createC1(assert, cfg, initialValue) + assert.Empty(affectedContracts, "Contract C1 creation doesn't affect any other contract") + pm, err := getPrivacyMetadataFunc(c1Address) + assert.NoError(err, "Privacy Metadata must exist") + assert.True(pm.PrivacyFlag.Has(engine.PrivacyFlagStateValidation), "PrivacyFlag must be set") + assert.Equal(common.BytesToEncryptedPayloadHash(stubPrivateTx.Data()), pm.CreationTxHash, "CreationTxHash must be set correctly") + + actualValue := callContractFunction(assert, cfg, c1, c1Address, "get") + assert.Equal(initialValue, actualValue) + assert.Len(affectedContracts, 1, "Calling C1.get() affects 1 contract") + assert.Equal(c1Address, affectedContracts[0], "Calling C1.get() affects C1 contract itself") +} + +func TestPrivacyEnhancements_CreateC2(t *testing.T) { + assert := testifyassert.New(t) + cfg := newConfig() + stubPrivateTx = nil + initialValue := int64(30) + + c1Address := createC1(assert, cfg, initialValue) + + var affectedContracts []common.Address + cfg.onAfterEVM = func(evm *vm.EVM) { + affectedContracts = evm.AffectedContracts() + } + c2Address := createC2(assert, cfg, c1Address) + assert.Empty(affectedContracts, "Contract C2 creation doesn't affect any other contract") + + actualValue := callContractFunction(assert, cfg, c2, c2Address, "get") + + assert.Equal(initialValue, actualValue) + assert.Len(affectedContracts, 2, "Calling C2.get() affects 2 contracts") + assert.Contains(affectedContracts, c1Address, "Calling C2.get() affects C1") + assert.Contains(affectedContracts, c2Address, "Calling C2.get() affects C2") +} + +func TestPrivacyEnhancements_CreateC2FromC1Function(t *testing.T) { + assert := testifyassert.New(t) + cfg := newConfig() + stubPrivateTx = nil + initialValue := int64(30) + newValue := int64(40) + + c1Address := createC1(assert, cfg, initialValue) + + var affectedContracts []common.Address + cfg.onAfterEVM = func(evm *vm.EVM) { + affectedContracts = evm.AffectedContracts() + } + callContractFunction(assert, cfg, c1, c1Address, "newContractC2", big.NewInt(newValue)) + + assert.Len(affectedContracts, 1, "Calling C1.newContractC2() affects 1 contract") + assert.Contains(affectedContracts, c1Address, "Calling C1.newContractC2() affects C1") +} + +func TestPrivacyEnhancements_CreateC1_StandardPrivate(t *testing.T) { + assert := testifyassert.New(t) + cfg := newConfig() + initialValue := int64(42) + var affectedContracts []common.Address + var getPrivacyMetadataFunc func(common.Address) (*state.PrivacyMetadata, error) + cfg.onAfterEVM = func(evm *vm.EVM) { + affectedContracts = evm.AffectedContracts() + getPrivacyMetadataFunc = evm.StateDB.GetPrivacyMetadata + } + stubPrivateTx = newTypicalPrivateTx(cfg) + stubPrivateTx.SetTxPrivacyMetadata(&types.PrivacyMetadata{ + PrivacyFlag: engine.PrivacyFlagStandardPrivate, + }) + + c1Address := createC1(assert, cfg, initialValue) + assert.Empty(affectedContracts, "Contract C1 creation doesn't affect any other contract") + _, err := getPrivacyMetadataFunc(c1Address) + assert.Error(err, "Privacy Metadata must not exist") + + actualValue := callContractFunction(assert, cfg, c1, c1Address, "get") + assert.Equal(initialValue, actualValue) + assert.Len(affectedContracts, 1, "Calling C1.get() affects 1 contract") + assert.Equal(c1Address, affectedContracts[0], "Calling C1.get() affects C1 contract itself") +} + +func callContractFunction(assert *testifyassert.Assertions, cfg *extendedConfig, c *contract, address common.Address, name string, args ...interface{}) int64 { + f := mustPack(assert, c, name, args...) + ret, _, err := call(address, f, cfg) + sig := fmt.Sprintf("%s.%s", c.name, name) + assert.NoError(err, "Execute %s", sig) + log.Debug(sig, "ret_hex", common.Bytes2Hex(ret)) + for len(ret) > 0 && ret[0] == 0 { + ret = ret[1:] + } + if len(ret) == 0 { + return -1 + } + actualValue, err := hexutil.DecodeBig(hexutil.Encode(ret)) + assert.NoError(err) + log.Debug(sig, "ret", actualValue) + return actualValue.Int64() +} + +func createC2(assert *testifyassert.Assertions, cfg *extendedConfig, c1Address common.Address) common.Address { + constructorCode := mustPack(assert, c2, "", c1Address) + + _, address, _, err := create(append(c2.bytecode, constructorCode...), cfg) + assert.NoError(err, "Create contract C2") + + log.Debug("Created C2", "address", address.Hex()) + return address +} + +func createC1(assert *testifyassert.Assertions, cfg *extendedConfig, initialValue int64) common.Address { + constructorCode := mustPack(assert, c1, "", big.NewInt(initialValue)) + + _, address, _, err := create(append(c1.bytecode, constructorCode...), cfg) + assert.NoError(err, "Create contract C1") + + log.Debug("Created C1", "address", address.Hex()) + return address +} + +func mustPack(assert *testifyassert.Assertions, c *contract, name string, args ...interface{}) []byte { + bytes, err := c.abi.Pack(name, args...) + assert.NoError(err, "Pack method") + return bytes +} + +func newConfig() *extendedConfig { + cfg := new(Config) + setDefaults(cfg) + cfg.Debug = true + database := rawdb.NewMemoryDatabase() + cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(database), nil) + privateState, _ := state.New(common.Hash{}, state.NewDatabase(database), nil) + + cfg.ChainConfig.IsQuorum = true + cfg.ChainConfig.ByzantiumBlock = big.NewInt(0) + return &extendedConfig{ + Config: cfg, + privateState: privateState, + } +} + +type extendedConfig struct { + *Config + privateState *state.StateDB + onAfterEVM func(evm *vm.EVM) +} + +func newEVM(cfg *extendedConfig) *vm.EVM { + context := vm.Context{ + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + GetHash: func(uint64) common.Hash { return common.Hash{} }, + + Origin: cfg.Origin, + Coinbase: cfg.Coinbase, + BlockNumber: cfg.BlockNumber, + Time: cfg.Time, + Difficulty: cfg.Difficulty, + GasLimit: cfg.GasLimit, + GasPrice: cfg.GasPrice, + } + evm := vm.NewEVM(context, cfg.State, cfg.privateState, cfg.ChainConfig, cfg.EVMConfig) + evm.SetCurrentTX(stubPrivateTx) + return evm +} + +func newTypicalPrivateTx(cfg *extendedConfig) *types.Transaction { + tx := types.NewTransaction(0, common.Address{}, cfg.Value, cfg.GasLimit, cfg.GasPrice, []byte("arbitrary payload")) + tx.SetPrivate() + return tx +} + +// Create executes the code using the EVM create method +func create(input []byte, cfg *extendedConfig) ([]byte, common.Address, uint64, error) { + var ( + vmenv = newEVM(cfg) + sender = vm.AccountRef(cfg.Origin) + ) + defer func() { + if cfg.onAfterEVM != nil { + cfg.onAfterEVM(vmenv) + } + }() + + // Call the code with the given configuration. + code, address, leftOverGas, err := vmenv.Create( + sender, + input, + cfg.GasLimit, + cfg.Value, + ) + return code, address, leftOverGas, err +} + +// Call executes the code given by the contract's address. It will return the +// EVM's return value or an error if it failed. +// +// Call, unlike Execute, requires a config and also requires the State field to +// be set. +func call(address common.Address, input []byte, cfg *extendedConfig) ([]byte, uint64, error) { + vmenv := newEVM(cfg) + defer func() { + if cfg.onAfterEVM != nil { + cfg.onAfterEVM(vmenv) + } + }() + + sender := cfg.State.GetOrNewStateObject(cfg.Origin) + // Call the code with the given configuration. + ret, leftOverGas, err := vmenv.Call( + sender, + address, + input, + cfg.GasLimit, + cfg.Value, + ) + + return ret, leftOverGas, err +} + +func mustParse(def string) abi.ABI { + abi, err := abi.JSON(strings.NewReader(def)) + if err != nil { + log.Error("Can't parse ABI def", "err", err) + os.Exit(1) + } + return abi +} + +const ( + c1AbiDefinition = ` +[ + { + "constant": false, + "inputs": [ + { + "name": "newValue", + "type": "uint256" + } + ], + "name": "set", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "get", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "newValue", + "type": "uint256" + } + ], + "name": "newContractC2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "name": "initVal", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } +] +` + c2AbiDefinition = ` +[ + { + "constant": false, + "inputs": [ + { + "name": "_val", + "type": "uint256" + } + ], + "name": "set", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "get", + "outputs": [ + { + "name": "result", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_t", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + } +] +` +) diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 108ee80e41..5979932603 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -17,6 +17,7 @@ package runtime import ( + "context" "fmt" "math/big" "os" @@ -24,6 +25,8 @@ import ( "testing" "time" + "github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" @@ -246,6 +249,10 @@ func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header { return fakeHeader(n, parentHash) } +func (d *dummyChain) SupportsMultitenancy(context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) { + return nil, false +} + // TestBlockhash tests the blockhash operation. It's a bit special, since it internally // requires access to a chain reader. func TestBlockhash(t *testing.T) { diff --git a/crypto/bn256/cloudflare/gfp_decl.go b/crypto/bn256/cloudflare/gfp_decl.go index fdea5c11a5..b718ceb8a2 100644 --- a/crypto/bn256/cloudflare/gfp_decl.go +++ b/crypto/bn256/cloudflare/gfp_decl.go @@ -4,7 +4,6 @@ package bn256 // This file contains forward declarations for the architecture-specific // assembly implementations of these functions, provided that they exist. - import ( "golang.org/x/sys/cpu" ) diff --git a/crypto/crypto.go b/crypto/crypto.go index a4a49136a8..c6da90cef3 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -257,7 +257,7 @@ func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool { return false } // Frontier: allow s to be in full N range - return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1) + return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1 || v == 10 || v == 11) } func PubkeyToAddress(p ecdsa.PublicKey) common.Address { diff --git a/crypto/secp256k1/go.mod b/crypto/secp256k1/go.mod new file mode 100644 index 0000000000..ad39a60062 --- /dev/null +++ b/crypto/secp256k1/go.mod @@ -0,0 +1,3 @@ +module github.com/ConsenSys/quorum/crypto/secp256k1 + +go 1.13 diff --git a/docs/Quorum Design.png b/docs/Quorum Design.png new file mode 100644 index 0000000000000000000000000000000000000000..f331ce581bfdd6b15349dd0737afd7bc1c138353 GIT binary patch literal 76981 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 literal 0 HcmV?d00001 diff --git a/docs/Quorum Whitepaper v0.2.pdf b/docs/Quorum Whitepaper v0.2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c2dac8f0b43f6ffe793c14ccd96aaab9b1fe0667 GIT binary patch literal 1887682 zcma&ML$D~owr#m>+qP}nwr$(CZJlk~wr$(CQTM(0Rh`?Y-^z^D$X-UQG3Ovv5D}wg zq+@|19lMS%gkmLNAh0*Gg5u$!moc?7cd;N~`_Dv)Ud+%MpwFSyA@R|XEU}A_-oX2h24_bHp_&p#^Wf>m7dzcCHuK*?UrMkCvVPOKmcE5?9jDS$wu#aKukcPXlSH0qh{$di23&h{&?AZmU znPC^_P9D|+bMT=H|7Tq8s!wkN0Zy&zp+LNI0Y~rW=`tMmOXOzp`&}$HtR`O} zIP>*lwi|Yl%^tp)Es)nyBhSK};d0;vTu&yOF=KxefqiJc1i}&6VoOM8!kb*)h-nsE zKp&dk^2ajVa_#7HDTrJ83tQcPbE4qf5gR?R^-Sz`wCt%qz=LG8sNgsCYC?xr=d?KQa`74uBc@dO92 zB%&-a2V#lD$Pa5EKMQM#_+_3~L3nquri>69h<(h-8()MlMyv{x8=8e|4on4j)zD%v z#E3>(pnbT<8;ZIyk|M7~k^(v@JMUjY*opYfw1-a$y`|0(K{2kaRVrJd2Jq_U%jUZG zQhV;((YSbj*^@_4CVV=r+=7D&zE>PO8~l0<-*g)mp+xN?#%>uku`a{+l_|dXg@+m!7k|x zqajUOPV853`;3zIFROKwt3r%v5^TkW0v``=3-Ced)Az@hL7=9*O$~oRcnYH&N_xDJ zJe`K}_&0HTW(U3Boj4*xH*TsK*FXs~zgz5bu&qr_HLmzzUc7N#NNaJw&5@ZS%w#F4 zf>x=a>%0#WaTtswAx{$WUB@L1%NVdttr6m*#=N~DD(8s<4Ax+(%GcFZS}zrssNLUDTUQ^X=|K!LQoq3 zIuA4ma4ZbG4;cIXQVFvpz>`VOKY(^5H8aG6`oRpz#W2OTellbvKj0;pX&@x|jr03Y zUY%@txg?4JD#UALEe1-KmSq5Fh_LIpnvVvzqIOGRD57)=v|wPFqb%;cYOm;V(|Xzp zoDFhhp=8h>nEge=P~>I`UJ$265kjU!4+dAef51#@Z6M)I-}Y8CPYHV3XXpBCGq#`L zur{12H&m9Y024D*C~pTkc?B;f!2=*n!JDAf4TV<7@)OaD&I=J7A77^HZjUNvk(l7r z>c-6$37G5wCN!+lax2F|U7=?taD(-c757XUWzy);#Eas`kW#eQ4{M72I5nj}Q!P{n z+o1N>d@Ovr{?;d?u+8CMk<|WU1uXlJpZuT#q@;IR#W5UR`C*o2!*Fd(qY z8+Z3-KNc~eBLH-PzqrE)5QB2(d;4(CEf`v+5m~ewOC-!WK#Yrn6!R}o!qJoodHyp2 zz)Y!o^WkEW`aT&S%4Tgc$@%pwU9A3Ej7 zTa~NTlH#>|b;E-4iIrwzriu+YaCyQSu%zuwnB-UZtBr4(XU&Y0Xs9LJhv1xCfN(cy zF=QC@Fp(N_0742AQ}{Dlu4{=^xDf0FxnW{6=y0VQWn5i8Wk^mwns}`D?GG3~<_zvlLSE~Hym#l;c z4KH^tw|LpE(;c^*L90F3qYpl~KP)Ok0}@#SZ)~7oL$6AK0qI|X{iAV9xJ|#AGgyRp zZVjT8B;ZId7d}hgJV=3m4aU$}7ITX0J|??NA<$1y!wGa=XpV!Sua{q#TwLZcTe6+V zmUO{Ajbz7OSqE!33@Ev?3UpC$7~Gl&oai>OR1Ia-ukxWC;PGmdkWNewd(Z+SP+hMcOubHI!JE=ri10q`$r9?b zqN#%7I!J0&nms0P@4HuXYS4@*1xS*GahmdV_zeey8N|4uPHTtsYX{-ki2Tl(tnFFtB2AFoRZSAqMnB!E#ceHK$8L3QxgQ5Q#aE!S1$Z$V!(-=M;X?{ zx+^NR@+8NhXP3d%U&@Smgad9!LQ?WFNHC_Vf@eG8)>$2^579}fCOW<{-?D-n*JCz` z35@(~NH@)#Khvg{Wf?|?T89Fag-y?z)L+Nf!gk_k}B>5}r zb-t?wQ8XmRvXz(zQ$CNXrJN*<7}BUL=xO8mkkl+gLpfIoUqbl6hL(>52?> znc25zW+9&Rr>@sSQv$=QHobc5knLnYpX?OtVFCg-Dv&F(Xxnv3r6iBJgI0;N_k!%y z*lV>`+>N9>Y)3Gh5ogBxi4Q}A?|eK4O6*O+56*K$_z%Z#H8|58PR_Cxyw&aPPA)n5 z1~GTM+$lMkyIIspTws34^cl&W?4tM~IZxjK;Y~)2<>gWBQ+yVW7wRcqUsR1nRj65} zm786_gzPU~Dd}g%4o9v>my1Fx!?(&2<1S7L;=dGjg=F>qokeu_lr%|-svS+E4#e}> zjg0XAFKd*h10HN};{H>VTehO_IHh%2*j&OoqH4u`Z7|L`@DA!h{gpg68+f>IU-zh` z)aDLYtgNO9?nUl>oY8Db`tvfN`=I={QfuM`7LInLH?y7=2Bc71EtBGWU88v=P}Uf_ zIiPxP{Jg^s5N5ZTkcjHHf>7+im_dE_8<3f}>5u|FYwCttqtN7R5|@QBd2EBIuf$b}LL@()kK`XOk0KTrogR(0AS2PkX&U=nEb5)MK)awu~^ zW2Y+26Ie$f?f#YBh`Mc*^j0{g+{pK|GsXw0 zAsDryW_)I+47omna4-^$5-tVOwj?%V5%#e?Q}Gyc(u(WVPj;z$tTP*^;2d}qVAmgG zrEdy}3!9v~9Ieag7F8zrCuvb2ic;uQdZtedj65+oo0IdbGS(?%*ozLr+Q4bXd|H#% zIp%tFmSMEwXI-apeeMS_>Ij43rg4Vh!18@-jM!T*x{iaA)St&}6N;F6O}!|SG-6RF z)8>Q&;8I^48-d5B@?Y&7_mYlEo@_6NfjbX%p#zVSqvX)3{BEj-=FQ4<>*5y0&JzE; z&bdNCxu}zB2OOXzKF*HypbR)4(}59FsXD}bxeHY+=y5|=sXYQ(D~0l{6|$ScG3J8j zb4O+`$i`I$%*`kmHVyX{;2Q^g3DXw2vSmJ8p4v&J;{f@JmlibdJ-#Lhh`Q$iOfWfB zr+$W}q`|k!3u(UI;duN4s7}9czwENwqWk)BxMiMXymWEC{;)vw`Ta+$*NX#`xm8SS zM%rNTs?SKpTQ(OU-tw5D0PuYxL)QHXy!+cso13=yC*=-XYaL1xnse~`qxDE4o%&=n zA;b7W{WTB6S?6G-HGn&9%DJt6L?3DRWMB)^%9D!S`-Dl$^>B`9HBxnAV59mazn>WH zx7SR1HGqkQLtDBAFN*v%K6QB{!*E}Ibej?8FqsMuig#2b)$+djgg8bp9U+J%lC5-e zR%TrrYJ-;hQiD3F&C^{>*(#+xWr{kH#U{Kt(^32>QjZ&%Hy`~|kPlsnpEty72^^qW zSH%O7vm0y(QmhB}Y07no)`pk&|OrF)F(*Hz(Tbjoz&b#>L9Pp>;($ese_R zIdk{bG2f?;mKjI=Y8H*^kIj801e$78;RrWeW{~O-judanT;!OB0(G)|9}jV6cM{%q zes*fYz*f**p*Yh0sE*J@&a1A7(0>mtWh-?uw;5|5e1XIH_<7k|o+gapghdsdfM$vP-k@A>N zhlPU}puJ65_=Kd?xHu>J001OZJf&;JJ|D))-jPJSBSrDFsNUB;u(TNfz}$LTW}HeOh%Q@Mx^Go1rDr zKiDQK0n~6SDCWVz+pkio-)2pT{Rc+XC}$P_a1bN{;pKeC#jh!C(F9?w4d}mHV^N%{ zb&cLlR3g6OMefTcTG-s?cBt~?t^5uTy3X)(+Rv^&*XQTxV|~{5KIxAP2+re3WElb2 zTGDnw`z;qC%y3J9s@vW}e-JMUshF`=2$C*cD~36R6xG?%P;PKv5j3!+0gJYcur5z6 zQU?be8@=4!4L4Z*d148N#1sAsG_OALtO{ zEuQ?MW&7vl|4FRCttC%H%}N+@GDH7^989pGL!W;r2LLJBp=(j~30kNZb2Fm5rCzqn!8*nYv6ZYw^S*^LVu?Jky| zZh-7n^Vm~qgR=1}1;t}okvr||-1y4wuOJqgu=YeJD?%$F;C_5o(kZJV(JTrirkHJV zMEz~pq>ZqPK_rw}Zzgi!VugR87Q32^cczMI&2&P_1t(4V?0iha*C1U$K&gGOkn7NKU;16qD&%#;Cdd)X#oDXA+i{iUsn>5HccTs z-9^%Uc_h^l!@4&gB0DX#ctW zPw4hPQQQBVES!v-Q2%Gf$njr^93$udO(Zv?GnGWbjtYA;;I_umxpiYWjRHrZA%LpD zS<%)^YA`e#w~MKE6aYa4W_0?8E|E!jLE)NOdC3UxebA^xdC?m;+oSZ_HN?T-hcVRm zFqYlc^>F{T)0K-W@@{T5yl20Q_j}*&{Zqrqz!vj(|K7I4!C@|LU3zwH@ID~HYT@nS z)5Y!Q;`KcyXT=Cn18;sKl5z3ywc|dfpTBGn>$Ls$adnjMezqJPDL6S#*=q}aH7!V? z-TZgq_!gU=)3gA2C5kZmm-HLXRAg{?|BJ+#V=u}Wqcyxg30uSqVGPC{`MC2SUe<(@ zvJ{2O&u7V>!OI6Nn*>=F&(D{;VK7{N{E)n~5lxV>GA1u?&Kk2lb%H+gY>=@qHYcRc zYlXQ9Rut+mmc7I|U7Qm<+V{=;+$?2vH1_6o;8%R~wB(5sb6Dicp?Z7&adC})mulcp z{YH+6(!cZYdJI;QYSPYwalzIMW&NX6RFMCvo`Zht;cm2@O{rzeHW=O&qd;`=p*ae_bMn1A|4R|syGs@~I9 zwWjTXq5sSAK3V>gh2>NL#K*M}Xgy<7Uw_9v0XQ@S;Td)|u)WC04oyC$$a#&aN?8(h zWqkO~Bq9u9iP%jW_adngfaOWJoc`NjvMKe~xmJsVE1h+k#*9Ni{c>{btg|i%d82C% zgruQHdUfu<*f{uJA2cU#mazIUnjeC3UwcRlui}sl1A^RNPBCy}0)NrnHZa#Mg7I2r z2*S#xPJzbtzG5d2Qv;uZ{7)Q(EVc^Jw*a94I|B$tw>pr4#WE?J$?Z^!V{OP{x*1!9 zI6pI-h*uj6$3qicy*lDMI|Q79;Z*=3;Ndn18QfhbtyUZ|I52_!dss(`x6>1LkP;g~ z*Gu57@oW8A;B;^8U8&>;lXjmR65TnW9Lb%5rKgE&^iZnfZzZ5tXmPpoy&VlH9mshn zSf1ezYY8V@$mBb7&m!lvIv^5sqJu^j&p0Lp$_ISV4BjDW`<#yd&qfTab`T9M@gOW{ zYh+Ps@JJNV%H-s^fgBc$Wzy)GMF(KDht17F5FuMkALr^HVk=^@A&Ar4#MU~k6>}%^ z;R5}jb{>(XHp@|Wu?eitwM}#hp1DN=GYgFx+&saJjTOw5=ZliXHU+bCxsa_a{<%R# zfT5l}3->#$fQVllTd=7i#7HdODSexc{AGp{)LEzI7$}^|b(sO97Z4MOAezS&^&C|0 z>v)5f|Df=uy(RoeYR$*eu_VGnJE@tkKsawt)m-yH7lJW}tw#UMd9j?_7YPQOi;Fxh z77BQc>GrUuc7m7&Cw4{OL+P2md`09+*a8n=vy>BIkS7+_z4p5Nw1}4;E~eDxNCS;J zS#7?y=0oU4r>z3P>kHpMjc%EAZ2g-hWpfPUsfu*mjV&3iD~Bsv5K68WoQ-F}r3DN$qV8xmXZ@m3${LiSLg?5MG2#}hV(t?;1Y&e;?2iIm z4EDG-DuABm5G^9xr>hofT4}@t<u4Hk(m&yZwDHe3rAN5nmCv&H;P!=L(^mRLVKwpq!4^v7fs1ibvKgS0`+}vZwNIKS({LPt=%dP`y|i z@F3Q-uqzPM4uODfpqsM-m*=aFc}(b&o8}5Clv)ZHUEQ9L)av9K>q|yTOkn_OVH&G) z?h#+}D-rhMw|Fp5pgWSLCNWA!H-2sk)50%bR4=Ys7~p;aPhaZvbu>otdw-n0_Ji03 zi7;Xxb$L+~CP@wA=jpk+@`?Vhy0RBba{39^x`BblWv(sMgMEKDsNmq(rf0oF`XKEm zCN^yGR`%ry4dNatdfHwZu}B7`gm}}18LPiXA4wT;%^bTy3FddtG7Vh3k#^mTTC_@u z{atrRwX}pof^@)*Q8$gz#TalrZBADaZ^TknN&`nVD{#ZHM-LZk;P!x4odg_3a3XXP zaR?;CWJIbR_ed_TuNrNdbffVqc-gqVS4BFTC2`82ZjzxQ%Mu*#Noh+nIlBheSluVJ z3>{Sk61XA8)4Fm!9lxNZQ!s4M8!_JcboA!NNXpg>+~P(R$wSl+EYHlNXvvp>0V`@b z6asI$ZdTUMb<~;IF7=B!FnX0HS@zbr;;D4H1+gPC5DLN|&|GvQYtZ8>l-S-{!Mx!SXcEOPQMi` zfbCN_Qj}RMzuWAef2B|_P8F14l6|K_{U>6a){)T}YgR*$L<RY=E) z_fvxUAsv8)srD;MA~9Ad)?Vw9crm*n@PzFbL;-_3!!&Vr5u%IZb@XXKroSxPE%~}& zaT`hE{BB4MislXF)qs_^A-L?kIKUf{hN$xEU$3aQSZer^b(XTIZ-@1i!u|xne)b5X zP+7G|(5r}N4;d^TP|A~1%0WtCa@WIyunR5=E_lBQX|-LkJ6n3JwXSlL`|R5b4c{xVv$t6 zJU7Lq(6^_En=C$yvR2OUkinKt>^}8yDzF?5K82aprr{Tlt4I{mcE~0EO$q;J3F?As z44JF4eZ=s{vz97AFG%+*os#e?K z{@d*=tXHMKBf#uezvDW{0hwrc=@B>!X0o{6!Rtv@6jOnku1})K&j(9wB(iA|6C3!fq?1nCvF@bcnnt zaCZBiq+3bHi`j=O@7;uS$;yK(&j2!soB7*@=OPkP16?L7d&0>&EStb8L-An8BsRs* zgDvm+IOi3w$LA@Z;G&rc?K9jLaenFk!^0?fC5SUVoC;`eEIA*;CP>uRmr;oLG{n_I zsg1ZT*>M(b?MSl!5@f9guonh8fp3-}XWa*&iv=t$xXP+%NRlu$adYrMJhcNZ99q_; zDbhH3kTy;_`jw!-9S#1GD+dsV!8k3t9^WDA9^woVm*XF)jk-?TBi1W~2q#V#qGW(0 z%{@%Bpa=S{rAAD$W%y?)5o&%&cG+{61CWw5S@@Tt3`2p_kogfLmwOl`he1Y|5zup; z&!0(3a`2sCUqJ_=R75d5nhaRv=`Nkb*jKbw3Ad zH%yla?9z(D+Qk#OU|{Bf8m#^9SzK+jE_$$5^l*K5B;a z{7SqSJEU>@RJ58@neLK7p>rRQ*t^g3eEM0Q9y8umo{#our5eI>0OL&+=JqLGp2$nX zAY`0aR~&W`PmV&S`t54%DC{JN7Uw{WpeK=ERy}UL^WtG{gCQ8#xhw0fIzyJiWWB+B zJ;Y2%|BN60K=em|tYw&mVL9jRi=XSXBWuYY|FPVH1f0zXbj1TVJV8nI{Yxb}tHE|n zD}sSs@VG;II5~L`*t;={TUEaVIAr5A7{VVLghqnH5IX~~J;+--s@J!uP82g5K4IR< zjun`Ykp9|g|TzDX9?%V)v z#yMCvC>F5=e~=zikY$Jgxd)s%b00*QPGm@Zg}0I7g~Wr~r88|P9tH8a@+NY`@Gw`C z9Sg$pjnT*u)?i0y0>wd-I-CrkfHFZlO*K2r0HY)$x2ZKl9}L`>yQ%moXC1WnzlhrT z%u|6jz3Bp&J3TSJvG%BGgz{RT_YGNSknb}zt@?fy2e%OzYHDI%lBD&{)A^B6R%QXL zYLqiiLE$=Pe1e*;P~>B%dStph?tvkjbFB71uwUac7BZFlOwM_ts+QU`S2@TdjPf?r zj*Jz?idGCiSU4~knN>4zYsWzLLg3D#YCu4M-Kwn(J5mOZy5t=?@B(VASF;E%ijb8v zPo+}VydBOzjkj_GH+NLZ+ZVNTev^rsVghmZH;kj!ywT2BDg%=j#z8)1|ie!lrgh~OTn0cFU?Oq5{<6jEg0mgTka##D&NFR4#GX>(w|C$r3{u@7NtQ%78a&##0pZ07QB)LRSiaO*NDqh!tPI1FsNlzwfAhB zg=Zj!avxN#qedZ=Y7?pPh9KfS62DAD+FWAA(GYa>=+hm8BG)rW2nZTAlR+<40Jmx7t@52 zl}5sCBrQA{e`v`ER@^jW$m>zOA$|lrd$PE~E>iF$&;*;nmTT@~wj`KhB1Mk22W93Y z8nsw`-QkpR35Y2-7t{(wSn5=P5Y+v-%Kk~ab%XSEEqruHkQ-583u-TeO$greV}-~d zEdw_{MpGsW=Gz6sfm$gu$Ar*Ml1v0Gs?;nb+7J?e(S=$5W7v_oJsn&3H4%TW|->q3o;6=L4h5ykokmBu!;^{#FOhlFU!55V8tzm zrvE&`ao)@z(}C8eEaQR*MG>%}c{Q1&s38QHv!ODP#QZ#NUxDm`7c+1LYCNp++!PJD zMyaPR7g)4#rLnLC*TTHPdDb(e1+Y=nXMDNHmujJ?AKt8#vlmvYDKjupje>(}vgM>) z()!jIj0I1g^f5vxs*>?lFVtGG#eTjI**1&p3!jg$5d&_L81sd~5n*~k)6 zS`MRyeZDsru9}JNV#H*A5d8WXmzu93|t?^Y7y7#N$WrAb@s5#0nA-c^o^;O z-V8+{2oe{QK4%n9V}U806QS!!|DX)Lakacikvk-Dp&__o-c!x#k=rtI3+ND|+PtP1 zRvL|{PHjEl8cDJ_ObR;7>Z;`~w_?aG0LkUs0fq%c`B%y=23yP_pHy1`($8tik=*vp9|C`D5vr0x&g4f} zHQU4EquM}FP@bw-#a#DParA!3UXBuI@3?T11q3GXHYL3s@%p{@?_eAT1U^2w%Vpzy87_%OLtr6;^Hmf$MU?+nMT5BMoulVFoqwtc~QRR~dfl zeN8o8BvNP)<`5*zl`JT*%mJ|Z6PD6jm6rtr41l@{844+*lq9&Xc;@n*(qI*$<+*0G z!zqelq#bKVVqd|2Mdqad=Eg_?yZVAqMSXrxfq;>JSRr-|%4A=HJBNDr)eJVtxq1?SDgcF8MmW&m^J zQLH9n=!BXEb@$PAL2y|YCu4ZkNGQ_>3vQut9&8lh)irdy0fYN?5Q5ADlCk;0;U;_2ARtv{9G)|qm97@Cbs&^KMW#YN2>19zKVSoItiSB)xM zEg-N(1$rd1E1{lF`A9bH1vRkXnUYXeBQ_0duMZ~}O?0{4Q4VJ?UO#AsQ5t*H+j$vk zFKL;QLMJ z@gaUvLSSMSba(<3=_&M?R zYWr%h=vE>tFQ}Jz_JE}`rYf3${b!bL#&Twbx+{cM5SzQZUHfBvJ35GdzT!~HeU)A1 z(_ONc1pLCk1ctWsRr$cSft1&7@zdAs=zYBk;g7bg%)+1Z&aK0N`p(M1V z@Q)^HG@#JQRVqy?w)8$>>9?8Af9#1SF{|%_dQ#;D_ym32QW2krb><<);!`7v+5hE3HH#Ktq_u{Xi1ib4nneoX=HSw$`YF_j+9$M zRI)min&;s|e*oBtX<`3GNdHSd|4T?rZ2w;y!~EZE4D5sU)^q9K9?={rR{A`7uV0J`|njso0Y=a{?10>LHg~l+spI)(*o>HCgFLS|Mt(x zwT+K-xxm%O!q2}81%4xz3GDo^AiJp2-4iRH$34fc?M&2m$^ zWPliw4WGLH((gG*tQOWKrEesf z!ux*OFE?v6Urm6MqtTocr!3bzt=&yCxsqb2OlCOw< zzF8Ttr%35?gtb&xn;w?wZzkf`9L+&_B8~iSQX=uPnA)#V-pC9|xt-A$OU#)xfG_p`f$pBJAk6wQ2V3k5OFiP5r z>g;j1q#$lX2`Y0%2`cG?VN7Q*C=u{T-Xn0k{W@$iR7l&AVzXFd=JbDuLlBv>aieMo z>F*!Krh@ZUj7SRsq_q|D0T{<>8=DNJb6isb!EKXYp`{U3)emMU!?3hYnRdQS@;u;O?JK$ z^GCtuNhF=E$9>hNY}@9nTJ+zD({5Rria5PdMif)1(@(Rzo?&RfPDZQbG=aSKz%C&> zbHtw%zZhgysxWjN0wdqG?~g{HsiJ<8kDR?cfC4QZPm&rO{S1)@GA2`8F8i&XYFHv_%qU(v~=^xtW4yZCD3_lk8;6~Eld}|0id3xJ{w2yE z`Jv{kRPuZpjQ0E@oGe8;7=*yDoJt{`dhbYG~Qnp+*YDBTR?OE{1d`r6BKsXv<$mMKcS2$I;ONJ>>QL+-&4 zs%{Llza6(HAAZV+dOD##LyJe&}B;r394vqd z{eCCJr#6s_Nwx-MueJjWm=^{|$De7~79X;jGZ=sUo3NOgv)Tsu1n_2N8KpLPgo~`l zaogYaJn{=hD?I`r@sZ<#5f6tMBQfBC62bBw344aXv_glHaUBr=j+rWkd94tWHX#T( zzYHw}DI`9l2|zC$`|=g$Iy&p_%wq;VAfEyqTl2WLp28zm0qx4fX`p%4YqAKm8TmO} z`XO0TBpK+b#DckN8I%GYQK&QdEMA!~3zM2mNOPHjgK{{KmKK6g`PT%mU`%q10u{Ps zbg|3(L|AH;`@S;J11i2ls#WdMvZ`mj#&w11)?CEy>jS9!;jpnspWx?Algo}jJ4j9i{N zyVMN9ixs(;I{hKM8zRY?WO|rc*P_*_4A|`6Wy}8%O$_}&fK$|vz=tObl!lz*WvI{! z(G=@ZwQj@g0EpNeAeEZLA!Ur#xD6GU&sYZ{Nd%iZ?<1|9bs4CngZ6Fr#|QO{mfNh` zX8hpNi?);+%sW@Gi=F=QiNOQ zR;%RA1Q*!M8l8;lBb+qEx93q5<2E2f{2^8-Q7H=x1*%Hpm@GA?{hvrstoOM>(J;6J z5`oXjnlb%>LMC;%=rtr)!TOJGsG2H-h;QCE6=CyqI*FjR4R4j@pCpjLP*U*>IKal@H~8m1t{K)#G$kgmAb);*?!ORQLzplo>)q$DjP?P*r$z_GAaZw3%c-iP zi-R~Nn4R56o$e`=BB!@WtxJQnAM!;OJhc&zN8hg*X1`X}vp>;B}ptgMd~pT4Vj~uW3-l zUEGnBQHjl8`O*U~mh)_?Kuh&KZb*F)mj5_b;-HE-(U&8t81Wnq88^EI@%;VFZ&j#} zz`h@{FixL8twLb{D`J>EuCvUU>$A!Sa6(JFhVoFBLt zbC7b&nzT;xSb<^CBo(u#r^w(6pB^`K;=oKdNYAe|33cEAl;6Fs*Y{%y_f3X6GI%l$ zQ+RW3LI~`PJT@|(0Ht;m!rk}tl_--zT13X-Igr$oFg19<9y{+a@i(6eQ#1*;t7vsPUhpV;4w0vEG; zB^qJ+Zr6s_I)RBaHt>$P`gKed4g1e?n_t#I6LEBcivN~VC-ADKxoaUUSJnafmg>o@ z%^3q&Ptit=qYjA1&Vv+K)%TbE!|va&w9ySV{oCPQfSCY|q^_QkqHCHLp`^D4HH$nI z-Yiw)I6t(iah$Vdq8FY7;DcFN~RzW_D-F}_a#1m;3HsMnx>f^fPsA0!sT*N`%8 zd1%OLG^G);9F8ka4D(_k7LdYL za8SzwPZKzGus3r2OhYK_)r~?d0EsIi)@pLv$$T0-$Z>@W&v-%H7r*=Pxf;WQUzZ$E z4SF<6e#0W+t9&%K zn=O_5rzne@D-Z5kamtb6et-mKv|Eo>Cj6y27NbRCIcgCdfD`Ic2xQ+4`l)L3B$d_& zjez~`R4eUq<$^H0{47ZpQ;)Ic%N6>C97#@>AI5e+f<(OSqShb^P9OJN z1#ah!v|5p_mUone9a)XiTQG{LHZT%i40n^tCWvTvuyr|@bK+tV!RL$eiE9+VljGj~ ztB&E~a?M;JV1XiepVJPhaw{lEs-)`35(-{lxVhQ>RP9y~i;c2`ryD;t{|m?vY&&hf z&nn;!-=M+vLY%0Ms9^*XC-UYVViFCGBfYa~MW=BXvO$J%I(yyIkV(Kj2cyai2v0>} zEM#tk;oW@G%Mm=}wrvJ6WH_g1K8212n2vW^TF6&NDL6syqGQZYpZ-}h)Amzn;&E@{ zNbGEs9yO}t{HNPvf2&N6HT9UoxvBsTU`}~3lGF7uil)sAAI9cE$Re?n(~gUGMwE?x zxE5QHE9~av?#GMjFRJb|fsQOgql|pjyl&9>Pz2;)q`)yr8uuf+OPE+Branhue~Zhz z-~eZ^2ovILKxv#i;mk<6<4!>z^YCM)_s@V4;`^DSWZ#A&kn)0+M#wva`LtEp6A?v4 zkRQkT8kcFFT3>TlebIrvQzodia~4a;%(9&%oFIB%*;p!1jY^xGtxMZT{@&7i>?sFT z!5a|&v=UM%40OC&Ta(awgGy4BZu6-i)9}1<)y{XDvY|`O94U#TV>P@<4O%;T@QDLD zXo{6xQqWYVV8K5F_D)lVSG76o7sQ{Si;OEXW3|cU?DzzKW z!;XjT?Um5lq}0(-gq@N+<(e>O045|a@tOXZE z42ttKWBi=`AaU~7CW2KFLT}xX|7l(()#5&eSEf+C`YLY@cq-j#jEuGCsSEYZO_ScF z<)b>4Kjb2c5uZyvHg9b1fzgJk z!1^t7^dsWDE$!I>4OQ2FLxXEP7U_;#m zDoht|e#jDpo_+90u2`j;M?o8=gWKmC^$o%pBTH!dfS^?EJI@hZAJLu83YcwDq=(v+ z9~sW#lfKt)T}E60mt~}q(Kymt4(5rfk(cS7?S*wnX=wnCj<%8_o}K){J_$ z5UX_r&BF%=4(F8Zsw8B(1!8dM>|eEu6e*mD{i2h$NSLZ+7oj{{M2l`hUS|x9kqvll zDI<99%?=7Z*uu#)I)gb-1g*)HJ>q&XN}{qY%uk-xv8OcHf4<2BAjA#`%_`*t)T7kp zi*h7WpmwMNWWW%6oB)m2v}RbtYh(mRCh}}CcaH#iEqPz`npVxc_9=c`t@s1JiI@TX zSIqUl@zwuI$LuU@|E~zZ!t`Gv01NZ~jR-KJB^{5`h8R|yTAhn=)j~q8IpIi_2EQX$ zI`annKgd>Gz0HPeL^z*`gw=VID#Q^|8(bcg-UxGn_Io5 z*S7=XK6;hUK6)X^-L}(Fe(`qIXR8PAk8^|49Sgr z&7bmCSIfR<>`yAX45(%iPaX_@6`JPt^^2lRwCg0@Et^JBMULJ&`6Wrsbn@chzMVNC zW`5#e@1j8iWBxoTfxF}2zdbQwZ8&ppusr}m8~pz;b`D#jKufkw+qP|seP4=_ug)O9b8UJeXarbf&_1#64z&6CvUW!|TB-KNZE~O$>?m&2A zw|#wiz9EHX>2Kj^v0@%8WB4-OwW3I##dKQCpV72mT`t>mT)v~I3 z^7_H?2x+UqhWh!1nyVv5rwx@gS>=qj<|SAsL&5ny!h6>EBsW;6E;TZak+Kg!7*MJJ z2Zl*bL~&TO^IGe)-Vb?bU~8kX?vT6jKUTMgki3M_041A0m$JN<6Np~E+6tTMK*IA}hig>&|@+^Tfq91-i z;&=xwDujDnH)uL;N~HFkMFpRXD%o(2iZ39MaR`Bbb80+A1Cn&H**|ffj}d?}1}%yc ztA@V_HK+mM#9exK$ce3sxIM))iJ$k|UksZrbC~>5dT)F*`Oj1wj@yrt9N-#|9rQ5u z6Px{`M%c(afl`-cri`RDdWDC~);~@ghG=u%ECJqOAyNo-p zj$``|hY%rXtL0%&=Wa(-TTL}A#44;v^9vmTSf=tCMvb`cQ1Rx_h0AOYuvK zA^Caol1gblv*YI}J1$5AR>yc*EjUIsDA^!y(f9<&}tFM}l5BRLvVr4kg+YrABhBQkt;mtlws*32=MD(abuM~N`xssC-Ksd>B0A^fP z9!&kS@BVV-@tiu%P;DEYc=k3 zGY_?QElB~z1WLDg-C+VymthF=IJuah9$`&(Vp91jJ$uv+vZRRpTE@5pC|JTMCr(APsaj<$^X=SpczB;UY`RI_`{V4e2O@Lb7v24;Ds z+9bvJd{sDN>U%CHnig0nXdU0+CU5qXcfjE1dy)N=V2*!!lwH;z6sKN%;ZVx+$(>g= z`1098RV}s7FUp}PAJywUSXa`9OGrSgVsd5AIr}%Sjn_(+;*|CqzC0~gj+V)tAyKbH z8x)yx4+NPE$2D1y4+ExN>~9;Ud-FRfaL&JOisGbsLsd6&wa+XA-a-Y@B_Eg`Vo8ga zR&A@69aiuYfY#TloFeI3z@72k)dVeu24Fw7bd2Eh{KGJ`rR$H=LH_&%9n7%?(TNn3 zn{F9;UjFNE%3_4Z7xg|>7q^G@7``i#nukt4q!x3@kvQf<4van9eC(WnqL^3KgXT_{ z(I2{n^YG}pIg^|(OhOL3@0q>R`NThCLMU>w*sVW1^8o|-1ja7T{o+uECol?c0f0h< zz^7NRGCc|wlo@N7DRk^eNAeGM&ZZHz3e9U`E>{T+mmp+AvJ8(LgG?Kg8t@$8$wdcN zD;q|jOWc>%%zdV1R&bam(%dFn>P^oB6MEeY93z}bV#K$0L(V_wW)M=iZeS9zZyGi~ z$+pSP9g=G%qjQu)jsX&F3Z{yJ#4~YXJd`mlVO`U1;A|=$Iw41Fy0|;aCV&!Vi%h9q zRME_X(44>wN%G}q@3vrD(?+76jQBL{b^#5JjghtiCsmk$*>mAyKksl2I{V==ime_= zD^ZUl#y?Nd*=4Zt7H`SA3%18bKcCzj51#rN?pQrgC5QA@`v#SffbMDLRB-}IJniQMWM>F0kxRA6ocSjPR zCmnanGbjcX98E&EP$M1S&2SjPxa0)aUYjrs)@A6EyQJ>; zRa)hB6abRjrseE25uWJRzj2EUFQ2G55Oss}egtJu^i@r#heM+(Rx{NT-U6J~XD+f^ zjtvv4AFiNfX_t%hn;QpfcF@and2>B9u%+2DxHxHGChzOZtCSl3qRSI_ zdMPQseZ%(e*bMTG`YO+(TDPqmRmXDRsBe@E=2n37Pj11xUjRT~4|%wRMm|W5K7^Ro zNRB#$?aJhYyXb;FWCe5R3v|?YpMpeWBQ z4*mkF-TMw{!O^pk<%P_4_>enLK6F z`x@Dm;(&1a{laH6gfKuU%JWTo)!p_o0%zOd`#m{%+IWBOvyEO1a=rN(0L}6A{CUl) zlhw<;X7I#T_CBeb{dIq==OumCm-aOG)!O2s2fI939n^sPYgHyEH)Cn9n#sufg1|>r zv~)iGD3l$&YU*6J`5f?Y{@sM(JvS4)_*&W)-Hg=dbNaOh#>#1M2G{F`2X6A$!Dr!O z`qrunU-mXiA$N!Ca{z=AmiOKI+XM6IX`$=fi9vDPQeE%&^NZln6Vs?6M$262Z&=9? zBHeYRf`nmA>CITi_t}>|*ln;&SzVuwm%eCF4G(P`{}7)H{O7z!hMHImS*`4r88$hV z+9}~pJHnsrok&=5;y~xO>+O#->{D<)2=uNYIQ!|HtY8UBW(w3oep$gs;~Zg)dcEOu z$>X9gfwD9CkfhSqwqZ6>|7Yh4@q6$R2D|MW*%6JRL6~%@?0v*hCkA; z?1yoOoZ$-ZmK5zPHUESa4>a}?6LnRekGC6+VX{CN3cJV3xT3!@?*iTun1{k+6v?Eg z0vqg~8s2E6;^OvgzMieVKo#W9!kUz`bOQ2&>`v1rc{G)w5oVkl9iGGjA4qa;}B1JR#^ePfcipj56;vC(1xuKtm*L zIruXG#zr^dc!OoPzZ)Pdghu%j(&I*-upyg5p~KMO!oX~N?7t7dDa>Tog>uoxpjIl< z<8C7HPSC~zWPW?!u(dDBC6dLda^R%qv<_KZI{=_|H&clHz|=8Q`E{kFPglRlwOy~S zK?aE}Q3mu4F>MdB>}N-L;feCJDwf5FjksHJ6c@4@t7Zi3rUA=^ee^3$j7&c^wHO;O zOhcAE8Da-O(Hg0!s*))%T7)y(cmf$zDUO@pcChE=`hav!UR}N(S~bW}TTu|*LCysL za=E{yDi-1A>2SieXuSxCAV=Q-^!7|-8Uff2$Y26qoOcJWZ*+9agW$NErunf@9Jk155FrM3s_g@kg z42P%Mjuvs?S2daUJhcvGCr^lr(C4s%k&kJn!iam9tmgz9A|XQMCslA=^*vtY4ce>w zSIA>ofR0bfBfjZ={95Q)3=UDZYs>k%KokvN$N(mXq{-?z$RmCWEIp0ZlZOL4oJvCh zsfFfMW@i;Y3~vBsD^2F!-tIB-d&=Y^p5tIrFv`u9fC}3j@C+DF=<<;& zm`e+`*yR*b^gcL+{NdcBC}Z`Me>K?d+fvWDpr*CxFSP*l!7^)Rtv{ol$kV>pY_qaI z=FxS$d)GhV%Xyw4l(j}n`OGeg9HJ5dQ8Ov%caL5MWt7_vWOLPgV^BCG_bVgq<}I04 zX8mPnZ=1Te`27WNcjG`kgi%v1GKl^tC#Fv(LzK>HgS)Ru6c++>*H{e`#sZANa~kHd zfY=x0RV>lRJCEsFE!u6K^TfdZ*N-ND%LSC0DF$Hda;$k$rj4i3hIwfNWqihR;6n>) zi3tsIeY4M;v>|SJwfkoi4L-B z_)l6Sdc|)daaf!3a&PdBH%zv7C+!F#?`hSH){IrUb z*hKM>^6exvopR44atLXVvlb^c*bV;SPCsj+U>4G3O5#7g)=Fn|0Q=(`YB;1;&k_X^ z4dfHr*jh8{4*8n^d~$B>=!MC-41^*xeQ{?C}qMRlQ7OOn?ht;5_YLD_D1o79n_5wzRNPATaJh5`HaTU+RlmyK^-e z8t063-cGDdl*ywsR7o73UM?35C;z6y`iOqEBh_9JesK%S&Zi6QK&|`SJe9+EBGV9F z02rn)%k^2WK7bxS?sjbom1nGK|MI;Pf5&2kct(}TJ$ z3S$wedcjEN$_hg*F!CJGG=1!P0Kr2O>#tCpFCUB^HW~;$54@C?UEBt$FvWL?<6_rc z3;IGV*ILW{+E?!PHK7n|bA%fW{N;k}qooJsW{89=j=QU!LMdgqy)AVBe79;kdD$+DbJF=7h#T_S-Md27dd2FSa6#8#F8N)=8jO(3zW0-jU}ZaApN z0aH(Ha6D2aF?TQMQiQQZ|cB{E&N!W0|Hl6e_pTBfdKRqm%3tOIpL9> z$SowEr9*|vQmg}ZLXITp1rAXbRuvL9J~QAaXc7rN>D60x>fWE9(41|=8=weS?%57( z!boCf(T7|fvUwR)~U64n7@ibdtOjPs0k|ZAy^XT=W zHBCCkp{B!D7kde?oz&rlLgPwDvU7p+#s+qZF}8rNs-8Fq7vpHD3^K(vatnaiyP0xy ze@qxiBN_oMqrw~N;5>Y^*o%*Xf`-`7qT=_;B@R6PbU`5;_&>Z1wpk%Nq=(q*(jaAA z7G%=Ql75a_XhFQ%O1ilmAgw@~gb@@JmiFIh0#-=-6CH} z*b2uwRI9dKjeqbPk~ik_N(n`IRmkC&n7c1!>ys@E4Xb1;%)o4vH60`^`ThICN)i3n zUezZ_&3VCCZfrQrYn-iTO*5_DHRZ{PO-5~D$tKMr!h|#$zn1(|l1?ICip+odBeWsH zD6GNKVQ77W%o(}KEjnu(9i^xlCdMZtSn`~#)%*l(C-)?6%_Hq=pdGFvAgyej7oN|3 z+;%E;;oq<(#%*r5R-Stwa$ zj9qlt3XUpm`_ww-NN%&Ad1OAEwlX!aXjXeE#W8dD0YB>+zY_j&S5Q!ijdwY+>j@dj zuE{O~ot}uv(v=t*3N1P%9oOt9b}4irno#O!XhNB)_u4a}KQfYaPXd53=FiLUxh zX#vTi0Kay3u93K728HK&&%jw0wn2mez>^BiO}P$bibW8O`CM{n2 z#0aVZ{gL3%Ts0WD>}b|nA-c5ONr+y42BIS;sC#4p= z?r5faBy$uwdXdSf*;H(Yw#ce&YW?Ft@qC6!m@S=y?DPoYn42Rm8NeI*s9k94iBs*G zwlKqDrIj-LvX(4!d|Vo6h&l7Jl6ma+>-_lDB%A4kt56|H>qrTzW|@#hblI+3QZJt= zss}RN-D{&0rVEh;6EmAw#xjCjUm`|NcZWL3CuACIBeg{HJhkf)@nl}pyAsG7 zpYZvhK1q!ms54lKE@XNaok1_5j2Dnq3RpukfwaBJi^N-A#HSN`C(N?1{DRz?a`#Fk1AQ>SaIc_~-og=G zVt8}kB#a`_(djZHIovL-z%ArA^@2YNtxK~qQ+h;Ea|T`G$=Meh{g_-+iu*T2us_uecQPo9`h*oXwpvirqs4Hfy2~YA($9)*#?Huu8xFhy zPA>;;m4=!+l;t6DK8Mhm<(6rWF1E7bt!HVjp9jg*{)5gOoDAF3pCw9{nUW)K#`Di& z-EMX&xBVL-X-ayi)y6zsz4e8ofNW`h+V;exeH#GC7($6)sv*}G>Q9&x{ zCdVV!jNi3YEp{1Y&f=Z2g5&AXduJ$$&>KnvUjTDq9_m|l?>&-CNvc8|JZ>ovf^6YU zh+dS$I*>eUxC0leL5i4S`^iyjaM~ha7}PiAFxl_6IA!DbuVT$G+eO20|= zZMRYWwa`_G>PsS&8*9xS4ARfD2>G}vp!V&A^SA+y@-m%9$&X#CPuTp~##w`2$7qpO zH;+{t5Z%@55u|p}vYTME#Du}Gc&qSYRI~b--3fsD5!S^OCr0T21;B@?*Y#x8;(#76 zCTnyd+mP9a?-7Uc+R}X3}sZMQ-wpZ7A+ClfHy|B?K@o?|1YOd+JK*gTR7Y2LNAN7DGeS$Ks0D0Xf z0vB94X*Es91gHHb!&+oN)Mzy5FtwQ5q54a5QMwrK5eP2p`q5h;BRe=rxx2QTutQqG zQi&oJiO23?#qZQRp? zv_c@5cetxgaDZ0~$e$D60?HqJeX|0=$WYB=lwZ!v9icNX8O~}G%r?BF&07d7003UF z_D}BhQsICGxBLUIWa6o0BSQ|pBu8^HOT$$C4h*5-O&chf+n$@^A7CeiI0SB?8rfsr zG@HXvsAosyM~$Wty-wC_`&&F%IvY%*onF%+>&Z;hxl8MMe=>`-0h?8L_fzANv&THn z+7!W`fkTCPj$X{8U_APJj>;7#od}1;^cskaurf~K`~LJ{qH!?2n|T%_TN>Itubo&g zE|G)^k%9&CS63jJ3No?yUze6urjv+BhcyE^Yj&yeOtSwSr6%h{X%zDj(sVF&?B9yO zz@9J$7==1jvMV<(3(#hF2bl3j zXLm;_J{hjqG4NbUe*7buL~n^cG!{Jr87S0uI9QPDZ>M#<9LyaWlFjP;jHf;pv}U>H?{A17$iN7^aWa8W}f<0IX4P0Z)b! z>m%G~5f+a$9E})${yK&`c&rwR*RKH8z;EesxQe; zq=sLITQci;Aws3%%5JZsNeOLK4#$nWpbObjbu@iuaKDPva%Q6vpr)pdjfMt%3U77? zf_<%8z%E|^ODeQuk}HQ!ZL7CUi$Ggct?`JinGS3OE)8SXM|bX}j_y|VIcX5yoas%Y zXCNl0{o~&AU(0{BCH1Wr$rQcd$bRm=kEd_9zX0|Tzl{F{LH`GC{s)4xGO@G&F9iK> zf#lEsNg$cl(TXE$a}Yt&dWa6$zW*S)T?+;89o|K^(ww$xLIe@VIU=<~dy$z)3Ic(s z2dw`6MQH4jKpR(@zOfTiyh@X6@-b+tlFi{%G5&qFzzO!o8u~qq>+9~r&-?lOse84R z-}jruKfmqk_WM}u`kd`c&ke>9{eHUXyBRge-99Tl-W^#a$s@A?yUg9`>FfKNe%}7w zvZ?|zxn69_QE6Z7`tAOGc&JljZXcgoz<tEs*(hFbfKQmX>vjaO~&`F%=HfAWEIQzz!~ zZv4(MyYPX?J^3H0wvP_L@%2hEk7vSwd;qL$CI z%bVMEH+9`?nkf~TH#5NbZ7WaAeC&^l6VR>550c`B zL3Sx<_<`08|C32)!Nl!GY^KNRaL*m!TA7~%>JHD;LGmO&(ZhVe*ZFaRU2mj-SGeL% z!e0SPo6(Np`jN(^a?HJaIGQgmBvntPyF(cCZG9s&LEzsn1Z~BjN4tQbX{aPJ6 zcvqGpn(9mfE{As)b;YxTRs?qrb-^YNE(Tg9u64t+Bg?uVIW4m%N`^r;UxK(+fIOt2 zL@G^~j>{|*C@m65x{l6Q#|rCb22+Hwe7QFnL(YsYW^p{iG?+kcZdd1reEbk-ckJY+ zbM{HPO64DZ9I!4!R@_VdeAqr& zbs{mydJw~(EaSsr<^nxdyB*H3aaG3B@J!>C@TP>Ug$_$tOH3fpR(BomT^OJvI4{O! zV82qeE!K`SBn#Pk(^F-W!kscRzP<&$opJ@vz4QGL)ZE^g_&G?>5=yd5z<%CKV;2_9 zEf`Kf2Mi=#B_RIVNaQN(v`Of>nQ0tZgt)SyiBo~>F&HD6B}>K zMkU0VMofbwf*ojJY;;8~ZQzIMym#$YWFYWAqgSSSA@`NS0oc)u4Zr?O8e)Yj0qV~RxkA`Vm%lCklL}3OsTlXohXO>4eD1_y!nBjOsIoX4F7m<_r`czPQwK=eFi;LmV6PP$+b<&l{+i{amz-_| zYqNk`=`$osRY1RnO9+zS;Nhi2)z6J4Y63z*I1VEp8XXEp;cXu3#SGA?jWIulvqSO6 z(|&z^^)g^1`c5c7>zs6g&RX)bBXhhlX~<;2Aowff{rc#H73hytrEpo4rYns{Y-pua zS(DjAu|Cw9fB*D8Ri{3F0^=cYjf)*L*FtoLIIg^H=|o&Z%f~M|nLr8wA+lnR8;e~B zRm`F7i5X#z7i-0S^gAND@+m$L%m6p(|Ls)c8H6ojL}ay$Q!-_W#zelQbWS(ka$ZXh z#&v7qa@Hz`hzGnQ#pNe?w8;R-VT~F5MX=MS@(^hb`va(m16EG?@z}yjDnl5Al)#*p zC8@!5nIpkStNhKneWsRH#(lQ77fPsn*rs|28(L`i*UrTU)i6NwOAKQoYM#+Q84r~ zJ`|!*ksbClmgCt|Wk94tlo5DM#H>wkzRsmDX^JV)irghDVIN943ZjHl?4g}^0VTrN znLhD`;bSZ8>4_FE95J$Wg%pzWH^H4^NyX1G*aJejL6RD5n#q_mb7uW5HrMB++Iah9qly~&m5jRt@iVKnMlsL)@CMfr{V2*0 zVo34dg7q-el){X1J~Q)pPmT7Z&0>aq`8gVsWZ~Y>%IIOvSN(VQ;&(tmh~}zMV!(EG zV^%cvr8b3`bf3Jplf7`7NRop#{a?20mU!F>h|$Xh_5k&Zfk=B;bPZtM`O&4Nd9=cM ztYEZcFa)b%*t(;y6VI1!K=(4L&k8c$VlBX-=`aw+O zj;~t*!KpI@;f?EvO4Lammm1$yU+Da)?>MSRLZ<+TC!%lM@pMeTSy!a1r4YKy>r+P=b5Hw&bgM3MXTOy%79)z_wYD%=6BgJO zoafTeSpB%|cVXHQ{NjaHIS(%DkkLzfv|u2%BTBqCgUdff2Sg=6 z?N9zpDc&EqK+RGXn16)05kH^ehK`rn9n$Ak1^Yk1wR3n?Ou$r_q|4LSl*A_;!1^{# z?k8uy*DnYFE9Am) zM5$Mr2ZX1TiywdzZp(k|`b=T?h=5hDV%2}G^7LF@S+gM2-!N-+9P0v?uI!Bpt z&F2Ix8rWt~rM5Q4d6hzlVdMCB35U!epp>hv0QJr0=LcMJY6KBR@;Q&K%x7Oee+#q`nHTr&Z0vVDH6Bx6$3k=7=Z$@B>kqxDK{$G8`2cQGu^s7mINdzF(e&VbKz_b3h@&SO_X~)f(FHljcCa8yslV7t&_QwT#@>%&p0239 z_h*D_6U}iG=@y-On`d;v^K5cUx`JN77nv}uS2VG zPRGRM)H1hcmiB4}UkIXC6O`fSWtCjYP)uu7x;G*p!L3K-mQ>Wvh>~88`ktL2;-Ezr zrF<^_#F%mo>?Dpawj{a|e^*{8u<8Ep2a}hlyi)qVr90rSBX_U7VGKu;U(aOl7{0gh zydLb($uK{hW$$$bd*hP{P%DiUjHdQ=VdOv(qRnRx7-wW^~ ze93l?$RM^!&OrC^YsRT=^&|Fl2Sow)9-6)(Kb_vr+Ewu`PS=(1DvRlrNtfT?&HEq0 z3)TGV$oTWnYbYKgmcWml0Mr4K3r}NI9OFIrw1g~kuX+B)-6Kh^xPWe#%fBQfIQp~~ zIB(T}BOpODQU?AYQne{*d_%1XZD(;H+L%^BxLG|W?%>5roYM`l4NZSqJ3x(7ctjey zG;}h9=b84yVG4FiPQ|f6Qh2bWA711#(2+MjKA%Rn_U|Pm3%y|?R|eZEtuCj9v1B=> zAUT`l_>-oVMo)l1Z?LCPZ$+~#VWw5*Gye{@37}M{iX0i7S8EpN0 za9_e>7lvv2$IAyDPF;xA4~;Z*GB6ZguM%1r&K~0WogOIduc1ytb?EzSzHORROkrVr z;5bZWq&$O>qcq!D%_DSvYWmX1DQ1xP3At0^C&59OF})n6GH^iPAc(2p{${bDA`Huf8jAXh-Mgk4{CM^uvR{BD=Kt7pt0 zuPxIY508s_)V{S5Ynwx)SfL^pwfq9bckV@cVyKq){yLo3(xmr6^y_l~BvNS)4pVF3 zAz=mpNP8`zI~@1<%|m8m^Hf9B}&)!6HI zFn(&h^_O4PaHdXT8I3_@Fths9CzoxWH!NParZ6Qmxj2P;y0xcc4(n))ZcRIF%0}(V zlr6vwGC@FArigX&^=0VbA;=ARZcn1QT+-?eZI=1p|JHaNB%3-C{ObyCocpwbE{_0m zIXSDek*Vj6iU!z)rNgLAW2wn3qDyWr5pJina73Cs>At1ulv^0x?|5#vZOZuhPVuwd*KlLd<`L(h zH=f5o3)ZY^aEzbGs_zp*FxY0g2Uiw}Tai#9DRD)*O!x796;9MID!1IKUM8v%jjLWZ zv@E#ef@=4KOK0CsASAu5vgcD%DBG0);qrV*-1Jn6xn=1Hft`}mLc8t0Ufa^y)#&vt zw0!~N22cchaeF@eXlW1YwLw0(xcsO6u!A<(z!X4IsRq-qX$ePP+$e#eLo0|NxKcTN zZVjtR17mBC#-#bJl$_pOx?{`M;g@JrA)+%d%s{$9lRAW3xkkRyX4d%TV0X2`Ek!kcGATE7;7PT?qk#6WkGgQB^=@@a;=IrQ~sKg!!? zVRQ$;y@ew8`P*fr;cb0U4eMRz9sSkK*mQNX#v-+DkzmMa3selUV?)VWDHiT5?YhJ^ zU9nXJo0Qj+XU#?pPd-L^FwNRg3@G|p(PDI#3P{*AV*wvq%SvSPJ)3y4H?jytWxizV zm=PiHa8darVg+N}3Cy_m1E~owynnPSx-S1Id(=E4r{K=3@bM0Brxz7T$ao5Uyv#+2 zM(^riW+m{mg87Rg_p){h1q+X9ha%nzMR(d2PqOK z*w#<>8{+cvsn&)46OqME!dKi{7mls4-;aKf4ywrSMXm%$JUmYN%GH&BZv|_+3DCO> zy2h@;pET{>>=)NDJZ7z#0#AUx)=5@^eU*&0w^K|Dr=h>__jg;SS*WcG9yA116m9+6 zSQFNW9C;D9!GJA(M^|KRyN}QOr#%Lx&7*r{L@s@GUqpVG4&$=U3+FmeSuB~KZ_Q-3 z==C*?4^J6roH8t#pPAY-kDfj+1dac2T3Rm`eSIcLOvLZU+biIbw`~Et8h&(Ng-#~i zRAaGbNG%9$&>D>STw+m(@5Pon`Zu%Er&%_j%w zs86wtu#EB8voy!Y4t8Lt7l6(5aP48Ug$@ug3ogJ?0`jLDs!70ZpX=%dQANE!%X&XI zbGsgPq#L=)$WcZ5G$eq5gcZhn-QuCNP=mh5w<8(fHw>~C)^O0k4HusxKHG*s22FAy zD0Dn5j{BrWZ?9_xv~L9<8&zGQcy@cv<~)*CUAGK0fUGU>G;~<7zDme#4GzMNM*{+S z+{W{I#y&2%Fck2B3De-)V!9{BBZD3Sa3VGVSPFkzF1nep>F?$To|g)I_piN@8~Z4u zYagIm8&;mdVU{pvv^~jmjRMJ;?Pyd<*cD+rPlx_v@eUwXh$q*tW9JF1rIDEf(qfc& z?wz&^D6|k_f?oOLJ{W8HhL?NHMn}VkQnQCw7oygCO#oDxGJ#&nOT+2>Ec*GQUt$Ge7Y>O7F{8Gc{WAt|u4kA7S)Tm-Ns_XJ ztyh=NO*cbomKCbG)&pXjX|>N4RVX1ew&cO=yO>%VKmP>7S47wL*$L^bU*Rh>okuPT z)Z6tJE6ZkdlFu+_gxb%^rLgB&KSv)cid?!~8Cr~cZ-XpPj;70PCNeq~8uz&iJct{% zm+_)Eo5T!)nS*tm4>Ut3rX9W$s~S2Gw)}$R98;(F6z~SBVRUweC@{({>~b?f~%4F3=0{vR05 z&hWo5obA6gGq(SeX7(Q#PRfR;Iu>$;U_+L~pDsco1i%<(%z3Tl#svh4aOdw%xX}hH zCqO_5O8NPVU*EOqn)2PT?eij?d^LHLZL3$+TlrCW^?0qb3+b`?>9-$O*Vl1z`{VR{ zy}U&EyZc4>{dsA3^Yip|@kl?)McApk%k%rHva7-MyvXiHe&>*yfOb&M8++KmYE zK;i`S5e>^~@nc2O5P>$aXIOj2o*dRw!b%}#zmg4ljPb&|BtKnd~X z^T7Cdp}eV+ylfzK5K-gQ$t@NxS<&`izVsQ383r(q_#_nR1z$(3Er4JQi!Ntf<7T-< zl)RkmO6*qzI$BCBF`4vF0rtd zf`U~8&|<`+&s8~iqg8lW#2Y_Xq{b{5bf4qgD>3GbV;7T{p`@uoc`n=iJ$R%lHEC3pNwyJ4RE-me%JF374d-3xrl3PF7L`G!f%YKRaJP3^6N4 zP6Pn0;N^D6Edm45a<`yh*ck@Oe%Qh7Cj!LW+0^sR0-`-?lGq^Rb?|ME$D*ywDf|8C zR75~V0>^|{N#q8Kk_@NqMa}*iS zm};3)flIietd@S;m0)q<1j-^FIqI^me*;E#9e(Yc`RifT1kVxKBuX_M+K@W+{h&UyrV5}6=fOIiUBu2?)*KJS$=_8&QgV*V z0#oGTSqHL&RsuTA0MEk{i$@4$8bBj%$x;8kl8YDL<5!S<)jVZ+Jwnn@5N!I{77f#& z%h*+wW66V{v}N@xz)OmrxE`UMfJzZeqKQp}hBKgHA-geS!D0wCjY}Cgwy?EB zXbEmZiR=y>%z^!skeEod)5rujl4=V&jF&Jf_ya(NV!JRNiY1_>C+)XN5bM!C>X)IV zirio|cKL`f@gL6GwE05`z)hR4%X2E`R_x^CojVvS0}4YLhKV!Tr&NO_*Dr+-VvR~7 zco45p#BqA!e{SGrhZYiNIfKo40K8mKnxTq;X86jG{a32gCs5jWN|F3ygP+v}_?YMo zF{HU#O?zv%Wd!gsrVQH*^eV(hiO#fruP0{Sp9bfncq9QgCich}8TS^iR zI4csu)X*wU6@kw*rrar_rV#8^W&?k*s&i`fdnVrLr_AnuXG~#2%<RwR&lyl$iiw9e4Ac z>%V$C5>fuz+0CI6nO#5D;LnMG-M6ftjV5W8lq?~G>fO6N$g zZw(E+(!_*qH{3t4CTtqqCc)=XegB>&xZM$_U7l%)tz2ni&r{n1OP^|-r3FMje*3#; zT>V6>iOpDn$k@@sVu|_pJEzWKuZMkANbGeV8Gl>aGrb7nHCSu#GtUc~`=!b0Q@@8a zr<(@?ztbjLdyAvPq1(d|S*hpARG!^V)e4ooRinwE_~MAEhOaX;M=wQvdEIFQky9Z( znZ5>t0qJHj^z^8qnTA7x1U*wc-I-wDO|}rl^uE56f^hRfk+x!wa)+qC4hH5U0z@qr z@NhL+G2(;-?nTF#o7(A}Kv~Tli&C8Sktv8XDGja3(3(#rnuvx_oHAH70W@O|Fe^4p z(eUm|lQf&+pnFsTr0u{hRs7#!1dI*x-irB4-6m1cWY{r8`A4a8+#<_V?ddZU({c2M z0z%itA3>}P?no$oSAUso1yCEH+N;GGwZ^8Wk>ug2MTabe#ZpWm@ZuU8&ozo=!()~E zc|G7i31d`V7FlM$mR9VW{&wW#xgQ_MtxO+ zT!1F$W5kg0k$_Vs`Q!X^aQ3xXCJcn|Vn6|9h)xsErD;HsIQ2lz;Mpi!Jtdie+gaT} zHd3PnVB3GRk@nD!(6|}w;#(k`x01r~*~I{OE>nj@RzRYY)&R9zT>MztGO-7V^ z5x0?9g>wraA-zc~SsFPKAJ;!ZAKJ{tx@%FN2#m;gz=4KDMwBn(cve^l|L3WO-nVeG*BFUrMquc|eCIo;?eFMqxGl1?bWpm@L-|eCZpHlP( z*(kkW+ry(_22e3P+Ksbc<-AEnORdw!t=)Av`tBoj(I=f^&8hFa`1|=b5Pox6kkaPR>de@X@p&TpfZ<4_5Q$XaZ zBGh2*W@K9jCF@&>KY0kE#@sRA0EATQpLl_T_e1H|iP(z50+cb)jJm6@1S@2vTUD_{ zdHxwL0=K#6_zyqsB zIpf@d2cUgYZYeAtxTpUzQeN?{!rchGat4Y%m_?r3r<=L{y*NnF)*{GSvQ3Z&UC)&_0|{I zml9z3wNqhz0=gD_FG{qlIpt(~L4;N*kSe7Q(Bh99d>P#W;$kU-LL1w8RfQk z|GI*%BNv+>4gO`(s}yFZ0oWWryUNz6icLf?n?e&&-o{@kTy;0!k!v4Q0RFqB!nqz1 z9xQiR&}-1jqenhVgQhmjktPU6^e}a38Vlw9k97GQpk}iGim^Z|#i0aqPOrr<^%CFR zBFb)ng90Zi^r8^#h5?PfWFhdQ34>zrWce$1X6$q!UGo$TK~JN;f)L>Ru0-RZXA`V< z8Dg;gOomZ8zOa6fcDIN!7gbtdzgP{7sa41r)<{n~%xx*gGGp%w8b4J`f zK`nu4(KP(6ZX$#H7HH?q#E5TC2Gwz<(HFCU4%=+?cogNIU1{mdt0RKL;lBa`*@W+z zY=%w?==4vQVdgntH)v#ua56jh1SA8=xTj_3m>+1~=)fcrs6{oC;qHm(C69k2WDcJN zI0mBQjZ8>$Bn@eleupqy=ON!2J^u!dLT zV96${yw)x}khh7#`MRGqbn91cP2bQ0=+L2d_*TW6vFy$BYB*0(;mYKA8lh~)@`Nwb zj=*WOk5DaOhznp;+i@|Sa@UZHWvm(0y7GGHNcI}UT}!I!CmSUs)W$|Dq_so%rX1Q- zODTX{NoBH*hznSvI5YFyqUS&2)q4h8>g89FM#ObV?TbwkAA?Q$p2X4dWL zY2URnz=)s@f)A-(a({@~pE?=%m0h2b`vU954ZeZ?`5fPp(_IMbQz4~$DdqY zhsQKg>-ZeXoAAIy7*2oJelE^O76LkJJQrQ*nC_6{*A6@L8NO&;v#GU=A2eyslGR3{3QTu}R9lyS2nTZ}v1Iu3hTMkHvT&7Wd1C3kh?c(sz z1y$B4TPAr729CMCGNljZNX4i`J{5vAdxTy_QLw}+SHZBRM(8zv&f30kND6xNntt6y zYA<&^8bWq3v2Z_jQu5I{PH<6nLm#xKyMx}zpy3YS_+YMpR_ew*yYu@x62wn7+~f>1 z^CQIXPm!Kd{kPmZA+Z8IU8RPX6Tq0s=A^V9$7qV*xyy~Mz@n+aN)5VMezuvwaE<1x zD??dxg&50@vi}Yg4N=ab=5?o2(OfmY`79LBFMaZ4Lki2o1-VGgc?t6)mK?=!z^soq z^#swMD~Og#BMxid+cpuBeQV2YDVy2(XxHivK(Bwdf>4bumwP041$#=N&5S0#_QLKD~qv+Off zNn-n_VBH*@%R*7vuXR}*L5^qGI1P|N98%r>o&u205R~1?MGsx%l24sJ&I0A8`+nmH zAVs)3ew8gHufCt$*e-|9%pi662k(W`+}L)%(IjQ!!zw@BQ(h0zaV9i@mPypPKEzng zRk{KHK(!WXN=755=`!hARXNOP^P8a9+5z2jQTCKjarki`j}@1y7R5R_CeF%Pi~o4# z%ANYk@iPHl4Xi*D)-8h0=t6bRHPI}qFC`(WO*mAxHfwTZXvvRY=S0rED*j$ShMoDG z4GQRNtl4Jmd0l7CP??=kM}YQ#T#>S?hg)9mkl|+uiow9bOtfjesKpIlU7c-MuYu_$ zH@3|nwr`oEdFLLS$JUg5$d*d==ZLqPzU7z$9(x7y4&gJw7;k7_{wosF?E4q$C|SRr z8=(Q3&QBqGXQfIEnR|zdU(+QYg2DRsQLRd8y;`VWzR0O)&9o@~9NMcAIItE|{ic|? z)=esrfWMcLR6|~f)q&4SSod1a9iwv8ikRF?kgf4b?#)0xkc1QG$Np#pX$7eiaLvn- z{MnjQ5J@OdvotZ1>n3^FWk2ztAEEdAV!Qa9$0ZW@IG-Pg9g_Rcw5-V4nMp9!C%aOV zEqW`7lu#g`6HQ{r)LjEvlo)nlGBd5*Z~S(o*-JdcUYkJp(%aONyNQKSwx2SBBz3Ol zZ;%2;()!%#v<1DvvlvV=g92T>M3}V=`R*Z^Ta=$rPdJHFU|sawQ`v6_t-mhPe@y|EjfrpI2RsWxO;zykDBc4c4 z_wV{utp6&Y%f&_e-N4ew-k5-u_5UZsK)I@V6squNc-t5|x~ekoQ(uNu3`4x}$%n8g z5v_3AXb;dVy3}NEpZE7oWp3`7IU_emIz*)8v*L=15oK-VG0)Rp3Ptk6i`UEZH!XXw zGv4!_q9bXw-HD5JCtmGS?Y8@j_&mC`zAQKTen7seqxRD_B7^nCsh0EYw~kI0jn{To zsi@`V^Ud6X2XwE~jaym>&QDf(zM~iDo#zN)@w0jKBup29I`J6|C2C$S)m{NN2`I7< z&N0^PJ2)N6B>iU==x1#}62eG%R3vZ`UfGf^Gd+1mW?nZfy)#bRpRx!~2EjR1Twx9%;2KUEfrbmc`=A(>U9`-tG}P+$|nUKo`zddW5( z8h6N@PmG^V&`eghGNXRZ$aPrrG(TsUYrF4Xio+Ck{J=S+To;7ea~q?0D~Q zvq3DA9Q(#o-ID7kwB)o1IWWt%0h*-^>eS?ET*j^_vTri|`Y16F@*Ar?>$P!GNe|}8 zPN5cVFD8f`F?Ldvi?-0=h#*`sJ6LD6ore5&BZ2BnGx%Mr(9 z-)74uUqfcszO)>xM+#g4DnM4Epd)hhQE>n2sQ>FImIIK1V9&_LseAetp)>m~nd>?2 z!@eb=j%$|hbp9mGcz=;jGQ=4P3g|exxZyX>vC~(MK?ztq*dn!J>WMW;wY(R*Gj9Z; zLEs0K^f@)gAily@!l7?;!%H=6KeX}}zOieV@~l1CRUkAa)s-SiDO@Jot9~ilsWJj- z%|Dh_Q?RXx7HRc{)~bL5UOmv?v}7!y5FTl;QZ!iVCCQr7`wahs_5vSK(oHmyVJaQQ zav&<~`bO!BeDu)RZzt_rOikaK01wRPGuePK!XKB;-k|aHQVN6yMQgb7M8M?{rh$qL z!^b5R-Mw&F4`Q&4tSHFrza-c*>mch?o0J(0riZ`lXVM$k8DQwC+A5Vqo3v)N*{=^! z7En#6Dab1|BR(vPHo6?){TKtUQ%yS^yRDhqwpF*^^9*Jqm^$gPgi8(!SPjxY8O~mi0erErg`nzdiKhSIy2)dF7dwSqW+4&m6?6L&**|#&R zdSDIJo5%_^U-sef0z=y$wnlKaCYLlsiX2I(w=6Hz@Z;3ODkg{+&Y0gh(gAe|6V$X` zLpbBTZ6vg9<|(Ia39Z$$d<-Wqo?Y+iR72BFf1OW6#1>iZ!CimJFn(EHpL-#J!bfdmM9#Fg%TCckIZUX`7rV%BF=A~3mDYplW6(Y(u zhgolVd2u)=ctx(^zcKgimTeN?xBGw2P zW(&jA}}0Cr9U6wAFMi90c|o$t2$T?qxz*b z+6r<>9I|UffPK62{v9L~f7kB+wVZz};vdUN&&vF7%lVJOj|wi<2DCCij0|Wc4fIWZ z2v|82sQ<~_!$QwMz{<{`2~8_!W&gw8fPfD0maT!MJ;BG39pJHnot1;Fo`D^}`pVc^ z>B$?|tJBH|i4f2#7&zMl+KE^JUZ($JqvfD^c%W$o0r!CRb_5?aCjUGF5c?Npf0GF4 z>3@J6aSOog1piHzinOk&fu219!$&frzsY3yb2Rzi$fW=C?as%uzv*Q7GxI+L|F6=? z_!qnWVkhH&VCP2}&wtX%_%D(F&(Qf#@iP5UmH)=KkD@vMq=)Gbr~lXa#{A(5{w-hT zf6MZ})bJzg=|AaY{@0=P|2*GV{(~Gp5@!9A9+v+-IkNr-IkNnlXMgKI>;J4A|EX83 ze-P@w>D9--5B!rqtbbO<|GHkWeSE+7w_dUT2flr5Oa4jcf58R-gaB|$@PW5>1hf(+ z`gR2B(0|R9{x5y~02w*xk2Nd@{jqf9pg%NI4*EkOFGTIR-jth7XSYoE=8~0;jfcn1-qzrU1+;VeX**Opj;PDS#=z>s==nI_vgTS4 zscOdssGqw|I50M(vUQg~@n_5O~}#fU3eUPljj!Cr1|+u_ygqP1+Om)H6Aazu3CW~q!MWW*E| z&^Ut#gp^X)#!mW#vvP43(K@l{%Iob#@2dp{;Ky?B-xK7HfX}##VgNTRh<^r|E(^vI zCqXLC{J5AX2}J}w(FqM+#h-io@p7jaHqLA45d@n{@x>G5!bKhwPyi|unWJ(ev z_EVKQ6YENpUltm=HBmQdh=dmQ^g0weMIY)N6TK0Ld|M!c76rB5m?eZv90@}R`ms}( zfkaF}{|PxbR_y2Uzxs&9sweE%ZJofpT;$iT7P4eY2YMZY=?ldI*$zE*SS}zcK2lMm z3s(gp8><1#i~VfBT81cf&{s;)@rY(vtWIYCYl*L%f=_nMAYJ^t4sndw+<$cq6IxQ# zmqxQ>e-uemwbr30@AUqBXI`PhB0jc~O>z3|_5N!^dTsStb^CzV+cAO6q;6t0BCp(1 z+lr;z!JK;I{o{qp^&m`;NY&a!1BAzYu?k1#=0Nv2y9xN{XGF_^RL# z2Y`q^m13HjzfY1oo}>7`Me*EcstV}n_njP1Ric`IQtnIf12gK!BPI9oPve1oPJN}U{!X>lKIvt z+*#7asq57s8{Moa%N4(b7W0^SLR#T_zvru$IOSD7!wuDeZa=3u$@G_sIlhPr>NJ28^0{K)QR5&p2zRWqB*KGeMEc6GAcA-YaE&eGF6bq zVqxaWA|gM=K-I z{Vwr~Ow2TjnSWMBu?ck`7G{L_HXM3|*N)2xJp6Y9yW!@vi6AJJ7ZyvCN1$_X z;REoQ$>RqwhPCMd zuC#!L*#Ew?rpO#_XgX7OQ;$CQtrr)J#km0S<2z;AiK#3k6l zVDHC5k2iwCG*U?HAlbdYe3au%1mIMn8Z2`Gqf6Gn{mMdSdp`MP967uQ@)AOui4jNA z`}~9!I}cinkc~y_MdP}&Qt1Msw4tWsi2Tc^2d)i>^_HjWG0UKU92K&M-QPKd_Xq_H z0S_1JHb;>aVnj(3U!{VU3}dyilb@epJi3OxSFS2p&DT~@AEzqeIm-62X_pqat9!hW zccxmibd}CD7939!)H&2O7BM1??zt8^8?9iIoRY?D$6U-R7pE*(hDy}ZL-WtQ_Qg2V zoA!pw(-x{=NDuG5GI`QRcQ;(-8n!|fqq5lixtuJGL4Sq%KCT66Qy2BERIDr=JCV$= z7tUSpnh8Ge+TG?-c92KiMhTxPAxE&qiWwy*24ERoReY}xmP8kA ze4cHZhp${qrAU5TsZ!zNM#IdhwfHInH;KFbHezZY5M^Wqc z=g(3b(s;a&zfST(-UlNNK5;c{;NZDE4K8*$&l)nfKSXe`xNf95YS>v`7*jkQhP@3wwZP0fG`e_JJ8fo?BdkyrM6EWNy(~9eaMxIA zzxVEOwp4Z+gUVP<*oi*i;aWX#TD6;|E&OoV&EF}uKM#bNPaC`Tn80zlx~mSGIQDgs zpW2yPOOPHFBXs7~hK{ClayznNfZ7~X`qE)BInZ)HH zt};rByd2GieI*p2W#(gkSSLlPmxj|x{g<~>9oOxQJ7J7$DhU&Ed#dz;n#dw1O#oYH zqDIGzw&>@-eSWi`>9zF?P^h;F`JkER*YlhC_MPE!f?9lDPXd6s`Qr6JeUPgEl*a4k z;`Q#|r`xiX3uo2rydxnh;&r*`qjvRPXl-i{nJzh* zE>IaurJk7;LF(w+CVJ%=H&=&A#DyMfma;-$<=TVpyK&PPAZe}xr&F25+jvhU0PQpq z!D~s>s0(~4QLc}zG;7at0VdAlc`%O_Pr?Yss>8a6vvR%Rovp~GlLQLC!)8IX-GcYE z&#dd4%ubLM8+q)g=Z;U(fM5v1TGdI3Cbyt`bxsJI7@G2Zgr=wWX;@{HH)n<;Ow-Mw z^`NER#e&MHEm6h|hefAd&ytzi+J?ujqRbBVg!)VO8fVmePX9*h(`$O}`dzKEHZOg9 z#mvJxYi7Nk=GV`5fbaX#b~9O|jlxcnXc1m_Ll(-(az&7i!lxNVWt2Nf<;`ZTJ!hMe zxk}dqi|LmnPsNC0n5e_CZ1zTXq1(^aH#!{27sJl>D^bh_6=cGAJzpn@X>a|oc&{36 zs_%I5oR2Q8o7OHswk*!C-&Wpe&pCN47{!;;W93nz(}h{+O;_ie51u+iJ@aIDgt6B> z_YwhS=lw|rlbNUC;qfVL#p~c%b4vdn(31fZ3dC0XR{FXMCAOr#k886)P7zubCmRQ@ zbmt4)ip~NnzB}gkqZ-xiBd*SUr}`!x7v<8Icb=Myg_odpXUhu+#|thl9D(0{JJlKC zSWY>q9L%{Q8y=5yexNh${1>g2OATg%)|9E=3}Ct@&9%ghZfGAOc%6)UNoL3q#D6k= z8{vy6d{)s5c+&_>2lx+^^S_E@Wl=7dm=7viuVN#L&3_;2P$u1f`_PIp|-+gA{o+-ifR>aL(CoNWXBxuAOVpV#v_ zTkg47S(&w}0%UjWsb2109;Ez{8#kH&s?aWdj_tbJ=P9h{=9_8JPVLb%0gpvf_2@009~?sdAjhU;E_oy35UCzUL5h>)%t5VLRCHF%#vqvv6uCIIvCe~(pb zcQD8(gz*)$m1tBo@64Ar`0p%L@?J7jGJWn6l9d(-Z$A+&BZOgpBvk)#Ix;%EN57O%! z&LE=N?+3#MXx8UlRve55rk~zl4u5xST?(snuDi_5A2~m}MYSaY%%Dx*KJ^-P)$x!A z`MUjji#lLMR$9G^M&Yk69(f&LH%R)+Z+O|`Q(QV(aWuBh-Q;QGI&aS*qg$T5o|#Q3 zK@S5gsQu>S?A*cay8TeWknwRELPvP$`})fG#Mk2oyd@`nx?M-LN}kq(WtfE?)Ir8W zhqjkv3&S{A$WLr))G)7~SVM$3m>n3_b21^x{X7r0i);{GOz{K1P!IGRT6bD&?s3l6 zO1wvl{hTWYm&wbPB_=q%$DSBMpS5~_-SZ686kY(wSRcxC$Cw4u3oX)lFvzpC+>R2(%ADlC^7KBv0TXP`N1 zqp>}vOCG;DyvfWP(j@si-=6&P5O@~QB@D_8XKGl`0DK%$8@j_f5RQPEke|f&MKKJ- z7(uro(FeHojB1d~rU>*PedB8=I2cjC_b-ievWFS44dv@Dp3fF1J;wtZ-Ui5n$hMO* z>p#stmMTm6W02JtG``WSpmMglEpv&v+q2!;ZaA}LqLOaa)V3@*IBT6{IiEd}6xlC` z=p*5zhH}??3B~$;8EIjkL$XyY zF4Y#y#SQLSC!JTN*|Ogid-#mP1m&mxAZcN%!S+Ix~n-d-iZlBllTQy_@kv`l@ z_R6WIj7`qS5Qo@{6l0odlzppf{At~Q`CyRuG}FIv5XHUF1os+u|7{tF>2ag?xoG^m&LY!XzIfSf{^ zUaMLv;+r-Q+plW+$k0Qz(%(u$e;M}FE7pTsV^dL}gp$?n>Z|`$Aj=v?9c6f##D7W8 zQL9@SRSJWxizuwA8aItqJhKaA2^-Rny?GKK)2685O;M!4^8x`T4Z-zosY1}LZ828- zT#umjRaoCxR9As8P88RiEKV#d5MbQds3Dl=wTg{wzM9aAX8wr?6bH1!f&K>V+Jm8# znJ_QuCDp;9i?LIunc!J8XHL8Q!KPtfEjv}wF6Q_Cn6?nkn?R%zZxlRwh0ix_YKUL5 z?^X>1Wlga%(m_M5GTJ46A8?o+80AX_Nyx&zY?0~`auWB!?FQdW(0od|M~NGuJAolwr` zc2KBLmDkA&!Z{v6`IAjEiOFOL`f;6{QGU&(Ks=r&KG-mX-Tk&`vw_~a`$cSekWB}tGN0-R%G&poWbpDV~4lDf#vj~}%X}5E@ zn=_@-?m_~BG1HVWYWnZxP_DEa>zLL{f5m6MkWRZ;TnQ&+{|Vh7q1L~rd?zbh8=dzd z{S$-%NJxli>>?3PHzheRb~r+R;JLTKMa2JYztY-4t>Hdk7v*UxSnG&|SblM`aQ^)3=9dMp zDw$~+gfHseADWF)|B|SWQY03y`^0WiWurUA7#RSgWWcg3Z+tc^ua|xbzs&@;F z@pN|giw4e#msJ>ZiDq$w`FXHzBnGVEwbwbh?X-t@5sHy(CN*84)mTBxm#WLP*33Bs zljNpEJHx@3FixI_fL1UbtQJqQID<_SBooEpKf;Q^I^31ft2fontr9bJKSjv6XfJI` zXJDaLj_4len6LTH0&sDcU6j-r{HjoetCpecNGhZw?wC4lGyp(=^fx=c$>vG1+~oH^ zGtPQwd%$3erej`yeH)5P7^Rp}fod)pK*5&TxpOcqGPjU@0gi{01GxzT)~03kmU>x{@h@i{%PLpHT^XmsTqOGGUoX-w8|>Sl%gq>4fbLinga!Sy|Zd{q!1>A zasuX15NgzM1r#jzoR~y;qmm<{W8RiQ-aCcacU8b*>Q~W&>NC`WHu)YwieqjW=sJ!# zW@>gqr0mjscXMh+C#kU)-Hg0o3lCsG9jw|H(|A%gDEGo*wnvJR5|po+`bd(oz4w)J3v@X!^ue;FuX=2q{&UBKW9)rIQZx=W zcq+{YSR?poRLb(RgG`-`KT?18V{NZ0X;u7&cZlFJQ;`#KFu>5{wedLk3{atw?1bEY zU$wz6&2yMz;juzPl=~&{QKeATIK((_w^ z-!7_d)9BcgTH_i~sk$~u8g}qHCaJi<0W1y^O#AC%#4Tz~F?{&Di2VLAVbt$cgRs)- zsB^lASDxjKM(vHtNCx#q*SIwld$Sr|`Z{zh;g^+Ta+Pv)zS5f!mJ_KF9dIm5Y7}T- z>jCk%F_%*@j~Kd5y*PCoZ#^y1stlDkcNI7H!)oXtLcb*5wsy#M1)Esa>&L(3UO@V8 z?5`j#&g$Nwm-Lq$#LO|se?U14$J1;u0c&Quv*}~A42OQ~-kd~)a4)^k)3&Sj#hw{W zb*g#rl`l)EVeGCk%l+-;jo=kx7zs=%^QGCuNijQVXMgSfH8XnSA_yia=(~!+iLvcz z%GLpyoV?P|FS&~G174ejKEuMfyWb8;4w}D;m#I>=n|tL2CvtC$KM$> zxpTcmSH(F-in6K)+9NHKCAU#jDY{FKe9l!ph;6wmVi8m15LuCXJ7yl-@L_`GcNKFf z)T?TnB4!jkNYVqe$6Q|6AE-keq7;n z5sj+QY!eZnwTMtegz&7&Uq>}{R79p4h=A6_x&8e_re%NGHZ?Rv=8E88tTe!YdWg*P zf0;7sFew0d>G!Y}hn>Q-o(8Er*9uV41&b-vSF7}PvXvCEJV&cBny4^{>uU>EJn{2} zcx*V0}yO!}Grf_hf? zmv2$EBYJ9-*X?g5J!QtA3350!c~pfTIWnx;rs-LBLKbdg<1<17Dz8uZdj#W4Z^sEz z9}JSHln=$S`JoIA4YMN5&mc}#3k4kDBU{b2X+tkF1vFKaQ)H}8LVb+wI42|fQc1bM zFy`N$s#<-xROKItNgIu|1(% z+5cHl=UlO`pGFt|b&jEAi>Ms;gx`x1u-9gIr+_}7TOt`UM26MLD3LWe@`@Q-E%%Qh>fq@f{0RmD)H#`5yQ zvHcoS;vo%=gG-K40up#XHL+mnKA0z8)BhI2e784R&Ic8*|W>t&&rmMYUh=#wQxkFs7`YyvG@FxaRQvRZ7`LCfcOiqpi}CY&tDKC zSP0FWssfwI#&T}yu%gMLk&HM*qI&BD{#hWt41@*|(fKpYEKxSZ(ZEZ8O|iy6zhl@; z$u0^DWpRlZ6l`duDB`ucn;MQ5IsUgPqDseZWpEuLft}v!5Oao^j_RJ{DiB}^{Vxe3 zfnb4w43l=I*3+2Q^^T4EwJw&t+uZO`l6^YfeWpi?%O=(8p#emkN{qQENA<8vmj|QK z35Ylc5)qKj!L5)_d7^<9mO-t35v~UEs=Ygj=V*L#glQ0Ybl&rqFlfnC`;%g940r;# z7M7gE$}FbpRJ*8bpN*Ma%xf$>CeNpeatDp>pFSi0Y5-zO#!HQq6!JUqJGIUS>!`Jh z7bBH;((pXJr08mKut>{hl#k&jSFw0K#K6k8lSo2_%YluRNb#MEmX)Mo2!XceqDjW~~3Khr4SVmL=Et(@s20`ZCmyy;=#R8LuZ=r)7 z*|)Ahf{FkPI_=ji3&Xi0j z*WeyaM*?K|2gr|I_46w+sFoPIan+kGEJ+g?Bm0YEuzCC;pjkz57L?7eyH`-Rb%4zN zZxyiIz;DP8p?V&9gUxpG+!a4U(!he~h9Qgn&gD;4oL4iGI z*ekd+oFLYOSy@==B6N1nXTg~8w5KS7f-@o3zqah2mpyjg@?xruU!EOLhYf6xgs`>- z3>$rmVq+AXnW)lK?62xv5m#cX^?Bm#oYNsMQ-nB@h9%*o2MYCYu{oAm?SJMD75jXd zG%|AvTQcO=|3za>=t~iL@A&wN>nW0$x>#k*f{q!{CE(AKHuI?tT%Ks$Aa2Q>Tl3ZIhuH1rt{ zW}3}8U>@P&q(Pm$JqR+3eV`Usr)NwZRX!)gZ8_UhL8A@k*JLV5XSWI`=ZGXj;{#L# z1X?F-&H%<9{If+|4wx8g+#s8W6kE9r1xXK}%*_TDwWYM1$*j@^h(NYi;YQ9bG<+pY9W;tm;5Gr_qji}V7X#M$;_Oh13`f{8XuSnq>zc(x z;Y}Rq4q7X!g8%OwxaUc6+oSZEgV-@7ELQ9Zp@CmpSCB>37Mj?WbYu|Z<&IzdoGpYH z>2V=ga?lR3tt%^Q%V4%1Za0~Llw=ijaFBoo7ppj4LA^e4Q=qVr^g!KO0A*G7oLJr+ zo>sgV@ysUUo?!R9MR9IYn)Y}$5eu+d*LNv{D_|a|Il~sAg9|p^*7=JHG}Q|9xU6`H zMTh3=t2S_yhY#Ki&u*fGCy`)2fObgXbNL}pp4Siqt08BQGvM*V`;2#`TC5od5BZ4S zV%p=Cj)Y?U)Dzbs9k2A2^OgXdL_3)J7n`FvQiXrF_WM+-)}qcIG$aNBnJH;-N<%&> z*y$Uj>h#S}mRP&BlZj|#g7(9+R)f#@Hk-_s3}tC7dJ2p%goZf?Qc|@z`Yk8eIWClB zd&Wj4BO8qx-i!!GdSE&jf5;?SbQ$@UP>mQa8+w!3-g;8EaWTVDQKp;w$QcW`$-?5Z zI~_A!$R%tMPzTsT14rBVqkdZ#p2yc^4Hh9M9RqzT->x`uAY+CMb&j_TV2?7yA5;~< zah)^DgL^yjA?LWh!eUjL|GHC(f6irpH1AwuPkMUKH-bF^u$HBSd=-fftInx7A|M&Jjg6ohJ6H8p9>fGP!|8asuO z{W+L;M2>8X0Ar5p_b~k}L|V@$BUjGXP4>@<2L)2uBr1&1L||BfJ549vywzcdwUmn* zN>-eL)<1!7y-m8**NpBqdC0T$G=sU(jAJK3`6IgPEmHL1xn}Fju_f6rujyA?jNgQO zCgudLdVd4UV6ou^e{uz#!On6_re%(NhypcDd557~hI|m-+WO4F#}e1$xVoObl1DW= zV&1qLyEG{D(?HUUCoUpr`y4H5?L@!5s1J_u69TMnA^!movjUvMK=p4L-t(ja(Z$cq zKfjU zN8Mjm>vT9%LG!%}VO0CCs*sJ+DWEIR8e;*`e4167NU8=4udOqN4|KKuaj$}z^j9{M z>&KtDC_>^2w%|adMK;@uLL4zMV@RL7XZFJ+g+2#!vO1FG4P6>99@nATvd4*AYA)bq zg-gPHe{2EqsYv|weGr`#YBvU!)Yr@pvT>_gW}qO_oPl+oHT3b|!ZL-2K0)fIg`BTzGM!r9dABd_)+%wvsYXiI&YNp41oB08 zZA`C#I3eI;+}E|Nuz>Mncsoz3yHkEzg;-#SM<55_$C*|u&uJZM$u<&x@UX6d zcDL0czX`xtVT1H%*l{AsMhb8Af`Zf*8ee=nCJz-TQ~Rk!ok>=kn`e%kr0~*&(0%h3 z%^yeG2SAGGCs8MhGz}(kq`a|Y-N^jm+zWDx8|p2ZTm+}g8XWze zfWo92*UlZo@zbnd*2+&-HlgjYRT3okxcIHIM|hdp0^oZJ+Ju1zgTGI*%ks0du+tH$ zVe{c% zL6OEjah~ZRG&ec1sCC0RWjFi_eaSLfW{qQ1ogv9bmEz=Nfb~sSz%bBeb9)Z1E1`r$ zd!EdJdA)^LTA7BTbh_E<_;M4OB-)%kIDNuk_T7?O-c9O* zElX!($%O2CJNs?VP`V3Kfrbte)nkEBaUmACBX)Y*3}ObtwOb3Z15F7;&w=;j=GT%t zS;E=sEbvbt?D`5g!0{c>{Gl-zA#dEUH&zVl3IpQV>hw@SXT35}Vjz|QVbZ8?<7X=Q zYWtNI7NP#)9C2?f93+*M#7Ht(nqQ0{ofKhbC!Bl|JwZX$=*Gciz9+sFXspLbAlz)_ zIx<4Wd_VMwVv|E_A24d3HkTdwP>GnZAr%6I*x-K+lGp+Kyb#3GAZ>gR$N>?4H$rsB z+_I}Yy_~7&nUmfuwgyno%hoPr$QwRErR~Z1B};>u6Mlq89a|kFFwlL+#-;>!6Edgb zB1C_GynwT!O{Q~hA*eY~-ViAfyCIx!Sy(9y>fbZ4Tf11}2Kvu<$b;GKb)my`otCz^ zcSqODhS9n#!m$Q^g}Z8=`l#uLX$A2FmgMm2$Eh;Ou%rOHeri#luD*S&mURkS;1!HG ztw$2ZJ;V0-F)Af2E-Gi%P!mKvCB4j2*Xmv|sABADj3pTtNx$w3ci3O{h1GEpr(xP{ zGOVyaS|ox78w0(bPd$4ww=o7{K^az%OVkj;)=Ol9wJp8gIeA)^c7L?mc z8}%BnHFX)YDs@S2lR6gwW5)-Y?)wu+z5(0>c+vJnY~GSkuI^L<=ha#V%VU4R{>aGG zGDGJCd15aNl#CzOy>HgLaMQ!J%O|g!`QQi8Y?Vnm#Md=tT{5r51^&8 zkb$v(jIM0Kz)2BD*BXt)rc~$YaWE5Y5>iUzE)>Zo#$arTVw>SikTK-m4|cL1f|CB! z{leoD3}jfZj+~R+vjb~+2t-Jz#%Ov9?Tw+r7nkqM7MX3pFti*tB#Z&NS=DS_ECy|T zWbz;hCnX}9#}Wl+gZ25;n)CB?Zd`SwB<`SwDid=J<}r&%#OszoRsGt<_kdWRb07+K z2261gBvUE=)1BCZr0#+%FmKX3@^mLhD|uY9$hu*%YUS{fvXT#wjH(WoQQ(iOZZhN5GiJTqur| zSllV>>*Nd|+9btjT36%}Agkx}brJmm_BS(iMV~A&T})$Ztlk+aCRCoy7>gZEhS?dM z?+sBN;cZZ^oW3+XO4y;W@#;~Gi41=<99jWJfSoB$`tjmwh#N+>qB#-3g^o8TY%0!> z-4Uap&(NvNI)E8;1nlfe!doGEO3rRuh<1KRhmlXt#6}i$nVu^l6pC0BseS8@ogpWy zPl{Oz8@eP^8wOXwkIKbvO@1c^7~yemn1WxQAPPlTraDzj^%-ZWX%w=W&A5;>1#`gKhWt3>nu%59RTW)W8-#xvA;EQq%%Go^X5~CVzF5(*TG`IBOIsaUC4Dk<2w9 z9SNZD;1{snsM`)HFLNRgi0!sb7y@r^`52OCP|IBF^UZS*R;wcBLJ@CIvY1RRdMFrb zN0^4qGJTpm_APNXf7zWPkq8zuno?Q4AcS@&SL>SkprWf;c`xmazzA&Rl8`1Mvx^nA^oC+&z)uPe>+=v)jAXA&K?nI^7|9$fxawvO zWjzN_hfS|->rCd*E(SBaB=H7d8_MRmdl|g;!>*y_(?b?tws0~8@J~GxoCJMOcz{P; z-7%%WwRg)VQ@pvXW6qH%x#yi+QbMG@DNK|Oc5YvG0W^=$&H~BXSYbA!C2dGs2O>9f znlhEWWNAptvIh;T4(?OFGjj}OX)Y>A-jhx9l>mV{xIxe@KX+*UT&Z-W0u7Bz5Riq= zM0I5!s>;A}GJwx5oZtqWPitkFbU@^ z3C98KzgD*_?|d(>kJ5(>g%N;Hyv;=r5PAruc+-kSk%NMIDBvekBxuxr=xk;Y=F*yh|slDH8_K#ypKgz*Aw%(n!2(!=jvDbBok&X z3S5b81>tY!ICb#nzA_$F zdI$3~X9-O|*9-(LyRJ4{8oroARo{b;C-zf?V4>%9RBE@Lz)UDxwx5v$j!nHDYcstT zYaXhjSW&lCc^=lEk29q+1Nkm53s=@jU+L~ETa(CIR z#^9_U42;glvOw{@Na(#q*UoJVhHXHCb!FWw-RSjYkMJI%AOwBwGLLH33>;f6JJ}Cj zXqGKw3u+h>$gBPmV@sRc>3uh<)=!xan$=zGt zWzX?Qs9tE2dUZxQnL0#^yztZ!^(NsZa4t0$HDwdjB`isDwxm%o8)@(LI=}0WSg}qO zsbm1!>^GC7Q~ca{9z9^_(9}`_S4^S@@1;+j7#tOx4|J<{Gh4PkxWu9QT8@|l;lJf) z6GBuMHyTS$==4Z(Rt2;nByvY|j%o}tHpEINsD`VGOyF|9gz;U~X_m*B!eHr=)($I~ zQ#}v|b(bxfSnvHout#mrn5?5o@vhSIQ-@dzV8PMZ43L1KLS8`D-0&)z+`V;NpsAe-8HB?gmR&*LVrD+(auzCDb(@2kh@a*!TGD z96VkR`ws}>d(K@nse3oL%eG#japh08UU9^c^({8^il0ksyFxnXlhXy*33Z0_)S)Jj zth+UY^~I%Svr{25dvuQknr-^(K81y947^ou2Z_SoYqjdeiTSBViJuBAJEINKm0+8F z;ZJ2O>;OVL%ZcqATM%Wf=!d+~3lkCY~;^cqHzEq>I5l6_kb9b*y|D})2Z(2v5tjE6ufGfGl$Nw8q@H+{e zp+O~FbguNDVvpRRTyKNU+@H9sEfk!4Kbr@doXzSMbrH2(Lr5D#1NwUU3v)W6Bw()UFscGo0MBEFk(7uCzo9eZ@op?MD^; z)apGQaWvQcd)x+A3c?1{0)z};HAu2kG`i`Uj!12ULkdhWIDlJaN^^!Q`jmO23ZcAB zEz(J@K^qQUY69+ zB6YY+Ri(3{%C*aj``_2aZ4j@H+*NkvDo~%kFnbezzrP0eT((~}obIYD*hBuqhxvmI z9}(&`)_Z1puD=^b23Cz<2hDA2RBwm9@?L-yxQ7baWUfR=*o3!b7Q4Pl7B_}<_Sxhb ztqYr(m=KhY45|OB`|e$gL5M14mIj~~=$9x*vPPt%2ps5N=o#Kil-ZaMW!d`-L@pdE zHY!Ea0Yz?^LGYl^R)o0Znb2|(iD>&rj;UcY#I#XRb8E{;S~{(aqjBm#V1f`P8oidv z@1A!;*kUKqI9XI8ZM#-Uo$2}_z`j1$6(hT3es}JS$Jf{1cQaHm?PIWPn#%lZ2o!)VPcjuOzoA-Kt7#q%?w40SXaU#};eXFxf9%V*UW) zmfyRDjVTiQri$bB_`e&zXO43atpY9o8dgw6KY;4)mQ1-%{~~%WQN@gmjer?t63nE4 zlPh#fLE5#}H{_g;MhczhfsR<+2aNocdM%>+l4Jw3?(4pXF$pFzqpp7RIoEY(KQNj` zH+#(fY^?c@vEPw*4O>R+_9Rh61IY9s3HIzd4`0-KKFpQnjjBG5Jx-x!Z6(d({b{)B zp)=~Dd^hrmptdbW6lj%9WTmB40WhCkv!$=@^}0hTwPahRKT6`5Db%}CqQ%X|L~&NF z?{8r&nog=CM+%kG{uzTm-MXR^+hyyqx0_vIDKRdI-|zV17L9)xwu|D zvneiV;-xFz@s>Gy&u-kx@1Sn(*Cu=)#6fIhBmZb$Nr1%iV#>^=))+XnzVfJ z$8u9`+pzNX>UTcmLvR{w-xFNjZzE2K{Hi8Y3n*(5XT;c$PrKXqsHE0+LdR`e ztVog8%jO}({cqh1N7+xbs3-ZTpFWQXacDcHh0V;Q@R{M$On2^6a{gS}S*2~{1?Wqp zS7m>~Gu1TnvtabSdDXl;uwnx2@7jJ^bDf>}J|$r_V$486!-(bU z*_FrLvFjD@_DDBM)tikmhRvc2?R2x(GUg!V6HsLDb%39H)FlgbL#ZQIH%)8tF%MY4g|r53Z& zq_Im`oms_vW?r@Wj!shfIyz`hHQUIFtWJAXlYX+f`w=wq2js>p12CWa|8(!NUytotzxxh!#KrrA*AA|IVD_)H@ z#*!0+7@@kfj`MZ+@pEFnw4?nE`g$hH)S|*oC)TWUHExoIJJ(TGuapasqknhMPqO`2N3QgU_wAp6>rfzqW1pG zL>DMvfoNTUfJPnT&{^kS zD3{{{ERbDtCh8^^qeZEYdrnegr(bG7qZ5}aOMyhNeR9o;PSl)|i826{9!)&*ph1`$ zuVe$f0>-C?!B_W?viyz(7#B22oH3F1d3>%mZ@q;H=g_+Qsp> zZQ2vB;rK0b?jWb|&RGido#A?VIx8T%I=uyv9<0{dn8@3CfGGwt)hezVyuOOYvLHIp zK2xupcWj# zA)|SWu6|QYgTMR6oQ3y>9M7*cFZ4y*_!(&4C9Xnd&z6+&U*k-Nr9IDI13{*y7@W;W9<>+_n8BtRZPng73Z7S$h@n zL{BMj=7dCYvz_favhz9>QABqvTx}ts!}(K@-jh5DSt{aYX5!SnSo66vfq$OM7sw=) zVTT)y-p5P{mv-!fWpD&P=Ni*nZX`Y6QJ~wsZ{lDo4>p*SAI9iEx25}xLmm*f#Z<* z|3*CNMB{NR@N&}qDHKvt`}A!>79>)DD?g%FoYvrauukg3oFp-852tL$n&Y-mU#{_3 zEYae^Q5FS|P@m(;^`^{dyF1dWj|ttb=J*(Ms=VrJ@_VSZOKEFe@w(G0%pO9)HDp{L ziw2Fe@TvU#lcDKh9`j@VB+N<4*rxBKrDKF{P#3_cC)loD!K&J5oCVKlSHUlwuC>4V zh*6dI1WaB90!ymPwM=fU6uCgUqsiMWHR6FSV7&gbQ@4e!I_ z`U$@O2fHQ5lQbTXoyl5^0jTzW?rMB_2(cs3Zv3#y@!bpc)2&7)V+s0y@9{j$`&rY? zCaVZXad#Lu2VOtYrBNLmJ~2|ohj>eXL}e8|6$GeCiPM6JVtEP&8;AhaS|9!4L{?HW zr4GUW)sxg1e}F`4YF4SV)mQ;$SaejPsHNlFXX?Ek330SNNl{$?n*(jlcCu0*I{ zDX$|0D*o6@Fs{3DRew>nV&POOkSZAb2VTh9-?pynPi=aKiZA?&zUU@x`>}L#rz8Jm zrV$B9;@g;eu;|`8RiIYoht&e!BP#2;7Ay|u2*xF*J*ZkNQcAGtTadD#fhtkGVn$R+ z(z;6?@0$OC5~;Nyfr(?EBI@+f>jJn+hAB_t&&qZd8I#o#aTPS)SPv4S=h~&DuO5LsBGKZXgPIsM=MKLa_Tim@Tbzu z*J^;ei@t5{;Gf+ifn%w#Valj$24}PndgJ1_fGC!ec6%?z|3HW#YJo(ASRHK7Gh&`f zOg~(Net8{8ixK=Zap>^+3!8PAUbLL%*-W1;-N}1@ZSWdQ{fE(Ne*}qL3pdeLelmpg z(1SUzic*3*mHMFz)%S3BHSMr6Vp4$4d@=Mp7&Ue1BM^ z_2G#N`UGp(fQRr)%V~$z4bZpe_CNSMO_nzh2b{@5Rz9}p$iWIxC7IRWGTOM*S{KYf zXDj>;h##*h+m@kD1|c(zkEFLG1V%*~P1`uYT0{P%zS*XdO1uWLWX4cCN{wqX+U$=+ z_}#Br-MCljNfA5Y0!9q8=T)8wDlG?K<&nsWay>`M@%$Ny z>=`Azi-Ww}znOX^DMk@cAon+FC9zo*6UDN@wX{E3VlygV)u#JrpPXYoq+k|A8xM{$p=I|Mw&H?-=L4{WsMA0hwd``wo+SuYrwkvS4RD z=4Z?49(i-6s>Zc0UC%qNb=FUXE4Tq>s|=Q;H^wDuCT1-KG<>RI$i;MW_gW5 zIc=$EZ60ikBc3b|c)I~M!!=~g{y8aEZITNL)&6z?RJig`tr9-vs)gyoHFb^1^Z=}7 z-m^9%fugLgqqR*==T4KOteXdux&EVhFj#7qP5*UWwdNLXJKO2a`cafHOx<* zT68gDRv#gjuRwpPD_8RKCyA?}F&EK(9p0ktUW8RsC-V0mhO=IYGZCmx0kCq8T*?>V-{&Xv3Kr#j5@z<7Z8R(UC%z@HM({eXXz>XKR?44edG;L(_OK*| zsBI;8OR6aFU?o$?+a}o}eqgsy%5O|MAY9LZf_W4iI<^^FF5 zX)W>XF42MkG;9ekFt%LTYVF7lITSp`_~5CUAx6XHaW%7*lFd0n9csh47;Cq?nHVFk z&PVRSI>&ykJ{qePdyo=0m+*Xpsj=YQNP8k2n)LC-ogt3V4`KLLAMhXRqtFywjjF_? z)bo40ySj3CW9V}IyMjv0y)_c03k?lTCztt6Wh<|=puqU%U|awS6ca-x=uMCZWr+Bl zQpI|;5j2!gR#x`udklr`HjgVMne}>WLqh{@n!#>Q5WHv}M)k!Xj3L{V-goJ#axAZf)ysyLvFb0S_*bKaU zd=V>@ym`EZV$s2GHa0eynCPVZI1ysaZ<7AHwJ_q{SSAS4&3*>o*9~rUTlx=x~(A`MCL4@(Mybm z)62Y_MNZgDx2F4uj~a5HW_dVx_-Xs+7WBhDEH09>?;Q#xXy0umA>4YfGTkIYZBgWV>0Z~qdp_p4 znQ6puhX{FG1eVpp2ntWPa~9wRr)g8{5-w8n{;M{mBsD4q3TFwI@q0?~^SJ1ExDF4* zc%P2-z2(e#LZO0meS7Kpc;V^1LY329a=97j`B=_*BNRcd-W7VDj(tDBct>N02!OoW zT63EG_pe!B+^F_lIhGcBJC^rQ=j2v{CFL=^ZofEp{4NKaz^~=^jZGb>gn^d^xUa)yILq%>_x_CidQaeMj8Akf|GpB;Jq4^go^#pW+Cv1Hz^uw`|TtYJyak2EKYs@Ezt#Qp2X4Vk;mYBu zkhsIU={gMHT98gHnG3xvtLyvV%1OXFjO3Eqwd~`WK;=;Mg^_uNe}Vb%eV)yE|MOiC zYA9dv{W$0SxVr6JM7X_T7ek}>=|X$+8E*~N;y^aKGt%4NijANpZ-;`9mmC+qbbB(2 zwUZz;kGS9nU*9|a!RZ^bwZvrbn}I3sQx8137)N5b@y8bWJ4AA~7loa3?>`11#v!=( z6oBpx(ShS1E@QBr()DV3NnXR78QU2!5pCjiez5ScSx&z`Fze@9{3;5X3j1+Aen#N zgr%<*EpSg5nG*X?Zyt=pe!5jPB>h%?>}J>F04s!EIJP$m^fXT0!o|Zb|2ufWt^0kv zQBcQZho4^fKD0fRQu?2DzMMmQIV^}7_`a-y&Ev&&Pl$sfFc%F*_#FWq0TfQ3qT`6j zAzUbCEjl+1AKA^{=5}!)d396}+e_dhfszOv9703?{B)Qz6yS{l_Zib@^J&5jie9lH z2p%0uwws0?!S?v%B#_47JI+^r{^y@LuQ2Qc5=QtUf=w__eF^Yn?hx?=Y7U<^FGG2B zy#6)_e1wtv5>WT(!h5kaZ$XLq5JYTF3f!PTG34kB>S;i=!g^6+Yg})Bylv)k35tX^ zzjr=##G(sAZcV|2pL_p7n#PfX3)$rn;fM(oa-nFu8YHf1Jzv&ln7EZBYzSXatsDeSv($$cDLf z`Yj&V)V|M5kLlO@C+F?VytM888*w*jT+cS#8+`JmqWn^{C#8HY*>zahbcp{;J92<&MQ3^2@qBKv6PvgtQBKyR|ZbnfR4^(BhAGP za(UalmdJG*V=hL%t5;>o|0S%kk$VY6a^MY`K8}YZ94R^1G#=&PZPD*-acT;KJQZFZ zdTxsRF_oWVt;?@V@X71#ZgH0-@S!i~U`#6)_#Fv z66|@Xp(FELDU9{LSnr{R%}jf2fkUku_~f3STXtt6o+Kg09_&e94@*PM#D88z77%Z(37bny*R)?Fft`7O5!|`Rg~$!1UoIs>3`@T}BNx|% zax>9=9~Q}g9qrR2`^0A*8yFkGbT>0$;%o3tSzunaVg8NH({qv|i1>o9q^mkH@tp<9 zK3T+4)k$BDsS@``qP7~xmnEe!}G;rqapMCuAq--P8mw|_IzBayfM9elAP?|ijW ztIng;6g-J?-GkM^`%a&oE8D|khqy^&!JfTX-7D#nVvFc{wNnn7b910m*Y0(5aJyQT zDxi7pCy5b(>e%s+oj>1ciw1w)f6PS@^Rc=aesXolF~E`cB9^oug2>*k+Fqy~=C?`v83hZCmp%OSEK%jumF(i2 zs}Yfn{P)2ALu;YQFglppVp}%WySZOo4DB82`>w8lBS9ZA`ed)nUMU)b0Njnho$f1r zM>7&|Z{V1+o+^FecQF29H`QBf)-bmKl(aWVo|IxlGdM^ z;z2X5lDf9rh3x^=m%GRY=#zV z*6(1s*I9LLi_{;yf0=n#rI>ZDrl_I&E!?1M-wWPffhwE5?5gNX4+hPCZ$YP#y@(!q zU8Fzl_WfG|g*BPUBvS8+|0ltcFe&7xBt&qjO`EOH=O2*>~T|KW6#`MZB?jjLi5Y_FrC@i5twRYH2)&5XId zTpz3CNrXlR%0)^DF;yH`)h^KE>putDpN?gT&ZZX)!lvk%g&I(B9&{|8r#4A}xP*XQ zLdQqBl^Dmq~)Pv^gr9iy;ZASmrr(9gRjTiHw+aYqT6@{c4=2NAC^TG9-&@M z>z3BVtszLE4$abCk2Hz4BvzHq?*i+ps6fy$xtj{Nc%T)+>{APP^8wzq*`VDPSS8e~p^RvO)0^vhD-YWTyh=2}4{=NVRBA zRVq#8KkwK4S{nmEMUYa=iuy@ud{QBW#-QK6iF?efKaqnsLrUk1@K*qVPNi|TbrJ}X zNMW~{6+t4nyxbSpo%CI2zY2=P{ZI`}RH6jHFlVtOBRZz~ymnsBzQF5btb8zhjhCa2 zZn?qPP^KuYynQdxm=roM?FQAfXxXqF`1_FXx5+C8TKL$UU5Y{74w?1xezeAWVsDgL*{DT}?W(tz zg3Y<1-xi~y)6!@MHlDqtyZYfM!WGIp7(^$0R5be+aRzjNBr+ZvI%@7$& z1F**aZW3aj#N9@p5H!*QGaVkyVq*RR%pe9E;5loXua(vQ>s?0d<-88x9hBT(In0WO!EL}O$sUuFi z00$awo-4P}FseWz`)uJ0ns4U<>NjzR`kPv5cG0h_Zh+iD&?vj;`V=QvuOrZ`^i<^V zBv;~nJ|-kp96Yb1m657s#MIida~eF(Rox?B?#ia!DRNHReJo4sc0e$sNzW*fT*Qs1 zTL)_wG%D>63K3`k6t>!Q!-Su72d=PEQZKsM?dpGWp&)BiFRC-$wsMs z0G5#|p-6LqTC+gM!^AS{qzisumWz*y3&|JY_`AJHL7JC6df%&)9^bjKE z8aYnH;c~h%-=<8Hv08%w9t_f$h+Lm!WXbqx_;G$LDC=jpgEGt)xoM;c(7d z&;{1zr1`YaqxhhYtfUs~|C!A^+^O#COZ0^JNwA^<#ct-nQXX>(iu4RX_9Hi4uj67T zZns)HTOR7~`Gb6O9}V(Cj(uI#3FyXS>Ltxi|C2&zx_NLv$WtED9X(3>WjD<9dLzPE zWSS?T=)620+cEWEC**4@koh}J76vTPay+L z4eEj#H|hu#nX$>yTgzlx8^_F%v3hLx*SzV3VjBbc*qpKDUn;<7DWhz15+ZU^62BpU zxzEvmpn9Oz=y#Bi*U8;S^C4`;YJ-DlER!_29zcl^MV-Nvz(l!(d)=}_QdQeePx}MI zmLTzYUoEK=)^s?S!sft#0Gs|tc1JHo1Tc?cn4_`uhaq9N0~&hjn3_rixal0y56T)G zB-EI|G7Bi0oY|Dz1Zr$K3^mf3ACe|Ppq;6y$E8b{f0L!-@}sgKHT=@L3@{zNP&gwI zLB2$ZJ!;?p@wagloc6f+^d5p~l`|Fc=TioA5p#L^ zXrU|~V>G->4#}vL#PJ-jAjeaTRioe0!OcHHG+1St;Bcf&gfW%5@z2~*-sURh$^s^7oy&`em&1{0N;a>n7jxMNUB0=J1LI-}E)Mybp-=rd&e zl~u~)Ca=7yNn&G44E(a0Nk*bon&asM=cN?m(18(~Om+9fLlp!05$39Y#?^*^qx}Un zug?L0_QD4ay5;7)*6)!Q?7G6A(p!EgU0WYvCU42BkaxwByHn(XWivPTYwsiVY_ps3eGI{8* zg9c?fQFJ4)9kOv|)*8BUTdI5Q>sIMjYd76yt4xBMuB&vamM7eWz0Z-imOCchS+|VT z=t(_{T!H&WN?VNs&D~r9d=9Cch-Mf8ViVt>-+W7YAp9Zt_SnWyCf!P?YaO10_1$(K zjeG{S{Hl3L!ev4od%P4cl zIg+PHhD4{?!DPvlOh9-ifFy;gN85OxG~rrtJ_ppvh%3^Q8j#6TjNSJ^TGJX&qhxI( zi*5bk5I4fOup;cQ zxUmuxbS(OD8)xbJNWlSsm)%LfJl2|7H7(4HnctG-ar9hMmttH{%z-N$5>RlaMT!wu z%K@wY*e?fEfFzVV9fq{1V3W;}9u?6+R6ml9W?BQTpuFHS6&b4L>V(y3Rp}{f z(hhqrx8nmg_pqhk@mCi8)bJ1wZ%Ve!Ao+I>!`JwRH!KA`22AX5lRArTg=K~1Da1Sd zG%~$RcbJB%Q(s(3HxIKvO=ht$-l5kk<;k2CjaNm(kPT(!jk{FcnO25Md7Nb^`+`kh zYtLa`U^>oohX|uWQB+X{So};~Rq_?IwI-n*%-ZPkXx{-ZOC45sx;2TK+7O7_$#6z+ zYbfvnoZrIAOk76!=xtpL*NpYUL!h}tG=ESexOUyUSR9O;A?zWl@H^i$sg9e=B%3j$ zH&ShI}F0HpMrsIccMF2A7$=J21P$>Hm z=MPkh#>SLQC)SDJb`~zPaigR~H;ZvR1D%9ENF3t!yE?yd#rY*@-qi5#)Q$}@MZ{fx zsDIEY2o%t3Q81W)NCV(H_OiEYZu#<`&myzda{#aL(hfF zRY=15DEU~dphgyPm1SG*T(a!LCRp5>{{b$&Ai|u7tcDF>WN2tes*_5jFA$&(BZB0a z+2;yi8x}6_`|I(bt@rWqGn&@|l~)P&Vo&W4P`*4J&QiAFd|LR79v%2dM%= zvqvGaVrxFAL`zQF^tSEYw+cMGxBskff|qy#eS<*mpqPqHsRiFhvez=)rTVIirR$L# z2VTqN29NP}_tAOA58;iKMigT)S_LxKb7GNOwkgo9@qy4lJSa*_TJHqBv^0G%#4w^t>IgWt<`tH)kmFeEMru19F?AYKQsrBj*FA^8tGoHt!5lT0gCqhowBa2}Ty#9I1U9_?6s^xl09iVN~|G;42 zyL)_yL$9rzY{;*ujDitJQ$gY-NM}+fO!w4xW1WOTpxwoEvUzDWhGft;vqbY)A55ps zmGEx?udsL-+N`;(EAFE3>l4u=`eN^QYB&}YGwT{vf)mR zgZy+jL{^59B-qqZeFLVFj<>J@)*rlzI>&5s?D%gy(;7@If7y9%H7;1+wIvgK>dmGz zWBcegCOmMX9AWzqkY8tJaU>Z6*mNu?=sHGeRz zXEn}mcA0U-k&)V|X3VwY8sMWUx_Q_oDHd3!5(w_3i@&L8F+%2d6+hWg$*n@O%g&uK zr>2$V^piRaT3}>9Dq)&U>sn^&n}K0hN#o7Ts|LBh)uI(S%mRr5QpPwO5N3xfuO)$! zLa0t;UoTVjWQ1r^S5v!AIKn!ivh)JR7EdZsBx1~#xW<+bS#un1Q2v*Ec~ z9RlY2xi>iR1(AWa{z`B%`*gC{SUTO+h=f|#sLQp$r98}=n32b+9NUFb`NeDV2`)@j zPT&>GK$kvQaadz?z)dm%dCQi#Q(bSd=fHjpOvj?)7iE=s)on5ANa@OE57p zRR$p|?;?LTQ{`H1VEe0)N^f@*9Ts#`fc|z`K~+}Xc{rbxmRCM_&LKT|+bzqx;eHV5 zHBkJyfOBi;{O6$UhO$b8V+ zbKzZ)8_kcqf7ZUbqLt<9krmEp;w-dVCh|{^ISVv^MIMz&=6;du?ue1--0xam;Y&ju z!;y;$w=;AdXuWL^KjO4apR&apuVbUb^&_2B1KVG1P?YwgKOQ7CF>=O6L6JF%k6<2laRp<jd`E{DBi-Br#U!`oK@P#{%VqYwtn*aer)#ORQrbA3C(k5G+j&)28#TJ=S(`%IB} zsXwklL}Hx=xZS_2YicWQf+PL?G|Iyr>M%N;G%}TwQSfGC@8jZY=?FofSjGudgy^-P0&5B#xh5H-A^n3mk2yNqdjBZm8-3$?BZcgXb!$xFkjvC|m zQCuj|mo>)Z7-@r_b!|C7nR)Qu`u+Ts8#k(<>w06bUBWEb^Yz^v93!D7-O(q0lKn}I zq|(AWf03DE;w0HJXkydGCiF~!ci+_cN=8lK=brV)q;>Q4(_-)5?e3;JAPe%RoZvIb zV{`S5DIPZ3P2ol2EY1Ilu{5Z|GA0Vui$eqT!X%6F!VAk(##Cn0w+#k4qZXQ)`9U=_tku=jp0Q_7H2 z?r}+xvDvzQB0Iz~p^2}s#QDM=|&JG=|X@gS{bCAoDckscNsJJo>Vwh?@Q z8{W@%VV<@ZH*V6gfj}!z%oN8P-hN!GsBqdXb59)DW`pcr4vplG5V6T29xj|!u!)eN zQ9V|UAc!LgV^ugE{mSyKPq`o;AYkV2b%4_WSN;og-QD`P3-A`e|Ce1N4 zMtXW4(7nP$t{6RJeG4*Cp*VXVVmdY7SPbX!S?Fju5nteN=jnEC)A8Bq=l-(TCn$Dm zIWf`VbTe5^ToYNg<=!xq$aYYigA+OMcL!3|gtahk9Pvs3EHDu0KLc4$)h`x68LvUl z%eQ7c^&3Scc=;`4846yNxH-N9w}`}6yp$A#5*Ml^qHRh0&YcS9LjH@73#dcnXuu6d zjQGb7SWioGW~}ZJrpem+NI(weaRm;8mSw|2xTlNb{_+Zx_MDs@&CGpMzQ};sKURVI z{v>Gjze1Kvku8Kcn0xbDrg7`dg!S`~W%;xTy>x31F*`yy`01_VK^oCoiC>t`rWix) z8mV9L4RL-(n?-*6)}qQXye$#90eER&(fF)tkxcvYw~?K`sJv`QL3I-5NJ=;z#4!ET z1fQNPWqW2jjuZAnf=QCojYi7v9TLTcWx zm_K;YF75xv@%Qudn>M-AV*I3B$}gp6!->c@#4fq<{o_bwUhj8XSm8wUe>TH#mtZ3s zSBZR&0P2iBVV^`Cmvp<(Gkb157$>FweMJe=u*|v`9ZhcjV=Vz}hR6M$|A{lQcmcnD zZT#h`hnaoV9b}Ymi{LI+#IyXcY(i1IJ_z`9?0hhX9yn|Lcx+hjbVaDV>r}v(Q8j49 zcdUi8Sg*swRQYLsSm~3M=u5>7*irV_Ik1g9c$TPaRUm%>O&vW*sU8wy$(o2l+pGzU zVUe$#-o5zr;3Nr-H=(`OhKoTp$kE^+HE!^;0nR_K3bk+CpQ4A>ygwl-DNgh2yu_Tn z<=_{;E_A_u+>fv?oN4@Z`n$S@{{*v``lkeQ?vCKJe4q>=dg&zw&jz!k(GN`Zt!Omaz)QKgey!h#{3yeY-9}#gGn7j6|1DQ@$AJ} zNziQ5#hatUkfQigPP>&FzSO&n@+SujBVHZS9G~isqQ}?>{i-+Krk>K<Q8RwdrgVnlTSCmzc{pZ~KizQm$Q#NURqstuZfMfUU&jP+B#>{xqnb#Ua0xaK) z6p5m>y1!oTRl!*8FNCnb zKR+i~>#o!IqiTj2V1F}3$ZtimdWIFBr+qSNs)UJD>M_!d`Lz*=H`Dp^Y84^SujY8tk?I7 zx4+y@fvr-MW7;+TSAIQ!V|nHMI%s?$=?_DR3!fiegFK5tlHBDqeAhdh7blLI-S_9- zFMA+)pyKDwcF67Nm{5V^~03R2wqBT z--Ib!wzmJ0DNvoJm*63GcQEt~kt>=1K`8ZW=GIc@xyKCiN^ImXR&pQf;9%Q?02sVj zyL>E;nRAmgngy3dC9YTkB5Kh|$mifWmqh`ws;MO%M-$0_zQmko5Z&a04AUzQjWfC8 zPqR03{=}5pHqZYx(O$Oo(x3CIk4Re0d01U+zEeGqkQqqlu|QOHKl@H2J@&OZ1i3%k zg>kyny06|pmDF^?cO%5tb>Rl_g(yO&)D!9xev>K-x(%dSS)}PE5_fZ$VOH@vi$f2o z(re^JIh8A;YLo8C7}v=CUeSf^iPFDw#^33Je6h(ySNO9?;w5s{(Cy*3rWP@yrZrWT zpzdjOtLkO=_R;xWTNkY~SMYrc->nN*v zfEfrZ$vkZK;@z{HMiV6QeBC0ECW9ldP-33|og>Y%ynT>H(IOyiK=W2uysOs|pg$ar1MqX|`#u8n7-KD!45GrPl-It2id4N_; z8bAH)B{a^k?R1ae!>DyJayZOVZc+mMq5xX2oqMnJMj35smuK4vvICN>SJZYg9ixIA zg^l29!QdkU6yTC5O)(fRx-Xgxi8!? zDeOv{6HU0z_iC0YONdhw+l2Ep?X`RQ_>Y2RMkUh1A2u?~e=}%ON&QVbM5ZN60qfWc zwE+a!PnV=X`)~uRDPIziEV*1yiU&o!U*IUGowcn?BXDN%@O6OfR8C`SKOfMO=x^=en@0fM zWIm1UCoMT_>$b(JBS+M^(k9;&QN9-F&Vh7=U)jlTO1t`F$sE_NY98ZE*-MS68Uu`G zqdA|N9bPZOh1U164(D1*Ro&+0fJ~-br<-T0hjgrOQl$=uyY^M34nGK)579QeH02~G zp#XYE)u-pRzcgW7MoQzy%^V~heTUzUL3z5RiVQm)H(DtYG_u)(Kp68Z$>PrDul#_+ zH7O8n$LqNI3a+EWnTpbIqFRYdp9ffww1{xNFv0HR4~Kw}ON*zW3t4tyQiSC$3oZ+w;l z*|mF@mpRyCDjQ=O0>@^z6^sLNScF0H0wTI99_s-wsf*1um?!PC$aJ6O{4NV3E^tA? zN|m-nL=CJ!?-R@utQ&k}o8Vt>hH|GrXay@VPu5S``^wv{rzv9;E>ab>T5mgKbYC5K zj}Y!4#~ej^=iCE(=bB5{0LfUzgSx?G?DAm}AZ?l2x-rwXizu+rk$E8qu%jYWvJ zK`CB^1pm?6DR!}vC$ZtNGxNaa5;2sQ`2Ughl~Hju!L~qf4H9IK5Zr=8aCdi?;4rub z4eksCcMopC-QC^Y-QC}OcJF)Z{TUV`=Tui$_vxzIyUN~$Y01Xa4K}do5<0NRUfuvm z2lhgm;gz>pa=RYQ#_KY=L0ob|;+Qt8cd_T5Pj~v6Gf5}e@p?lX;}Q{1!XN*?;ZPQ| zC{CKWyU)puzP`r4$3C=YCN5>9MMC@Ry}d1Gw%*oLvQc=r<{1H3u=D$b!M6B+>4LIo zW?Jk5wZp$|sJVE%00w31^8l7-NZI;>8S89*l(hM)WW#k*1RQ zHXb^0J;UcxCiV_xecisk644nWIqfENL<;%q!bl$B)VWj zM%+80?(6IWh%+J#!AF^*?$r4K_pb1(mIK^EbVl^T^7p+0%gDStB=sR0%g%@DT(6%M z&26uxI(f3nSUmBp*C(=3JW}M_qr43EjV}^Z5R@@wa2W((jrlgGK+_Vqr6{oanUedZafbF2va?Z814B?1I+ zKagC$j{mGZtC?qYj+0E9 zW#X_QMo*4G${4%?6ly04vkDgxlA{|>veLGW9`13oNoiGrHbD83;}25 zlE~HwxM>L>5`qP>S1D`i2D9{}^Pi1)>QaF;je~n>|3l371x=}JAL8-I0BQUD>Wmv7 z0rH3}a()bgk!snR3X|u%bpI5=%F8UuSCDR^TB51?zFA5WLl+ANud99$8&vJ0HKxLO z*b=sp=%~p1YWyR0?HaPY0v*N_-th6#7~QCBQ^NkRCEyEhycEF#$Ny#WT@~N5;uPp4 z3yM0MGo^Qm`^u4uL_BS*CXVgJ{C<{oT3H{uRM0I@z#_1hrDIQC zv^0VEcaw|+0s5b9uVDf#(&oq4di+4wcFHm7K7s)yR7Uku#WQJq$qIp{TRpa79*=LDsW5!g=3r4kdGRkVG z^5rV!%&N1U=iSqEk^efhWbWmK=%K^Ad4)3z-S{NQIoY|1Qh8@DXQUSzv(9CRWqd>^ za9%`}8W~dLhS9`XYh62x@iH3P9)5fb1S-d%wpupSVA_PiFTQIU$ug9>ccP&((Q^4h zKheIE4{nyyk6u3bsW5*@poSnZ3x1yIWA@bmpunayGl&Xz?mi+&{E{qi-S*xC@?7i-xj z(5N8A3ST^g{C03Hm`bL>DG-Yd#pNN4R#2de?l&?B)j<%KK&?35!k@JJelz*ChB#;x zJIvU6pFa5Ic$yS#V^Ee1!yyk_ubbH^MT$JRs1WXdcNlRHgeNr(=iLRxg^riFEeX+a zv%PBhl;889@l^P9u2oF#)PY$)Tv~W_{Owo4cJ=Hj=k}WfFMCt>hN%91O2f%2#PG^u zZ1CC6u%cPL6Rpt61PSv)iFBQVG^r^0qmZOgzuS5f>4t9bp6e>Ak*F*)-jA>2^L0)P zixkr;RmZ#a{%f~IzR#Y~@Klqi({eVY#@QbTp=6wu<#uzCrDUw2103K|EY z9LmH)r)wr>5}Vf*<+pWBeZ29&rVx)AgiedepQ1@;N)Dl66_Zwmi-gU(OGZIL&lVhy0gu6Jrb(bFY3Z!eijEyiE+0Yo)b*pvQb z6C~hRAq?02&^-KPsK)+X3N(fV?B!KimLt(VfK9YG+<37gs^@&!7 zy?!{_Bds0`w~piDKkS1lOYx5ueEJaM=sa|)wPlX6!q>6>AYGi%S(IEf+oltw+ON8U zB565F={V~V;=)E=^%AIw`O`dYxK*Hl7q4$W;l4=;n^ib2_F;xV5KOBe+EjnQhg1IN zXmj9J&?mym^|B$Ix2CZ?g&7rKCPoA)p7IsML*(sd6X1DlGJC6&(P6DGqa13?Q$74HS`XkH$MhNj38+ zn0j8;3GOYW9RDpH`J07_S&(4HLdrI-hhu}avxkT#nN2pU$jXXcYcTTTwU5j_*-T+v zcy1CPDgqGv*|T%=0?<4bPR6`H^x}Wq9zCR5)|&WwJZ8=j2a+%;{lk%9CGChQtBbQ) z7yPZhX^tho*xl9NVR;|G&Cv0oii0I=OT&cO6WjxdDtI5AvF7?E-pAH!r}I1>=%szW z8`{}C77sHZLZiMt%lH>&VLUBE8Yn{^e5Ri`pgOvm=!5lq?wQY?l)}XT)s3>+TF#V& z-^>7h-arZhXn`1&NmAN#3(f`>E}kwm^0viF<~4>zH0k*iaA%d1hWl6zh4~rMNXp&H z{%A66&N}q`MBys4bq{mtl@c1nF&yf9PJM{x3rj~B4FdB=h8^2=HBO?!g8Nr#IznE%L_8*!28D`p{M=VjuN?*&B zg=|pmCtnQDT`_Yfc0|$8I~g#FY2ss`7MxtV7*iIyG6V)h+UO)CjianQOYF&aDI{I(ICO}1K8PfRiCSuLVOAcvzPGxPsZ1{@ z>P?&LrxAT_uq^!p1nov=$(OMV&brSJc@FF|si;UBOAVO0yf8^#0l3D7v5s~d?Okt~ z)#v*S4fbPXiLnw@XS*DC>KF!9wOmc9Y23bVfBz?aj=@_n0|uSR(?!qMxlrazR=#md zf!dndP$s@xxR2B_!!>-267yN00RnO-;W@roI?f+$(fQ=gnZush(~Uw-g_>LqH6>_} z)$ni+QY?nLvJ!=}IqUkc3ZxOu)5ud5TbScW@4nXae`ruS9M*ttF26-?AQX@(@bVqr z{-86Yvh*1GC0k@_#%pj}Cmql0_Y5wLW$HARv&c+H6MUnN`C*tf4YwaM7!raz%62Oh z8VA8gGKp=sv0msz6D#*2)}EuqDTqYzp6n=F#DIe3Fl(KK`wq8-12;BDiH9%hdvuXV z8bW+9Za4$h*X8`aXK+@NCR+m$2R(v8y^t1|>ifZ*3k2JMphlAn@hrgBzytXaRs&pB zl|c@*Ssmvqh)^m$8o_o@>>?q1p|FlBlEsHX856M>juHwrKgPbNloO)C8yIk8#|g!C zmR2PX?tayijI6J0SyMCA5RG-a1^vWVM+o!H0Lj3Mot~P9+uRU3I3nPK3JrNQ4Magq zkq8OEzd4BEV`cI^nx7^diY=nm%~NOKc=Ru{vtz3hv9Lyig$o*gJ)#M7*3h~fgKkT- zmE?;g{?WXDBjjZ6XNA$p!HEcPEgiBLjRZf>{okC4+5?z$zBCiqz~ zjm4<5jz3`ue#;brGh-OZP*o@obL#sAZcu`ac?d5G9o1vIS7eB)%tTQEErom-iy4?G zXks8_@~T&&{h^h(rSDUzz>RaC{?nRq{1G;xN@xz;H|YJZ38Y9D4^UaP8f3_9BgRt~ zUp6$AEl{|Wd$(>DwwE)tQn-$n$8zGqU9&?)x>PIz9XpHs>vzJ*9JfE%JbOBhODhFZ z#7hwuNSaO9a3XYAHK5v{MiqRU59v{oICr6coS$cfb<_-WcHjAeTUUA9BBgGspLAKq zy-Sm>R3=<4>NcTck9d|ZfqTG`9I=dJ7C;i(sWVE!36Z5uvGk3tiX+X5v4Ne3vo0%q9yjH0KLKyqFE+ z)**}3zge794@m=ZZ$f7@)mY>$ojk@wsi4&%LM!C+z_B)#RvckPs97Z435B|HZY>i2g&qhoLD#P=D!AG{Gd&oO1n*}U_vK@J`kEV#L zt`81Qm8@o=RxPPCTtEPY6YO?Irus|toeuT=FvUFO)QFs|vp~1SLuI&RijESdpgW5bBn80y;BMsTdJ?BbnQ zv^o+-0UzlT$=QlD%_ImaR~x?@qvP>x!QLtavKFzKaSY66wkqigJ_S{v+;T(jj%vZs z;?;PZd{OLfCgkmFINh9iz_KvMrc`^iEU|cv?>nQQ-gH1+*GQ5dwwy`6Nb#1{aoJN+ z4PE!G{$W;@9OLrgWo+tE-D&>1Fx;?wB35MMMg;_2p z-gI8YH@0Ht^5{c+_0yBNIokb!M#~RqX)%4Yx)shi(h)Vf>#ww0TB>TlgIF+X3JIse%z@~y7TMed++-rFdKQSZR5S^cA~ z-ouMNj?vuG{1}o|`(f%xoU=|P`}}1~w~M%tjsbe$Q?N}`->}{p@A5z%X=L#G@SajK zgQw`}V~s6GA<#9iyhN8EMMLxIN(MxOkSR;>jV)(agpM82FIE>ue%cCkRce0=b>h^M- zE@=mfuUJ{81+o_+@ORK>&o9v>N6TY^q%0%FSOW~nA(4D72BkGns19x~y~#`)y(xWl zmu=jAQsLQCTx_oG`PriiHkS=*;-6O;83WYUCy@rXF72ephlQeD58iMtss8NIk_m&5 zrgM)Y1@oPOYxDvCqHwPoCg~Vdu zwM+EPF!l3;(?A{=#qK^0%hpwf4eH&d)+!;}+XtV{ddpC7+Dv2e1_Fke+?@yLt25kW zKRvx}cV;zhpO#Z7TX_L5-^AtAUNbb{U4!OpTOwW_r9EUd{2i^J`thyd^p z&=`t@5X6z+VqrP0PCq<%ez%@ZdAxRTS~%1*r~dh6+A}NXDzBbxGP`l}*##%N&~l!N z&Cnz-TjrM&FF^}u3S+Conal@;-0MmHF|PQ0X?-?h(?oF_2D<*d1okp9hJ@5x3Yb)S zf(2eBps@`l*MWBMxKbV$J`)^KwJ`~59NIi%GbLj%p!UV{_6n|ja2$X7VCjeP`8&`1#5caMm)lg2G$Aa>5B=}rs~xxe)mB~{ z5{J;2W!^|{r=Pm+&?@R*pZpE_tP^Q2H77FWIO0|^D0Zi3_92E^?fMx>VEF_zVK@oaNWVY-jayh0FRQz4Q6}}JV8~w_0qSt252AjqUNq0) zmCc(lU#edI;vfJtu9mbj9@}q=?-F=R`sXduRK(?YjERb`tF2CmWr> zDg0*oD#-zVZhp2C`^Dw)HX6kuWdtnbK;u|c4)24X){ga!`CxB!rO^sA>2?zUT39>n=C02KAPx+LHc<@5RDT)INjavLK*uVHy{S)p|@ky~805{fR4 zVKn26vbI|G44@9X=OhZCse^j@2hEd@IfebUZF0txB1dw-4^@sHIYKmUAK#MtxmAA= zqt*@FU$Z)+wG?sn%Yp3XQ1y?pa5x+tkxjV>y7U&b0k~9I5lFc=%ks&^5U> zyEpIFmF(l6sK7?h+%*H92BvVm7)HLjhX;T|WM%cf+M;>nW@sK#dT}kgSJaFS1EDPP zVfs^iYlV6um@ekw0&U+j17BfqVY@MA2F@;IsISi+$X>ceFks2uu2;*V*4?+6mKTAk zT4W0e`H+{Jhe6sfXEInrt_ar-mg;LiN1k8A zHD^?LdA93Rg)@K=$Qsm9n&aGTHfr5Z-wMIZ({D>?p#+E`>p$NO&Qeu30~_8FxA=*k zC;i9YbM`{Rxbwv~p7ejFK3rP-7Nd_sBZflG{ib?6L<6D5K}IR6Sa7qrr`5`UA;O}HrHrDFmAWdWcH(?~(q+V8nzU90mR4f-4 zee8VUYaiYexX2d&oJ@t8t`k=}0+nKCg+#j!I5sww*|7*7)|3)(2ur49035tduKXFV zw(fOUCc@+J{Gz;Z)ZFOrJOn{6AKIK-i%8JJ zVL#~c>Ej|i&%#y0A#psMClX1}rl@TpnbJuRZ?sC|H=jU!J5+c+5k? zKgLR~tz1lP*Ud@Q(my8O=R5t3TD-J&VpA4UAwRPI8kowX?C};c!A~EA{kt(Gga9jGulA>(X_uPjJ;2cO<2{^t0f74a%Z%YS|hRsMB~K6`ox@ zByC%~#j@5gG%-Oz*`3jr$%lI_rTuPM?cne*r!n;)bxv#j^6;{A`)((~y361-E5P9D zXXxyeDkTyS^tS)Xhp+j*-jo7@LQQWL+*MR24IcKs=&hiHJ=62NK6XCcpXg$uaeh8( zub>}mxqEw8Q(cCtK+Ir+OQf8@qg5y^(O|_!3G^gt6Daf@{u(3T{@yfPe}*BstJNCX zkJDkI>$tQ%86s1(g(PYx-7)UBTq!}m)l?`OfB&Z18hyfzhV;9PL#LXxeb(J*0 zz*PTCNxAESZg=rNI3^1EloPE>*c`6+D@*>7j4_ps)u`IfHb39&1$FOh#EPV_+2rKn ztJY1W>Ef#jW$Q3lmUdEKO0NF`BiR)&)oaD2elHP~H=OlDy5GaBZ@uVgY;Sis^SBS) zVxzNB3b5?CgBg0fMzD=33wyn?yeKHM3vkbsGHbs@*(&JyA+2OI7Atg8I4DOrObVfX zU0hMy15Z z6)1J$5p2X;={_SL?_bRL{kYI=VOcC4tRo8qm@?$a(E0;{lfVfft1MxTu1yDY?kV$V zwhge+2IoUsOv?YcGbzZR82Xkt9NupPJ`(cPrw>e!B(E&3kSZ2JBz^+4Y8hoABnXh* zHJl3nXfG_at!1r&^R#@e=M!Zeq}Zjg_IlQ29NyM$&t(zuI4?OwW@Ed6I8m5h(Nwb; zgmnTZaF1>JcRF-w;=m8G)XKE{m>R-C9*`YUFxj+faUv=tJk zmv3^@mdBM=`9-*Wpk?oRG2L#YnLAqbW#}8+t4KekD%iG+e17L@)ziG6J64)+E!sp# zC=!O**wJ@Vrm&nJ2HvgQfY!OT-E(VWITbBrPlp`}yGflJ9G?zB_)Fo%@bKNAuYB z<>n~lSxw_$wmCW@0QK^j(O2F*>zD z$!8wLpZKNxnA5k&V=m}yz5?5}MIF9KR-t(CFy2w3U1y}9%NYL z;k-FF>x~ndx4-_-q*MaemJDc__ujA0FTY-8@b2Aq8Hqyc+eSCao7J#EaGh_l1jqV+ zg@}VbvF*|Ha6zyQS7ZLt#`|4Vx@$KO|5!8|s0mI@N7JI@14DIc8F{xf(iD$J6Y|Sd zm>~-RHy#+3h2^DFD!TnAP_5^IdGf*_IxLru&KChtdL*%s+&=p9{@?O3WC(0AIM|az zn$&Ro^`i2Ml#Axdn$`M<)?uUQV@rIae5a-?5P7_q(PJ5-!8Jl|ow&%AfgRRnqp==|1^Z*T&Nq7gsS6vZ-+|2Wtd@Y}-n^qj<(|ti=hLO=o}a@n zvqrQbldR5>poDWcU>7zPBR%<)=xrAPjX&TOJ;N9<623ZhuQ# zBX^`TG~sWJg7PzV8cjUxWXaNsD1L`vYK{?g6#%}rNt!Wp%T|h}N%B$zfQgn6R2ta~ z#q1@Wo|M&f{Y_nm3F~VNrK(Cg+i{>17oJ`dT)Yg0CYgE#y>zfAiM3IB+;AxUnvNz) z*Q}{M%v9K#gMWyuF=CwwpCNFk%cK^B_AsYQ7F_y=-7;b?Ia~bV!48JR)y$_Kj;>?| zSIr7@(p;oyl3}@TM@rXdU-bD!W#F7iO>hk=@#GjEGxhh>IL8DZl) zd18Nc-Oa2Va%7DN?4T&$?cBDxt4r|$~`2aTH*w^0pgO-o2%R}4^czDq5#$6>L^ z-7V{*e{SQy>{hyEP_wyYg;6hq*p*J#C>DKG`snNB)fDdj6#(hQ}y<%kHFodWKA`*D_U4_sV&S4=4$qGU=HO|#RHW#j`Gp{9tWGk0I6AR@@ZH54J}jfh6k}fm+%S4gVUckokP8-= zhWGQA;5iXfpcdNsr;C%0ZR~K^O?lV;kbWbD-o{JFKN^~<);s`q)j6%y=7ONl^rMlf zKw#$(!cCQ+JSsnyq%lAjk4F~l9MzcYlHRu=!@XW)Y}hZA0JI*VCQn@Xqq;GNKdCS; z&RklruYOW|xi_uJj$qoa02 zH-*FNlg^+qdCsb{ODCEo|0x6u=?kPxJ;D1Nzl8t!%h*l$MiFB2QLb0BR9rW_bd*N3#w2{ajxVn5>2Y+i=&K7| znogy-KB+Rvr9Y@XKNEYWDVMYV5}pT?VF?_u(W`3W`0)N~dH=dhHr?hqX8jm8C}xPw zGnykl1dkT@vUXc3-aemd>66ewn9+Jg^hfdibR5R8Ql|(qZZckVX+OVX8IR_p!j{oF z7#Vi9?aLv4S)lAXVY?POfobyy&=c719-t$ao#Cly3eCpwFpXvg+toEacYlw&h|`g! zkYAc)0ymKN*?cg6%`rhkl*`DMNe>BDthkaI<~&np11Z~bKb*kDN=RRY9>X)%P@QzC zKF}`Pr@8#a$^J1DZPBkwC5}IV8by=c$9TVko9UxNW`Eoi-{uc?K1T~c(7$ZWz+X^Z z{9qw7I{%nU>*EW7C3 z@D^4+JSBDGX7gQ;Ua*3}5Q@Yx3pn}d!;U1ObjcyZDk*=~X%!2%H;HBcpnRGoD&Qr! z0H+|wd`koknEVpv^t;U9UxDdQf8z{)Q0^DsQ{gWx)ssG|AJS9Dci1n9KYvi#GA zgn8upc9?j#yRvM@J}g@CZ0dB;?>R6%tV*mKax3e&1}zvMy%?0`rUTh&syGPUiV&!S z8kM88s456oa?OOKY(!1S%Vyg5WOE5k;(Dl+f>+HjQj_7ONu%D033(4>C5WS8b+)F` zd8x9FVZed}K;5a%)Q*5|n@^E=vP0aAi@}&A7Ne+5rX3{cj%Wdpmhx=Jsb!^|0$GCl zYUELnOSVYUp2i+hZ}hLvW5A=f0aHiRI#dd9aRE0jY#`4F`q78x5yEaqxBb0K*-PVK zQBW|SQ0p_td3ihoad9_M_FCPMpjctO)PiMz`~5a~_}WW^8pw*mwJX)QfW6S(tYDQz z1SJ0i&l8y80mPC%aa6wR)%4-Nkc`aJ^i^1yuwQF5&Yg;rpmF@l5R&JR-iXnQWgNS) zEMl0|7Y>maD~twh$dt+8z@5O_#2l(~sOy+tq(XwOd^`k33pA)FVw;L}sy@uER!S@= z=n;lPcXo%8Bd(_i+m^Gd&UapZz+8w{B31OXMN_LR?=e#cLr4yB3+;D06Uh?i9rivg zo39VOs5}SGOT@5zV?)Ou;k(?+zPF14>uw*Jm)R?f}!z{`J zP&^#QqFL=oAJ1wUUB&St!ioO!+hKR+;zP$!(;kc7JxtVd5@Ue@S!Yitu*JDQK~G+pvg1;t@r_I2drj4>i1<9W+a_Go53(vyZ4!f z61F=Xlvv9&zht*SOquWkGO6!9eO$Y1pW_;+9{X0RMSDx1pi2zGG~3L>r8Z2XMJ4jW z#FlVl*7Q!_0=^BZ9e=|#o>#~n;D+%n%=jL_)&71CUu547F1nWC4UD5-?gM-MfF^o! z%t_zn`I?}sI>$t7%nw-cQhi1`8Chlb4jczwp2y0KLLVr>%uu@kP2h-2@1W{Z0t*Af zxLgN%+2n{}>;?ds+Ds^2*PE=EUW7<9zIz1(EX}Xpfq|lW{k6O=8-@A1-$s|rhVC2M75P60-WL{`{2CCI^*8`Sfss92v| z>58WSH~BQrT@mZsGx4f0UdPwd-2|+8@h~D9^DY$VQKKNVj&L=qjaZslUWRr;)Th4B zt8zWLvmnCV1lZ>n8CF1XxozNb<`@Bw2!DQG!6dz0_&};@uu!G(vu*jVsOexhj561i z+~q`nZvvFn*z1t}yNJcaAOd$4Z)D@N3AU_SjxQW;_Sz`mF%JjqX5my&dc!y+1m8&| zTgHwmu3BxCRW5nmvHiT(=6~1hEN#;*bFagykN@LYiBEdplct7+!mZ!+JC*a>&zk*N zhEdh!5`z%Tuq!XDs1C?m9c3dIwg@A8cYD*8wp?{$EVT7^p|WqjJ`mNR?|@<1=P>u%$qW0S6fPws+)CS`81OygiBV*WPlv#wY_>q=La`=i0(5n$5AM zL!X|#sTSM|x{Kp7xH7 zHZ}|yjx7nQkBF}ET071>k>JfTS*rT1N*J9vaEXuqR4*MzI$kMItXP3*CpZVT3(iiR zq!N0HK_<%2BerP9AyCYZCvBj9@226TQUm@)Q`Sh_O}6``XJV);q7R~U0Xs_c<(Pgz zmMlIm({POMKSZMEXCSs<73U(Zq#XluDq_Cx&c@{+W2!=~oQR(&ruiv12>Vxca@Kw(U}2iV&baYFJXrlqWhN{c%HJ0?=&+_4wkV3R6^1xoH`PNJ{AC&TM@{|%sak* zFyGKQ1Pr*SE!$5ASYXWrjNaIFG~!VVFs6?wn49739iO~;$h3T_S%`g<$lXmIu^4gq zo-!)*+&=*wCW0F-qP|BNbIAc=LKfiXpHzGd4JNA&mou6|;pKd1qLSNuGh*Gthg9As z`U_kyE(cn4tKjVZ}?iw6>Z8 z!-m>K)1C7%Rmp!z=zt>o0*w(HN@xJJkxM-{ z^WT!3mQ+Od?tL7DK-r+0_z1TYdd4|*EdlDM_=nCd4(51}*D%F-{WkdyTv2`|$mWYI zxr+c37wG>3%lyYqL1nH$KkN-A`bF1%e7ddVu^9#B}|l_Cb0mI`7Ov}+usQ3AE{7f|KcifP21&HV=EdR z-6)a<*L-c_dvy4Y1B?rOIB#1kQyz{91v54;jgPLiyJOk=<$$dCSho6SDo|`<^5krY z4b@0v@@=?uQXn4G=cz{6GAURUr>7^tB9mpW3 z&tT?g_Tt(99}QVJSIsm4e{i0hA;$JuDPUS*zqo$RLKv^8GC#P4Guulu3@t3~(-8n| z+Bw;{gvw%qoGGFe?3TnX1iwSmq}P4rYJHP1iI*%Boq_)*-|;!EzAWS+jY~S&XPn#m z9ADGE@%KDVO0wgHXctX*a=!v8E@iR|=Lvl~Lx93z4Wv<|4=N1Q&t%C0g~5Ln<0lsh zP+b2t+=x0Op@`S>i}je*>M)uC8_22=Bw9Et<(S8m2v{WJ27tbfl?C}5Fyf2~;TvT- z1x9H{WST)z`#pbC#RUVwWJ!U@Fx}EfC7Tk^tv@GvERM}b!o+le@IV!s#>SzfQ%f@3 zA<3TDP!Z;8TIALXp$a{MIti*BJ5Ft*n}5xrJT^xRJ6C~fOZT1}qe%Ja4zCizT_Qo~ zi*nJY4gu{Tzi}+lvWmy9PH@rxj|J9SYYFDYB-u$7bHySgUlg3{xKZdZ5ya&P#rMN| z6@KY_QDpu$j*Z{BPp6dOG8yvdP~dF%Z@C@0FhG3`n}ZWq@6wYuHtq7e7V*wyhfqNk zWx_%gT20#M&=_z5!zg)V?!G`_NB-~mkc-NY1lGLnq>r8REgcw+^fsrB z&$pGmUKI3v^S<$~JpcLrCCwjI?fo_0alKjI>b`REZS%J7oF7aU_Y!$wBBNlBVM@}F z06C`aWArv3B;72xX7t>)W4&LFSILMm=H2|X>PLF6yIR*rFV@%Pe)%^a z|M=zrFTaoErp_NAO_Nx2)lLnSn@X0LOQ`GQp=4z9R?AOaXtqi0f&KBv4eFk~hJj<1 zOj<31vb&(XS@hbp6}h7v^-`bG?7%2vyOf#7I8V!ap|N#Tjx8?IG2W+trYqMh27n~^ zTjN~aMqG=?WY2I>j1R^&E|zZp#`@3j`RwupJ?Ttp?W$N_dP}XOYv4!CU*0y3S0UK5 zi(Lfbc^XpljOQCG*ydVN^_71fJ=867$C)z$-y(FXd^I!}^8YrgbRyo=nUJ{kZ)(5* zE+jBGtL)c%RYUg$$hyL2IEU9w6m!RM(`AdNZ%9bhW?#QDt^QcqijPG3W94F^=0avY zEgMF2O=Xrv9$qU%_;sOu$zx!875M6P|6RR#rXic;HH5sd626CkoeeuUo41f@eRu!YD4{&%_XnFc0^ zra>ysS4X(qzSl?voY`rG?LF3>&+K0B9?R(=jb6V*&OX{zZf?97i&X9|H*G$^*OpHCjV|Z)&_qhK11(K&Pe5BC2&as#t!rGYHZdZ9xMm zIOK8vVkH@u??5{E24%Zn2F>lHZ%&q>PCvb_nm&c^#VVU;AYx}HT5V^{jSaVp>=1$% zXMvJ9xXD`b2(a_-1w0GVpqOTJ)aT`U9=1nCrS-eR^V4^rL8tJ``MZI1_)&X9-j0M&vNqAY5+a z7#Y*1pbY5z7!Ix7ieLJzFNfL;*+Ddzy@0ZHB$gIOduCW8g3!8OGHGNvWQGwwBn7i% z6qi9O*}i8#$J;7~uS;9+IL$JT@0AnM*33?8Gj2Ma%p5Q=OoPz2d{YX%QOB%}Bej(^$v{YNIR!_7@Y zrIA!lB{K^oM3$CQ8UfETXYn@DHyxzeg$CpU%Jms+Yix?UOV|#|&$Cob&3z{xr>E}= zms6>>ghaf>xug%iXb=$2jLRbjC zCH!9(f5h)~jrsw9 zDN+4O4Yb`ip2V?B0oIWK>BMF)Z%-)cI05$!%U?- zRghq{n}7aG?OC3Gy`FwhF^XkUpp#?3N})9)W^Ss_UdqXiun_q7!(2>mo6L*e(aF!W zL~i@q;l~D|m%jMr9yR;D*80+30r%^ihiaD>mnh|?L!1R`$K(q+dPlO<;ltHVuc<6Q z&NWm+^f>@J^sn`@y7WX`4(BA@JoSKhvjUH96WO$HTK$ER_$Gcf6DeSOIFdW$T$w~C zn($5M6)dmG1+IV}zjbW}I_aLh>WO-Mfl}v^V(7G@=bTM0Ho5^uABx1teeZYHJnCiT ze;131bJGT?gYYclLg&CM3qgg{+?Gp<*JP$}>it!Dm8X}3heyYq-h;$}OhTb4#$f{= z;!J=|>`(Ee0{fu9lq&wvt?ig+!~W!M$qzT%8&P?-vnKf71IM>vnB&aVx7)+b-uN7| zu_d-ttnio4G2dq#-FDN0_j@7X^@pG`?RHy`wBXby2D9w7VdHX%4h?NAx8PrQ3Pzw_ zko4Z;AO?S74}xcopx|hI)#9bXR#)?UeA;0aAQpg7gdpX%R_mQ%wjW_T%un`v{ZoK- ziU$shwRKHoVnbF!n^F9L+K;B#2~<{ITbGCje*v{GxpWX0;b+dq76%qmabLR`TVMAV;-%e%UgB~@C^6|i**Ai*pg^hY~ zgAqFTHTeQ;e#O(9=*ZZS0m4DKQaD^e!NI$%d2pBD!_62&hWGA7Hfe5u1Q9iLe{^(7 zMcdZZFg=|`KlOgP$HB$qR5)!#gX;{q=J+^jpc{f>OpH*E(JwvCyc6kj)Mx*=ys>X2 zE&P7>Tg`s+Z4WmimqD!3O3pKdG10hVR$!wieSoiJK9|KKs0t;M44fz?Y1CV2FkTz} zK_Sm4$H`P2&D5~s*C1t|JbbyrOpsIDXV~XsbktB`>b(bFI|rTLwCn$S&{?{>_lmU* z6rU77w|XYP#gqqtnGdI7%sr9%B7~w9K80CJcGw3xKRY?0JFLsD7A}C5Pb`n(H(Mzj zoAjrYPrrMoQ*?)jBAmZ{?SJz)&V6?t>{X^uayYv*$}69(ym+$gk2-cgowxPA+P?mA zzUFwdaLM3hA!(*QKT(89DUXVZhVsKX3Xl7z)#0Mo)xuzQcJ^7NQF9ZQsM-GFw3%Ew z$LuUyzU7NX#flN7IG0$TOB64+lZ)MjQ&Gc|e><7B_zxGSNWAGu&ZCiyaf1M5=tpE(6mWJ$$1G>bO+ORJ#C9(V>8K+VsrW@C%9g() z|G|!vWGl85-#Rc@L`A?{dHBtFXKD=}#TP!1l#jCaiLEzQi&S=&{8MP|)KQK4RNe2* z-x}6kFV0o;GuoQ7ad_Ym^PJ?3jFUKepTtncndr(3w1@tv8g)Hv8MOi^D=gxSj#oqc zl;Le}^#_{1)23VOIPZR%W8aS-&aF3BmT>Fb%pP~D$_z<5Q+C2;LCwwm5odr`hWERk z3h(DToVGtFSJDN@860$6;!($E?l&I%?k(Q)Q}W&~2b;qF1#tW~{CjCUZb!wm^bJ=- z(o%ls7tg_WCmvoa4QHIy`Jf{L=bM4cT=A&(%jJ4XIouzswJfNFe0BG`^JDzpQzyxv zIlNpBUhh%kRd#<%Zp)|P(uIyql8-J-Ufwka|Gb~;OrB=oJ#Ue0f0^|K_p=*IcaFzB zZ>rq&1xDB@f%w+^fyZB|g)QAm`hJ<)*R$)={g@q~ODysQBJYY8)=UNEuc(qL zld7?aiP9}6tPC&a7x%>>YN;62HT65Ia3iEkW)w%WlFt95GOajh&HIJ&`SpiaqxZ*H zqkcI;UiXt?T85`9{T0sx@SB&br?#zLcAb8fwi-1XD`2V9aZiqpjtEvC)87xguhHN< z+!MfUp&rfThzMEgJY@C@;fNNrlwzg%Ui&dABD`L2*X0{GR+RnC=$q`WrpPlJPQs+$ zj)TW}UT@A~fI4@{@>r%ijklYp;5JRiM}X^1w`%^oOEhpNpl5I=EFAi#gO>4?tD?&7 zKCq3qn~gMVZD+Q;bqrVVwLkA(k8|I59JepGzt3a#{m|#QZHdVtbbY-yYHqe^vhQ^M z-10P%T|GOTmWI@enJvG#pGj-|Y$HpX*Whyl#%%CXcw&C6w#Z%@F<#yYVQexNEg zlTMfGzuVt#>$mfx>6MfC50iW^$E5=U2E6_r^0r)T*dxOzJ=e`hc6@wxiQ*0F&hol-~@%Vi^TX~R|!z0XDRd=sj6VQg6Mr^k9M zwe(}rv&>E4_QhIy>i7ZpQP8Bl$NT9TrGnyAX12m@|BI{t!iKY=j$KEc1sr{*f`?rKHdF zBVW5n>=Mv&pc&`M%V~Wjag++&jL%OGck%K(w(&?x#-l@PH!9%w#NOJBDdfvEj5HS# z3JZ;U+X|=RD{k$(f&GRH46QAO$r-waN zWO{%1_T-xDTfS22E3e((-J<91or5U?HHV27Y>iu41RNg++V_oadIu@JPG>K7ra7q~ zr(SkCverA(hr@j@<5Pj*db=2$9M3X!_^Zt4YJN~TiSGv3gxIgL-6?POwr&sqxB^pS z{4|!`{yMz#q*?81TBDafm1}1-NPLTQaterFSkTSl?M=iL>af1o%FDccyePV-d1O1; zB&#@RKyo!8*i*%$lh;M3S~-?uAV2&x%88h$021;}#!~^su-hh4^q_FTTkZ1%mCGVi z<8IRn6Lt8P!pdB-m($$djNk{=FW@nCz=e>-&h&y<7BuVb)h0PRP0_8PLjM8UX9Y;g z+cOf;i~Sw;Thwroh0mU}V9o6XoHv|O)On>ZQBTx$F;+|Q_HXnwa3>u*eY)WOpVqc~ z%)yyYBhvFetAAQg!{0O6hwLPyYFt(>MJU1vg*dYJl*!Z=o}0upLRZ4+Yi4Pa`u0zb=`Y= zn!c*Yzx&ik_hRo|IBwH^VA)ka>x<5CVdn#GsEIW?DgiSEyL^)sP3#Z|brBL7pmg^Y zt#Hx(O7`oHsQU4N+qu)4n-e(iVB*`I*;72@6oAH~a#Y6hgUC=8b zr}JeJ;p?M8d~%WfRinD&uZ8M0LuUs)+#=z7l6UO7!@U5mZh<7P?L=%Pr}^AdkoXb&IX)iwNj z=Afet_v&P{a4~lr*e7NbvUJZ1d+$n^wz#P66@`w()_G-I62&BwoF?Lvgs%+IFohEa=fUFYZx^MI;`^4dJ(TJ$S5dG~@_9A`g@e0`G``r`LrmJrkDQ~lxONDkv z3r(oAoGz;54QEfMeC<5*XxQdGHcM1L)a^3YrU`kUr1N;&&rFp2|HAY+TuF{MbU}5$ z`1Z~sOy6yPG*!@-|M*JQcknk@G&6MmV^s*YUnLtw5By zlkR0Rw?IasKsrxu^K}F@du^mFdON#&;{cWJyo2y`0WKDZ$PN8rX~RL5FE9@c46=dC z`-X=%fve}JzgYyPxm~Sey`b~jP$m&M?0c##a$X6XlaG(Q4i1>v-4`%Lfj5+*?7cvp z-H3d}@39alI&*xaY}m9E#n>C?W3$qSzcq9I>x6tTmEXz5((-Irp6%=prbW}~PNq&} zzJc>{hw_Oim*c`28OiNFe(mnn^)%+KO?M|Ud|N=+?J=Uf`u;qA0Q`%}qIrZ*A#|~l zY>x{B{xAoJ`ML4IRH6M5Uhkt{A%no(sMdk_D13DiD2bP5uR9BS@$5H_iJ~Y7ZuY02;Eh z!?D}sxzv4QG3R;fus$iUeB~s1+T=yZu6PGOZ5QeI7EZALAVYi&FK8ea6=n%MdK_pf^XgdUzEY2*h3IY2$8s0h~e-Y6mR6FdaJAUAMu6kg)c=d^17Ssr6-VX>N# zZ-(J=Zs-2rgS2=xLr~3-fr-yyvgp=DM@y7ilTYi+ucKbMimff6Dc;&F5VkT zJHVV}ykJ$Xv!WCpl5(WM^0$)fd{%A-J&NtSkAviIF9MaqAK6ORQTGMf|xLdsBBa%X@x2gS`_DPw#2c7S8TEHFs|sHQzV0Wz?;)B0 z*pvRmuDL@HeOy%4ql0>v#oK1%VC}f}%AhG)-CH)o~wutAWbWkYF^r`pxz|sf(I9&#VIB?Iad5Ndu5TK6-8u01sa^x@m)oaFo8-gx& zXE%nC&rLcHz`HOiQ(&Rt}(|4GBcd$ns}H(RyoCAQ;|S-_^^RDKDkbfqHZ$FAUh6k zMfq0K3)V2aQcl6$2!!fDQ$}oWf^xEN_ zz^g-(PP-%NKjA@l4LjUXoWIBJ**@w! zQm*EHpL=z`+`v1C{oC_ei#fs2GC4FcPmbl8{o6}k^vVearV8>)u^|(FE@})<1V2Lvy+B7y8|}Y>kS6PXNMhjJ5T@ zq*ixFOJLYcV?mb9tW!ka_rfG$9eZ{Whc;*H^j@g`OXA15Ps$e}U0bRrj_K&BolRV3 zM2x407s+}UazM4{Dn$2oTO>AJP7=->;f`RMYIY)_t*hs&n`=_EN)6nNcSI5bkVS~^C zvO3?PV{4bkrz+3e30+czJ?sw0o9ni%{p;i+g)36coj;Iu9jV5;4o(m z+ZY;%3k-KwpF?%O$wD}u*kdMDIPK)o^1Au2MZuQJLrhF&aB(^R>WERD&yf21h?{&CBJZI3_Za zEIkM+?q_MuB74C-~D>yeEf@deo4Lh)~|apzu}WTh-P zc8*ax0z7dByh~7`gb{!GkN#N~K4j`)Az|>qUa7O=haBOi{i1L1U*% zJ=#HtDo9KnUPCj@&_|K>PHXuGXe)e?0V`2EN=?%KQ9C!e0b`GYI| zwf1(I(x+NbcK3F@xo)lO_GHRh*!?1^uGRA|$KLSmhOc~1T-40vmLBCk&WVatiN#?c z{iCwn4Q)G|O$vgEmw6;P?r5LQ>FiN!nRp_OAQ=s-FQ6w!Dx6BlP&}qLvk83fB4^~a zEhe%_K>i-`6%aRjRdn6Vij<%4S4&rOzMy>AgpJI8O|ejfV3S4!2w{HztK7}MOxj%p zDPPn2j(>3}w**M_FeA@%uNGL|AAbx-8XSBH1cSs4}@a&Kx|( z=ygp@jHAd9sqv9rhE7Q?=_!O$wMLw5^i!Q`h)U79-{bdn1fMnE7@d`O4H)lGk$>Rl*&Ot|Ciz?pR4`zX|))^lOD-}u?7=-pc&kTDn&!~b> z?aI#i3WY1(&FGI%xMULFRwJ;3>C2V)3|A)Ypf$C!1w9*cPY6w?Zlt>A(xPzb~M z;_@g%qsuqmUW!lmG%^#cQhcK3GN;P@sIfxwTUF<`d3R~H@AU?$j54{k8vIH|J%2^Y zIg_H+b~tP|DGLR<7f6Mpl80ofTO41IY5bo0%GA*$Y*jcHNJ-F}_@r9>ZYgb)2JGj? zKEcrEH-W1zB!z+l5Rr!asfu7ZR5&L4v@s?X+SJ!P0o4e7792D*RK`}S>%tJ&XO%qO z9sUxU{hJOCwyV1e9$sMQ~W{(~6OX40!h$9jM!_U7~j zhWe>>-?L1m8l_R{#q~?zQOX6sBB#nC>p2(!W7upvK@`Df;;g?K05pvH$!VCdzFh^N zL~Q#W8}RR;?jE8j?qK3Q5N)HO2_@ajb;9@H_P>1OezX4Otse zK=gH*FmQWmFY>bKP6ew1Kn-Yg>ec@R9Nt6M9W?*1NXuD>JPl8O1)}I4Bt=8B? z2J$RzTMOvC`lptIA=53Ir};jmaZu(%-TI>2n!?_WchWlsk|h1dY&?xK7Z41*Hya5b z-w}xc#H?%0a>}+GWH~$B(JN~TqQ{tWH!h>{4#YhB)a7a|u zb%5Jji!TpR+VNh)1r;!saELk_g?2Z_Oxf2^lf9)0Ve7W0l3JRF1Erwr5d2f21}^|> z2V2%!vqgSJTSWPK&t7<2_Z>kP|J9?2i{qii6ONaDw(|1)PEzp{6U*nJ8~O8u|8|$Cm35d1mGJp}=$Nk#69JkmezC=D2`>FYt||50Ih4DXg;#+V>I8j}aF{ z`BB28Lq9O!bfd;mP?WaEo?mdkZ~K7k=$mX%;*l<+Bc4=SS|?yGI!KTFrSe$Hott(* zzkI~=x7`j<9SU0mXAgU7DqHAm*)i$N`8D0cp+5#QG(n+aG1I|uTdR-~ncK6|0o>eg z@vCXCDLb@=f%8U(eU7_L{a@>0GQUa58Y^NZE2@b{3UnWz_8?SC8>`LEhx$1$@qxT` zq=N8FTo9@p`+jxh_d`vx%uO-q^r6{=FLF=`B4aZ7TJnsXZz|O^!`Tlt2;yT4Il(V` zIu~WkGU!j{rhe*Te~YR=2d-DNa_PW*hwVmK;^8iY9*je{UsPoGbcW&kUF-W0%g2FP!Ih5h(@jKr%9g6VEEHa)sn^xqB zeb#6`6m?w%$qXp=5-m&5l`1Of&n$vS^{cEXQul&8S-|#d3DtQR>4qt6A^st-6lBeN zRZTc#7DJt+Qi^Fq)I%NOywpGNyRCkB_XYFFt0FYiTG$17>^B&6g=xYTXCVpAEhUR|F69Cb4#$IFx=W{XJEHtQgzC zfT{*Ai!&^q&C3(5H2rY(pQzBmdo_f{>K%wCcLV3 z$C-YUl%?Ur=5P_F^5{wzjpOLDS!TQ?N`_rfzQy6;ZP!THBvFK&IfKZMCWC-}{3Vga zw+^25k}itU-#H-3^)Fn}xq%+9r3Qcd7SB}J?dq1*UwUZSOi@W~G}-O-80=on7WHfl zX7Eno(us8ZGBY!z9)Tc+zE5EHGGv&6Lu+nc>&6j$BD~DP?1d#17+w73u^J@T8|vc% zU*v^|;vckeZY`|1MKzqg9vUgfuTto<=Y@a|r1Fa(;%A*LAi7FePQOVntz^{syOB3~ zBfknDN=3#K3g3wp)Zw2DSYla=Zhts0+4T*#l_YAD7yaHta6pJ5!yQY#(j9J1x%%op-NYs%{F$as6u_c^!{bKj z6jSnPEh}|j7nsilt9Z|Ia{H`JgU5(MGtrj41`g-2_HCoGBL7a`kB94D00kXz&49z zn9j#X=uG&4`Z>^q&5LI~N32@!ZDgty*%-k3@0krQf*la4SFu@GJrhM%?jKJIm=8xg z>J%Z<1<2svzuIlpxY4$y+KM3RA-&%WD?W05tqIBr$)pE_NB7FoZpx1rO_0JT?w72T zvev{pZAU51+;hm3TJc^Fl#ac~!27f)G5NXY21?!l2!u3DF4Ev{zXH z4}T4@+Y5}K$gT_bMn*Zh_TnkXQOo^5wzk9#YK#3AZDh(7)!|i`!$2KDWm(>j)znU5 zS-!?~vdYxVPaWU|2GC+3>L&mWc9V+2@u7(no%nglyc1C3q68Bas2lTQnCdFjC zVjTZZyRl;D6R^f3*AP1g1T3agu~!qmv3*hwfpGc1D2)?Y*&QPGQ!z}bpG#SNk!(ut z#LBnE6arJwk?o%RM}H6j>K+a{bK^mgVhP&IK}e4rpm3CS;&_)BxB;LPAH0VZoW zLQ}Op)3gW{^W;ch7Tx37o{tYUcb#}lw zW#KB_B!D5&PlowX37IZ8pY6h{Hp0HEbVgbu-**h)Fdu?m-UX_AmIA1Pxmdb^@2y;n zz_m(drG!|xDz&o%RUo7en0WL{K~^b<3za%W9Hald^b}ED z#Q_Ae+f-y#vPDS@Z!jn=9_tkxSJxAlbWQwYphYjQB5!+!dTYM^RTZwk%|NnVxgAUS ze5_jh2qEcP>ObAn1i2?`gg`5j;`#3I@;odH#ga)z4CR-O$SsjJQ`!kIL{?;I^xbKy ztGO&b+JH@m!lWj77N&F0)l~#%SSS*~=vq|CZ7_ zD|5^3H1}2Vz}c{28}%fS=>b6q&@Z?GtBkQCn{SZo97j02oDK;?NovP{AR5~5E$&d* zBj;blv5&U{c`kpf*H8{(-jCF0n2q3f4Nj|&F!AY(om3nYDL_n#nLiHhSoc4OOfjf|5x%ysz@7Z&ik_W2=V)L-8z}Aj$=}kEL<$0@1CiNElREs&P@w;aPMo zY0t#hHx%(a;|i?aEI1ZFlBcHeLgO__k}z8eSD)pTHAk6Yy8oh3w#kpGW5MUE|1O9Y zQDlE(zM0#*$;N63CYjImnA5V~9NX24E__|uGR3bo)LN+DlcVqQ&C-h23ML8#wN>d{ ze+SQdJiI^A0LY@sfc|D9Pi_OE(jE5r;G2$!)aSJMjL@AkWtHQ}!tJ33{TIGS5dzPs z=GK!Ty(zlYr=8hGVS>kl_=oQy(+U7GbYDmCoo^S|bKXs`?SA1Yxu z-f(Qlr&aXiEj7GA$*W&x;#hDY?|gKzR@SJ5_Ls+t-dls_e+h5oMJqb@Yti;%HCu;dh> z6-iK&e_VC8_9;_8obqsV2(PC4$x(#%Bn5+wg6!*rlxrueSq+oee#4nECFYot3Qvu8 zM5JKB93OCjUxd%7O^lf6wn#T?QqgP57r%0rX01<#SrCyFvg=SB`tv5!Z!+#d$O-K9=A+p ztsCt#Y7-S9Vm?4HxjJqsDj_05akcNNzqXgX<}d=!D3hyE21k4wCJLS_igog zdoSmfvb9~%w}zCjd~B&s@6>*aaYpErVh$hcY{2l__`z@Wgex?wdv<`6v{LZuEOy0( zG@@*&DyOb0MnVJriM>AyR1V5(Fp3>UxY*-NkTLq6$2ohBd$el)TrKFGTcx*NteJ}{ zc8OnUc1Y%rI6t#rOGbZ2$Ny?k9+drBu{ma2jLg1xU_F&*CQZ&w;~K4FW+aWrp!- z%pGoKq|xCAWMXpJ$)rke1l~dUs7ThrPg?lTzpEmtd-0y zh}K>U;#Dw+p)}Z%jMv-scE1tx%BH2< z;FpwpWV-^n%9f~2>`}kQpc4M)70%*t*Lg3=AQC62yz78W#U2 z^vxU2H-~*2&*;1(*R%Aa*AL5NF4dbQ8w5;7mahLs0h_X0Or1r|H`&KKKer2$cWfK@ z8NeK52!b{4C>RZ`mY05oD56AIG^a7@uc?zte_vqouU^?l=UU9CZ?h2@_y{5ty&Vjr zo0}N5_JLl@=;vFel&o-yp{I+*&W_WbnX!$2{iL4R6SsW}&p4Y~o^WntjhxZR7s?~z zw|bxJix7&``_|E9fRfS9_3~bZpW4b~fW9bYBapA>2))BCp27C};%GFbmehSwYii*|BH_wAE6_?asty|D2$cYcyOmj@yr768-!R>zEe?VNxE^YMUvc~hf zpxt3kHaJ;JK3Sqp*ZU~4CFDI!(>ojp4f=y`MT6NY{o1 z7)P)At=LOxdV`IHs#A$g7pwtNwQPXK>ccZm4l=+s;n9H^s5Q4YyVxuwdEX7#-2+=J z+Gs8ocMVY#IKvgE!?ouIm#h4eN`;JapG2nEFo%y=kTgEYM73XNot&Nxyw!=`M@p~x z3rsMEPA{gqzA9R2)Sa{M$YrDQ-o*&HJy%Q0mH&-YsXR$t1p~ur1M2Ff~G+QNRP_Jlj-)_lyGD}rkPRBDE!M* zRE-*Zl1H%b<#x(HX9*D=ZzypkUPk*Y7`dE2cdzLT;8ViXrY}qdY>a27B|T6DFdZ>R%=3vH)V6sP^{@nPza>`+EJRj9H;?`ofYE zLZRBtq$RrJoROu0m>*!s?^V=6TuFbkQ=g<<$&$&2fdx_nc2?h)J~SE7G}kJi-3@l$ zJS|aG(iq!VKwZQ(j!ryKeYN>uswQiOc7=VS-nukbvPP;xD@C6D61bVCLB;sUA=6{H zL!w%8e5!l7^rz?G#-5w2)v2Hr=G3P_X6Cc6X_`fR1o!>70+J?12?(4oX`S8LjQrW` zQ`xQJg>P67v{etL;)1^C#M*o&$kfc6r|U4|qL!$CKK-6UO&xym50N{lAqHJb(12UT zoet7Vl4v5<6^=qR;4^IJHh60AqxQ&+=Y{UDA=w`EDXe5kk@Bu=p?~Pc8vLpy zOHI}obGb+-s4-{q~g%JU&&6=6QNe-9tj;Q4h^v9k#h!60=f^e0{1COBI_j<4|5v0r3)( z2)tIGwFrh7s&7{~#jc*|jC)nDHPf>8&v2Ubc*tdqQS;ExU;LeWO@uvV+t14%Yrs2h z$Up37Jx;u3IY^Gx(__-%Ag`6djWb{lJkuzgN!hZm3S)vztJwni411bq8Q7HRg#djY zHWaqeO(1Me=Z=63;}k}`U9Pb0-i}KWKtR|qHNa{X&4={G^u$gG4mq#R2k&;AIwC3l zydV>$IeT7I2;%R>N{7mV1!5D{4Y#AK)r9skw4Db-w`prdYfMjzaf{@phSJ~uDFy|- z`*@g7pkab8vaS0L9H-c<+y0To+2Ekubow=ShAis?X!b3hqepEt3|f)uh@UF!LjdDx zOK@|PjVUR~vjcv>l=lS}X0E zT-P@$G#p+XXymv-ZI210kTGYMK(kpMV&f-7Py8Bbyv+GbcbO75{B+q#$&~6eXepZR zC#wP=&gA44KBwj;S4m+g^`w8@U(;5Zs;`yw>wT!f zhw;j7g~;OL+>vR(+dnomqYb1$04|OpQUr%sn1C!o)sRdQ`O3fTIn@U;zvi0qXPvmW zwgfQD%FSF*{aIc}JRyl$SvK_dtdrKR5vVL7Wu(!4R{@Ap2YFC5Z0S@Z{ypk&ol7!W zkMAXQbzWO^8pCQ~!Ziukhf;a9HYQQk&ZfK{3;}?L`ghINi_X z-sYt}7eDM|%E?v2D>8m%sHFuaUdlyp&0@CBjoJ)#Pl?A~@(8KeAgvDM93_-wT4cbS ze34SIob(SZW!_WA3l;=Ms_oc~rm4tNsZuFURMpqGk6Q4=&E6Ak7q9|s^M?_m`Lx-+ zPeo`$Xv|W{@8IWrTes}W*rS;bvbRy*iA`0w66>>#Cxcu_@Ue~4w0k}b!Qr#uapXa- zhD`pGXD*+t=xJ3xO4SOKlUGPtO07}-Tucp!|>FJ)JtED zC+v`GD95}LI&^c<@bF*WCKk5!(`mRwZ&dzX_DoPX?@w%WE$%tFV!E>eg`YG51{!BA zw0qTb_Rvu_u^VwP#S28C|4r)Sk#ez!a`zzNjlD_zS&E!huK6iZHg>ysuQIzN>4A4{ zySen{-`@6q1?}j(#e~96W2KWc?Y|mb=Yh;QUKr=%bWaGz-&2(K71Snc0D!6b2N8B&3BJl^GYdolN3M7ID@MAxN>jMIFft0#6i|ey6V=9xnH4DJ!@9w#1>2vyrl=m z3Y*bDw#c1>Y)TJIM*vf7Z66d}CuWV<>2S_o{>MK{bvH;qDe)l^Sig_ZV^I>GvCw5RgZ%7%T}f!kjjwi;q1)m^SV z)c?*vK~z_$_74QdbL`%lLTX>V4{s#88FkZDC8LKIWWTteESVbsJG!kQF-oRBH$yhM zC$+5XL?dKGO;ZXSXJ6yf3_+A9H0R4AhBkbW(<*R^jd0A5rMB=lHEDZ8`Ld>cKenc) zzqvgUcV|$+nrV<8Ej!p!eW@5_cTd25{8_a1^)p0s5V&;eF`#ADS>K8JS<=-fGETuf zQ$co3>p_Gl1{G~z9!WE=APq|O) zMAvO43vw~Up7$}hCB`)L)Z`{|`oW5sQzUxwQea0|Oo5y9t%) z{6$arwnJ(mKTRGR=xy!U5EqB9CMP12UBCb=N3q9r++#3y{KBjdG9^@_Ki!1PQRW&( z*sMlh1l&C79>Aj5=-wc6~-2X!)0cM$O^H)zpw$}@7?aVU@l-Z(nTurlaLTh8yfWjS zU#v6!bUmHdpGJHayWFgj;+Ljg>$oX?2>at?m&8ksp!VF4VkwhUb8H7$u7LIMt@2zJ zvs?VuV_3k@KhkC9ai)kSw>UdLT<>q`jcprjE}Jwk*gj>ljpw$b<}&N70=yl1 z`l^jliRYc~u*}7K+P;?0RLx&GFcQP?BAx!&MA+?Lh;`>+b}*Uoy`D@IFDV?KZ`#v! zquuZsYv?+mQSahWolhTTH?|W0%57t8%1|9Vx`&g&7_hcm>2XzLF z*}J~^M14OGf1xv5;{2U%&}4D=NYUUZjpA#JQKKJv+=`5<1CcTZJQg?e2YW7@iP~i0 zLDJ8D1(wqAt|ooE9=5Lb)_BvgOj(3HgRr*I5Wdqc)zXYjNb#4%{GJ=GsfMAPbf& z%HzS3A~@+b+4iZR;&Nk@Z~JGoi)WI*p^1%mu0$&0X#LmFYL*y_2(?`}$Fnmn3le&<-}$9ktH)1Qt_vDb z9G{D=GhCz?*Tttt|LJY`CRY3Qn7^hK01hgTS*dGu^Qbg3ULryLXZGvCBrihgqBfZ1 zqO2uU;c}MB@`dbA?m46Rzt(7dF2r<1_Mar#ffKW{s1Qn%#4p}r9Jx)^l-&eJFH zP6^O~AcZq?r_~R}&2m{Vvc5FOz>zort@vh_dE{}n+SS;z6~9M?`hkig3tx}^6fe*5 zF)0S-_hV1pR%y1YN*6@SFDr^e`zGYHy~v)u7G>6sI01ePLfd2e|od& zfUt}=8@5C>>d2`KF=~!X#Y}vS8`;2m!J}bv;bI_O;|={(=7ma#`Uwb>v&$ubuEExk zOp$0RBVNzAI;dgq7n=-;*WSxmf>B%{-#iSFN)A| zpMYR;ngP@?Pgg~2)kV~UgH)cH{SFIL8PSW2%LG+F0hb%ntHljReWmeUigjiywVWWfl_IQ1wV@kXtBY_$eLRN&8Cg~_a; zcg8?D5mcv!J(0Y1c2n76E3#&=@~rc~Vki@vZN1(KN1te>zxR{i9Zo+h`aS7)r z>>=6OUAs+f7*6$9i_$GR5sZ({4dyI^Y-)cu33oj95TP7O%8Ug3WBGRUt2HL%2Cl|z z)AW$#^=gqqqBr!JJsN+gkM(0?Q(a^FM+=xt6I>FvU3L!501ENdy;2#P-Qd20j#iKY zQGqA!r}ra8946igTCjkMjxE3Rd@RZ*dvJ}0f?y&zm{9`HYnjfE)ae%=p!H;8X=J<4 zJcXJlT0VHQtaPa5^5;fs{u%y?cSJL@+>!pIX*uI(SRXdbIt7*%WMMGom&%M(FPpV>Jp;|cIi(WlvKX~~+;g{=_-UVX}hrbtz zWCce@KwTf<<;Y^BqzSx7LTIPm80|CezY3-jLRGZ1Q#zeSp8Q?TOfupsbfN2Gwsn(r_I}UBBra`lP05v(bdX~#D(uF8@*X%iUPMjP+vb7v$cob*XFSXR6)88TJ3LZ>SF;rSk|6tWdq;`Y;J}?NpQH6dQZ-Ce z`Ke#)LrH|*M3LY0x1sx!nCkOdY=aJDsXN#f!~$8BH_#s5uCB3eo|GOxO!97K=CS1% zBs^=>Y8D#DkfxAyd|n7Kbhh)5@R)MMa122GqZMZwLzav*KsHyLR=wAX$Tv?=Eev!S zocc3)lA)d3S9ySL=_GWUfV-q2jWB5X%kfuZlC=L#6s{@biCsqCYN>o6>!iLGisyqs zS_qlW;^9L?Ijv3IFTYmutky8bmQhm|(27m>LDmMJ_XmVLv>bZmwIhRs3<68tr0EmgW?9qG z-^y@YX}fLgY}{Or^>&=!ilAz9T7M0TseTwJ3Q_a~g4M~0a2c-CGB6IM_ z0mW^Jf9lEI(SzbReSA$=lt;?9U3%IYoo0m;UpSv%m!{~wAL@+WD0H78`1Gp`kN@ux zm0>wHnYo-$Po-(fFB-?OZvz{%Oh@>52kP>%W>C8>?AAimktmLu*D@u7zo*1(R!6gn zj{Zs06|c2>mgY|YnD1Rd9EXnQe9&xoT^K!XcxkHnTq3~&`&nciAEA7}Ax&G| z5606ceQjDR&dUjpF?o6N8ZTydG(wfR6xe&`(FXMP2v7sLU--&k+E9}*JF)ANy+`E^ zciLO7ZTlx765go)KC2kCSmt@#-ONlovl7lxER(lUS!66(CBt@Io@Bi2*D`BkSy}Jp zrw{p~86gGMoY$iA3Xwt9mGjSNbfDha=ol|)>7Yr1Rm9Vpy4+(e2|v7)dpRq1xi5w- z(xHoVM%h#6E!NjXDrURxFx~GR6vwIK45xztV(Q(o5 z&=|;$YRFD!M5{K=wVFZw2>23kpH?Z90ZM(6r)*_`EoSS$9p4BVd;9zC|25fiXI1+D zO1=8u8rG(}*X>I14G{8~8S4ceqJ?IiMJDut_i0?VxuDD4luw()%X0H~R`MAB^#7X8 zyH$_YY3BjAb>8sL!|@JRcjWiLaC>ciNT$v%>o+xm`4p=($cBbw%yQKj6}xD=9Xn8U zQ8bgY8=@g#sN4L#;uRNP%`zYamNS(IGMPsAO0{Kb6~EU z#U~rM<*FE<)(qobjM5j~*OU53Nv{ZU{BldUd`x83$S6Xl`@e;fKK`AZGf|eS`Q@cg zkm!bA)8E>7@H@}Gui^M|tavW>rMxJaf^=kJ-$<8a)nD za-Eg@Uy8Nt(u?mBtbt5A+Y*qxa;mNTH_=$}Fv<7b6`bz<@b72%H8O===!rAhi*ajK ztD@qo?TPA%Ywtw%n^(SDWkp=r>s9!at-1gBq{TQHU@cesRQ|?VDnK;M zKrCZXGH^@jt@m8$U+_~nP;z;!yD)&ATRNrC+f-GzKioJ-rW{t00 z$A8VR*$U^j)BPiy;nlTRuX;1K&2h;_utQ8DdJ!n72XZY5(oBy=fY!Z+Q{R`6sK$Bm zkNnRh0H_=H;vrv!V4wm_-F`QpcHEz*as-_n9?@ip7ReVlanT%rhjN{WHq8+~I;blH z)ch#?|6%VfqvF`ww!tP4NRSYMH|`n;(gX?aZjD=TXe_uUBq2zEhT!hrxH}wzdyvK@ zc<|uC!c>xTp7)t=J?}T~%)ePPy;ea%ckilQwQKKNuIsv=3b>RvydHa(CmdNueBsdU zljCoRXP2v%ahm0wZoTfDvwmrm`$CgZqk@~}@oDAmDzTqgDW*iD^g~sw6j1h!Ylg1; zl_}WC`=&te{%p`UYi!}EzUz!ZngCd8eq&&K?lxkq)E5{Z)Y@GQVt>Dy3aLME=FdEmG|`qu%~;Lw|>Ac9xN*EslD z=k7ByW7SS}@+?a?vF$SJ>dvyfui?YXP`D%Bc{RaT!pUnMEYS^25l1#DJZ zR63wv^&GbSgXokg7e(xc9QtyCM1l~9u z*kmuUj((X(%U#$X7`|KMRbS)(3Br{H2C5g`k%+AGMP=Q-tWJF{xd>r=WE^AeQuOn1 zg6@aBXl1bs&1>eHq52VS)L}=8(F3$><3`}|D8Pf}2s+fW`sxFuDIhL~d@zS=cER6@Fua*>W*02g?z6@Y5w0|R8?bxA+9oJ{hT1QZ^PWVA}AXcfO__%H7 zq@DH1*-mnRZ38@YHOw9MqN}M-K2i5d7Q4i{YHI2rNt6h6`-U)Z?yTn6l4F{Dr-HnD zDuu_?7ezurajv^sI-8b5$|(fJKl{l5#**M~+dC&6F}5Nb@dBUMBCthCfuT=9*n_)K zWrL{y3%ARf7M&9alu7z~5{mRe^t==s$u5kIJML#$ZyiI4+u2M@k*bUn48?31P5RtX*;QIpkgW8#&* zPv(OIp~&)h>>z{JxnRN}5SZ_U!$YQCVNy7lyr~$S<-{cbQIw>WDZSjR6 zSDT~2Woc;MbVFOj`b*s_TVIaFD#ZR1X{Ktg-dheEJxrXYf=zszM?>*56=26)HSI%lcb z&$rM_g;*XhSNFEn*1AZ}rza}r=eXXP%f4A6ck)3-@r)&S zSN3};4IxcJPmR>>!>}X{sT!>1Q@&{c726Yk!L!7Mpo#%QwFBHgCnOXj8DC= zS{2D*-~Q&%!&i4dCLo1$&}or4{D`12$y9%^=kk^N*aVM}oI^r(>2@jnb6V(#uWF$v z>S<7z!)Ewalkjxf4*H*1xgD}kW|)K~(NGmvD4#JOphiAY&d=yAvy$q?4Erzmi78Gj zX-t+;nv~VV{EOwtBqH9!Ax&c8lA;YZumHIFst zRa9EKlNhB}Mam`95Lf;Sb23;Lce;9@N0#eVRt!^u(*W)}ow|E33T&t!+`+rGXRQIh zpMU=Z3eaALLilEJw;_{C6I*3qx_O0LRu2N}76h1#g}(G3Nq}3=8rhO+0FHu0Q^28} zv=5@m3qJj~)u?1e-8opmzbsp>u#jGYBDuBQ`nC-s)Y9utJzu7yEjQTOj&%G^<0np)Xsq;O|_QEWdW zQhv#mBOTsm>?g zj%RsH$Aa#+p`EbAE_d4#@N67M>hn|Nvsfll^*m1+4;S?wt|GeCE9zup@c>cr_IV%{3C3wwn zEOeMS&r}+c|8V?P%_*TKzg|0)+>XA*S`%*7>3nN~OyF2768W=K0#v(9JQ^KU>mY35 zt#A>~3h$!e3-GVZv3^`W|0I+*APrDK96{qDU^A9Bz+cRff~IWt;bUZig)_kn>$Tsx z)*F$m@`el_v8CqC1qjr`;LEozWcIB%MH-K2ZAWnh8w-FqPd6~*{rdDdPdQ#nD5bcju zP;&;RlhZ(721|XOaCLI`Av+3ZEcC@>_jx#yxEN`HwjrSB>r+@>y>t*k7}|xsNL?^k?jJ zInFy5eU8=c`Ix_MBz@bme9xWJ^-a0DbFZZGwnW}AZB5+6p-KN)9jVc%IUtGR*3dF1 z4jtER{4L%AFq)ru$XjFM`-~z|G7zCKL+T7!1fgkTSqUzdnhKhiiud5<3Sv(p&;GvJ z_E>q{n#Q0|PyCW`Cplj1nF95&PS;i+Ml;td!XY0+#OsnV?NGN*EZ*fBN9#A^ZaVWS z9(kBr$&&ieowk#Q?pF5i3{eO6dlQy)YhUCO{&QIpzXPn&Vtxr_j^c#Sulcp#rcv{l zaTU&30$xQRqOd<(EoQ|JeGoR{QDo#mj7iPjijB}Xq!{c|Po1u5lp>BtH#=_U`F z>8wR&h-0t0O8>?oFpJAIO-^WPLUYJ9PNn9N zWb&p8*slhrA)S4%Ji^Px!^R&drxxUc-RE=DZib^$h6+saw)~F^?5qSur|PQNeOC*s zI*Tja{i&r2F_)OMtzK}{+GxT{$nF>Tl8JCClM7}+SnyrBYnfUd8kG)_E28$QlpTR1_DP%koiN$9UzY+0=e68Lg~Ok~1Bn1(JG6Og zqNQx4^LX=2rc4Z?P#E)wP94eSFi$B`f&Afg{s2-64!|R*dO&Jq8ST8)BwMIu7maVT zP3;n|H138-=D+%tH&CFP1eS(ywSq#K^Baw-)z2$xnqjaKpAX4cAqfC^_`OSRDb!r@ zsh!i0w4`G}?gstRuj#6k`^G7ZgPq4ghhAr>2z7}BH+36MW7kZay;*1uh7iqom%h~8 zvx3j}Y~7{vicL>XUb2Z?#R(bl_%ga~z8?_ z>ct$v$#YOT_c;U*=WpDSgDa*M=*Pnh4R_7;vw#GrB&j3{(k2H2rBkzUKqlh3Qa>9v z-Wf|cnZE33fC!=H72V9>`kdq+ae$jT%=srKWkxIXy_= zfi|9q_D?{nt!S0wPR@59_O{wHMF4hR+52Pngf$I7L6fap9CEys5KZXGKRF4`ig+%O z{hUx?-dlFIT-NBSRdzeLOQ3TbAceFg+y&Vo?zEOg5bE>TMVU?`^nJq_+z0L5d(@VG z?%YB=mA9O`d@r5zs8l< z%Yss^9IlV=mdM!G9Cdvdhsw}~I-6G={=zn7%bPF4DuFo~#TOBhliOSbAUJL9uv}JW z=y%g$#xdUW*3Wz`yVY%jg?p+HGA>LZ_hK41Ewa~+Y9BwMC~^NM($rzFu&J5^xIR4n znviI#E@_KmC@R2Jrm(q?v_yl+#9l7<$cIqtojJ(Z<@jI?(E ztH$)X|3JeXP^t7cDz%DLtKfmV4;%kfLTkE!L}{YMak2|syctnOZ|9l99C288Dmw5Bj? zQ1{>TwSi?Obf;eTHJ~jG?|9%^)`h%=V7Kxr^e>1*Txv6)iw=H|vg7!Zo&eI&mn_C# ztR}fqL@nn9!{)_97mmVal0Ghi7Y^F>$9X?h{B=QWV&~*xdArd{JGW42&lTavli(~Hs)o8 zue^F*)d~!bVccpPFcceVZan#VKEDRu|G}j-9Oq{DxQKoYy_Q#uHXv9awSKzqlj>rT z2br`r<7Eoc=_ym>(#PYc~Gr_J|QR@KsTsaQT<+09;S{)1|FTV@` z;)VC2Ihg*ePhMBWqI-TJh;w*m=V9dbehh#=>0Rl1J#v2`oHM{=)E$N#;#p2r4W(mR zM>|a3a>Vx}TvW-X-Q~zD*?Y_N`Lmy}l0LJJ_3fgswh;L@OCQzY#=uAKu%2yF%S#5W z8^xn5_kgJgil5L?J*gi+K=tK5{cE|b({h{?km=f=6xSSLk*XTUG<(Iiiq9Va(QQn1 z>rSm)Z{Sns{M@YjrGR^|dkn))AWf>9@*290V*Vk}+c&Y8@%faEBByucp09p#xV!x) z$*;Lh^5*cWA9RORGySrKaQ8=>vkQN(REeLwWuFo{l5rkXFi6|?OXpI)h8~ER?U5?l zUT2PBFy22Dp^aZ|a-tyIcAXUo7ycMJh}fC0M|O2Kp{~KW&BENn1~=`dX6&lT?=e~S z7WJ@G$zQj~I7}MORtx;r!vO3OeD1@g@=T{lD&aTz&cRO?Pe0U@$B@%8#>#4`G;v#b z_7m2mHNFDEMGhZ1yJ1D2gk6o_uE|61=N}+nuzoI-Gp0Nz@5_*~Lh-`- z!UHL%Jyi#0WUp%(y==$)RcY=lQIEe=i5kTZX&? z&?2-qP{^QJ5ql*e+7Ir}Pt_oS2;9`i8YhrO&PqY@cCCSp=^7?zaaq zEn$xMRZUSs#FgREfY70z=JxXCZq?>rl!Ur})Y5Wlwbp)Syr@3IS=(7>Yil|^W|4AX zLXwc{O&PTD_Ul1Hb@?|7!T7PRc=*LYnFocR{anKU(I(3gp)UC18Qbrqlqg{5BDfVF z%@B@}HX~**d9`^3S94N{_vAZ+yNNqJuO|b-^XgB>#5Xdxo~|?#A(>5L%lZ2>gKy!Q zU!iNig6?QbF|Vusgw!?Nq5$D*AuNNDJJVZwI}>Jtr0m)$C8>5^8&(DtF0p~9i}q(0 zuoE;`K{k)&=k&3mSexwH%!NRulUz2ospVE{_tQCkWrOW4ebw(}2wA!1<`75jGLLsK zKedu36-cJwIs!Z#S$Q+&9{#rBhNL!p+?w8&%vbdus0Ix5D$oiQ^ju9r$~N zp74{TQT3~`P%XMNGHFKySKUC&Jzsj?542HhTr{d*?Ds#$s87e;C?gyE-ATv`LV~ zh{mjldV7M>FQMC2Zew;}oY?Tw$>$|Pvq39!4%gTezj9s{t!7Uk0dj-4X`wd9C;vU^M zQMH-8X-iXOfZr4g&`*i0& z?awfFEGNAfe;22*isUrO=o80R%w)1dlLaRg?A`}418Ka6gDo<6iulry9orAAvU0aN z?#M#Jb=RCstsJB9WP#XXu=0MlNkT;lvO*5CTxR@B`Li@4-XpkbK8YFwGO_4eEEiND zW)ejQ!nI{80~y~OGl%ID!5M>K*zJz%MW{mCk7a^z>y~jp#2f!S z2tiBA6))lxKVz!ma}{WNPA&yyEb9^Cw5JiwGeDC)Q!+E|(BK4#2>^aa#mUG9r~IY+ z_tsKB^=5>O;s^bH!%1<7RhA(#ky6AeY^V$jk(VXLD}s|=CPAXgxAp7|Ago=B_m>713Z}e$$$l~8;pDIY{`sxhMN~*(~v{s%coKny) z7Sr<)W*I8PKZwY9$`xW$OuXU@5@QAK?Pj?TDc!32)sDec;!z&(j1gv+d-9~NW`dQ$ zFLB%vu*rBSdRP3$U8SFxk2J5=qoT4sgbU@+QCqgw*gP3%xB(Hi0QvLmYHMztM+>Bi z{vp~Ei-~RN@($bpVKPC)2okN_gDkt$%8~p406U|X`2nhLL2CqJ4BATTi`HAwk!38U z2m)!?{_;!|KP1m}N~ewEkM=8uLC7?l;>wSt9-RM*xf%n|rywnOWnl7b{4Vt8dw)d@ z%AGQfCDwa1aB>V1ED%5HdYkETT+dkUWOlXH6VLEKPv7ga4*{7LtK;1`(>CB@li6>< z^G1COpgw=tV0qFh2Og}hKXHyh-5vRM=L^7*5SB11gVnso%Ps0Tec;ZA{H8qF2kyvv zv9|GQ0zd9e2MXx7O=kBuBUqR6WgZvQ{0f%n0uWY)q5$O|-#989(q3@bCdiZ&kK6+= zO7F9Q{`!T@nM-PiQDe9l#!_>HKctAB|5KHbK|~Rw5%BNbVm_!ovhjh8j8_1N0)}vB{#H;c6xx z6H(t`?P8|J#g@gC%wuvx7t~VRzti9fK*1Z|ypJu6v)29O2s~bZ+W(u!Kte;o@sctq zpZqZ~)+285?Nx;_9_#&N?5{zrPNR%S8)&1e5AydLKx0L^rD|%=vkr%w+-ZP zdqG_y`oYr6aiG!*CUrbs)K_NMla6N3JD8E&HvMM_9M7I<`Hd`-@WHAnMgwg?8n^%D zl>W#=59GJaY;0w*S*1q>mJDO#!miqrKkUP#=n^4 zK?D#ljxd5BB}6_@81J_hJk^7)@xsW}MOL+*4pQPMo0T8EtMt?Ep7e$vo&C6Pk-ho<+4;fCP;0ZSbBmInG`Y&%^dq^_H*dJv-;PMOPxIqruY zmN+6d3jbVC+7no!MMrRf`}q=ukq*?nMD(*|W5+9k956%H8hpLgMW;$7iFr_;to2)I z{mhWZoHrA;JX7#;lK_nt7d9Inq1!6AHB_dAc@*)SKM)c% zI5&cI0HEMKNuHbr%GfF5IXuV5^^8KOF9qeR8tjBk;+92-y(m!51 zATk)RXop-w)=tE)?;g*ldFXFrGmOv>ZtBn4zKo+{+}x;;@9J&w;e{6W_gL)s?#mLY z#83R0DTYhI7kBGPrA{O|OeROjyaZKKr{mKvZTGP}A6`m%6w1J-pzuj~TpT0}$5P4s zH@X8-@Jk`EVpiBLz(v8zkD%4tQDe?lk!HNPj;G;?Q0z%s^bkf9Jq3WhqD|PZG(l$Z|G6U$wUtrQXF2b{rqBpxH_Xdgyfc=9U6fmeomFPMvJEQ|6e_*JgPFGc3~B5ISjcjMym9@t@N89&vZ7zbAn_sc@M;r9dT&eOa;?hr1N&P4^uSjNqTHqgLrkg+ZIin+j~RI3$Cnr;$H#rWVnY0 z+)8e+xeBOvZv9a$2KrPY?L{tIs9FK3ZL@CJgId}M`N6dJ(LqOX(uI2c2PNP*d+P;B z>u8e?a|h&ruNxfz7=&@|w!PmOr3wLnZNCj2(nbqg`pr>r4K0l^{--`=@r`(INI2hy ziH}?XAm57NV%*54SL*;~QC#w}V)EvCU7}vc6rwJO=FoY11tV!q{@|N5f4$$MQv(i~ zs# zKIMFYBm(Gbq~YFIWuwD+T(;cZE2OuA_?Zw3%x{c$%hltC;I z!4{Da(b19cRrDoKWmWV0w~wAQVGUXZ;u*Vqu@(3IL|thvDK;f8OEHBd$Q*?|C5|O{ zNj-&@_0plFxdInGKzl?c=LUr_;nOF({43crU#&weowL0?w?jYCg0xx0j!t=TLHpSW z3W)u+8hp0%#Jh>i4dlI|F$z zS>wpwc5;dwSrqmc!NuU_ULkink0L~6w9R-&-b73xc+|m=3)fS7yQqw_+&(!CV_6&m z;5V|s!K3$zdq}0|2V2UB@w~)BOdoEAo*{(mu7;-02jGh_S}&qUe^8z9JvmLGEbP(n zO)?l}iz({adHmzOKHa!E5-!l(XiE8_gqBZhdspvp^+|0|j&zi*Gpy%iHT7H-S49Y^ zD{sJ|%7)ZUZT^{grE~Pc(cYoG#ko}-ekQ5^Rpo8D*7n6mR)?uQk{jD)911={&!@Uit3XZY*@WmREY4GBwF)7H>#khs#(9hQ#F2c=GkW zIrKHX5vrgun@`kP=vKk!0MpkQ&$U8%OEWFHCA6Whh-+H*noNx5ZZo|*;^0X#4$s7? zaXs4m9BNCO+Fo0lx2*;zk&vswU7_&KJWqr==GDE*2glz6U?se2MKuku+zu~=P|u1L zg!A>_+2Y{ybf<>Dc7@K!o%QsO#xcVXCRP@G6B^PytdJxYm&&+=czp;_d^`J3gYE^^ zK+w|crGIE?!omKJ5Jml?`PPhr>y|~x8hpfl_wQrkE60f*@GhW z31@Y(xmuHV8E4C1o5WT(8!zMa2dSqxu;*xK(lJcEDAMb5)VDHrG1C8@xC~NVJuItuWdB8vd8uYJ3{nU z4L-W$4a?x?7L@Lh@LK2&Hk5YwBo~)Y6pK;7M|CiB-g4TgvnL>ut!IV%eB*ni*vg7K z;;5}ryH%*TaMdIcH)&YHa*$+Wn6S8`TWvgwJ!sbCPOR2Pe$FX2gm3g44oX90y8V;5 zj08sQ*g=CJC-{uO8(}b{Y>L3zu{AZ5oP{rZ-adzT9LCBx^+G_Kz2&PBFVkUPv!haE=`}BEXcx*IM?g)L~Wh~13(vx*_Cnbopl6Xgvp`4be z;Fw4EfloHLxGbtjOJ^25YgiiKp0^`klU>-qb{_0M>BN5Bb-SY)GeXG1I&)~)SH#5? zKD0t9s_7@7W|;tD4n*qsT|gXn<>j`n3=jwykYm%&JH}5 z);x}{Ua=6HY(rtvI8JW79-hBg@@vudXdNIn>?y_F>J1*IEs`m9{VFQp_+W0gZIVh^ z->1~i)F>xCszxz84|YSD&L+#E<{Frh7Rz2hub_Ui6yniXC~Ri`q#H^61KOa!jE$V> z9(~F64Gt?YzOf!yq~{WbwuRm-KI>-lI~kPSta4bfRZ$xrV{N)G|IC9&mq-qB zr7H1MJbv;GGLbX9m|)1rRZEpKB${EPsTAQ{lulPxMiVMJ_lk^*$zT;%gXpBC26eq= zdUtc&Y(QqHs8wUiDMt|-0$4vy$!5(ethCdfyl|NP1&=PaPcHb@omfSpKj*9ED$Z2h z#eQ8R@p-~l235QBye>+UM1Dm8Da=8vY|KK@-U%L1*yD0E6*n9#bUh4p$pYgH5AFbE zIT@Z})te+{#kcZy>zdm$dS)Chu1pN*A-M9GjVbPeC$9tDEIpF4mQ-KG5~cJ0SjxzX zhq3DCdAp>(G<7tV?_CDqBboeP5ME4Wj(d9<;nNb$-$I6LaL5aL#E_6ajUI#y!8 zE`4j2eHi)CA)_T*UsN$aN^MS zkqV^wr9Ar=@#u|a5VAQ3#Tf~U+%5zYA(oye#}?z3X+X@>x&Lp{_Cr zPr$oZanGA&A&f$Qra`k6OW)Wrx1NEToPDVIOe(DXqCTBMBD$NlsOM`eN*${Dwzo~Q z!JIFv-(iT`A|E8jF$d3X-RV%yXu8k9`;5bR^lj=maq|1;N_DVFLuDCZT+`=DOrimS zAm>7ihaMI0I=I>{dJ7I0gJ9(M*6nro*D2akMrR;`(!`->lV_(@+W6)32rKMu4PsKy zgn-7E`|D}(l`?Y_xT+R;y$T;$8XIC;#!O4pU)2_XYp+y_z*?g7F->oTCn;(A?jxK@ z9yD9b)e)k8VLKPm_dV+uTV@Xfs!4u{zZ!YyueEG%BkXO*c-oJYU9*SJ>R!p*!RG_B-1D_&3y>{a4iFf4kc&4uNs4nmNORBf%a{R;2g>v0|EQ zt=5~LFC}YUh3W@82R#bz4DE~CDAof?!mTeI(BWF4|AH3A2dcqaeZ(n!^Zj#1S9<`& zjnzC6uB@^3RBD3wn=01q?)8waJ9$DLVp5eyOjiW5 z=GIq|{&t7s8xb-@=8I*N^G5ZD&)$T>DiQXz5wdebgnY}@r@2ac5ClW}g2KbWvYEdS z(g9Kvf-<{|E9m#>0$h+lRJbf!iowI^tXnHhcw5yvsx z=z^O2wi>GYhUS>zN*ELxz|yq?AMu413z#d4%O%0wX-CU70#Et)%zrxw+_Ffy9DIQt zc{ZnzKtGF>#4v}_Hhau2S!OEl{=*j=bZn*Xwk65@ka8wval-BX$fCA6Sq)+#oo3CO z1XYEBWz8(HoY7u%PCHKd^JR#RK}!Ktob8iPE~RGb!m!=u!E>i&-;<-c_PdsKnXL11 zJG>D({3nB1HuW;jB~wH3H5e>MC8?Vqj;V=U3nrVlO| zBnKDgX2O3vID@HLInS_&qLep=przw8zPEkQ95cym*if<4X-=lq!e>sW;|PCII4pMW z;?O)Eru0g#_RZ11mO~m^fBweX6j-Zy1kBL;bh(zv$?y$L;HR{57{P7kqWEwSijgg)##O`Oje?vIE&-4l^%O)z-L-_+9Tw>xQ^pL-E1f8 znM4&WW&PAPgLo+WyfdziEMH3=P{liB;X^~HFXF@)FH0f6$r~$UV!7}*-1R0F;O=ww zzAfiXq0e1>HhcexcUN!W0LzHgiId~g0b4bExfsW0(^DUoW>b1umN#DxsH;C*!FCp( zeQy2sHCxWT%bKZBBKV*2GF}kl8Eb2DT&cHdiSO_8Dj7Syu~TZ@q1qW~Gd_Cu$>Bk; zzl87cF4^_B$S-oc?A?cY@2>iVs!*bD^M`#e?`x}+DOXXY*lxV4sL*_>#IKsB_DC^Z zyL>OkbMAmT_?q=(J#7kjv{hZzPwTWz_(mi21JC)a@Sj`r3DX#P^*ww^iI#m=LUKYM1*rC@uidG=?QTL6>$ce9)t-29l_{D1%VIVShtN9E?j zm>*lIv=_2Xm@XE>2($S5YACptY*51w1g;Por zDrITzWMRpvWa()A>)YHs+}t7}e_yD(nY#nfBXQtrS%Ls$J_v+zHxH5oJ;KDo!Fu=z z2OH-x?jt-RdSW610wQ*58ZbRC$8$a&4sLEiaZMRPVHFW>ZaFh~6>VK3V;68p#gipjuOw6h$#4V)vfBSX!7YOeG3dtiwR1{j!Jv74;q(>izp@0EZ0aHSj(N4e$OF8ZL2k ze089NkTU`IyQr)ObP|;vgc@Vt>3Pgt-ao`7A|@dPGcYnSv#|0)_@46%2ueyx%gD;f zD`-Nsv~_g#^vx|St*mWqVXkiO9-dy_J^>#BgMvdohDOK4#>FQjCM9R* zs%vWN>KhuHK6iF?_w@Gl4~$PtBB!QjX6IH`*VZ>Sx4v!f937vWo}FL(xV-w+FBA~! zpKbv^|6{-KfPURWLqkQw_|-3zd!D~Kj)!)ih70|PxH^WZGd?Z%y9WdkQCXE859xR` zz7v|cjA0Vd^R6%){p#B9p8d}{_Wu7-&;Hf1|LWHq2pbgzxOu2}AW_h1GIRD@%>R#U zJZI&X7^0I}VN^d(!fxlvOa1!Guym%8T!DAS83;xsx=sjL&r+FWSx&@ChDl009KwsYUwX&6d|CyhhpF*B_^W(A* zRXa4V5Eh>dLvN0yhNQM}jwQVhD^slnIcdpGIz+Ga*4&7lmKNXCrVMvzP$9%LF)XliQT#s5aYJ_&zAF0H+GDom|(mh4f?xPM5 z=mtF{jPhL-=Kk!&y84yv3MJWq3U52%B*ftWRn7;s8)T<0ZE5l&KzU;Q_`vaAedgv{ zh)qc|j=##J#qoXt_EK=@aRFs(lGCHCEc_Cv?BA@-9KUDxGCP!2hCp2!^q)3DIPT2{gIxnicm_wV>%!Eh z9jPWVUUg|JU7)j||8>){o0sE!X=ANrX&M0=_Pzs!9@OG+c0D$FNVVrp_I6v0DDo|> ztVdmI^y6M3S%tn2UXh(o44-K?)?vI~I5PT~P-L*99R_K6_m2Ep)4jOaSDDYc!L*`` zYgdfm=K1P_+GeB9jifhMS2_%4U0%no>8{#usOBptIS!%}{<@skDtYGT%fCJ90|Lff z!K|@CFJqQy0)aLEsQy6H5j-$3+~Z0i$%2Ztj33dC7j_w6I3&d`<7`9}mSf9iidHF( zPmy^bQiJlB*ZXU&md3j1p9_-lWO5{{P0K|1cc2FrhG$s1B7(@A4DI^bkaaqgZbz^B zNOZ|leNgR6QMd>pZu-Y=7ZD01@3n*D&X$JR2+1D*2wVC08VM(?5^oF_w=&JnsF{vc zvJ_>7`&J&8o{yMOiyDuDf?XYtkW zQHqc5F*G3UY5kkJtePFTmxK%+n1z6{>^}Yo;GW-!f6~6F!DCdG;7+)dK`{1=Rr@W! zKiTIx!S2!pD)xvq{zHSN{j~I)JOkyz(G8im2&qA^_N3VCuSLIXVGlF z%t;}^Z$H1~Sn%ppnK(VIABPT7UuroU_J%l}+4Yy^wbwmN$Jcgd#fhMqEmxV%XG? zLT|tJWgrx3uPJk6PpA9|F|f>CYIxLIALVZC&g+}gx7-bKoc+-(SyLN9k`@Pb!!oQ7 zb$=~#s9x7NA(?c6(}lV3Hq0a4UK#3DO3T_gUIp>JWm23ptFD%MF@;Up z6sw_=khEBfuyVM?+Hs+f|Fp>FKh9buHg}+P`epsu63a_>x&u2ocUmKyWEK{?|8|PR zhO7RR;LFgT226!NJEcrjv_cjCyJ_{G>Gl8r{bvRHf75lq{(BuW>;3s+^$z4wylZm& z$iJ|dNc3on_`0@W<}&I$3|O}Q^J?^KIgTj;Y}y6)0^+N@D{ZTSI}nxnR4jWb$(-vu zeZ>{2r?U(M>U#12Y2{N#)_gk?VtTK#7J70mcQ%T(gG>GxGFmybQS;>mY8OS8c z3^uAEVXVeC5l#a|J>1!KM;%_!9f)kZ?$xe#x}mt==jYecTIbBC!w=WT_m6}MNDk~W zjt*~vN<^}oj1)Blb%I;YNMEL^q4T|4IjoUpIBzDgC1b+&(f0f(8~n9yu|QDPmGmcO zq;l2tjV$aWWrBdShevall6c}Y1D8kjWZ}Z^j2ERSkK}9=vn8QulR)$Ro4CNQ4y-)~ zn_ovCxI}nt)jIr;{VDzMXu`I411du0U*2*D^7?Y`NA{KPu>Moy)80qnzD8yzw6Xxm~n_wfy5G<#s}h z()nxoCHO!jzg4iMx5MNZvhZ5j#~ozq)qXn|a%=fT_8L#!H@?x~Y!*oXn3R-oi>~FXn(7sfJ3jDQ3Azl*V`Jn`dj_#Z6}Co06ul>CA!#)MNsM{dM8*L`;NF#ka^4KBZvm@pR4BA)Kxc z<6tVda{~^s>khuv9bske@$=`Ldi(rF{ys82g)krf=u0mKMIiTJXOm?_Vl`|mEB1J= zClYK|y&XT+Y1dUnj;i+51M()5Sl*F8Nl>D)bfvg#;nGc_y$(Q>*b96{}-C>Aws3(XK3?G+& zUDiW7;$=P_Bh?}(8le0aslA1^agts6kLV@&?(HB9{vMlqPER<4vudBd+@_echR0QB z!(11=RP_28r43Q_1nUD!c!7bo;CCUqJgTYRh9Vu)xle|jWp6(BmdlUkQ366FQ&;}g`RVbZZOrSWD?r3|(t5gu(;IvGIgYcv&xsg? ze+UF)tVXz_UICp)_YKh(e2u_b9CfK4V<`T3(&~IC!plP_mrN^Ip(yK{4{{`dpl&W9 z0gs%+NA3PH!8f+Np5&nT7m=I^ptG`sPM?JH^caG!n_C>0i*({ChC25aWV`E)9%Rf* zM>$eyLP}kU(c};lwD{jx+^9^NfVG~ut3Y+8cv`Zk`BTKal-VE2IbM_SImDn!fjPUH z9q?~K|7nvPuX4-yaocn&>l9 zdATURT2qj1|M8UXzx6#3({+3oUlPmA9~DfMjERwR-cVm?pUBy}6TN2?z{z$=KY)j2f2lSH z=pe=2SjfBs=@~H)pmg?r-Ip@8M3Syj=rEQ_e=U4D`La1kxs=MpXSXo(k!P0(X{2G} zdwGk`-N@H=eEt|qA0Jdt>XZ0VGllL0E`q=K_ep&{?tvxuj-Ac&T|p&qZC21ro|!9c zI04FM>93_SC{+~d@h@%{lGB~;bqhCrWE}dsHB>ep3hK|03fh%ZWcm3z>@9Kx7kx+F z@+DG_j>_G|t86nAv~eo>urz#Mc&{CnQca0$_Ai*bThMpQJ(bU+ z8a8H3AJC5U1*rnfC$^pwyS&bKy^(2xF{21-jQuy>XAnJ5S; zbg!&zc9OOCdfxK9MQ?WiRRJ7Rz@x8yeXqay-gSP=eSdxbY3oA&&CBr(^mM*KqV^g1 z&^!KBTa~;ewi#LghMNFG;kynLqT^6la4D|SR_Wf*9p^{0qgghW+%icXM?XvE_7x|= zTy2%Vi)L>CJfacb!_Na2-lI=fdl%&1@$y>DVrwg~Vo->Lv4GC4`k{XOU$@xNy<)SoW(jC-OX1bVO-6kg! zw8-rgLqiV-^?3R-!%^~pu1B)`;)xeXDyp5~=mUgGX)?vRItH@U8QN@f#Vg5zMp*Ld z;92__41M8*k>+tFlO;pU0l`qN$5$-zdcgPRB)Z!woX}^cEuOyMBJC8Q?Eb>U)R!=h+s~`B5N(pYnlYpTpa|XYOv}W zua4Z}8HuxxHdD~XQ>(o*1$w1wnWK+r%|_`ty28+t zQR&9Y%D9h7-_-kHt3Ea07i68>>eK>$L0wfVtqNt)U5UdLIww-5j^P=O=(b!x)tKS8 z-^);-?l@zVI;;-lSzPIu>5RB9gL^(Pr8y?b74vcXP`X*dL}utqe5 zxLftWiTRCcf1RsNr2FgVyhaK?G+(Mwm&{pNG^p{J?e834#)KT7JDG$`ro7Nm#CxfZ zpDDelqPW#^jDt<&gH^B7gqN4TpDtS6X0jgPgiIahTK*T`;x}I-L1ebTQPw%A=r(Bb z=!90osG%7N-iVo@=c^URMOQ`N^v^Z*LU$3i(L63eIW2#fON6MX}Ts&9F z!Hl$CzTV44u+N+k0rm6S!>vsCx6a#&C%+XS>MzI@A)FZjZs9hFMufJu_j3HbcgJ1_ zkIF93=)J#e@;uCafFr)GFu(iOYaeTJ&C+d9I09y?TaW#2Ej>qhudn&T<@4X? zw%O}m{*n2A-{lj8;yIJa4UivZHw#{*u{@-(DMq~~3A7(B4m^D)Tvi@c=qTS}Eo6$w zu!RGb6W0X;*Jk}GJz>m9hND#q;?f^Bz5YtF*!;m6E4@$P>ebZ;du818@GbP$#eRu3@^q>%+>uOux@Cn-KJuRBU(p$x#6?CtN6 zwFJN%A#-#jAXpn_25_A@UfNe90Z&*7d`>%JP47q_!}9OA(EbI8wS9`VL9AmNi1)iR zlj>T;*`AoM+Lle7P99(upRexArdDzjc?RfAYD`}A`XbP(FF>u<> zm9bMP`(Vb{Y)O$p$`jFIuIz`~powCCTq{YzflTU*eKb;74`11Xjalv8uLLFvaav0p zW$ev%x_VSqQ$)+cla2OLwhr+LZ{$3K}FPT@TCCVgx5;Mx_-}GXOtNYLdj|kQykms=Jfa2Y^ z$SXI4?urn2})Fw$8$h9q`VDXXHTt2h-}H_!euuZ zEeXY7Ca1SSX~jo-3wdW!Z{JK^5Rs(eQx1W!=GZejX`I2ZT=lp3?kXpMJ{s73?49{qcu21&SqV>r>uu4TM>CgqRcs;jrwxwS|vD5?@A7y>s-sTWTQNNOv zEi&??_jQ?Ie=!&RB{G4=w2an}hCFqkp>Tk~=gP@$)@9aCvE}hJV#~(#wN{(u}LKP{^VM0M2DV&2(|e|A2taa~3sczWc$ej?z+Yn_0oJOYa3)+EU(g9>CSSY1l^V*{WUe7L5|;}xc;G$0|5Vjg05-@-nT(~sg%!AT(g%~ zM6CdA@2h*$_GC#vs2!P1lHdJ`^)q3Tn&yDqnA4S4y+z0@4Xaq{CNm~%^+vMslw!%M zHNNbO4^5sjV28b6$aPtj8JTVx>HKVTx)H4SEdE~kvP}evcVO=F(`1+^+o}&#vYvUt z-dvWR3@q*@hcYh?A0D|urw)5C$xQRsG*ox_S`+R#wf4DQ{-FulY4zMxH!$X6SWTG4 zt3+VhbP^Cbx}_N*&~Dhu$=FlnlyMByS|S}NU2_F>(nb}z%n_Ksi*8ElQCWC^#!KQS z)c1L*qf`l7zY`Mis}KnV2naYa_)VoeHE5EX{jmuB8E(Fptt!qT@MU zAzmp+XHY`E@bKgF_$3k)d!{{0znQ9B+6-=qcB3<@J=wV8NmU{ApyXh=P1e98d(1jCIinfXGOo-26^{yVga%D>bPnkykt>2c2ct#uOe!RN0*9?nW3q%Q(n=#SV{kd`ycU#*BJP&4VGT5-l`vUV@toMsN3d>EjRWb<{7O!RTaWI&3yGJJ zW_+X#-Z1Yw1U-=G(ZKK6kiG*gam%s^A8V34Um#gDiW!ObZD?|(k8PRFW=38q(n#Xx zzyw_+uF!$0ZG%Q0>1Tn9`VAaMsA-VlvPrJenO37p=8WiU!TX7>Tp!z`nWHUu&kEv8 z#x^kbs2_b`K%5Be<*XVc&`^Uw-s~C+oHnn^I!e-2c0$!6wzwrV@DlN9JKBmoJ{oSG zwDXv7lkA@S+vDM1#Lt=i%(WGU)ilP8cm3W2_AhH)@HJLe``)*QH_N{^Fs3PQH-e74 z@*C5ZqMwHX&@gi+3h-ZSrky!$Q6T)_1l^9k(;G*m>ianEt3c$k20S<}yF&4MMx`z1 zja1=DPD0w^dsT}>YQ;%5eWuVN$b~#T>VzvLEpL1^<&=z?5p5|+66HbB^m2+m?Nn-s z>|+v!hj}azK5Z8pgB_k3W-xmS!(wK{mJXrfxp1<4m(5I<`opAFq(qPE3#+vZGgeug z>qW!IB2s5`s+Sru&D74hFW=xE*5g;e>n6}hoca6Q;?>qM8uF0YRQ`v1` zC+0{WFEvwD$Nn{h*-sScARR=6~b-zfVD30EA(f1g&UdRgoylN9lSgiM=!k-gIb*COA=G zf_7+@kVh7AYjKuO^Lipbi{mpc|Er}eP6m`H+g6oCe{R9}`c2sDg|#+Pds(T18>prHyiUv?7qL=~#4pmO;$-3L!=32c=dZvs`w?QsGns&ysVQ)gM zR!EhAKQG({Eln@O?ZKNkN!#h2cS3@;TG!Q@nO|DFp9L2u;bD)%zFr0e`|?g6ybR1O zmfFqBH!8Q%4nRmj+cwDN4G<`HfClyDO;PmMZ%{C6z74W!*#=3(ht1FfUm;Svs&yR9 zEgE+5%Lf2m2U%`BkGu!eyc_G=VCe3Z+`sdizu@0mmCq$AxdE zHuUt-l^|g?$i<8QRUW?=3kS{45S%x)^~n<{KID2s|EaB_G1bvEWhH^PHn-R9G?yD6 zO4#T;q2BO+E)RI0{xja#9U=U-Gv!o+zyym(re={W;p?t)3hv~s!RvXFIW-H*Cb7?4-h&{vHq%t#A(TwCmZ-~jF7 zLg-ygxEMVRbg+|;jVXbVN;78AoBe|TyHtIUvyIKJ?7Jb+O8 zZU7(vZGYc<+9`@6?a>V$pFiuq#}+OV9EvZ@biUOSITBPP zmsuO$Y=^vnMVUPCF;^%KiBb)q@zTi5TqSNx)Q#UuRr?WPwYSvXYt8+CHk6=}6AMbr6Gu2LIjjQMFeAhkrODtc_#2ih}T|L!1vaIXP4%&`iZnf-ja{Ad;2Yc!Zf@4 zYszmY;&eGfH*krFdwUskW|M&8x$1yLAsRayHZ+OfcebwuKCaK-YF$oq(L2C&k$L&V z8={%3NY19DE9=4G&ow60P@R2wwXYW`uxMp-9XgYPtJ!0-D*UEt;!#H)5nf!)zIJ>3 zVpf6me4~`~VVsswM#~L%IWD-3TTl;T=7yb`?%>J_Ti}UxIj=+!UE(7TPzo=@;uwUr zJZ3+~&Q_{~dv_F>=JHaj{Rs!zpHWA+I0>xM&VXLCYFRtX4C3aL*;i<$p=mi?oodw` zz}5$p>A#HKfV*`NT#9aWaYt@u=_gDbsprb;iYEw}FaK9gI%Ng7vMjZ9bL zF1e2Myfj35cP7}2p1*3a?%$6FfnI!4Z*%rOfm}TdIskf+6Jmy!vd0(Y=`p<6+9ZD8 zsxo+J+9uTak3F(E>lS zxWh+vnv!Y*M{KVxs4%|be9=)9%@=p_(TBGMy{SvNGd_!PoWm*>jLkPf;(5;UYJjKA zxU?T^^sMR0+898&6wWqNcV531Eta7f{5>f9%jS^%RztX^{W>t&KA)-kQhxEuh>2rd zJg2b=fgc$6g+U!6Je}Vy(Pa(86h^15l)U#zT=2DtiVx0bdM2yOj6DN2fLX3L8zQI! zu2BR2Woum; zy!_T;m-)}8G5VHWm!rnpjd=;7-unjdaAu;apYLW(~NVQMgI1-8qB96=QxGeBl}3Bm#?4hWZeeE_}gEJU1?c0Kj7a!lQbtw zF0)}kx7FQiwMyq*R~OAP`%L7td2t;7yfVV%S>;v8OJS#mQfI09W}1+M#?3?lyP zIwD+$K;~@@#%j`E-#y*|Kb%agrslZ-zojnH!Gn?J>Ol;5Xu*pC4XH)zDU)mm{O$GB z=oQkGJ{tK+?X3in<2HdwQ5H#T(|qPut$NB?#XhBz{O$*mAB>+`ta@(_|QRuSZxA0u()P7rq7+t4iaqE0PYYSTnH@$oy+ zSc~)Re2gOii56`tdG-XpU<^gVB~~n@d66lNYOC=@W~LRg@+TsPI08>CsS_~1#@UOeSb)bLM(9~|*sYxTcj{@>?_NucOWPZ0*oO)p-C zjBg{9^~ymUq<2?&<^nwC2d@_+jH{A6W!p>`>q(MOR;`+8m>O##rW}51{G=V_m9`s| z{&PpVQSn!_oU76nSI!3lk5<(l)b8n=(V;^%=Q7|SRu?@uxSTJ_;rlTpY9 zH?qoi8+14$2uZnFWc)7r;cVbI@?Nc6TF`o1V5%e&T>MOflOoq+Q@DqZ%ahyV5LPA# zyBvz1xe!#SuKxa4BI4&a%)Q!(f((JIdft$T3#}v30t{sPT|is+E<*8 zi38lYv#TrrM|B}(!AU1rk7)bwY+aKbt=6P8vUikb>Lj9B|9Cx+?#2gah;WH^z~(43 z=IK8xpVouPd~~@vponJAIW}9bKcUVZZI?)mceS`+l{%gh=15#&vE$qaA0j<{;y&J? zoc&FAFYz@9Nl7;3e41+Oi7-G~L`b~Y5|C)MipU+2ft&H;N;p`dRtbX*}}7j;wy*}WNP z#{_a=+)%&PJ0DUhq9v6+S^-+so*woi!RoEjzqJ)RFu>1%4N1RDg@;V9C# zL0~Y7HyP} zgegX*_6iKkp6xb{T>5AZvmWT_GG6+CMR|R>M#NU4>o!QT8i;Xl?!N(~3PSj;8XAMq z(+#uBBW*8%@UI?}IOkZnQ|bjAJM(%S{|Y2ym2wP9tv(iebB9sxyw%C_tA=`(EM*(a(XpKaYNd?C#-F`QH$J{1=4mYIM}wb!)g3;Dd?N z6_9}ECsh-wvw>)zrdkPF{=F0c^&KSWt?pxqW`@EY;oPp&1f=?x`&2b$YmWA!TCYxP zLx|G#lb`|PF|}j->zH&J1AuMT>VAW7fP6O0!zNE$_mmSuK{;0*P+SHupk-@G-kx9Q zt`CnXLNb-&ve{PrHVC&2+xZ`x2VtBx2&fmBv|VLXw*z#?DjpkzPkW=7M3Z5B^=jR5 z5%?UU7YO$lz7yG0*8_OzZ>bgN;MaE0;j#R8&#K2sC3{-Zr{hGnL90_=KJyaGG!T|L zkWQ7 zwqIG^qPb2;5j_6FO9Oj^w)r)(@Bw)hWJg(%1w3)zuS~L|<^2=$*mA&!k6e)lBT9Jq zwS#yWOB)r-ZnUv`(@r0KTL@XEv3OD(r9}8_IWx;>XeS{~{@QO=LUQPWIjp5dPl) ztbgV=`~@Ja)d3%Bo_y?oF79}kV(a4*!dLt&%_m;394`*o22l+bg*<|um^js3#+j18 zXZes_E#mJyW@PbA(eGEAUrrx%!OvLt?-zYX_X()=#YrZsv3bS=rLjt%uojW`-^*b#|30slygU&{I*3=~A@_p@ zkd_|yVCp_DGQ3}Amcc;PD7)}-w(8_-r)lv)?aJ6UL0iVoP}R%N>Z!cdFA_>8sG4EY z(>YoR4S`CiG^h6>_y3V@{9RZCJlV-Kyg=@4R7yDTEbN``41^V)6#=gw?1kAH9@%Z zKVJX$RBHdXE3JPqimp5miB>Fa6yD$@I%_ZFAlm$_ zo2N*w$VEH{c7sj!Dn5YK6HjPmw10Xy5=-2hRh1|KUzlSDGq?qH>pT!a=3L{QDcSf~ z-If-nOLp^pe%p#e@_LtsHUh;oO(AwOqd#3Q^+qV=kcNf7ivr{{?}}So$L%7M{?%V<(lf zCp6fj&`ra68E;~y4VtI@>~*Yb)nZp^4u>vIk2yk?QJnTEcds2=`kHx!n$@^-_5NA< z`(xPbL@q0&edQYk*8fR&`v;cj`>hSE;A?G_OtJ{Q#NV%&+pEc>YA^Bxq8=&Zc%>00 zJ`B%Fa2QfvoJ$^gRB6|yJy7hw$8V(aYf8i;^e0if~D(GJ7M;g zA9Lb^Ip&y(I4etTJV42A*q389R1=xIot_g<$(1rMc&Hq8xoQ3B&U=i$b!heE0P~}E z^5}Wo17DxQuWV}_4T80!Jtj(EqisF5b!$+W@$t3hVY^n{ZP1OrHQ<M-=3rXpnKCt-%WU+*idQJj3*wW+bTx_=5`}aPK}p5>{K-h z?m>?XD;H|CUy0fVmuWuy2frHZVdgp{S= zwTzUdj?ILnAG#v&Ul1GzBCN zrsp`@dnGw$X5h3u45;Kd9y)s-*VGnBQZ=q9oGbZAS#dwM;M%(oFCGq@K9ee5v--nL z3KA)wC~q-0AbP|qXQcDfwMQaiuJUw4@dgj385^r18u<7Am^A%TUCW#4ZyJD-0m(Q` zV*tvs_~#I3YQ`TU0xbi}#PKe3qTo677{uRkSwjK{$*ihQWVVA37{3drOobE}(v$!vD@YVFw3PPcy3=(oDv*mS$m%MtFc=9-Wjyd1MGy_~ zU{*^JmX$*05S0gpcYs<3+GbPQQ=4b3t3L=fiZ&A)!mKT zps7<1FM!~Z96sDJqZJxFt539%GV~Ol7OZ$w;U00n88(~Ck_3Jb43(^9UbuuaZUShY76Js7#n;nd>4+*QF)I+QCFspOI_9o zy6VU0n}mWMypwW!O#_)}|7XGLA8nWI+Gl$mxdedJvE+R_xpxX*(%f9BL9dQb`30?O zNHrf@-LDL}@GMU&=bBk!A*THk8(nsk#;9pNC;YlTu5~NgVNPc}^|4{y8w5*_HXcjW z%3JWLWDFXmvBPW{23JojIp}PT<7gK0B|BpcT7JTAb6;~ z72GN0SI%yO@^~wamr`*@J^)OOcn3hs@O^>yHaudE-Rt7((RB*-zQ`(F|P zW385{3)Kk(mG(%j{u2o=K!cWTP@`=76cqdOC~f7koEzX~*t3rOcN4n*#HarF`+xt= z{eN9Uf^UVfciUS5<&nQM$JwpaScqdeE7fZHS6JYOeZAE^t+!gQruecgn&AiWnn@OS zfl!&#n^{n2sxZ6zgI}%!`HZJ9>uRYx)yMAIY5st$diO}JHhryIGOgTy^Ar%sD4{YUw>yAP1AjsZNOz!e*#&sZ z(RH<-1`y_YraOS1uzU60qnccvzsZje`LSF-o~|z&=EpwycVI=!Svs=CJ20SrsSUv+ z{w&yJ+Thd(uQCuQQTi_YkFrKt42|y+Pg4UaFfuVsbwRcEWJ)YiS6hPz6MsfCcW+KN zu^$+?i{iV-A87tV`2Elo{!6r;K-v^nUYP-&66;(b)jYmTAuVL$LN?I~4~%xY*$WB%C)(Nzi=99Jqpkgqw)S%J3W^$lT() z);7*Au5Rugo?buN+W$Ij_Irge|A)E1CfMS)Ec-v~^`GhFpr#~oGt<%pw3-vt>~o6l z&ZrHj*Fpx0n1y%AAg?7Iq*aRHn|+wZdQVb- z3$wx7`HJ{qVn(jAi}s3uel8Vp2cn?OS7=5!$ky&~c|w07;k|Lt29P4M{{;P%5(K3E zJkM|B<~W!@x66mQLA2pO88;_U$Tmo&U4Jca9dj=uK(OvjxNWkz4$xBxQ;=Jz@9lS0 zG|2{3OxYc8t0a9=c&fc1$^G%v+#>TvN^{!+^XzA+`MGtW!xrLZXLWC$~Zj9w+VT~-zu zC&*g^NqGKqC@Uc=-E!t0^5sbK<9CNT?q6)VrG?-mdR#WY_^FW0xm#Pgxe}XiAL|~Q z1f7`z>w_lV$a>%U;-zPFnH4RZ%}TRrWTJJ06DzQ<(Ud@eAqRSv}omGa5Ob z*ev*biKvY!eoqC8;^X2;^3 zSwke1wTrrhr(WO6_KtFwyyskfq~7HO9_z?Vz_Osq(dH|Od_<^nQBU0?Oc8PEcwh3( zn-J?}{8N=xWsd{-;6Ya>F`zDiH1pQJ){mD@1>QL^4pGqUr=fdqzYXd`#e+hvQ~iWa z<T`OVBluQttOkN&1 zR2=YDXg_39+49vOFQ4aS$G+4HE;Pi!2X0+(UPd#{&%Z0N$74a>^J4VWg^ksn9JrLE ze<@f_J?DBs2}IuUmQJehEw54i`pSo^`79R=z_klFWJ{&xrVz`5fLSxhtMZqzzFL*l z#d*rBX9K!AI+IsI7MdS5ZMwu~PL+|FEmF6sME~9&*Fn$(A$>Wjb9InTR%cjY=B4W!Uxe1^Q7= z--4sQ+-vV$&l1o&eZr{{7i@#Ry=~K?`>ZPRdQpvhzi*fS?gq=^@lI$yIWBztb2xJp z!7?wzQNpd2-ogY~sgR>`$QJ&A!KMJ7bMd}Z5y#g}lziy(0&T2B%K6#W#4?f&Vz!eN z#IIh7_m$u}=OW-)DytBX)GsPN6Yh*N`zPIEK*uv<1YkBJo(*5O5y+huS{br5Q=Din z<%jNyy7hHec~$-@4q#_jJ^Q+=I%wnjlf3z(?Va+$$+^aZR_~&!p~HA4$~B}a@JsVs ze;rdpAhW8Q_bmK$XH9)WUPkw%cDye;=6X0qDOzGJD80YmCaqKsc{C(zt4 zVfv4Z8#}f^!)(?-DUF{;ZQdu@%7Mg`y<6V@kt_c==WnbE{6ADA`MtH@g|Bb1zBW}w zUpqkVss&J3SR9L0-tX13+qImTuPe#T!wc?V>o@C9gGv^dcq4U<3ua!kh)UWze|B*? z$ZnPxhXzyfWg@vAtHiaO>MHiIsmC;23E_=1X1&3N@udffI;|he^@$#;V%quk0GLf1 z@o$47yv8PsE_@zXC;tGilxAK%wgEH^b@gSY z`WmaOg=%eikU>I_Oi?^E2#FFpdxq@u)w5hHaH^aee6;NMQpvpHQ$ITp^|qLDbZ9uA zW7Ra`o!6>NjC+pXygcHYOuKJHO7oym_Ty-)+0mQkeGQlp!Ww=!BRZXA8|ZgPd<+ z>oxj{uv@j}@t`F6g^|#7=i&T^u->x9VZFm=1+GgTL^Cfq+)HnBxYS)gL&_`~8r^jZ z+%Y>^BI>Rt{;+}U6$)gzd3774o&;@KvjjT8j2239z%x})7PrKrS)V`9)8$6C2op?{ z#XO-%uxWqyg1d{gnrg=U5rihYoc2Y7*T|;+;2~`D<=);Kf<%P`{bfl9JS5Mg>c8zE z7aY0B#7R_G`0%5?9G7}R{Y`Hzn385uyNM@9#6`96=ffRcktkH!gGZp03Kjk8=NRnM z;6{1gB3X}Qik>QVz5A^CVnmgOZMVG5kcJ2K$i!wljW5qLCv7DiHLKwrinw5KF@h00MPxjh%xbVv2OCDO% zc42~nJd#5kAopBL!-d4q@Xy3^53wXR4s^x_dJ|W9Q!U-;)@|Qa2!4K>Xr^HXqxKVg zdyJX@Xz@|g1PJ&fom~Hm3y_!s+L3F=$7b_J^IYM?R@#`e(I2R@p3_U(HVdymZr2KX z;{=LiWKI<(SUv_Fy#*P>!AK@dVrbpiB(%4JAKORqc}3HV3>*cd8Sk;SFQD;&3C8p! z`02anND0VbqcDApn5iZ2gf0sye5eYiXmKA8tL`XP^Q$pwI4!#p9V&+_8c&%^>DC4!O*y{B)YJwSk zx#UzjG}A92Ut}uANw_%T0&G-O8RU%r8TzH7EnoSZ_BYleQ;X{95~;bR3_w|wR_1)c zmU11)i`TKNB#hVP?K-c~0gJ0?I@gVk4;io1&2kcTE%O>lTGSfUrfaT zKrzjYo-qO%f`-#n?Ak}*7~8h%3T3UiWU{Ruicn?@0K%)``*!D0t9FUl?`;N zS)>e@u#2zRO1dGxo;RgM8CsNoP$<-vPNM8-@>5SKONmHn=G*gSV*8E?zH92z_=fL5 z$``qAZ}&t*dI8Tcd97Ewgz+}$B(|l^SHk^O_2Tj3ZNR9T<;N=E$I<)d=Qi)pRQIDj zmiB3<$c|@6N|TpY_`P8}U5h{*@RYO-E?tYbPSzAebY3GEF-k9+JL@cmG3!q1NGWmo_hpf@y?|Oh3+|VzGCiy8B*i;l zSf)JgP1pCttiBbn^Y4q%UM35sSCQdq`HJUO-(WxX8|?3*KIj|lSMsQLoM^X)dUo%J zF7f-HO*?j0iD$nS{b<%&N$t_8_`ssVkEX;{M3o>{(gkLWLaiFKJkO5IJr~nv=4j8D zuINDja>l^;js$az8fs+nz{ADl(C8kctHs3+6mJqDK>q5Tye{3$3d5?J=6s$a4JEa2 z1!_qxS>1Cveg*xxbH9XmVFELSg_+PNE+@#aJ83VbAL+)^mLp&*iHhI{iT~0p> zY2tm)IbnG2)y&m}K~Wvm#&U5X5|Dds%ldwP%yUYR3VBuOsmB)?Zg+GUf5Cqv>(q(G zN%skRQhN(YE20ip{s2*09c3~r3(`%cEA99b-Tj7X{6{YzUklOw75;baA2KB2rC6sO zxa$M>ZzP1|#EAo6WzKR<%lIk0V4Cv%1@Mbh4;`NhlH{r@w3{7b;RRjFU3=FcfAh|2 zlh-|wux$|O*%my^=y@2KhtrsDNB01PHQ1@H&b7DtP9cviz2Xc)%OLo1Awf~{TFP6! zAg5;`ORKs|`jxh0eNvW%oo0)Vd`~qHBb&YZzTrDH!R#HATJLZ9@%0=}+e`~-3@N5(Jbe-vr?7P z@W>I|=l&9X^P6lI`Me^;Tb03>59_!U55js>5Tq8$*XceW$bi>WwN{rcM|j|5bt9CX zosb6DkQ#UjP_$b%nS!TYiW*<# zeX=S+;6{S7g@?X=NrwxNnd$MQ!^F>~I@tAtH@V=D9!k<#z?@sV6Cr`7)In#~YGG8v%;z8SP5km=;Cz43|8dF~h%U73~ygpWo*{nXy8{rc- ztsr3+*DiS;6~=|@DzVylbgb7!=uE)b3O_5NixDhyStT775vCy&YBVa(>KuIp79y?H zPl@g~y0Y0HVz=9h zD)J+MM!lfbM!{iraeL}f2)rt5KrO!MJyxE7x$&vqVMeDzIh1s36%+eU&|n%#nWR&^wx(9kUTThZ5eC&s~JeCpI+&$W+YRz8)NK+gN)A(^Bj>6ulcQ4_m{6L-VVACgiRSG7=86;C6guX8>jVZ$}RDH!ITZS$L_&W z;jU9jYe2;f7RqJx)np27N%Kv05(MOVu6AJk5Cob;3hwx*?NGbc z<9hJnojd(c*DR5j98Nt`e5thjI+;=pO}>EM40flPF8KwbX4hb+>Z&^}O2cLa2Yn^= zKd)~39?AYsm^7bPR8jRAj4G>!^R}IX^9Mp(*=X#d4^*VoUoYtxicu*Gi!{nR7FKvY zkh+|ZngnFLrqg?F)u^zAtF9Y!Z~_ z_aQKuQfYxKw~B;9s5BYPH{VKZRKoubTA85LUb}I$_x2-po;p*rbX)H@`NgD4koUCi zVl0!OVq@59r~agn-iB1h{*^@Pw3q;F(!`99~Nv33+#r99zk#}TKb^I|9N zxl~h3n>_DWZF-W|jY+CCB(mT~rIOOooq&Mc<3*n^r)JchJ*=P>et{ulh}e7{`_ia1 zm-O>&<;n$gUQ>gefA9)g5yN|LHdgpj_}e;=htDpaR=x~7AqXrak%GNTWrz86(H1*}!fz#Yy<7dzs z0IF$gDf%vKiG>6S{9z(;rSLqNthi6yOA1o4gOpVIQmI1utn|GK)Z3u@b5><{gIo?j zkTUEX@Cef>Xe$gnJATeDD+>bhNY9VzVAGz=H^IBk^%`&90eIk#G@n$@!<1PH6p}EN zt2;gg`)Zt@uSCNjeDhw)hIUEKz}iZ}lpc83=BWB&a|}R1@7A6GAd#mPb}!)E$8%oj zFKC)=3_z$Vak|bo2>oDNTj2?a4aN?F{!M_54nLe*11K>&NJ`WFyG4d~0}XzJZ|ttb z|CQrk7{2lOmTU6BXcXY>Ks-T2r~OtQ9h`rVtQ-to(Q$7D-d zQ56Y}4bD&()dM<#yzG^&8GZzDbdE;0sUGKai#u84chresNa89$Tw3KhBy;*mI9tAUcBK^gU>OdhW_d~Ismg-j+>po$sPb7SQ=ifyR-l|jjeygF za5C22ck)E^g*-8li8853hcvzP3KA*f!C6}w1Zc3r^~r!uYjS~dw?rqHXw6-%4Sgln zaT>bJz)4s+lj9zPCd;DNbw_hm&KsfaGYg9aM~JS=&lpt#3pwsLZM~2_IS8Q>2^@4F z*0*`HR4aP*fb4}XePEs1Jd|p~ub-emieC%JoUS0xHZr1|0li7=eiV}^{zYJoRrcqvgG#@DYuQmaWf^)zZk3p z$_FhrbG&4T-mJAfBA>^(?o_*^iLM~d`~av6Pcq_;Ji3oIN%0kO;hZ&XHw&FMh0x_* zXfR^zaJ7e=E)4S`KrD-M5(UrG26?Al;_hd!X}GPq>Hc}DR~zx?}->*g2oK?GcA-{GIaMVe4EIxaJVnGYdQD9ALDZWp>^gA z_(KbiZ|S}7m8&3XcGpxTKJ>{D==!3N*t;Nlr>(r~YqsC?Ft8lANP}fy^epo)PR^pM-KfXRfMfs#}^NoBgzrRyWI)h8zL!hQB(pvTabY(h#sU4pZ1 z30xVU7Rqb_Q#c2okm5T*;pJ9@b+6O~cT)Z~x1@&Hqtx0aRMUD2@FWmdf!Y%N&YSV^ zgCLRYr6+XxmS^aLoEzW)88+AZ4zMAMX;*~{1N z1xR45ZTw{1uiIK1*Oa=Ms&+Ki>ZJOLJvnIbs4dIv8*Y7u8$(~}VHU*Ml0;@$z@X+2 z1>QU3&&NGp;^i%dtG8rw@m|~q7O+5#-fRjW+}$KgP`?(YpU;45O1@Z!My(aH4pW4K z=ES}Zd>qPDn|mJG;?vzY%N}NLiYH{>TxahGdQk;6wVRLX;QB{Tp@ZBo*xOWJAzQG8 z_K{47E&VWgh7%QC&pqVY!%87%U}A{}S|VdpuH4#T%2cL=ij)Ep8$BJWcy^!vDTB_l zhn4r;3pIc$c^}t%Bmj%BBQp0$);6o%HEhurCBvVpNh9R|loilUH>I1S+F&VRY@hfd z2D?l>lw&>eVxHSe94d4dCsj=Fr#gHqveE%tbE-W`D<9CJ_NdHl+bj2MV#a|Gba&fe zG1lB=vVn5q&5h71vOOTX;pHYI&M{+&j=XgAET->wxa`hXr9UEb{J8TCqT`3v`hVm0 zk29Nn4KDks8R9>1|9=Cqhb49ub}tpqCij22+x#d6e%$#c4*oB{&wo_*Z{nbee=!yQ z0Z2;!eG%RHr{4j$rF>6l%a*c5XIgws2e1jhy1PCIF9d9@RQ5jAkZ%oD3nCozhvi4n7Qzbk;agBTyP?dw9;_@?7)w zNh3-+Sxots5Md?buyCXcJimOuvrj7ry-B&ZnVoy$a_=otL78~yukw%o9-6CfbXvbN z0r^*uEq+fM|0iAZZ$x-vvcF{@4w70Se$@4qs9lEjW@ayK>G$Fh0R5-*38f|bwVmVR4LYO!Q#|CxI! z_2?3Stvs5

spMx0v6(<^+sbYx(^upKgJ)uM8bd5cBVjjtwLiUaGZoHhc&bVdwgK zq%ouwT9rfSp!C|2UJjmennjX9J!3b}3PmUVhgmL#mR9;~T}vOXTZ zmn%u8<_un9^LEOAw-^r(Q6cyOiVgnU_xb7RN5w{JStfY|$DcCU{wESs|J=ZIL+UCY zs6>;?5!-8t(3}5`HALuandC@|rTq2FTYc&I;cHmyl7n*Xd+Em#X|(Onah9~&C!#xt z2P|h)YNj=neQatO(2lia`>%ch4N3Tr#qhl}J-hO`*PMm ziYy21onZAfwP9~fNBP%KgAd^%>vyZL`^XJ$+=;eEyuw$63Ln$Vt($NrIC!6o?9Hbe zT%&$Ff)HVKEZU|QvlOUndYpu~#W!ZuCsHZPY3WMM#vUvrzp43%w7yRuY8oS7%q6 zaNIF4*a<8*+JFvIJ&Ny5yGTSGL(#kJA9KLUltoVc!a4`JKT)Mvxts1uN}W4^o36K~ zDt*+ue*GZ$J)PjhJkHT+%GW0+l+H4IL<-Gm9n{M`2iWPD@F>%|#=4nPzlGb^Xl%Ms{uvMimU=Qmlx0#E`q z#<;LDy+m=sNZ7w1Sq)jt_;4H^LnP6Fd0+`?x#U=eP*aKvh{PXBJ)2Hj?e($K98hy1 zrak7nJ5J~o&$W&n59fT>Bxx3W{3yIw_OwAmO?Fr(@ccpzsxIQ?QZwLmTh95d<%em` z*7Q=7cyZ`nTJ~ITz=->vmMHE3Pt!~w_(7|%ZCCU$G5A2&?+BT3PJp5xT=dK--=V;9 z56JW|?-IuEMwTw7jb5LXlN>1pAKXns@Nwn_UaNU3NI^thAR9x5|&IXf+~@umIQUxlHXX}|NYAF zKX+0^IJy&6yr)Q#R%Tzt9WGLR??@;W^+_Twf4-uoO0t4fM!h+M)`%g$`569I^DUD+ zuP3gT_6Jeg&~lG~`y4lncLWHLxiVxRBFs6Jv^b6khw^IPE4MWhu}a#0(AI>%C$=XOeDpm?r6lvRO8ktH?V=m)Hw zU)X*N-~In3Z1;zH{#oI>>AA(rmu|SkzW2bk6ny=%$SRJZoowy}L{EQG|CKz|6=VX{ zvkwh(F>gGzwi&CL<7%HW45pyvqCisw1$U??vN}AGk6r9&sH@eztn5%iz<%<4=Ooyx zZDbFMclbi;6cahvSdNNp5f;4)T{3ew*{!j|=5J4wPf)b0?!H@DFVa;B%MEF)`ZeH_Qe(zds^59*Lo@I z25LMFQt;N^O`kr(RdD8GNrznI!IR~Xmi~ot`or5h-vU^@-B7FRx|0)FVK{0l)D_CV( zB@ql~{|sqluFTT2>_E)lR^nc@YR-5w)`Gz^(W#T`P!@SvdoWZ>i&Pb~pQR@Ix89-a zO*6pI?=-?mXYe6S2%%WN6@KEId8CT^kP*?1(22{E%EuEbcv8_FNWG0^dywm8-dr~V zts7yGe!a^FMyl!GKKcR*!ZR%^!pGpj6V*D!Z~6inb%_d8F1Po8mW-DOpQ{m`@y|8v zhS@z5rWZm*R_V@Ndex0r9fL|i*GbB%MnM8_=4lkpqG5JtHWLXvQSWk>2d4T zWV{ae49ylK!`$g*ElSNe5s>xpRmsef7~fx9%jUyX-qTYNDiZ{LTg(vI#5f*Ij&qczM-{aUGF24fJV)-u*)He@y~K$Jt(J^1 z$94%;8oY^&Vw*5I4A=CcSMtp6;WixXl>dY)qXy^AfIhuTE!3(AT3;;SX>4|lFhsm9 zwxO9ixWjE=pU4e<@p`+y%K`<;9#Xrdd~$%m3$@`S@_1#IEWwOi&5#?&e{5IO@IV#Q zSyrpOCTzKT?NUOc4J_<=%g$+ml1?)2bs{3)x~uq(BQx1ZzQIs?VoT{AOKyq+}D8z|Wvsr?|{rBueD+H{>A zRc{NoE85hS{+-x}#P+9*2bKpjpOlm;U;BmtVBU4I_O6Mn1Dsrjlw`wqf(JhF;{))Q z6VHkg6x(ERD2SUuE@T0X&=Dn`i*Gn(joh^FRv=R=c#}LNvaWnTeBNrNrV*35^56uy;A)3xdOm z5$G5;fi(x*0@6> zkKZr&xYmO7QsFrQX_ja!XvJ(D6NEkJRcy6`v&8o9&o8qv=j0L`Mk~ZhJ#`BR2dQGz z5)R&5zIsP`(F(DjVVRXJsB!HcfDqPk!;V*%8@Mp$9penK7#QNLbnGcg66=10Rm1;K z6|HD;>^*BJ!^Kap^Z4f_E+MUr2RW&>KanTRGS#vuUwy1x;cjB?S_)E-HIaPk^kO{C zkj4mE!eNtA9i)Kf*K$m zb9Npfz#@CkEwCwK39AS*&dz&T6(fB#G@k?uEy|C57g}y8nlWKGD|Yx108WOonDkrw{x3qlI<> zvI?H;91O-$w9&XvaV0V4A{A}lIwL`|OUOcUGA@)A+}5_FwZVnRH=c52Yssoi#^HmA z946hm530ExKk!5|k^3t`DhrAt+j;pelg`CywHj+qHC5eypjCK@K#F9(<`EW(0u4kQ zUBvSRVwzWRIK;J(e~7=@@)5Tf&CXUa2Y z{8*~%_reEPcu(}!dUJ6HT2@g3<{ecrFV+R&g7D^1g~S1a(a>^&gyuj1MP$MfhWT!^ zY8e97ExzW%4%z$B!N3SfY`H4^8Du<(P*WBtyQ0ng!Bqg0JDP3qSg)kQu)=#LpGwwz zV&s{GbzMheHj%6P_)DQxi(aj3HjkJ551#u&mdT2X6vhE__piDSFYV?hFrP`G9N$SIK(4)X z8SvB)mT=M&_U;mN&8-I=Y2X+0wYZX>KKN9gvUfXieI}m;+QgScJMfsgMYWT3j3WJt z0aq|TLwV1uw1?Z_u{np^4H>UV)Iw_Xhv-J5SBjUA{tT_YGroL?nP}zB{Bma2Yo8Fx z(-V5~{rR__U$L%o+_}u|(@f_5kgr#+lDkk^M*{10?;blU;r{Xvi}!;b^zJJ#52~z; zwnXpGnx;Y4Z&m+V*Fsd@`za3y!^wD%V5L6k(| z?k7Hc3U2AKK+W8GO>k(XB^~ey?%xnaxHP9s)yj4sHN8t0G;lUZ zR!}XB?uQN)Wi`NjK2a*q#&qbUOq(M-h!c!360BZJ`Dx;J`BEBLQii5VUwW6F$EPMm zF%>%R<|H?4r_d}jEwpcmUN&9So>OCs+L`jUA*yEZZr~7xHEm2)N;61zYvCmLO}GX; zygvS+K)i^euWf`$d~|ElHrFjLTxP#Qy2@VTTf@ZCk62L3!`ITh`0mJW&@T>hKEccT z2quhLZENt6R&_htCwfg>?H6;z0lD67G<`RkrP)0ht7Jk(W^*vTh_NloC`v^iNmV*y zAOq=V7&8ji-#pAayU?@y{*ZdpxjUY+=uLw-CWnPGfrekPaWGntHk^Lfx+>IwdZM7;ZAO73T$ z3uRuO-cDLinlp5r?yYWm{^IO&GA@45U56<^jfRP;d4AOLOWz)R9=l5vy@j(5WCteh zai%a7xiRoD_?JhqfU9iMQVy*;bkZs>-{w(RiEl)nC}mrX8qYKmSAN`rQepL!yg$9( zZTGe4g>K08A%&i^cI@2sX_n**C)Yom;Z$66aETB6*gXN1{^7t|V&P4#MvokRlE$QJ zN1!x#<cEJ7RDgZIi5;(#n=zDQ+h`wqhgDu3CShYXV0VGr9NYu+JbQ z_?dqXQtsJdT}Ak7F-XAb%mvbgd3rxxkt-xsF~j%bk?a!>o=UpYdjk~bKbI^&i3<1@ zN%1X`;w&})`(z4alJUI!=(XSC^}x83Ik%oxzB-t7`NE7QB`9CqOodr3pxL^CCYJG@ z2fR;d;->6!J1|B6EW-l@r~7a(8UWOEp5FLOR&bVCOT2R?ZgLLCmEb0NCYM*2lZBW2R!GF>X}B2w$3?E)$Imr1_yV&4TUn6L){5;OqWdC%@6-3VyW7H0HER!s@U@Y!bQ=G#{qH!7;>4~kJnlCjYX#Iy=a-_Bf{ z7BWgKt!IvYQ|z z>BGxAH4on7*(saY`fF{OAdgCh{Zu;AXG%^4Kep#PKjpNsy{!9kgN5I*DG@JFL&7U% z+om{Sq!}crzA2aFXp>p*&f_0*&uX(*#vZMgR3uxV5;GM*a{z?@LT(2aI~amYTLx|!&<4gG0Kjxhc};}_|7Eb zlH=fbNl>$m2ry?r0Vr~IiBIxxDy#J3QgGRJnMzpk6+t_CuSr^7v-yH-xDB5hTDk*h zCpD5A+8I4yHU0OqW9`fb+WZ`vgTnnb+^3CF6x4yLR*4+(Yh5nU&8`PiTb~3o8}&(i z6C_JHNe;JRwRHeE6%e8^&Ig|JChf}{rs%dJ99GY{a- zwZ3#;sTnfL^=Xr^Jx~VSbK}*CJ?gk+E}G%*zo82=_L-q{kgW@i>Y#7&9FRaYgRh@y zbg=TZAo&rFI`LCV_809FYgte=G<#0?VQASOB0gYJ3(^cwp$^Q(&ci5=XTn951;!de zWSf!Y!f~6o8kV%g&?)RzhU^rcXwYfJTC`EU)gpk8h zFh3fY16R))L<7b&YJju7-AH)$Q+#eL$rTOM5eai>KH zSXE7rr44NuZ^&*ku7UQ=&B6T3X*{w*)Lfly{P=$S!c6fny5mnkU3kVCLd#}W^j>u` zVWCmQXx9_8;+4BnFthN&LDqpM;l*CCo&~A>ZQ5BPx|;3QGx?>rrHc#euZ~nP;}5-U zSEq;-EQGWl%+#{gbf_18n%i#mhV^T&!$HuWOi9>^&>MC<7O0fnBhH#PrzN2y1upJQ zM<3kI$QEIW!S`tnh=CdH{m*pepZxqkasfd3N{N51$UdnRc z(njf=7n7tW$}$_Oc$^6abmTq|!< z&k1YWrs^9>)dm3M2I*}ndcdDf)MpAdr0B*%u*-qd+ivpeWeHtzUb9WDqK z1SffAG&*PUN2nHk0(oeQrX3oq_ia4OShtq`0@99O1=MC&!_6jwyj!7^KhoaQO2stPgDN zg7L$;Pc+^fUC}QOtP#&v&SE&So*FsuTK5<-$XOhMh6e_OM1_k|lv#BL@>TLBh+EHk zHMu5VwB~xp6Wm>5wR4)&%HFNG%z5o&MG4GRZ7wq8oQBL_0(ZcgGu?~lxczBeApiAE z>*jGAe$hhlw&{fo7XXTaB#=+Ow`7TfO!;GRxK&Puo6#zNU@g!3MMwBDOEMZgjepOU zzQM+0&LMReLSUtB+(Fi*L=}@a|Io!6(lN=(d^+o;hb-mTEis_c>E0>0evala4Kxbw z0D{xRS^#)%I8OWvH=dbw=Cl6FomXLa9@^HjAjc}nz}fy1-TaHy{*S=BX^m7=))y7Y z435Y6do}bghmiP(v7kQN0-}_Uc$T)PrxfLh5FcxWoz^%RTNq5=L%gyA8NGC-tS)2e zsP{4pfFp;b5Ztv!z zm!smSF=n}(uE0IPc$e)i0g3H>Q8$LF=Up$?_o2aeKvs@^^$1_?zM|DLgFE`JeEn7T ztvbp1)MQO8e$8O{qiy%coo`0oUu&!XhVTElk@upq0a5de&YN2^z0Ov0kD?uWE!OEbY`QN&sd(~*Xe$oL|;EH*fPHX*p} zp;VYIhjo)$@vD7AH!eG8_$6mH`yON(UEP!_0BNd<5&{D4C*wr#Fq_4XZ@DMmB0IKPBBZ<-<`~@|W(^%&73aP?5oV{dDCmpxXqH z+iJ1nYDyk62~t$fUYS#Fj!DyrY@C>Fp> zrAtfeW`OMW-wGUa zq&7O5^WO1C^J~bBheWy;te|RCt4H|9Xc%mjmNPS5Xg}vff#>>Tr^qK0g4^BpS*cZ? z-Vb>ziaoHIT4fQ5sg78LnMUdxJrf*I&kZ>D2PdPS2O+16197~EDU2;M}rWDNi)X_9yr%(wduh3}X>d)QJ* zI=S=CWA{xB?zPKFABmRsC?Z;!kJ^Cfw@JWdOs~3iyQ(&CRA=-(c}2rDw(!Pdr951# z8PV)vZp?Z9#b9d`ihS;zeYHCT$<_^ofkW!+*1w&F=asRK2cQH;xkkWOUQY4OLnL{iENq@%LV_++=PFXoH4SQ3-=y5w7t z^k9Q##qe!u`)%lBc>??>kQ6)yhbjiK@_reQG*0Mh`PDSmv+pKnwqJDc$q%Jo=9Qw5 zNSS%+9IRdPx-3@E{*ev<5WHV5Kvw&~RqeI$iCis#b+Sy%6Ml&f)^~ik6?Fc~=pgsC z5Z-Xgj(H}mq}nj{x79I5B{9R(Y|-i$dIY9}tA{9tSZBsQFR*8hqeo}{D@r#uh=(9Bv zh_sK>Gz~(XEH1E#|9JA!`xKf=Fg|sC2TLc^Vr-1D%3As`zMADIIzPl6ft*tFr*_*z zeC&I}4}|hx5yH0`qVT&p(RX2SxI|6XOy>u$(BE(W1Mzf=@_~g4BNws^M%I0HL;VzX z>j7Y*A2~PCw`DvM*34s>&sNAJ?OHLTIYwp>DJo+%^HQj|!#;cgi5zQgE*IUh(=0@m zVEYfC?&a?2HnKFRO2p{*dZs==eux)Vmwt9{O3@2aQmiD^fF-<_$B#GElQ9oWQs1*d zL(Ga1dKR1R&oK+7SWxf4r&9;S)UwwT+qJBRPvUknl?vSaWh>yyy5KVAdHPb22Rf08 z@&L`i8f0d~pB{2)i!kcYujH_G0>Jdvkfm8t0{9gncZ2vPR}uUL_OB>ZF*1l^lC3UV zLFi_reJ9u+-z6shFiSTev*f}h3P&lbNLjmrGalJ%H!cYy zsPWxWY#EO!7q{1k{1bP<1K-&IWgWR9tr_aZ)z5R@SUQga4!xojaUC<(Ge z=;+2!U`2XI1@QpMUwHC(_6Qj<63NjE_|ze$0Y4>_{K@{eVEzBEgY^j^zr+40kp{34 zU&zyySWJcY=>hbEl&Z=w!VVc0OeCD0Z&g=%_p^1orz^t|+0EK2-!Gu_EUE!DXp4T= zht52!VAW++rFsT0tI?`*In1q8I5RrsBc2D&0HQeAKguNeweuIGX#Csw+NR;xZ`$Yj z51}Feu1*R9IfXEOb&qMyXTR}Aav7NF8r?nOEUeh8EUXw0?%%6 z>;Z3)^44=1vtPC8>;TqZ?hl+s3C~KaA}fGKa+;(ZyjI9p@wRI*g%BnE6Op6(>$1W8 z#8K;l&~Zm#s=c^kK)EX}aBKIS0f73*@7`H6TEE3tNMXG8cpI=3i8EOBS&j-NLEfo^ zS1-d*#EqMVjx&qOG{BOqbifMVOSCCIpe&Wcx#F>G)g^8%2^!@b@kDy52QL!_)TA&U zF(Yd#)Y7Q$pY2&4`ZvuZos0YHW0xvgp}>1w)}yWkJpIx^i-InpduXuD`~2Ds9r6 zR`X)bppvOF=R`KoN-!**f$rAxNtpp;s5TTVd?N?OBm@|1Z>jc@6r zwzW$K2<08JNP$N;9R|}iWa}z^0XZux!1CO}meIXL#`#}UpSKRGw$v8y_&7O-?8Cf_ zwZ3wGWkp<`flg5ncWW*1Tt=$m8NKa(9lacXpfNN1PZV;X%j_`3P5Ox*KcMox%cC_S zHi#N4!|TL`8)!I$Nvba`tA% z`PNT+^vZ%9)L@2;1E?xS4>HG-o<%~*NS@9DN`n=gu8R7+-Voud89&$z{%*@oCixjl z5D*f#oaqd3<9~~^^lt>GEC}W|bfN%O)jtt8@T0Q#gVOhZYm5J71l!cc#L>yY)X4gL z&-T6*HZKp&b(-@XF)=O;=lf3XcBWhk)<)*0*jzHU4{RMY?2L>}xo(=eSQ?wE%iqA} z(zY~lvY_D=5EQ`Xx@BrxQM1qpGQcjIFhut&ORT6O9lymz?DTCsPNm zn=+a=O^t0$Ou25G+L)jJnvdr?pM=EsCHXS^WgUbk4HU-|WC8*{;4fn!84w;e4lWKB z9_~flOZa#M#0(_FgoMP`XlTh8_&5axcsY4^M5Hz3M8xk%@bKKauW$#VV_;|?Bx`1E z3VooVXP|q26EOazOT<@**+@v(bVYeYb^qzlmwFJv1u!X|J}Q_FghBvDB>;bE0#O5H zLCqU;n@$a%gyD^yAE@*}3_J#iiw~?Va7d{e#2LN9XkdgHXS# z7V!TU>qP+63k3}g6%F&eUSJg0^NJIoq0@3>T$WbDG_t=!$K!W_@J3`xQ3Dn|ulgp@ zeTQCbVg|mCj9ceb`&zT#SFuO`Qq6v>*x%|k3c83223{U20Z0`tvCYfWST zePgL^0^!k@rE-II05Hb<%(M9~(@>>nr21YVyypQVA7S||$zf)25Q1J%Jqp2>R+0rV zVJ4@c_Iy3H$Wp%xr0}BL^T57-Zb(3@-%Ug91G0W^s{t4Ok{16*zvHppQ`zNDNbzYc zN!p0-eR-;Jife9hcWaILc)sK=D!`pS@Rte1D4=2p@nyCTwmTYfH<5 z>@%Ek#WyqH@H*HGZt}H7$MK;XZTZ*h33P{`93|5c6}C`Nv8@-{GIks9QhYJ8Qejsw z@4g{Z8^xA#pmt3u&27@`Jwou1nyx_AT+J-|L&OHul1<@&lsY9D^Sg!Bd6eMK|J13T zl>jkq_Wi(8#_S+nhK6isLqRil>sb;Bdc0H zXuT$Xjr0h+u?o4)Nr9+}kaz~}?RLM2tyIySaev~_pC%pKv4<=R${mIIic=~xP2*?MiaJE%&_IJlM5+4>2Ju5%TWaGy0wWT-q+sLxHv(1wgtleGy zK(zr4SFVG=1-Y+Z@wBQbkJn97Cy+lsZrlMz>9?bAE%CqG3(&sKqh^cW&!bGH+jr-w zoem1*x;3IY=2~^$J3_hqBF-3GoU~v{Z3Q#<!q>3Zj0!tz#Sg>1%nv=NWBdfNhoN+T1-lFW={FRnAIiy0=4?1_(JD2 zJ^jnWqh5JbpKezA1xqz$A0*>tUy_sV4F7S_CT?>p-a-o%iKm%w!0f zCb}nmkk#|kgh}u%4>G7sPY)*b7ZCT&i^T`*9Y2tg zl6X{NEhgcM@hWOErWm(GHCt1Pdksj%%k;k%LN-@{s5TIo99pM2v6>?U`GR}y$Nv43 z|K#Ir8&3N2keUz>5$@gz#6GIYW|ciIRxbhi$!fvI0(>y~Z1nM4P2u4?80;E~y|K7& zKJc8ynBVUERD3(~xwry?4b)ark6Z_lk|I1>OKD)P!a_5p<>&JaRC9s={B7>}Hq-tm zYZ({T>pqRD94Omio|+_WkZlyiDVHQ&KhCPPyGhM+M>1&0klM@~SqXch%My$Mqw5B#XjNPL)3Q zo`(1=EZ^-q2WU~MaJbp_{dMyD+yL)Rj*rMtYPcom$M!4q$D{!F)<9jt_cvTIgo~$F z2Qu6a|NfayKE~9akDl)!JXrRl)+xR{;k?;cXtI) z6!+S4SXQ$0IoP4PQgFv76o65{_Yr{g0pb9hEx&Gc_>;~tau9;ikP#o!MYzPbbPf!u zZs15YQ7cXXoLKY0s{LcGAEffi-qPM{upt339++kApQy^$nolh5AJ7L}@R9|o*kZyZev)Tk-4e)9-Ojlz2iZ!I3W_X3}9)oLJ2Gscx31;{Zy zS8!$eVj}>}6F?vN;CO~<;Je5k9+=>m^m*AQ#)a>H*u(x=<5oz6W^_GKyVa1bmj`Wl z3?@-tp%v9l33ckYirlxBy8pj03XjEHDCUo->VN^Yo5qs zlCWv1Tw_|xFTBn5F1pjXwA1ZTQ_B~SWzap>W{^{^3=4fqMt%a`@fz`rfTV~$bl{J) z2soj@r;QVu@-gYN?Oxu|!pWn#Tq+<{A@&Oh3R?Uj$d4scf$e5>f-g~wdqKm6CV5X) zj7l13pIqO?p#h+|2AxBQ^W-#X}$cy4n+z_kUh_m?cd&qY>uq9O`0;bFL(+gtv( zby)ZKd!b8Z`|o{ylQgtJpnG;KsGR*bAB{h;O{iT_CQvof#Lp1#ZJLxHqvr7u#kU|ENnBMy>z5s{>HsHilk6{5ry0nmH_$WxnSnb zKcG7zYe}k!Dp7jv5(B~GP$`u297(`+IhMd`o{*udd$npN^+!EKD>uqOVOH+P$>Dp2 z1X)Yyso+ZTO|ST-eSOnWziE))ty+E*693NC2)P(}+=ZilpO4i3$7_0g8edm6tH4C{ z>k*s(>{R=|dA)`K(Lmls|Iq{>4J1A@L^BRiwO5~A(rL6d)n3^pVzOV5_=aDZl2fxr ziai|Z%YQ$TQL4=WSEAxrZ!DC@mQ&RQ?>a22qz1lzz4tY91%QeHM8*7`Y5dQ)h6qr- zZsQ#`FxRTcg6lT%%hr zB$SN3nI4~+uJcHf;*4lWhOCh+H3Y2b$qeUBMW&}FhL0hTI^%_UGnJZB?Z$&)rb))xOfl&O{)W7Wb(ekpW&il4{PgS(2TSc_yLMW984Q=<~M(bBjZ5vt}{8)ReCl%7eD$>v+ z!>|aJC?ml58w1kpbGqN8?6}uZ@RUgHMs_`6^1XZNKR3w#K`ZkgGuQu7bN_$m@6p*$ zCD_~AOu^M;^H5O)-2!_;+{*Bfx$3xHtK(G#LINowzBP6BCQw4*B22E5{8YeN;;z8O zwY9Lpvi*z)C2nSY+pBwuBvM&1LP(Z<2GpZns1m}Bp;6_XaP^@Pbq2*sBLCio6HoST#oNEDr-%iq*8W9U0;UaJ)|JLt?&6Vt_xDD|_R z)){aj1aolwdwU+Lu1pT(Dn=!x;>hmt7MorAthSM+vz}~KsZq#l3RTqIm5l0AZA@m0 z!Kzs&Sh1;_QM9jHLCHCQ-p@0xf0w5#o4NW4I^($g7#~=id+t_?!J|_c_C^!Vqq1cs z52Ov(9&;mc>zouB6q$!JCU(JPTKeI@{a+eFZ~*l zvG+&O-bCz_4?yP1;;e1Jn&g2Vl}b`rKxosCo#wCaq)~55l?_F;Sg%gd?ygA@bM2Al ze`1Kx>#NLyA)ud7MR`A~k3#jWo>Q5`jU{GQy%ZHf(BqJWBS6xbOOd*ALKt`EOMX}L z{e?jz-=6=w!;Z)n3o>+2a2=~M;eeJ}u`cWMEHJSI{K2xSajfFWg3wZ@Q;}j+vI&j9 zF0>%*Ih#q4b@XV_8kY@UdrhVENTQ<@WdIShZ=1cMQLb?b^6!;9o0g9v|9A=TFUf_F1#7_tgaQ%4r;tF_l@WuYnk)w_J zt^I;`@g3wFAny`z=O}EOwz(tv5HeVhVe7zCfH^SW3RN!cW^_riYN_nWdK#=(#3sIo znvHgS+FwckAv9pmZ+JRF90u*b`$!6{j-3oNnwl17F{j#Azc2}4qW+$^=gRI&cZns< zf)>Q>p`!`YC1o5*FLnz&Z1 z9P07D{h5A?$g5Y7*uaOJ){nS94f?0aEf@39md&z?G^9cEJ#E&jC=Z+A ziDKdZaCa$MM`6BRLAsj|jO^8cLQ3BF5ia2Nkd31eM7DjGRQQKQJ3kZuC|9jhpIur6@R{gV8n+~%Of*N3H9~N!c*g0| zaX})gJ*%O+G1&Pltq7<5+{TMwBE=P@@=E;&*nkIzqb$eTJ~WJ1TN*Q^(~$&9*pq;ThY2bW& zAGR;?z|hHf-cZ@P-#{is1Be8Z{J63%(Mdb&)aj(vY9+9dwTyDJO@9-X^}0&0+B8zd z#sX#Vr}y~TzWQZMC^fq1aS4WcK34v>`qS4qD8rdNSci@24}ANTX{1 zK+qHUP{ev|1(o|=)&O!aF%Z2Hz!VWa021SOPZhQWK`^=Q#ueY8i%K4lZMn!0x_~2% zMU)HHMgdYcDO{UX{${86WxK=w@bCP^!i%kTVjL3rJkobRn;%z^olp4Q-PZ-Sr_9A@@v=<7@xj3iw|%bpIXV;Xm;i znN{q-nh>)TaP7_SDHEn${c4KcoiJJ(mvMaM)czAo?A}oiM!tG_HYJ{P))1wor+r4} zTnApajDc*%thU+{xvRVX9z!eCg~ux=)+d+tQ(5 zHchE1*%D5zT;d0kV2mc*yjgWhlwTh~G-IFd-+uU}Sw6#s?=c1`J)N(xr?t0^w?ec; zX4%@Fl4X6P@8q-RA_gVP-cqE1-8KP5$J>os2*69r{%RP3g@x@OH3!B6*&+y-GH}~# zd9QmgCWr{N36#$ejhZDtaRJlPpr}Yo5p5JekP``ELNk?~EYunUVy#`{vjg#+V}=Iq z1Qgl)wHdlNN?K?STca#cRxRkIa<78`o``>&efyVeY{0Rh6ADQm;^8gA(Hyg2~n$ zK>6%-m)K%&X}i{%EvVMnej4>*1C7@pr+vLw1Fc$Ks@K##yg`b;Z?%^d_$XpWV8d$k zQ6H(~AONM(1zmL1e+Y1Z9V6!o;%sev(Jsn+)XIWrKo`M&N`DiuKeYV+wxEswK%m48 zLl*aI7vm8y=4g!nb?Lme*2#!7&efajl)v>kF5%RL@>*O^PydTJ>GI@oa<(#88mc!UU z|GL1%`p*6qyor=`$xnUELZeHjYn)0M#4%aTw_y4vh96DDYd!h%vk1x2f+u52W#tW; z=(SdxAScq~i!a6TE@&Sli$c=v(_y8AV3pstPX3EYd4I-IK@0Z24MBfxm3K+%awm^e zK>9s&hoi(ij@d-zw=N45u0UXa0l!{o5Z;Gf!~~auk`_JpYMIVyXRTj!=>d2~DTr~a}fHw2;5fNJisD|ni>?Ym! zY>yXv7m^^raj5p|`}>Ti=FN~pDDTUdyS(B-3inOLpy0*;m0eVhj72YGu3y`Sta$N@YJ@np1Gb@!XViF*Uz4~mb(%31WE`@ipz-#S9tpVtK0bHv*@+APuq z?EiDLNjs;G-okn!3pqmGE-M#tpN#Skm(lX>`6_Zkxoy&ua?VSVUM`Z+`Qe5zK1$g` ziTz%gb`+U`_=R$OMThqCO!*!F@7+_Q`kQR|lf-NPp#Q}j%q4xAR}1Hoy-E_lt(yYg z6j95@tQ4c4JuvSgV37)M>-oK!A!~j|otxiY76dbh$vKih0Ti;OMYt-_>p+?e7O8Orc^YdhhG> zzM4Eh2a}C_VNL<>tl2{Gg`kTDdMq?mkS&@Dt%CyC~$}{nsTHQC5C-hqr{FgLAvD&~)N%$P?i``~NHZAsz_)w+qjyHJ5mfhSM)ClbC=N^6A~|^|f41h>iuix*eFa#Q z>DvDQ0)m9-0MZCZhteJ5fPi!lB_%O*hlHpgT>?sX4+zZAq0%A^LkUWkq?DBZ7kAyW zyPtc$J$ufc@BF`S=en48-sE|n_qp%qzJGVQ^&coflO6-9MV|v-|8u6_fAW9hHhI=M@CWc3-e%AeT&<_*K1r`WQObDAo65gL9$Ywq04&> z3>BCfq3tCEcsJ$#f9usO2iV9gmnF776Qb%^XMviS$3d$GaSo_=%QPN+ z-FNZu|3sV+t>+;0R2-=C<5n|^s-+?FYj5#e9})E$v88!5UjXFMC9Zk)$6lu*Rm$6< zTER|m>D@AX@Mq(Aj9_i6+_Mxt>c7KZ_f8*r|94TvYak9{VO@jUburvh`3B_t(8GPbd$+{vhL?A!okKEF7AXW)DG@kcZMBq8x^3c(33s`212ppQqrpJ%KL z+%Ir9fJ@*MwvK_|r+=)qKl-oq5BSY))4<&{+rBZDX?V?`!d+lwFRT0~dPe-!rtcET z?;zQ)_hEcn7=b0xMf@8Llz8lxj7#8jsXGAg-TC?-8RK=fvVMu#4sEJ;+NMB;zxJpS zuP-1RILBMR%YN+xT6{JKNvGm5MPruRhV2bT=p~m_18kl%&V95{)n4Zf{t#yhYFwXz za|JH4;zZ%?6}r;ZhQ=6#S+mJ++)71>eSW`F{2{yJ;-*|H-!%@EM3^Hp+~Zh`H#+DN z9#LXXT_sHDe$}d+635teN0^p0gvmh+W{8h&m8mP>k1r%A>!50H${3QmJv7!?mc$sU zAY}KBmF3lj(#i;N%10@Pt>0@tf#V%wt$o?lZg-!pHMK&>(sQLt26%_ebFLo-vqI$b zSy_aN7;K4OG*YHK6?lf_t==?Eo^8C4|nsCdajk#+e0oTm2WWYZK7ji*qAi>bLx`clz?_hJcjF$ zUKGM^5kY(qagVS|&nEHotHsC4 z``H9`o~ekvnY{T@W(252KpSABBZnjAV4x^Vy9`;00AO?h4xlu|84V1gE2eDfD9^zX3Qn)g4hoDltQlC-=Z5wZB? zR58o+-ORfF4#2@u4vkY_mZs?I4Ru*oiw_iGhq z+PpHP6&@dXZO(gmlckFM)~0-!zmdD60p(UhiSe5?r^m$QjTFiGjFLR#>2>`~$VgxJ z6BgEJFa7&5AMf?cgP)^Q;|Rhnf12$DaV0KLYvh<- z-LF?lH$lr8Dx|F@xgn>-J@znEFK$&`X@H@QPUf?UFH%o=@V$!3#aZIfF-hCC7;Yzs zg;pMG`MX+&#^Skegiy#gu#(7I<@{XpC3Rd+FHwLxg)6bkLUt8+W{?b`gD6j2S1imX zgbn~T0IcmlFR|3L3G-hg*}Gv0XM2xg0Rxltpt!qyNTsuwVMd!ZVxa4M0us(Djc zqq8u6-kLeH_RjB~!oQm8_*6`%5?2AT)3=KSq?)J`Sa}KgL<(;uFp10f{^6PYZASmK z{oO%G|L!ps`o_Zm>0kOsMRze0x|X$>j1&MGQ^oT~T0}5YM@4ul`q*)@)lHb@*c114 z(`%T5Gfm6;t(~}>=`WyzUB09l`-4OIfz2lb)8%rO94aId>J8Qje0rTPdH^7yb5U*Q~2!I-{uP)8EBe)ExgFLad2YYmZ)UQ zqg(YRq_V%^WOQ;wbmVR@ad;I7gy}p*p<)-zR{<~6yBy+bFqg^d1?gz59VxlLeN|8r z29qBmIiwU9AV9Y5^Oa67(9NL@APSU3YcJz8+RE*oh+h4ac?BCTJ>7gXt5^H_;oZ5t zVlD!|QVHmj&RV;9KC7(!R8>6owSI_G75VPqohjAV+R}wDNR)R<=xYx9Z{p;RYQ`#c z#8?@63UoLPyj0Y=soUP={*&lJyU|I^iCy= zRt;R!jy>B?*PMi_j(wX@HI~PBrb=IjXsAM5pJDz%FzRO@6xS3S&ZHLdwmL!3ZnxLS z6snh^NNhN@PVx9%goJQvbx*YA@04NKzKPo|nm;M>h`cQ#^=YA5R0tuIt%35vA5o37 zsxu>I{6)S}uIX3Fx{_DoV4FDdE2Ylm9jj;hq5Vj`7Hahh%nEl&#aOF?0IC}rR=!+D zfo+{?XdQ3bkl~aJ-5pD|lVF4u1VC!4wA!R`Kfo#nB<5(S3_P-9ZwGn4{5{pN;9x!!-fxY)1nv zIN>q$<*nROnU~)C>8w!GM~o^*Ea&5{7R+q z0F@S>e52r6orQpDjDSZpP{w2nw-O>mmRXPQpg}4i+TBsZRPZhyo75}E?4k}t{*8)d zveJuHH!7)w2San;-($>8aHd0T>j^MogpF9_y%`*5h};i%$R@VU%P*M#oJ}Louax2F z-cYmK93Oh!|+EToq44-uFhK@AN?iL#1=L_6Q%&{D-y>>KMAq>7emn;>=F$r;3lu=hzXvZ$|~=G8%j>kaF>*m^C5c4N_WyxQ1e8 zegb9dgmsNRKQQ0*dO^SYu%8I^6o@`G^hGv(CDY8p`j6nrbmtL(dgTG?)v_6=-?opM zFBD%~RWOie6`{vw+{eA6HsJnp#rhG|CN^JPrj<<()6=_zPy-s-_rVr4QhKEBFLZ99 z(F=aST_{jH{iv96!Fzxz{~ZUih|=G&)lu!Xd0g@?pQ%by%$}OgG`4&ZR4uOqNtgW@ z0JVq<{wPw574efuBp?Tja)&Q+OdH>}Cs7Yz4mydC{~(9>qnzch`~G~>#Ghjz!FDu= z0C*<#&Fb};S_3w<%77t;$iQN@+}VsA#@L~}pUXw@Ov11Jpd9WE#vv$T%t(V7hiuo-g z4vbM{$j~S2cA+g!Y~+sCwuy=*>S9;2iU`{36onn#O?z|MLd4i$w}#Y)Je`s`te~P@ zH(B2Fs=M`!LKz^Y!595Cjt_|BD^jtfHxnq`TtK`|TiN9ry~NBMa~ z{%cGGTp!8xLvE5g>vC4Ihe38FQ&%!y7#lRQ#MB=gxj3)S8;xw~(6x~;9D z6Y}KDK^@+xt7I#lMOoNXx_k_&Pu6x~@E>`UxEpC58H>mf!(@hIt{fNi3{&A-Hs<8X z?Y}A8Cyr5jG*Mhgse2s{JCg=w?=OSjg-yX?V&0tJiyQd;xurGH^4q z2r7?quwb^xyML%l<5GxGAFmDio;Ii48q3xKkt7YPR$@SeS-J5?G={T#Fpq}IfXo^1Wv||& zEtT&uYA_H8^8NT8x>#BUKz^Nwq6sx9om<2+-UGh6B&SQ79n{F-sPnIuHSKthydPhU z!dSs{Ou6Q5aBuuR{-|}omKK>BzB7=%npHrrrq@_QdWGD1{^3P2&vb&eki|98o5hX} z=trp5hL5Be`*!#soy?g3Cc5HhSU-kvW=so+?fD3&NviAigy0pv9Em3(X*f^3`lVJO z?paX)lynz>e|{Ai_22BfgH_+DVE+Jh7JtP!HM@Ue5R+~TYz4y^Lg+Qdq-&h^j5X{w z9)71{it1akQxPdyDTKyxMd?czYvCdq z$iQx*_jtm?BZ_dG>;bRmKq=N^-^4B%=9T6$IKIh@NK)n&Wk`=0+ifma{ownuuskKs zkDfcN!auTsVvftI3aayO9FSQ)MH74#=hN6>@hUN~3Z|~tU=@d&#FiD-{UJB7vW zLZ(wmJ0C`jSm(=neeB$02@%liVcX3CY@s!zD*C+Mb4+}BxiH&{Iyp478_@9l<&ueK z1>)5umY>w!kliV{rB3lF*~r%F7%TnDx`#h80Tgnt3Qxsk1W$Qce`o-)O-6a#hRDsH z9OH46@0b{L(cy$Yib+cvFI=hQ(W%}xIBv2IY1WAE^rzt-k>rDsnNnMkwbO>EIfs?j zlB>p4zI{Dlzn+;agK^y+x~f}d2US*riMdkoDQR0u$af7PE1&YJ5=QM8&y%V_*}#bb zQws)L>K^l6_v-K&9vV}#J)sv<=4;Bb?!@!eShS7^M8dIVGg5@Eamd#mR!!iH-_A$C zqHWzSI3_O9s10Tx&FdV6EV%y22Qu;Bh{6fvd!O^XXn14*C8nG+(tj!)vS6 zdbxJC^+_(7)D%)rZBT!{GIpJnzFTp8gjK%+HLpxKCJI~VxUsD65wL9X@J%m=oO_8h zo=0Uf`68zs^~%j{>V|^0OHXUES>$9y^9R0i33#{Bsp!PA{$8jvF(Uho1Dp0w>_C%l zQeo5q7SqltoCfEhU9p1Yzm$fKQ~B2a3YKM^cwMij$1Mnh?gy)r>8+sQ3iLLAp+9JVdSwP{S_BjdY z$D;6W7O7@E=iK;L5U>_w#$S2N&g`=PtNyUR`Dy?V*3wUgS^ce51BCD8_}ppWy)PL5 zkv`wnAcr!e0i~?ZV*y3zBtgq(p{Gd@5Kx>1#B#nHD9@J!Im_^MTgJ*V9cvAoj-~)X z2iCL);p5EXEJG?+L9M{)8|Sg%jQvWP{ul97Jb^qi6bLncOb+n*uTQ{J%=}q)E3`TY zmpt^JvdaCpCT_E6hKB?hjfg{L491OH0UzeYrPp*mS!u^d+`)XZS5h0}FC@s9lq6kl z&JhV6L!jV!sx<*+Yg&0Ps*X?DNaJlCsYa32s zbTQ!O+h>3T5f}o;{CIh`E9&wulOh3$##nROGVDPj*-=Pc{8!oGZ>INQ2?HrA&r9-xu+QF0_V`)3MGP=PRr0)y<=GB8fTf?K z=S_kD;q{WB901E@_lLx@Xz;yaU6ZXeR{+H7F|E>SpA64-Gi_*$;gzTk8PRLFRS=)hC zyD3os3#9Dt1|-vNO29qj|K?BDla=Lqk^OszBiujv34R4-lb)(V98<3TY>~iV2)?E- z9Kgo?=~h*Way7G%;7*?2DybH{(iM1=w&ps!?YbX|mKRN}SGTH~ z=EixSRS1I|mg)oQ;RgV-tXy@&7_T6Qb@MCM^xe~qK z8yI!XZ_tv1mNxj3ydAfr7W=d~+TiYPM|ZVU*R+7jSqj)G53rH86Qi$eB;5Q}u!U?h z-%X}`Dl>xHjxY10R=6KLbBE(XK@gQJ(A_ikLi`g-T+8}{3WIaH_H!RbXM?3VT;_!c zD}Pm4UT1(}oMm}I|0jRm?fZ*k{-5KRR}xPuL`@t#4B5mva6L`6@j%9j%9ey_zGPqrY$;wb4oN5TWy5{X7;zUyb^TQPRYf}8D(oE?Rvx(=dn8qgvv3`%LJAo!iu`Pf(1gHPn|M}4evthlY1CFQ) zLGhQsqH1EWx^Z>FI-4d(LqTLxu}WNWmo9`EL!OIJ=4x|tgGw5t25HYtA0=!O!i;8& z;#_;i{xXg_vyy|a&N~2n4Bvo&(XwOcBjX+bIpcnm{aZ%Xp3h!>_!{6d4hPXZP_ivc z^)B-2yBK(bP1DrXrw5rKd1`Vo1x47uU`pVI;)i1`5?`;#Iwe|-+z4UL8t)KGmi}Sq zhclTWVt-xs*MJ=SHABwm=-)#Nkia&D3rCJuduCf*!K$|=2TTKyeE@rT{?F+2Xg||U z{?mVBe;LCyw=;8gaWXfyJ^N*EVvWmlgZ4V@*$+`sE_GKE7f%OsE;(Cc3v*m9X?q)c zCv^v7Q**9c=5AJ|=4!Gxak;du%v>yKdH4nRak*}rTUl7T&~gi2$K|?d<>IVj?j&t* z>tJtZZs$TPh|48oW#eM*#C1zrFlmrYWVW+)H&cMqlz|X_U%`GgYE+Z_a zB+ku!+eA)DOUJ;_KoD}z)*Nc1u4kZo_7F6}ix){QldzJKvg(R(i|GEtpD!;#MCZ}2 z5a?r|(Sgv3&@hP5zO;a7fHq>Hef^xZ_w0j)j&TkX3;R3{?giiiwUS8qsRT~;;5rgH>yKZwpaPk*!Q6|q|XCIgR&QvePw3F#Fw@@tGt z%q*b{hG_|yKbfKnZ=JzZtt*o70T;1F~JiQ)1dK?(^Bse4{ z_Gw&v!n5aznOWI6xq0~oh2<3pWMx%#P3`OEme#iRj?Om&gG0lpk6zKN`Gv)$ z<&~}NPdmGN`v;#7&-#T1!uX+E!1s6iMFjK<{oFZ>bJ%D7LPK{y>p0Ol%&RxBE=j3k z8#`X6<9=`+d^0+u>=h0@kJ=`&iBmr=2?Ou+wXL(ReeK!r>sY`a>e){n`&+-pL3kKw zz{|rR0!e^A0-+00JMY&~4Q7BN_toX5Nx0Vl;K+A%2rv@9eUbUAG^d5N3CA8?J4Kp$ zDr6P0%Ss{{Vj+nxEaJ(9%}Z8~OW0{ZWb_g_%GoqKDy&D$=ColCwdSpOJLQ)z>P@x^ zqUkNHv$k63TcxL<*5;9tRRa7LHc!l`5l(rVK|Fd%U`;{fc}mb*;s$)E79MvVT}Eyd z3vW9h?gakB=E@(--m#t3}vG>dh4Z!7L`1XRjE6O1N%dvH*(ECQ4A!6zDZ?fjqR zBV+lR_6*K(Of+YY*}#%L_1dnrFwpy1I$3m?Zm+kagByfQ#V;fcE3vgozv=m!_M3zj zWxl;DgT42Uh~(Q(R#LrPs|K?%;@g=}rF87p#4@0K`#_tyL)GrW+Z?$$J`|^-K_~>9 zh^)lYD4hKH@g2ue;GM+;{K{_{{b&1Fil+sqffWd@gT2_3Pf#AeLcfgSwF{?WfHCSm zD)fVyL@+skG5tqW_d<)FAw2lRM;PcgJ6UK1sIcwN^Xqv4-;^~;3dE0Z_m9qsfAl_L z=-#}o?bzt22-a7$c&Tx3U;?@8AEjtm37FB@Zl`Gs;f3!z#~QeN&60|#HeeG!Ff1eP zJcN4u)y7U7Jad6im_`WuZD!?iamHEAG07{`G>xnF^iIO}YRPAj6mEm1Ed_naAC~jZFA04I0$^72?E}bFy1`TF1RD7fIIG)&o#{!dY^xV7b0PVPWD}0meIh8NEISM9^bnDp z{Ne5U4S~|GKu+zIcjT!RjDsQ*P4U)L`|*ArWRA*lV$W(4-;HHfm<$6!ig0DFRqdk0sdufOA!D?RYya$UTL^*^@iwr*VXb=8Jb)wL1=D-`0}z7&H^UcfePPIrU63BZ|p8DAaLzg>w6Z zZxq2B?3VsA&!hB)^&65y_wL5&s@TyzII&70dKh3@l#ca&8Y9DfTsueu9W8bS7L`DF zNX-tT7z7Bl<9_`!ZuE1`bl&clmEM0@_@{DwBN5$ovufSQ?0^ zgR;sqcjfAJC}0Aa{s*YDO7pYq&fK9_?JP5|;ciY!Zb3oqb=hRTH@kPWviChfoxU+)RFO%9;7>c9Ex>yU^ z=7EZGk2QwuGY8l1e4=D7_MvHwA5UqI>PK91Bh-0+5$PXqYj)K+Hf1&k9du1x>^UD`K;XL_Q{pNGSt@ zoFQ!o_7~OW#^e4>zO# zF3-6`l-8@$K?e&C+%5%@hvZAVwr(R@Pp*uzr}XU-XZN+d(P(=_Ev%gk+k;OxU4(dA zw;D&y2U&x5YFXiN;|9924g|!3&N|SvFxz6gFrwG{m|joQ2~wZ4J;}1L3*m-6MQpX! zkFbC%%cZM7@Mr}EyFMx#NQvivCjSV%As@Xh3H~a-XX`Z&;zJ^;lyTGj309gTU6Ms? zw{N;j>Fvhh^s+Ki9!fJaCNEHbW_88v=#h?+YzdqDtr0l#NoVAo*;i0W!{{CVXD~1d#0WNvanq{#MX$whh zt?$OZ6G8qYOwBW^DmXhXAfK!gC=ym8?nfmV%MGz$FU+Gz$k87V)w3j(8of zWE;eb492gG;?8~WQrBwC^u6V@ay|X?6^VgDDkWW|(P`rit(ifNnWI8K@=79&yUfJy zA!C=Vco?8lJx&ADgw_=#3AoeAcGgW0CVoCJACam<7JABAiWluhfN8R^rfa z3*f)8c%c8m<9KV%r&3PCguo)-#TO>t`$lq{Pf(tNi>X;M_WlxIrM zfWm`jy@1cXeNX%HgsdoSxooGZ`hjvwJSn-83H4;^|Bd-Q;KeOSEUnF zytQ?w*WB=(-YSyf39@P5iBAmUIv*nx9e4#JG0Q$fDtF=yZ~uJ9SUXU!i%E6F?s7|4 zUi<42=<`vY5z3KBBPie$ycu_8O2w{ox~R{%p{8#~oxhCP6I;m=BQvv_!n0l$o={Vk z3_+7%W&&rap%4@Y3EBzW4~`zTf?N~lXLYR9^|>^NrC)o69p*f*emX}T7dI>A=b25B zBqWJoi#LLHY>MTUcTz^ZCF!Gi?kq|D9O7iiu*IhLwvwNQuZz;mt$5k?Sl1qV+;EAT z`JD!}qa@WXaqode3rCN8tNgqGB`wm+3($ux;vc}Wy;c~N{b3qMm9|A!U zQY92K*NUz11fKA}2@)c%neM*TJv~>OQVp3)1WjdD%OS(H4I3?YbVaLU111YanhxZ4 z9_bY&Jz!_`y-Q$;(GXqP*1d#Nq98fK$tPy$A@`Zy#sse5;|gDrQRJ44S^M0?`k`LH zs#u}$PNnm?rvg2e7^C?mFx?TQNMrD&%A*l|JTKH8{#5q5CwCI8LyjLa`is=g-FGcC zST38OkR3I6VU15}&`>dyq>Q3)c{B~pIEbI-ur(9)A3{SdZFh>N;Kd|Y;Kgbe^|<72 zVHH@$SPgu>$o%r$OsSPGZNngv>*I;px|4?&Xq~x`JhuQV$;2+#xQfzy>ggt>3*aOk(mRaQajByh&7*W+i>$2PVytOgXtQU;J5C3< zPr9l;e@f~5WoT3xDq_#Hd9P%WQW#4;N(KTF{>D}^Q_rtoHhV~ylNs(G$Yz;w1=6aZ z03ogZ<_2@6{ZtxXk2spEtI*69?%1alyL8Jd6maM>fBYMfHy0=U+7W5%i600LJ0+(0 z-v4rUBxo#ox0cG~o0R*+Z%$0$2wAG5vAhH$$oTGqr91)ExOAsrnP;@#NWeVOk3y>8e7cq<#(1>O$8;vC1s_<;86rU|Q9au$C$>izgXKGxV{;vUI!& z4#Jj0Nsr<@EMRa`hpeV}8wVE?sqC;t2n5g!AK(>;DlpiP=~&R^uadYq>nQI%nSEub z69P(58sb3eK@!o6!$&`be6Wd;I8e&N;$usFHdA~ot{tgfAHmOIhcmIPq7!zo=OAW@ zk-epr;F>?tN?aUzPV)Gq0JA4{dh*)2aB#8k?73K7zl&V!nHQn27xpAvfVfYy97=mrEf-Mj2%`hin7ANfP2pCN}hXv+596^*> z8zl}M-Ljy@3lb0TXFpJBB@805=fGfHbQ3DEmnMRV)1}U;q}+V{p0(`5i0pKA*wp1w zk&F_N=32gzoT5o7XOWia2#{bm$crS0B*EL10smUYrNO#$1A$*8`~Uql$-+Cm#Y$hL0}Y=H>j0>3G^#J2-B z5;N*dM?+}i+8A40CwFL64c0t+BRL_baF{U~VT^z&668XnqOX6zF9(O1mA z!$x+kDV5A(uFM1{Z}pNw=7FNA|MY89@wf-my|}qm#(Q-W1v)iH>3!#XnYK8S@^!(L zNOKp_+ay)TA}qC=_ag-fZc^GUBDJ4hi&JOY za`Y?>M|=v4h|7Xox|5F2Ilt3qcT+fK7$yud7ZR|RbfQCG4`WUh!HV8+ND z+C8C>)%mbJ`)n3X1w-FAwt#(#Q`#~d&q;vQqohu0^In><1E<-&=R&U347modCu9OA*nb% znmbBLwIiKSVvD$GkMN0cUF9{kd-JmLOQLe-?#0Wf8I&>D41F%Kd8;L0Q3p|_UL8b+ zp0ky+)?JcjWpUwIvp)`{3f61o>;rc>DYj-dg6dZcBcwC-6cux%W-sTiloW~?;ZMtwLK0@Sg|KH ze!?U|Cy>H}GI5D_nrMI{-ZtruX<)HJDTY;*0HLVe7SE?`m-Gv$LxO~pbbF3xp3gha zHv_&=>!-5y0j*|Z6v;Qb&D;0BfN(vcZDa1m<3wQ1DsLgHW7QF!!5UFvX@HWz`-Ha+ zUtI83D|e# zx;&bbeS(4uza8*h)k@Jgy()V*GlUiQw`7#F<75Jdd57dZeP1>IZp-dpV3S-AqD~pC z{~ol1_G?!5C+=f00hzOA#}k^HwpQh4Bo6j+HaCue@^rsl%k5tu0f?jD)8uO&rPt!I z1T)fVAc=n~^|@oFj8~7pu14Ten7^|m`S`Ubl~n}Ii;hr)Kj^yfuZp9qOiFUnT6Xk6 z6d@qTDA7d29K>c#s~gen@-`|ZsbX8-=I+p*u=`z|`Nv}S2obH(*HeL1~Z0; zJ^=3NBc+=qw%@O6@AiJi?9vbg@LrBn1R7wM{EtXrhZb!G;8|UfIWW{Wu^g%~Nd%C{ zZzEfHo)U9R(Ao6jV2`0~n7+$b^f9ylHw>-kczE&f)XML_vo%H4OhjTVtM?2{_b0_7 zW-3J8Vcx{U4JQ>631nTYsQsXNX{$or5(XSrJnphqkW={q4BA)9R5M_~ah?pft@4`PiX|1@G6`}65prbdx9;2$IQCx`e~R|z znCGa<2)cv&>3!fpOQ>t3hI;Cw*#>u8ce_HJUTW;4oBl!)Pg?xUnS1$6U-!2%J-VrX zTz1jjhb?srvb9B0iW!$!!C?F8`Vy>gxHxg-b?-UafC8Z4F2P7kEq_SN#4>7w-uV;r z3QTx=zs0NaIbWwieA*;E((u5Sch;6wpWV+AzxR0y{Ya@nBalYyy7gaELTZ3IuqAnHOk zR6Z{l)n=C4iyFE6G4PLHtH=_dc;={4Z&=vKT6F7V?=;KO;)A=?_ zjBdNxp~05QJoUR~>_Wu-_oY?#_Rf2ekd=6=5BnkRn-cKM7k#*__XR}s4q{<`btzi~ zTQ~C+Rbv9WOgeu0mVRl=ZB@E}Y0#xW$_QlBbhp;jzTD&E)|;SnH(H&hxN6Bu;Fym~ zH*jAtl+yVNaB96-Y$n;Zh94nS99MM-XGQdEB|eUeWhVu_c|^c6B~TedLpVV@iIl{{ zgdJ!DlgkqKJjR1hc5Tj*l-f`Hsus#Zd~QXuJfZc{HmrrMG!g`!kL=M7Lt(dYm@|05 zZF}ahV}!NUb5<@cr;=5s+C055?k}WBV>onQ;KtxCg?r4E(`8iynb?_b9<91 z8_lgp{+}-I7nv01wJ_U!R~gYc+oM4=WIc}q6$ASw6t$RATsYC&y~X65GvRhjsl@v zclie<&dE+cBN%R)P9ub5>8(rfZglb4_kVR;zB0vBmZUOZc)>A2j4iz1_P%Py%RVU^ zDx6-r2F?)B^tFbq`(@=m(c120=%pThuLH)7eeSoeC&dt2uUe+#k~bzNraX$@cxl|~ z$j@(htIGgK@wyXmCiHDV7~!vp+ClrL7rzhfl|cXep@NNO-N-y(dc=W1*HJkxhA8HGIPI$qeE}i(GJ+@{ ztr>KKLBlE`fHD0Fc;z=t{Y8cy!5D1RI*wW}0i8$n)ORJE3Ryp@jVdzCI>3e7`)S^4 zS&!za&w%;=cj3)<51yS)Tek0Au~_0+{Hs;iFHmpHH$R#fT1TqUndE|l+FAY|ndmii<>SM}XEM6{9zeMK&O z9Y&IeZdnVAHy1-b!X&iHN!^Mif<3YPnaXPPihyd&))o4>!5+4D^}z(-5e)!`266lb zZ~X@K{42I(GVHPfL6CQ|ejvb3kyR@KHVFX~x^o3lOd57J)M<5j`Fav#I4q>ZgJOU)Uf*>rI8 zBebuXo|NgJ7YdL*F3F+(^<|Tm<9@UV*rkzI@p}m~3lza%jFg8tt{N&>_u!f1D=%!G zOWO5d)75N!V0P}_Y4zbTNCBfM+!?gp=`s&I2O`L$OsoTR6HVCBtww~mCjs%{a3V8C z2n`{e=y^tMyjXh*BJZUt(L+BW8t58xI$i_4G-4nf=Mt9VaK{`fHnZcgK6+k$o~k5e z+{ObqC+E0FUJUx=O^wP_JcR%CMC~+s8ZlR}3YJo6#>7&87v;IQsJVx_38#3-y80ve zJDX)fBHknF5Rj?SfiLO{NJ&ArhV?p4gGu`b=8Iv5-3UJdSOtJJ6^K&Z?Y$6I)Z%o0 zLmQcb^OXM?6$*dD*#z>&PP{tofMwXm53uK^uFIN?$K*BEC;or`e z1uO>x2bU(Z?}e=EJWXCR3@Eicy@VX(#9O1+7g}yYy11yEb84pSe>NxCA#)uTU%M%W z7(_(tcY^GvmEur9!}cPl6%@Jc1?!ZV?s+Yp1-X8o{?t^kIEMUJjJ+2s6V@YhoMTeP zr|ENHSyY%XRb9HPLr~_-a(2Ku>br$C&+3W-{!cC=AU~Ac=~l_x#262H+abVXt2vs_O-Rv{))H()(;$h{|zxYg6#fwQSQC zMeSV9UXBypCw8TWcRn0w8Ty}ezS5-9l8m>@E5g$(Fu$$toQ(U%)q9__nW$9RtD3{E zGj@s5zs~e7%(@)W$mB|eY2B|rbN>5s+|Q603?O@$#ut#Z?l|eOx7_JxI9b!ML?6oS zF@PHl_%*^Ho7^-l;qu=b!{2&gf9CO*e_QzSW@2txY42POB~Hgb18mPAt3UTI`yOs~ zYJflM3aJ8+SWH81W;;VV6%bZ}=-)qxwrB!})l=uCv5W>yvi2pR4k7R%kze_Fu%E9mXnZCy9I>!DiUOMnc1pW>r2!iP5~yMVCBeQ+hgwPid!&)ug=+#U zzmnbZ4G44zh${GPSwY(MEB)8P{3TWyzJNSN{C<7FkmjBqm$feGa;+SQfqX4U!Dz$ zc$yfEV?b7U7}e7`VocR-BzH;bDNs!^vl#ujZoZX5Yn)+Eb!etDbrM8zh11{ z9!oQfuPd0zKI#hy-?E(DZC>Lpnwq*fz^mWOC$NRHktG7-BnKUi%>lgV-Uc8GdL05^ zLBJZ|zehvd_PfeEd?^`cw#|*i{-hK26MPFxqpdZjqXmQ!#?|B7Lw^q`MgKR7yaev8 z5-S4;AcyFteD9X>Ap(vMBn7_Y&zt`nQo_HI@3D~@Hf}PP_`U?jz2#x*SV_opFbr%AzKf>(_x)mC)B`oSWf#*w2SF!uI|6R8 zHq-WDkp`7kWB zNELky6nih7q>=9!7OV-2grbb9#pALoZ^^o8*OZ6ckGXylu6koiH)SF$cvP$P+BJRz zMflqTK3?Zw?XJV&(S-=*>gmQf@Se&$pWWlar-?3Qe(gnThly^X+obj3)@+pe2IF5q zC74^w>X0J(WL|S|L=BD9Cwlpi2X^VcF5^{~KU-9+cH!p0qM{2ez1$|Nk1F(OJ=E-)28I}rd4Agm>T2y*pT0@Hmo&RE ze)X`XU+tF?RtT-S2rvEUS)mKW7yPiyyeJs#Ls8xQ?z3&u98Oq<#>A%&Rj{-YfVRbI zHJDlXZGGm04G+D0_Ei>^re<)EW)|8jrW)hbdPefzXD& zvFg`UJ0zv?rhz_FAX{4fJT#Uuc}Z1~ATNusCxI@i^`D~gm{_NXVhLf8E4Z26w5W7Z zrQsvXv2NbIRu|pO3L~8d5|1MXvV;p_Pt?du67rxogMPDz)+5E?0;dwWaIe~=Sp0wx=6vSA$KTC<=_Z=>OS^R=mh?e% z!FQc<{taN#uN7j-#SrDgjB&({CWdk(Rjc_yR<@_$hjjXmc zsupQOnCw#QL$EoaPvJ>`CRmca%@#Le(~W#t{p7A|IzbVfan~z2>z}H< z{O4;fstTeG1r~R2Y)Fz-{^&Sryj+pfRwmNEe;fYhzXkJ5SDLoANKwexb*_POS36ER z@!jGyN8h;YM({0nQ$R}ks{Wvz$Ii#fh)1!=zD@UG^}TvRL{Xef#B^CRP3Ccg^b20^FtOQNw}Y}U4hAa{JB5LTve3yYS4>V~_(Ok3>RX{S z4V!+Q*R~J|6!U&wxcsdzAf3R33e!ayByrpc^3vwg*rED}&VxXQ*Aa4V1ZGyM8f{rP zREoDbr|Cr=E3;Acn}mcZl93TKrEon9IvDwsV;q^8)ZkYyA#Bh*>|SnKO($%(L9hGO|8;3T0+(Q@qV81AO^mR(bZb6G`#FMPe%q;`-0q#3h+h0J1 zGjTQ>*MM~BUqI1t2hb9W<>JSO2{q3WMM3K(t&K=GHp|Q_nl#~x5CtH>Co{?)tq%zH zA*TN(bnx(*)707>6+y&jPS_-L1a+FG;OCA)cZlt$Z^1`b{*GflIz{POIO3o_+82;6 z(@|U9(J%LFH;;HytE5YUPNfI^>HtNY@Hi+JD2;$z#Z3{zH~xO0YHszLXr*j1e2|${ z(22OC9&vcCUx)lmB}_gk`i$ZKN^-c#g91|98Hex;gHMSmppx&myJh<{cGT;L!}bSe zOq+>z@|8kr-n{(`w`P4hR~s64Wl=d*qI#~sLPZH|L0kr*+{mvX3SC@D|8%ic&~S>d ziH1ggG&fFt2>1T#3#Y~fouO=O&LA3jhv8WoPbKlVbmOpHDMkLi)Uwif$m}Qw=loST zG&VA6y8x@mPF7t#Nd$o9Q z*#fWNq2`t?X!+8q#x$O3Cfe7*UNCN~v)^^x+R3E|SJ^JZ^I^M77ZHNVLHYGviSv;j zHIwC#2wd{nr>kVn={dx{8pW&0Zv)Lc9Z-Th5K z=?vQYb?C~YcRp*hq%7AJ6}-ro6&aY|4vQYzLm-Z zZa{G=)$hZ`)NMhbz2w}#8vu{&^)S? z-6K2OSIP}8Bwmn)7e^Vr1w|``S-2qTA++A5_}oFYcy3ShTGqb>2g@gA{zm$OALU;R z8Yr;TV1E;CDuN!R`lE{PQ1h`m-GC}g-{K06{ChanIa=z>L=)*@?0Mx(e>(onGah~i zCV1rws0d@T2n;M5(YKfTVwY8^7`c6qa0fEeMC(H1$T%|TX?A;9B+7Ap#-5=Xz$e)c zqseH-VoK>`7-K&s7)|k&L8$wK=x!VrEgdL97$>C%DlPMR=QxdcDC{zprGyiGhP!S0 zWhJ7VK0j-81GGrdpn2JpBER0N|Bt<|0E;qh+nym6lu%k4loAPPq$LFDl9p0n1f)ws zkdST!M3Al-a_CSR1?fRa=?3W@{|9~DZ+Ab}b$9js-v2n>IS!bar|)O(=gRXsuYHXH z0y|h6|AP(#K|qE-lh{amGf+Plew1es$UkU8UU!G>^LEN}7UP?39_nyO@}*)NgR8`! zH_P#yG&w4MkLV<@+s9;!4=Y#NN&`-*L!jI>4eTru<;E~R8CI-kKLUVqbeH+@BaY)~ zrrX}79g^3N$NTrf=hKE{9t5<@69U!HFgukiQ6&6hEv4CM&-5B22;vkTk#FZ{^r8b+ ziiIauk)+~PiU_>&NA@Ao6AJh#^C=z#2aFX>Ae`t@Wtne@rZZ6MRSD#_c`Fj?;a$RA zUyXY>kVSO>Kfo&gkgC}P5JmiPGx#50aX~W=5a6D{mh<&dkI>l*vDOr^2E}QICr@y9 zYrt9Uuk#QAW=7B#`{>{P9(s3U^6nPlMec3^Lck6(GTYc6+~ix+f%~SX1gR!ris`^J z3<3g9f)?N8djOMpuVH#34V3~!AgX*gOUW^n-t0yL*$kaJg@y#y5uHUqdCN zECs(+zUBCgI#dIj@vS>Vo8`%!k06bSY!r*1o`3se+0S2a9+=oc^N_nh6Qgi@5!se? zk%RdF3W>fL5&;>6eUv% z8E(9mY)?LT3#9DD&J6d>9U5i^zv0hQ`%4YJ+wpFYO3g#Ut3tL$WjMVFo(3-G@oE(l zYczZ9_uGgPtz03R9W~M47P756yQK5Ra^@N(h`axf+G77>y!L+@B}F9Q{N>qr0+is> zq!f8LYfU)&GUwj{T)3vs_@qp3qnqeM)|+fjjX{_Nbq;qZ4R2>vLfwQg7!?*mH$_R- zY&^61IsCBPnYXk2-@S12=UbHiMwwA>5P%e?=i*Ui>Fo zcHdHoC}{~|1UH+u2;{i#!}PrJS9%RPU$C6p-pviR&bwF)3t~&kezRSF%hd#e0~KIH zDQC_-5y z9OI^y!@brbXzgWV#Yb)$R6y(FS&Vpa68qcmI_ejOqx>&8%+j1HS|Hl^$ImTE9gW_4!!xL2c|^XJvCUzz zK<|=Ifah4=Ea9_J^%iGnfmwRT${MGdgTt9D+9a(raYSsDH_U38M{AE%ai1((ODIhZ z5M+#0N>T&7Z4q)xO8^24yPtb6vuc|a&yi$FRg{g09ANr zwZk;z;;yR>uu*DFs$;$yMU+n{6)`HepqpB((<_PRvZHF`Uu#H~&4ItlXIx#q0o*f5 z04(xV=-`j{3V;)lAVfBZ6W|OF8RTIsS6Y$cn;MDYWD3%P%02@I6AboKM z$7;5gP=!LAw2Go$yO=@;2#EKW0)$gf78z5+8-9Z5`>pbkg~$XA^m}jtA?@IyryS(A zg0gCwC0Le_O&26gb$k66F&qL0PcpzDby7Tc1H^3LM&~aZ?QH+V!|EJQ2SBUuapkE zMQo-}$$~-$HOedJhZSq}H8c(Zj%7P152}a@4kc7?axZowpAIX?0F7l@0$-G_qut}U zkCpJ&Z;`2=lW%SeAUpcAE^fcFlKzQ>#_tKZE3F-#vZFw@vwK@slPB8a?R7JWCYf%FxbcThK*U4Oq1Y>wAvp`$IYNL>GrwIB|~dcyX6jbC;HZ zaN{evU4JX|zFT9#Je!EXUKPO)8lm7Gs*{)9w!CH|I#O-3)`uJqq8Ca16X1%L9NU`W|9F z@4O-Y6DG@NcU(q>LWTel%S~SODK!{f70q#%Uqm+FL6sMe?(P^={AL`zMN}yK!pL>6 z$feeM2>nqhXw6xs0>pLQ@kTSRB%ZoxsZ(({^!PAE_IBu9rO zoUT?YpxhDL#;-GyW0}tOgrdLiZt~o#q6Fm7b7PGIhpfCnt9C z(tJZk^YhX3J@PpDoFppKu7MI?%NGAxPrH+BvWarUA|u!=lPjS1mYSjymVK#et*D|rzQNeh)WMA=pv*G{_q zSa^}~h_Oafv@|}ZUM2c{CSG4lbnj80%!>o8fsB)E8115(UjvChof9HIm-%=AbwMFD zqimOn-aC*n{e<)qm27xsU`7~Ta_a=Wt96p$>i%}=&(^uti6S+(S?Q=bmYWA~L2jXB7I$AG&9ZTCulyj! zZtm~GuKXUL^S$56lTRooHbkKIj#TS&#J!bW_<&BI_SBwV7MXelpn0@@WzBrI=KQmL zvaRmwIBUI~LdgK2Je47?d!6j%0n?~&7*TRhb6ZL?tj<==)7~;tQ}#l?J6}eN7`cj@ zR0);+M_`){M85ApktvnHrj|DPk_1zE`1|u?Rkoa`gqETZP_o{6dAx?GAuoYf+Rroe zv8!*}ZL(n$0NufUEIAv7Vdv!zKhg3{%Ir_CtU`i&D*tw z$5Rh)m3z<_HCqnSA-n`m-wC~Vc^O0)=2Fm1LW>)p$Hcm}Hf%FOaEO3rJ|u89zhS%} zN~-AKo+CVfhHFu2o^my5@Uq=P!aSWfpVuib>C z!~Nb>%2WWD@J>O)F>N_c`53`KVB4C8bNB6FM!w~Nw|jplbxr@n{r4mX%FE;T=XkR7 zA7<-@)e~X%KI0Y_KA4Q7qY~g|%Sj8s`>Uo8(dP8I6TU0fFX%$*O!I8ias@MGY$D6?M>KWLlDPEWT2TTU3SKZkR&xx zpnPM$a)oOkfED7!RR&-~fWS`&*3g)u(g%VZ2&qmEL22(fMzGv49j)f^z;ld{wB`}H zRq7}7P@chyw2L{(LyqHPT>A#MXC;SN_?C#grfiOKa0*TzR?-46Ct}W3b7if&Y7DDa zB-s~<8CE4DwzAq9lgPGWf~~n}J#JwLM^|rS9<~Sf?O0b-c7`*c2Ml>wnX4CGHO6MJ<~LM`FWdoUjRl*?<5Q}!Ley20co z-TfdaM}bwCP+O-q0eTsTHf3pfcC z0yYH5#42|d=?}ETP3_s=z)<`Yl+h<$hr5r}z70)i(dXuAh2A^iev|y8?D44~#_=^q z?h9JO<+q{-0+~hw+cJmjF;`QxAC{(gEI-mnBItixsT?|V?a@*BWhRjl*!hS2+$EBl zrQwzMA=9G;peX6Y2Q@AxUoy3U)^PNx<#$I+jmp(j9%raB?y1W9^kebI-JWspD9TYx zP9Vo}+IfzgF?-S-Oi0jG(tP|G0n2CH8V_G8jU5ZVqmx9cp(WU6IirLCdcd_a_;V zouxq9nKsO>LuexTe{C}ScQ@(VN*BndYOrNiTs}Dl(`3tA99jamhid@f4Q`kQTzt{z z%LX7zN1Fut;5EWTHPu~WuJIL~<);G!rM|9G=z`1Zp7)iVcd+Fu6C7AVyVvC{r9K?L zet;x|&SWF;6+k#XKvTgJkQRGwKa~&0ctc!AUDOPtbS;o<7gz@J-@FlyA3;n;Li5Pi z6&~eh;3YtwehcTi$)zyr!@)BH%;pxto3T)4CcCx=0ohgV6^A{32mL|jC|i#u6;G1g z;mskMtJ#1R`^h@`nyyAAquR$7x`*JES1wx8LCr81esmouTK!`O>co-yQLtqE_A|D@ z0vHDfy)j?3Iok*R0Pl4Qj<_YyPG?u-t?aF=;iWjDR+ILp4xJ8npTRZUg~#qYNnKqM z#nWCQ>dSuZYdlm+7&FK$M)+pb*%_t}V7*k%SrD;qS~H6l8Q%@3 zkfvY>)XtZdQBx&V5C%Pe$K5|WsT@NIM+dN%uCW8{y6amoSnsH1%B?{-=q3ixaQBb% z%-n6^^R9@gp) zq4VAE5CmG1me@Huil*P~&4hnA6sB|nP<$)PtSc{ufefoC`AS`cgX1BLG};X@@GQjo z9zVFN)?B3HlxTZ}&MtU6}SEOva6??#p^A1-H+ z|5=CW{E_NF`4X~=JOQeP;HqOJSWXHV6S5Ml5>fLwPTQU9JL?M*>CetnQ|@RsQ9-`( zIZS;rWMXoZg;L6x)p6+0d{rT~Vq*O!vR!2JEdolgKYc~b)YBw+f7$HIBDWiuv>c&f zSDdSEGa_3Oksb*E0%?W*%5`H;WBHFD5qaqyuJO&S0YCuuinRq>FPqoTEo6V$62JiQ zpWz(9iTPIyf!jV1-&uvwfNefsN5XusQOQr5jnkMp`8hglnN zoP`)slZ&HYJH;KogZaSi5U)JT(y@e*EU@$x9F1Y^$}-DxES)7Co`mMw7c<^e z5~?HSJG-QtcqRz$LH|S>vkRy|%9-B5CWbo90&w-OJik5cVU#vh%KAXO0-F=h-3;}4 zYF?uY+AA!XN}&?f9|m**w?mRQ@D!o;2!r({s@}>FlhyukTCw%~=ekt7E0$ zfHHnaQuowsh-pYfix^>>Y(a(vjn}?iaznL1``~5C&PoR=0YGG9nREN(=oixglu%M7 z!pce)T474r5RVbz;Ox}#woA7gJ+B^*2%TEunb*KY?~fp*d;GWSwrkDPbVR|XBU80z zxw*lNASH~8asE>Qvv&1EWi;i1;DBz%9J9amyZj9-k@22yk(E#XKrJ%|MI`v<0Q6`N z+~T;YVqTmd`vT|G6k(pnOh9>!E}*Pv8-D#{{+mCafx6h;O_ufWr-^)Veo1jaOSr43 zlJx~al^O=NXjVNpfRS}FVqJ>^9K*Ikz*+m6>HX6j!%GL3yeIC8wRl+c`l%JxkONiB=wW1So->`JJlMp;eZge?y4^E~deI<|ckK;GT!L_7R@|H7X- zq@d>xmZOj;ig3&`3+C;;-`AWqUQl{zd9lMA5}Kr@p1o~S-hNSp1SyI0yrs zRnEzYOari6znOjhsg1{4L+DjV#W0FjOIcjR7>2g)fh~| z-UURE`Mqp_BVFEP&r^{GD9eoMts?tjQ;+FX+e-i%#!q21kPmC>`Ea_6u-n|pXmLQn z<2HZRB2nt%yYNt(W`O9Xabb6sVdBQi6r6@Yi$YVhABipcNq8b4SECLIdTTj&Wok2D zrwi|VbD@YfXgtzv3a$EKm}`6W;PW6BlFMVMMTiT>H+IP%?rT7k{ioD1Y_+mcugJYV z+=M%!3lCTUJdJ`F6;`+w^G4o$YRrrzJ2_@38D+`V5F`|HN~7p|;%Af zC?_Ts!0h_NMs7b#b%4^T*y7+c-!q%r2(x*q*LMleN zZQ)LOMJRA*x4UasK^Sg==Za_H+Y(P+Zxie(3p1<%B66znpzW;J#3h77BX3iSqg0)N zjM5CxF}hZea(Ucp`JBr8?*0hdlc=;elZ7l$ukg1Fj9*;SZ|=|ZIiu-w(N`@_tvvXB z(WM0WP$!f*y7#F0{uHah$n$TIUs{E-^I=Swj zs+hju=Ts@VY&IE1l!0;~PFSg&OS|DlIo!B2U0=J%>;|*I?Li$GDQPZn`%9>v4n-tP zbQ_vzX)$z<=^nRsMUl5dBXt*yg>0>H4;}h;t}q41S5FruAIE&4)mW)-*bZYzgsdJi zNuE>=!gU4BXXhez3w6UrE4YmS!1`bOK_g=$0a1N(bs!p7dlBkKEw-YYv3ukvji_o9 z=`ZN@qW=RM>Tf)+;`gtL;_2%`q17_28McVRx~v@Qd(oH)i8?iq*AdqEZREE##v)A0 zVjB;aIn7X(ZSs{LouI^iv~%=~x^P+%VE=Hf5(ssUHA~=`2N;FTc##iiFNtslzJsy) zEVzc+iqCDq>c&i;5k@EgK%*Z;68eLQK$-b3%EZ|fqIl7#)8nLLwbTqg55PY?HW0zO zvXgpf3}gyH^Hy*-04Vg%+M=-%v1)Z%Msr4p86uBzLt!bF`WRv{sObF;q=t47AxgeX zCO_JT@gzJ8CT}@phS+K1;pMG02Z3H>q+sMS2Qxq1%KC=O|BJcv9ozf@8~T2VwNDc+ zd)kj5d?w|vKUxVxw@SZPpI8uZSZv(E$BQ!%qljogh7vwFZl76J3Q~XgrZ0SSaZ)yv zlf=V;piHSv_`T{PbJPMoMNh}Ott_*88n?EACAnM8aBL4c`KhsI3Bm2ix@#T;Cwx0s zGU0?`+>kp{^kgLzO)BmP!Yiy+Tz!{Pqv-mTWsH6}Qs{=1bao1Q>hs81M&u?|{sFvr zJyNkZN3!6jbP@I_-XAcG;q)C*?K!(PDH}DYI<$ z#cDP4bi2wKBX{O$jr%Ra?-~00b~T^4b)?*>e>%zCK)Fq?t*@~EG-^TnHu{OWixV;2 z*rf}l4}K7ce&ZXZbYCJ7KLtGd<=`jp_%-U(%;YZ_CtWdn zGo2I$XGn6##HL)=;ZonMOW$zh)Kq!m2@SGTsDc(vBw|2IWj=yj#Ii3amRS{@>2a>@ z)|TkqAQfKff9Z3^`|RDi*sNn6%WNIl3QQ(jX*hY2yEss=-izRkalw>g6RWEYLf#_! z1OS@tBn+abxh29)ckTFVF{vVg&eT&kjpUH)-}#b<}!mFPR~!K zpQ9mX&$uHPmKsjJm684}_8QK9Tq*iy8sXf-$D( zN2M$YYQ33AL2t7ey<2v|&AWBwiZ$DM+qZD>DOzH<+FHl=bM1@D6sz$F+yaCqgBE!i zj@1NnDr+ka7gf3Qi*nt&(S<|pKV@)fxZ<&`-24Eml~ovxiW5UP6Q-;(cZr+8kKQcV zM)Uv($^IoOyx-Tg|NNGW98)(iC?s%Q-_-P2uJS7v9%^I|fZMy$^@fUgmYdvE#PapD zlA@USwqa#?il%7q*MiTvb)(D4TZ}ne7=};|q=pt>QS)ZOSZaJRGx5Nw`L1VEOLKj2 z_E9#_O|x>?0B;VP(|D|my1xAB*~l}`PSCcp+TZ0+F)^6~5M-d!Wq8}cpcdvq%z@@b zw>QNg;7TZI4KjdUy*~)@qNP2$2QO#L+6~b@-%)t|%^V18TH#nnnZj|_>xvlDx&%0U83I8|<`%K>&gG7|QiNa{zLy9oxPz#rzuYi+lM!jQe4&P{KWK!%C9LWIu0*z!9#Z3 z+V;n^Lv|xJOX1{6PwZSSaB1)kTdOA1CtHZ+>dnoqg?37^G%zcg zSw-fu(_;1fJF4T%at(%JlQ;X7k8^+~K|+$`#U~&k$H0t#eW&`o_VtyQzuH*IK~C3( znxQvT%Mr(Pq*_u5+3$}CTaghmI}z=`nIsNXsI-F@eXd=RBnPg=yhqD2mq%D;!#sH? z%Cieq@m(7~!02m~q_TNUJCey`*!5_iUUlc5?)zl&4+ejN_uL(6-DJx+Y}4ebe^-9q zwvQ9hOkh{{uzjQ>Ocr~0nr%Ce$Wz~ zHrsTwgBQvx_pRe8H@np|o$EjB%tCD@+kK37YiI$JL~gA3PdeHok}JPI)1 zUJD^m?JI<@Qdw02I2x(26_zIl!?CG>u8u^tO~|*&NO!WZmB$}Jb3NIqNoj92-5U>$ zJomROM9LTd${wlIKvv3^P9y*NmiBoaV`|Sb@s|w^RB zS1lo3$QaWU8V4)fQ&;r^G(rabL(NiSj=Wz^8&E!Il(|;`SUs^bW~o_8VKG=$mUHVP z)2f3v6Gg7QBT$wb;@F^>k|W(uq)jJNFJHf6mKt|*GbpPpbM1rG^31X9#Uz1*trQk^r3Klsfz-%jl8uSW#BbYX0zp%Q_1{ zy=S<^pkpZ7Vv`%9GqW7M6~~dvl`-Wkpk+c z@rYLb>(!fIbIH?zp7ILvVW$sK4S_*;;bD&y&&x1+W+( z0EG2ZNZ&cXbk$&lGFt_Fu6Fnl)}4%$YmX#|_qF0`ps`L<>qT?|)rwmZ=BLS104A|v zq)Q-UT6|!eNXbh5+>^9rqVdfRWl8d`3av8&>d*N(R6I=qTxA!HB*A{h2*2iS_3hW&38$MJ1SV0`i321=^%%oPs{y!ms z`5rm(Wt&r0pL$Em-^V;QNnRskgnjPi@bMj%sg;SHy{)OC<;f>&BMYpn?9}YkCm*g| zV^ei7vUj;}%67xj@UAHqn}qc}Yg^U(hQ_9B*G(PGjZIag#j)5l%}wmhsIT(y@?f#a zn3~@;v!~|dW5;3>H@CM_GPRYkw!Cj`Wol(l&4=n;^E@p6VVeB z5fBhvrlujI=eoknbM*=*r+}EMlz@e3Ex8O||c->gZ{m90ZJu zhevdth?$s}Sxb;pQ0p(hKE43qp8}KM=%RvYK`8iORDAHqCJ+^Hjp*P{uaoONd4W+- z(afl$CeJRJ=c9UTn~SnCd~2chAkpQGUr!#J;Oh)HWh!1*xZ`6)W_ zqL+j!Js;?=8rgcE#v&pnAtk$biGh)cnTwl;mycgS;<}`iw9E}zRW)@D&0AX9#wMnB z?wXlf*x5TcIyt+z`aJUW^AC6&7#S5E6C3v=J|Q(NJtH$KJ14ieq!eCOUQt=q(Ad=6 z(%RPks<*Fy05SOX-O$A3)bz~k-2B4g`o`wg_Rj9!{=vz(z#!Dm!vg+)bzJzsxKPm0 zP|+|?#sx-kIvF@V8afRJ#yK%%OhcRVw44u55r{`TFM4^J?yAZMLL=KAEFyZYiHqwe zL;Ezc?;Du+-x}F31N)zG4S~*}f`K0o6(1x5>h7dNKa=! zAx}S8_=dzgZ0}w~5xh}vA*4a$!N=CYt&)rOo3D@;Z7CG9s zeiM-q<3}bgoxu}$8O4~ORQV=Yj^-6b)==`lcF9zh0mmn=6f(V45WMvUrZWtqIDF6XoNo?|KnqQamUepR0(Krw#=3487@jwf*^jjvT& zLoa^HrQc?*dAv(r&>Q`lfTcY78XKGYi0M zZcahfEBjejJP~{_+bNBzT0vTpt_;?)FbCU-tjlR5-RMCDc!C@{_c@l-B8QO20GwCQ?j$!Q@|^tB(cw^LQqQc)Gan#9%3c@$Vz{0d-Ld9y}pdcc5O7`>}8+0-#`Zs5!hE&PT<$!E!;OhG$UZZuA5s zXGyoL`i|u)dXq6I0kkOA)_FoF+_2hjB_i-a()@23E5C{DDR(kAk~;CBB-PHFN65Y{NBC5}s!?Xp_@G5RG+>x{@^H zWv-JeJuxQB29-rivTRMM?d{8&Z@V#db(Yhf;IytSD=yQH1gU(^bj)uO`lb z?Lk+WUOgqVNibqJH4-ib!~=@jjKW#LH&25}b*Qv02|y}-ru7Gw)L`PH>iFkSHI`!{@ONLfMuzjyoR-U9w3;ma1+_i0i@r=33+f}-JB$A zD4hzB4n9miSRC&d(1z!DwjOsKJ6O+JKpi9|*kdOo3Dg6=C0qZq*F}0=9y;CzNOd)B zKG7FWKm%~n4+2--N0|7^k_Tf=6;$@f0E{p&yW8KVf`P6u*RX(U!VpA`wN?5Wy1zwJ z)nI1w^h2z<43NF*s08LgEB38j4;nS2LfD$?o6v@xt{pvkljAB6gF}bhsW#t=g12e5C+arkbAosG3~h z-EUo#;(tYV0X_LsmN95+Gooa)BwGuF_XI!N4sw{-5!J?Is37bGV0*S*p0~&OjM5OL z%SWP->{=~du0ydTvm_A`Sg&fj4HKW#Nr;l&A8F+4usSQR`=E@tjO{SBSvo@zQXr4n zE?Wf*P?08aqR?nELmW7qF(#~lwnOQ{B=i_k}&l;8r#fo~_3FxVFG(x;s%ds2d zX2*+LFoE_mdlgsmjH7eHY4-``&eM^*-AOql>^fSvSfFX$*&4yE)_zOr?XTR@MsU8e z;W%&(=?tebss!vYRy_n}N*Zdn%1(zzJ2~51nCD!O@(xS#{^Y>uZC5OIA#}=j{>9SR zpBDAIf7;XO7NvJEu9$S0;c~=R52n2G#Et%b{pS-%e>$e7!^3&T7h42wcPRgRn*ZLk z|IW0pJ%s;#ZvM8gS-5NS%!nFmfeXc>L2P*-jgeCIg8*4q_oqN%C(eWJ+i9=qQ~>7Y zv*O=$0%Qw>mhqS_Ptlc`p>#^q7d3G%6EEE&_MmASw#pKQi?Sk9_blHEmxAFgu*TCY zBxCM*WO`CN>j42geGA$=&nVUTD`;x-?qJJUw$O<(qCPF_zLSi5)p(G*9Fn1<^Y9UR zt;IGgh#GVT47Bk4DY#5Dp|ds%Zz{WXmkO<`JYrf~fp!GrdlVo?ASClsbpM$Mv;cKK zpdd)^I>60U>#RGiX{uG#3AFYxN}Ho#L>WzL7#YqFw2SCe)GhOMwVdPWB}cK*lh*$G zVfco1fOR~MDuQ%BOjjdg<<-z|NzqEP?T%7=u0h;`m@Y1G#>C;-pq$z=aewE^ZJ!AS?y9@E)5_|nJU%ZA z`+QK?5^A?HV1(>+2>tg&|Gjnpoeb+1|9y@=iJPA&8GJKdpgjpdN!h$WZ*|RW(8(V2 zUHW_XUwUGdrCourD z`^Z3cb~Z>Im0 z{%~Iv{D_lw@zIFoPH5K=ZE)hYXFj1g$YE17GEx(eR#!k!~R#vap4j1mI ziNo`B?wQKTHwSP05D3X{vNAxN=C_cNe+%>5_f4S87!7hSkJ3d(RGua2vWj*Vzny%Y zkaM#r`b7JZ4$(jzX=9$gHeRu}nrq;@QpCy}&4n4`B~94ni3)j`&qh9^9{0?hcL7{r zqxP8XJnwWoX^VF-h^V)mySQ4^8o1LQ{-;E(Uo##5)0X|TUJ(Cj1O21x`RhbbsuT$B z%S|9g@YbV;{Rs83a%-&ckV=1xmWlz`nnIi3)df)siZ^N2mdK*k34ofAI^qemYJEv* z*sPovhwOcEn4OMe0?>_XMj}~NlzhuEZg zIaTR%s`wwdP=6@3zUG#-dk&QMR$frtKbyRp2a7t^ac7AD>LJ4c=&CCqw0;*D|I11C zZ|(mANFq!hUN?>yB&@#~%N@%Z(%p^0>%Ug>wk968qn5?CVmM&BkDI!Y#>vE;C9gEe z>b4efElBaN1&pJ?6iu(uSm`LeD+$jnR>iu)?Do_<0lH4c@_;QqzBO&_i(&69eG2#A zDq%dr%g1MCd;w4e{gklwf2{cYmHG1{;O;*wA@UE7`*SO>#GH8Ftvu7cYxaiOH7nP% zP1t(Z4E15_C-ENbhrNLAPHkc4z;(=9~v|fY3;HkZu?|FHG%s;~LPD^&-gfBdFm` zBJx4&oUAZ|d_J}?wu)Xo#Va_DeN4s-nM4I4<+0XhLB^i$9jiA6_2AU0lOXB8;A;HB+VnGR4;bcYeL~Zr}NL6S{mpU#MNctwT+Q+q@9^!$D0OWCk+kmHGGvi8T}m^!_9$_?P3}foO;? zzAZdlRTs6MhE~XXL!6Vkb(W$Ewt8jXs(h>0#5ae(>G( zT`VG+wM4N^sGEh8u-CNB7X-<{y1pHe76}3B^x1qstB&OB#gIIoYn3nNo^20+A3jtX z(t(y@lZD0z{eAwHKe=Uh0dlV|#L*T=AanW)rL>p854AJCWrO_5x?jNOzv-Du4g6}~ z>;wr?cUuZ89;$h9q7j;v5F*nTcn?d#FS~%!k6C*nFJHdwkD!UW@&EwScoRlzR&%U8 z^@dlNr5wI@?`~PBs#C}mUo(j6LrEqeD>?QDjxV%sSnw`bAznIB!Zp8$(1Ha@5b{l( zoR34jIbel$^MiVO!CvV9V%!P7pMHR)4LNQ(P{Mq+=!rK|+<&QDN2!6Q1ya(zeLmN` zXq0fs0PdXp*mGLQ0eS4Y>mxF4;Ikl#zgOO5Ik86h^R2E`CDFyvf@O%PMy?OqNOa@9T zVUsOr;0J>+{e@&`cPIiv=Wh& zw$ZktZ@G?(lwvs0H2%xa%6`fr z;|t45*sfybp=q>T1n`p-oC0QP_|!+xpzQ8hY@`^`N6>0FM#!%Yc_yMvs&oFTzDxE4 z$=Ke5Tj<%hLxKlWMm)2Dw(a`Z1)gnIQ^yCO-Lqszi`w@zB^~1^n2(M2odpklzrh`#h`I7rZ#du-9s)4DKr*m0cQn7eW4h?i*BrgNv` z(Y+}G@H}39{5g?bKl81&sMn9r!+HYU|I!mI0n}Ilg1-vlC9*^h;I0Nef4@MV>W&>^ z-r=NSfvfc{M8B8@xG7uXtB6`d)vV|F0stObEB1?A``SC9q8hNrgYngYSHBob4R>f9 z$}itXi&?HxD9Ox>M}d#r_MJYj&y?-$!1Q8zjccZF?VXs8OMuWR0`O}6aKhaqWb^(& zB4ij+zqcDt-?}UBOuS>220T%HNU2)f2{^Q~GHwOG3boGxqm2OLZCLS~zLLB>c+ibmKg8iC6JKeRlF+;!Gt(UEOONO( z7VAbdhaI_yA>ZfYQUYVIWCh(vlCEFLbAn2o8N4`U+{V3B|8h^$&shX1bxIh%>iKd{ z3G3Lnv?tM0?JvDCWBDe>8!$o}w{iDz+JTY*mLYq7m9r?M^nB{N zQTlAz#)pnKpW<>>3Ar_`90#HMrcDL&6Mz{W*W7ivl496r%Ix(Xf2_(AT{{0&GNeD# zD5U4CT^;ztOzl$8aNIe|X@(5fz-&pZ6c8VPnFHE3`N+e~=Wc^2gdnfClP_41#mvjI z*<0{|T@z~8*;Fp6m!PdnH(Fjgz3Ie^;c(4F34?y9E08*@BPQ!QMH{T3!Gni5j3R07 zpzlb!)-evjJ~nji9BqtYXw01Dht&g?K5lqJs^6>4wiI01Xdi6+wq|FM$Mw^KHpp!^ z-*nEGnfa<^3xw>7P-jnIF~8k*3Qk~a^RBU^yr4q4u|QZ2x>BOn`t?)#8u7&afh%=X z<~$$FAx<+sEZg*&l29E9;W&V?HXJXa8Dt}Te!WrfVrGhyOshZleD2F`_IWADT()1Q zy7>BI=cA>utx27m{?BBwK#l8~ffGH%uaxWVkQ>8Y4wl9)*4&AG+tH>V)ze!=;r7x= zb8yAM#`!VnH7g->dq*b$jfZKzo0E2AM{nuqyD^g(0v(32D~2|1@c6tcT+)x9sK;xD z4X;TKz2YaF73Lg-a#v2d-734cXcLT>Ye3LW+B^fi6^FM)5e5p?wt#Pp{;F`2~SgG7) z7vzTml@E1s)>#W2F3MhSQlbLitZzTMY8J*JR*Q*A0M>koWY@c)f|z^UYByGG@xdC4 zL(k)_Pbg%xe@1L41@miRpx-ZR|E(7wZX94R4~h2IaJ!Z6$1NB{PS*3_jQ=`aUZmM1 zm7wnd5E!dHb6JC<=1_w@^dm^w^GTUd3yVTmV_Oz48ZZ2gRwC>1_7XmxWmaL%ialv& zW5?U=PW$`XjaC&Qpqy-!n6fxaEAT07*MV*j2|(xdYscu{{TWS@YS93&x&h)C8oz@< zb$c7DxuHr+Myr8ahuxS4e=Yj-*GHmmy%Gyh{RKa@(a2805omDgvp&i?tb7TpB@yt$ zq()!{T(%1eXr+TOTcRAvpYrW`QwlEsu8RW7POE|L*tQ;4{ot5M>?7QgCKn+aRWmZr zDBL9K{lpB@h1h~@gZSha%u7`RN`Zt@pzoV3zn?tc`Tai+>hZO(@&8!CvrtUSD^LC2Z#wcdR@EBu4fX5wwG9(rwj0E(8h0q+Q%#; z`wBi=IqZz6qn`g#%JtYHw)<#;#I=b zfpuN1i#aiJ3NUJ7UpH$vB}6O3`v^I22X0#fhIkv<6kvkVWO=q3u^lWNo1u=cyoJ}? z8r2FkKKq(i*Uuv*PwXL@3B_|3mgn+swB2!Ds1~ z$XStT_Ho&^D^QtjFxZ83 z(d@Zp>*zmTSydM=lfE`tz4XYr)Had=uyz1r2j)4=_Yt(+TU#O<&$`8E8onZVGfJPq zCTyksG#`rW!Zqnh$0%9vmYxqOhU=m@>%_rpS^YP)?K70f&(=J z*M#zQ78OoCY|&P1jk*iw>^DejBEU9%Ktr>Ac)|H$hWM*D0|X=VJbz=zEx{>-FC6l- zPD?i8D#Xm?{l=Ul054p9I$TLLT7WjVhk)T8s;`DO(+k`V)ficP!hon@Yogj90~|wF zFM%Ly5`Ez?%H&KPj(E&5l#(n&jiOcJta*gH3~cR%wtQ__WE?HWY#Tql#$W*J^F-;2 zbF@#H=mJ4gM;E8;IOGJ8rVRcsDN~b z3|%TIh;&GIcgHaP7skEkz3+SOJ?GwY?i;`Vd_FUK&sux0z1H4)J?qKuGm;(iQ~2$` z3j`|ji@=pMFJ_fm!1*=D@PX}~FJ~Q)C>%a}Y;g{6s~%tvfxtUyN(rDYnu~*vF~q2Y z^f*wN8%h5B?m%vBM=#_P76Woral&Pq>}0-k6gZfoQ+lNvFlMNlZl^N)MkD{pwWT(Q z_Xv<(Wzpk#-c6f0>)QygxRx#{dObNa+I!v)AMrN0j&f}X#7%6jFq+xnU6O-X?*CPa z1tP6%#F=;eqt)&EFapSW1O>eLz57nS&N>Vgvflr6|C@-rm)+|_=sGbEoD*PVuxWD2 zzH)dlY?BtnnZBP0pVX#2>TN}dG9KLn$owD@AgHdw8Hm1l#0$g}jICto2a67GFGmFOku^H4G~cu5_Ll#zBs;M)xTi!k22 zPQ5ZA#UtK6xP-8rDQB~!uPL_Slx{gx6d~p5_c!Z__ zg2^d%Z6X~`4xf5LdKB$8DsJzka6ivAyiXJ(N$IQUBwe>@dfbG&eH{j77n2zJ}_0 zh$kN}Mi|740z_re+vo2Qc^F5a0w)0tsqL%oHUX62o8ZX--rV{@#;*_+crL^{Yz!4L zhc1UJthu$}KI6;h zK$JYE&^;bwa?7Y@%P<Rn)uC^a~pUjj@Ig5r7ep;@Y6CSXwR# z3(Q!x!3=%?pS~GXU0vIokm?cqpg=+vzs=hlo()ritgD{bx4o8*4|mpZ;mx&pT~)#L z!D!Zg)3yG5kIQp)>%MGQ@qZ)V8IF;)9}+?h-tXJNCtd0Wzgv(8-V@f1}b7=irYd9+o-WQKQ<|CChY5Z zHDzfD`-%1Dt;FM55lmqtAdS7|h<4pbhtC%B( zd_`pX{ScyS-nIV zh|DvWmY?V=wcLN4=KK69(d<;3c>n7$RnJK-T^B~-=L04pWElM@?!ewzusnuyCTwhT z$6t&YpcPiyUOR2`74k*Q$hquz0V;UYN2VjS+TUm>Pv27{@l*|sVx|00WRu+rX9J3P z54sKU1^0GwLExIMC>4=rm zcEAsmDm@T?jmu`_6aJjRU!v$e^_Q;Vi)5j9uiYJwk6G@lXhtl$;5X-=-7pE^4#`43 z;w8QPChsfco!8#|=A$Ny-L17L zHLBQjHqs4rpX=b+9nQwDeS9sE#6E)>a0Ef|mlYg7l(i{O(%pai#K3Xu(Yv-g2Dhn$ zO0xpPWshncrEwxPD=H{g~FQJ$XEY;u};o|LLN7 z?69ak{sU z>dPMwS8TVrdrSefH6C+@2g!}vs;F6oJF70vhKD*YDPpWkI?k$lS?2>Z9kJa&r@WyY zU8X?INW`0@eX%C_%A>1YFw(VoEicKW{)( z5{xBxTal<=Fjo%3Y-xXiuCRCVi-4Kx-cx{^qlO2T5P~5fi^ji2yLZ@LfEIR{k=9X} z!yX3<<^#~8&^JL;m?Rbe&cfB8J-}_n!16AW&Bp;MlsCKRB57=HYF=Iklm>s`I%+DthGor~$ zVgY0pGioWhOF&$b;mos*(1=OKxSk|`>eh0l_@Hv}F~~xHsgpBf*)36#yb1&)J#h z`i${V?g;V;Y{WUhD8-Zn7!oPWm|p0NAeJ){2{sLwo>>nZw^iE5KuHANJAc1)B?lX( z2*bClC%(%X%zI6dX}Mc;mb79r55PTy1^XkHXpm)L!*6Lr`weg*z}N3L*%p3}f7cJ} zhhJk9{~hHI)+c-0i(SRoMl#Cx@}3=`C7BL&g#pQFIs()v=ik6*gOoC7Wae#cfSjt2 zv=@IbU~&3YA3D~9d*y!nrz+}bwPM3;>noy7h5arEj{nNz;vbd$Uv|aP628p!iRj#MAC;gW8AcOH@Zinzt-YF+p+aM; zDo!WNs|oJ7I6ts@n9Y{_C=2@TSR03mXXFBBipNl*?W(y?v0J(M`*PcB%e4hL(%e$( z-xh$Dg?PN~?V;Wu3jmWPDQLxovIe8uiF>*%a+v?sD_w;Xs#9VMs19WskeV82ZVX|i9;W2dt3Dr^bi3}ymbgM+Ar^=QFfEyUguAxTZ%sc} zsIbZ*!CE!c$ak{#DIp;C8Ezb2q=;!p6h_*JvBc`?`OnwL2h^p>-Imz4j|56W!~yYF z&Y)Nvyk@#u_8zSK#6qy(ILmvO>P#<)D#`n0&mhRdyx1B5o|oB@2~|O#^j55eS4NKZ zzEf%t-lr$y+b1`@zH0sR>wD>3ZysxF-MmcOYYctgXCT+~+KKTQpjik=zOP+uNtEHo zJ=&Z7Tu$pp*B?x<=stP->b`Lp8HR!P)%Z_C!o!>;RG3y<%xkg&))Hr&-x!(s@P zJKI=Ic2ir@^m?$)TYLSF_@gm?2*~vI8s@^F`=n9*s)_P{w(TfED2jY3tjj}vMavXCU zi~M_4^V~4e` zf=B@^k#eXDo2cDC1V%AB?O!-Q|8j=?8T;qORvwj?awpHJ>!YDHY_p>`=0f|Gr0D}X z`kAu_i^Im_q%cG${lykJp1rusy%JNjh0$jGpYVXN^PEg;dFV?XZA(lR7aKMpODs^= zFLUB4Ank{eB@$z3r#o;<0&j99Zc+KH7;O7PAap-n>iU$Z2R=X-7ivdxy_$p3vfc1XgPp(| z@j(TP;PL(afRI11uYbxt`Wt^wd8ZxKZNb-X;7!PcwYcxTo+nUW|0CEz4m$-3z687X z>m6;Mf=b<05Aa&Ib5u_QyJqwP@Q+FVcPI&dULz|mENNtj&tkTT+z~M90+q4dYu7bs zF$VDX7exsTMwF#}TcU1+-XfB_Cjxls;3UB-(-{k zSl2JT#TN}Cp1oj?=gcT9HdM9>Q&4JMKMsziikI2CJSAB9>sp3Cm>&QCoYEgh-+v2h z@XKTVM{!CgfFdk5%^=xkG(%{_NroC0g^Xmz9yQEP#mGgr<{dH!Qp3^17uTBJNbyDlIQD8W$d2ytcqwla-TzO9<%+}?A{jbER?f2uGm6*`aSjizVQ~KogYXlM2~m^w82`XJ3ZD= zFDbvL-a=At_UihuK@GU;cJh&u>Z;#Um&>#A#pKT_(#CcW3KPo5xzIPsQ8J&x#5jeI zth*~Oqu5)s2TSE)G2DtLNdh~PGV_uhn=rEEssh8YG-fO+E~%?OR(pj@c3jt^L3Ki| zI{#&uBy3^RjTP3Tv@$I8Th+a=dwc)kFM#a6CFvM!Oo9pqH}P)q62nhaGIB95>bi{I zr+$*(Oo4m)XF%0UZoDP172-@9A%8WP1c!{M38lLxL=DHKo;v-4hAbvx&P3(&2c++_ zRnr3-U4aAfLf5cN5wJBOx?iFNOo_!Mk{sazX#7$)7 zi*)sh6&(JR!(e--t`bbPc^t8Ds{v6{S1Mz>v+ltT7aR_zS_O;bXqO6H4xW!{Pt37I zaBTJTwUN0V;IW6zn0Unjn95p~E1c#C$z4&g~G0HJ8D<3Q0_u!Faz&b zNYN^Mt}yvXY7Xs9J&+V(Qx{1Ed?NN>TLYcP2_Sq@GVHdx0@AEG6kaf#&!Ax|k=?Fo zD4@PV<-$nQQne%CsT-eGVw0TEEPCBZ=)eR22HVk%#8;2*>42W(y>Fd0Kdw~=5t2?_ zuLNldq--wRo5yLZs(Iv$q@Dayl`sIEB!~0ym_oz`(er zPPZ89*$h*Pbf>YN-_A`RESzOd6MBKSp2r4~Lb4iW7$)~*Eso#|z8cg+Q#M>31a|oM zE^@SmtCX=8CeI3Mn(k4ein$OHL(Sy_2H`h8iB=|CBbtnF%tPac?=NYxWYjiR%5f`_ zyr$OD7VOD2ObHM)V+mKSc-MpMSbYqvbF%-;O8UQP6{WL4%M|%?a@IkYSW&PTyCo=a zp<2*40dIjmtOL#gnVlE4{Sy43gRqf*HAqMoEav@4;>5u4a;T@ zyE^zPcvT^;tc2p@o;hZ!9;3-497@DIMdVYbwZ{isn^I3bW4n&0ISnBgUC+YZJMlPI zEqtFX-pJDlNNHo`a%nxGU{L94`D8@>qBOww_kKgW<~}vJ|57-jgf%goro*3Nnc^2ebjg)IP8PR5+QUb75S{; zcBg7W1toiEMc_P4vIeg!#aN~3u)e|W42gPNSmNV~L;+WY0{uM>?p%k?A=}KZ!;z+z z?XdJAVZFdBhnAM81g;BHBpy|Hd3-rUT$VL4LN2k`nm#XE{X$K`wRX)u9Rdp5i0-VE z4Ju{w>e*NX9zR_2EjI{#=DU)z6?~moho4Xv;4{)sYa#olsvD9J?1aD73*t|XDM^mf zn}Ukt9Clzo)wz9`lzxch^X0(YD}7ae{pMkBhE&QHcTh@n1LfEqj+}~D%IN&LLoMC~ z5SzQPd6YG*L$Tr8lWz0I`%{v;_~RQr{t;fP47*d27iA1Fq-inaXcuk=#8&b}Uw{4; zlKayAMulNFz+aRuX&LQ|o;O^!gKcR;+_vr&cj9Vc@S2oo|* zweql7`{Wms4ze>hiz&6O*DBgzCH+)u{TsI!oG&+U9xG6i?nz8m7$7Fe<0<6NHzyK~ z5Ff1wO$x!p`buSt>?pg6xxK7Qi@6jT3W;biKe1u)7}wZ8_G>3?UPJVC=E&t1SVP5K z>=|VX?Lz{bdFZJZrQf~#DX#uD5Yazi&{*QYYxIdxv1}b|b8Ja>=ND;&kQg0*ni5zs za!Fnx<3u;Z*rN`#F&H)}Kp_LPF()b*NxAdieuv$Q`E3B(mXSdClulm#>gOt z?D2MRANASvy#|OB;?_wSsN9eyNqTWob^%nXVa=bMuyM^g)ZHC5kEz7Lg9LhTNy@F{ z72q+@E(gjC{&N|YP&ZmO7OK>rael2nY+2BnM)?BZAW?BI2CUj>gb-=jJ%O^7g_1Q zinyM*q9L0_H^dT}2Yb{ty)5N8n@ZL^tw_oCF2c@NM&=(lH~dNR>-DIsp;iMJYwE+p zsTEcgyW}!lGqt{3XA5`9l_d4Kwy(5iNPMy=)l68^P)KhRZ5x{Q)(O4L#6hm*Jer!` z?(|U9sodnW$jzhdgPw7W4vkKYk(L55fBa7=KIse z#$zZiWe^c5u>SBGn!AjIy6od3zckI*dVB+b1v-b;&V92V*R404`8)-W#xU3ZrJ)O~ zM-Ids5p2QF3?7Fx3eCPFAC|E)d5W>nqjj10h)*CG&q*|gOSxf}+Gmz7pP#r=G?6$Q zF^8&L+YP zEz4(Q7#*EP%cGaOlekZrx7^WkPwDnCw$B&|@fd%hw`bM>adXqTk)N->!2aT;D|AA$ z&GP+J_9<&E8|w(?##vf5JbgLss6(@a$B{Dme1vw=J!eLtvMt=is3mQwS9O`nhKtrQ3gGvH1Mc7QE{ zGp1yt;o(+}3R&SQnq|RQLL;R!I4po2xP4&F=g{Pn4Hyhd@SUX-LuBHG-A*sp(-^&7 z_)Y{ETI1L=hMrzt<-d`LpT`y`~6{qwWZ??$Gkjv`!t++i3_UxI}k8W=dB`}OX>5b(H&tdezXK`M{fjF2hQS=F)B21t2dyr#f{OESr=dO2z zv^`#gl{&zxrO$%U7~-fRAD%9QyXo16s+JpXTB(zh>@I&fCGqaYni6CwBL}{J zjSCK(4`ZO~PYk|7Km;!b1n7K0{5E|tdI_xs{~%)zEbbXt<_HiE|L{ToQT_o?#GS&) z-!t7jAyH8D+0&-0wKEDRCW_h-c#FRf+g}@1V11N`H=~2H!E!;o1E+`ctj5767(k*fHyVXh`J%(`r!mBLj3R{0tyGI1N4}KwTJ-Ym$ zcfjI&2fP{IwjFpXzwsc}dYx?h@(Q^wTv>K!*Ao+xB2|tYQ;+)+ ziR&2qLL&^O&_kJU_l$q3?C!Vrsw%=$)T=?7#wTN$%Acv!i!?xZy1!uYkzQIrn+6tQ zj%&(3vrEX2fAqDh#l||E~&mmkb6Rf4Gx$|k?%71^7jIrpM3Ncvle0^ zh;~dx_d?u{`j0+@Eger71&t^lX9+EuuBhRef=jWD){c@lJM`2JCR?X=&n6O=wuQo} zzf%EUxY%@U(GKN7sUY-AMa15qzu1@M;G2P!yOoSS z{NRoVzw^{^%-fs~0Xd3oBUj)!h<+n~fgk&)Q(6 z|0tLGexdS+W$`g>R2y{QUQPBv9Ax1~2jcqG*gnR9(`$d6esh%f{Y|`{4m{c8Hvs%u z5^qjnH?S174SjtR{z2Rsl#t9RpcqS`TOEK3*8VpgbUj+DBqBRtzYqGeEBh#MRus|& zP7Ucp50s$SlaI`Yjy@E@Cg@;e0`L!F@ERK|)o*1HD30G|uCqJ6B`*;fsGyQ1RU*Id`q>$}fvpMbi3aWc;(DiWORRih%R+f=qT&x+| z3;kB36i*ic<)`hy2FMdn3=U7I3r>D6;8F3HrI6qblH@`_pw>y*2_-%3Ff9i~G*aSlW(h*Kzv%Y+ONs|b(gZQ4G8wM1`qy}$i2eG!G8ttigpjA6Sk+9U#5)9&24w*2sA=gWJE*%fIK4o((KnUyZvZQ7jz1KjmB z)_x|>6N#Yv*FYFgyoMj3_HsZm8NHbaFW`a=qUO=>kY6G8TZ#C!Kdz+?hDZk8YEf-T z{ZW^EgxP(Z|Jnbd6X^#$QrIL1bYGDYcBi*}`7}&kkad?UeGj-8qtD8rCjg}fzqusK zhN`RT$04@IEs%Ebv?AeUAb$2_V=sF|(S7t3ZaxTi@dtE#g2{B18usnC1Kof`&p-!C z5{45Aze2z@j)Ee-{UTw74zO~C?-vq8DMUV$jf+5^Jyly~ZzkZaC3;E~-ByAgPb5^` zzsB;d6DL(pM?ynK4b98SH z%@aLu2bPExNrj^}FjuG-``CJJGE6Nf&!q2BZYC0|9;vFMx8P&Ae?4SL0*RhPYkArp zH-JW>(cL}ps(!A{~>wKKb5pmqcrLqmC#4EhIa?>VN9 zfN5^qEerANDa^<>pyxraBDQv5^2sN4l|&)Ood@cL@Cq0QfN%m0WSrFH)qx0mH$Sc0 zrmGPx{@@BHO-Qtj-6C{#$oYYkbDm$0G6hOf7yZRBrhLE zWb2xJ&+m)Tbo@IGQ@6-ad2dbLKYo&Fm<=lu-CTn{0CViyW+@MZm_nCB*47d}M=XbY zg@A1Z2<>^2X%M|m4YwW5nqR}wAX5lfNbS~SQYfm{cCR384qb=000ZBgcr`DKE@a1DJ zw=Y(YCVI|tCalXBduB7ut`rp)a5~kSZsH{zcN^u`neNf>e?6 zW@c^D{ZcHoVUD*6axU><5DAAWeGE+j_ZnvYYd?dh&cI{!I((Zk#2 z&fN|?Upe){p7H8#bpQDSq3I)CX72KwCCV;^Bnac9iN}e=tC@?X)~z?<#tEMq^-~-+ zJ=zYLha;mu-ES9{Gu?0-3>!sQ7almga2elefY^8#>b%swKO4O|hgm_rxrUuqTC9?Z z*?+IiSm9BXT7`FrxLM6c*;HX7aT;Pg&XlqVZ;&c8l&Jn*gX6waJ?~Cmn2;)g2r>D`EqsV%{W$yuTTAP{d2y51p8eHQXTFI~Uq? z+NV6P)}-=T)3x|XlAT9c(=+y7WA5%C+dO96+U(;<$Ql>0>1Nfg`Gu zvSqvpcj0#O7fgm{%W2xr*ombcly($890xaJ6fy3|jnYm_EUV;L&paqJwvNbB$kM;m zned$CxpxO{4EbCsn!7ewC#vycEbA#9=c!Y;GnNFNkPe(?2^q=uN7Ds2$cc#@?MY2r zA=EzinN}6^ISW;8q0fq5W%4b83EngKoSA7W#-yPnQx5a;7v3INO)l21y0f{*kf$RR zkg0etIixZP1B<1ANAOr#yVlztiMt^aypoLF&yTo<~uH{{rTx&2eKOOQm9|9BN zOfTx0>UFyp$N#zgq=&2zi(5yO)hiJ*ZwsR+5Jnju$_tRX^_rn7Eh;|U zw6-8n16Y2vmrQmlwU`M{${jRen!=kg8|ckyuR%7gO-{r{;n=!!ou?>i3?tWRoLeEa zJf7&$&I-zXqc{vE<*#}X{3+pNw}JO-Q)0Td@zqER_6twDDhuKpINgLxZ*Ri0O=5B& zSdg1Keu$Pn3#fOsO|Pmqfw&Rqey+MJaMmtCGa z`@{w-Vcqe0tO}FxA_;eg z+f3DlPmqZP(Vl%5_r;R8B~g0gVftF*fqBpmwVV8H=$(58S+U(|SkcH1JdBADmVUv7 z)zyIt`C;}2-#ix#BjDxPdmZdF0n$M{`>ogQ^|g-g=p62{bv zai1c0&V==L%Y## zyw7CzJ|+?yYQH@)4I@__9%;^34!D5~BxA0+nK8aHTXqUQ4S4zcx+&og{E1`eS`Y4a z!S=M`o@I|=_Gx1DfQ&k@^-)0*3T0=uR`$ti;yJWrDp4~c6u_D*$wo~(NTbhsRT$xRv2yk_tJjGoss<}KqLmGC= zn9kZ3%46sD5gr#7CJ_7`)R6g|*G@7;TU;0Lr(IHf5F$CM7-Q!JGbbJ<6m3dNW_vY# z@bZhM-8+|n;iMBiKYv1|Y8rZx%+fh9fhyBTOrxWZTTWoa5F&g|H zGfPMNZkcAhzN%KW=#>j%!8ec6s(EqGkk~=o|HgiOs_*Sul2G@h&O0zfv0Z$IbYZll zbA#4}l#e!g57Y&e07z$yth{JedmC1KYI9^Joz!L@?t&(3Zd0i z&it3h%Ev@jHU;&&n-pP+qn->%Q>=@qYpv*!>Lxix=B&bc*me7 z3qs}dDo+XkSN}T?bxak8UQS;2irtH=SVxGlrM}w+4EeYJ5rvDUqjt-HyZu+om@+@>ftdZnm`H z4-#M;g5BT>?I_0fZ<+}3YYfm2fJFGM5~wu(@iEyGeOz0j4Q>F|1_l%m)9_JnnkaNH z%ne}1{BtGj8S|O;j+TTsI3&+qN9>$WG3Q+{^x8vt2x_j^9;PRr0@C<}67&(;4gNvW z;dl?V1X4jY0=e01=xFWWMA@=ax;M6!8^?x4gC<>aTB|+LCiRVt!9SM(ycVZ@h1^Sgj{=oJYYJYlQ5EeM9_UyoGk~jf}0t@??x6sl3~Og2ihJF!U}R>l>jjTS9g~@ea{B{0f}C*`*~`n?zLj|u;Mpz5H)lQ5c^RX z-#1yuWEiqX979I|K$rV%lfA8mL$aLhv`W$v@qLruDNP1@n_F83bSvLCwV)Yl?E=vO z7{|+Hp?!d+4dW=1gXkOq9mpp?Enfu5!R)_KqH8EZHZ5Npqc{z8>wtOyR0ez$@as9z z5uA8(wF{!Ml-Mv~EC6Kngi^q_+Ta{f2uQ@o2()MZj6yUNwPo4@kbD?7Exv0I{@M^O zeli^?oa4LHe#nLq|4lIe=l;GSb5lRimQev=a- zO(od2|Dd^ka`NK+G4j+TljF2uM(AsiL?X%T<4*Zr^!zukx7rah2h$T+-E&x7p&9^t z2*C?{I$78nxX2*SlL4|5ra8#>`$xh#{%q^N$zw$BcV!sGh_nTPkF61@_I+~cs9&IOV#52vSc9)xSEj$J%*%s zWru7@Z!evg^M8I@Hz-l}=KyEb&$-@zY}^inpnOtz^9A^xic10!ymuHNLEB*R(8<4D zdX_cCh*(ATXmyWkQ(@Q#ZzRPsI{D)T#3r1@Z0=c4Yof4QL>9U*4i?+Kg*6W11yw(oY zCpu!1=XsGA=^p32W+AKIsA>}#L2ktL?t5u1+(>i$Q40|@E_}9TXmUwp9i$~F{)`fRQDQVy ze(+>FFQmaj3JR=lcl~+M7rr!5Jhj%Q8Q8Q}XjE(B4q`Q%mjB7C2dZY;%R9Mvb&WO-vWo0XQMjJz3qt$` z9(;}j%`K|r%I_!!-4jR|&+` zSE`qEAr%??*>2Ht=)mg~wgi@fC6(21wazfb3yqGSrLGn(_AGt_;3(T_NAnedg0F2m z2|giGE{f(D-uMbZ1)N*b6H~`(q7;9mUYR*r>fb8R6H=q(-t(#JH@(AJBy4x;v1L@Q@3cxBc`H{9!q4JHXDNHTE*qNrz< z{Txy2=@0zJRJ)pwk9GFOq^*%LmLvmOeRW7(7I46a7f3DwgHT-Ur zXTJPjsK_^J^2A>T?@ek(`cpYlbI&F+j9BX-!N=y%yCwFoyP5bF^H%yQIJ%OG7-)dY zs&a9_!Fuv zty298k$!)m<>eQgVej>*w)g#`Hxr;r4EREFj);6|mb${boyT#S&c2TFtU~$+$D6M2 zBqkAT7?#~T5$8r27S(BNGz->@A9eS2D|jnAcV3p92drT`{(^9c*wam;redmB)XS_I z9oLdGHE;kQM?Nuf;jq8{Y`cKBIctD%9h()0Cm!f0@j0#akm+;qxgaM2}b9>Q{BdV$v&Q2?p~O+$I;cY-khl;4#!9mCAP%Vey6)xyOE|W z3wN767|KJ|2u<523q?YN-WSCIh*kM(vCAJ=XdMRS?(Cs2RCl^FX4pcS^`=wF)Ucd* zBowoy9hly3k{*_kckMe}36Vn*h{iO1vH>Gm5U}5x%rD0O3URFz&0BT@%ZGtH#?yd~ zPynFd*}Kg3X8*k-Vx`ozuX2G&|F(hLjQ%NT3>awC0=rM#NN=w{4}<7|r2U(UgnF+5 zL&aQ`DsDe(@MN&EI<`gJLU@>oXU(>Rb6vc`A7{=Veyr_!(pok148ex!nO7y3-RN)& zxyk5w8bf_wxvqausA_rsI-%4KAZ7{Y=J)#JhWQPfDg+r>Dmks#9jHsy5~;zh6mK}> znjU;;5Qy-MQa}mb#p@N6#P!JMLS+^PQZ0d72@Mda%%-}fj2x;=wOpiT$xOEA@=ba3 z^qNa6s1?|gV(4QODjM`8EyeLq`*vaOQg$~M3Mk0Fh-tcPzqYSJG#87GI9^=NXH~XW zWO_1=BLLWcg@-wYYQ1wk*0h{H#bcfSIg{;$bJphfy!if z6QVDWOiOjrBD@*A{80~nv96!I#lQUGs{9gGNsc^e|2)a0eCpquiN6-G`Dc_{Ej1nE zWF-VPt(t&`421N*&ftI3J{E~-Eh&AF(80?9^?kVNV6Dv)7cc7{ox!AePBBRlRzW?T zWGhgu{3@`0_GG&6Tb{d`SB;+u_WxDy)8BLce+c(Ms!P)Wg8FZR8u)wH`b&rpnNE!G zRq6kdApdxrSfq^l?w;Dg>Kf=h)#%Er-kox{M>EfJy%eA?M@+cVSf?c+J}Z50Xc#$B zB>&~rCg|S{@wQp#eFxIK-3qP}r+D}lKZU1i4v;I{r3*B{+BM;`iUe=n$cwSBP@Uy% zRtM975V|jyi0(gvKfgC8l6!DQk%rODEC5W|PhULvy1I4kcU<&dt!(EdV^OVu($Dr6 z&Xx8sZzZ}q@Z42;Ljp2FdgZ$MGR>!p(*Vkcr%#k~dFT--B$Ut`P)r;J!EO~>x80$N zKtSZehu%$aM;X5S!m15(uk6>@y;JxK>hU_`c0{RhNI??Rz{d_j+N-C%M zAgPmMB-WDv@Yv6Gf-d9ClvNZ*;ffIR#kP{zV%ChgUyKjrI--s$gDMyk{d&O5C;FJsM5nWes=?)64IaY2v8=el z-hAW=pkq?~@14`uiie9E<)!SpI|T5NGJGFqp2@!Q0;_-wW#D*(uJEL6)vL*h6Z&hY zx9%erHa2MfI(J%9sW&@;m}@ke?&((1Z8U!mXw9_St$7*vX}ra%7NhN#^d9#}tFjL< zOfTW;;UZJRepYk(v9NF6OdcQa*4nz};UGwoy=XQSpKz)FWZA5Rl}tuoGI`jV9> zLzYLk#+ff6WU%V8ac~DP_X3gc({0tWNk$7=sfWO`0I%F%zWL7g$jc6f;y+|EDEnT% z*HSMA-c@@?y^-^ytMzIeX~>pjh)yq=MrOyIzY8$)x8OB$w$=6T18N72FTmK6bytkZ2L7tK3n7FIl0t?t@d zSZOF+A>h%qwRE$g=NA$dBH+1ZWqZrUjh;{BG6ByOTQ^rVD;HTOhdWM=R*r7;A_P40 zwzu7^TzIa^YF)LmaI&=Gxo+in>*Q>HK7J7?sUJQ0I`DNBLM#KiV+FBBwS$$xZB0XC{gXy8NY0$0I7h)jNy(uv&L^(_yFXvwK}hj2sECcQFc=`1q!?JF z7+>olP|!yljBlTl{+@g=FtM<4aPja@5u64G6rX`$VqjrmVq@XpU}J+?Ur-OhCdD~> zkyi%yoVpnvgEJZ5{m3`?j8_WZlWTOYGx3|dJUB%_K}mIy{MI}uwZ5>@beFF^cWEp{WRuT?DH3KNy#ax zY3Ui6S#OJw#U-U>KhuHnm@L5b@%l4^$&a*oS2-No|&DSUs&AO+}hsR-P=Dn zJQ)`T1nc{-!0&%KE>bWqOl)i{Y`l|kVPM`n88|66&P86_voh* zV>9r*bZ!9Hd}u6uO{Z`{UrZI{2gLPi1BD4oWjFiI--8pXf7p)-NLb{&QuO0_$WC5u zwbm;HXsjY21sJ&rK+&HBx`!Nfu7SSya%5Vezg!mnc3&y=o>kSs6VzMnMfSA54|cO! zx|`CY#w}64_VS|1PcU zRE~q<-xl{P<|ZOiDA0g4zP&HWp`7wO&Uwa$&o;m_PZ)Kn}eH-Em# zK=Q)>u+L)A0oHmuSZe#Rm1JjI_Zi8oa;}YYZ39tL>X#bD-I=Rx`}%IQ%?`h+O*MEh zC_;vFeos)6Skd-OsWar=L4)Wc=E_ z``=jpFOxqE_13d3fqK@!*uiJg=dCbyTbV@Z8J)_hQ*4~9UY%Lp`VDNNYBW9CTdW(T z)+MaEI*?4<*ZL$Dl9^*zvAd}%S0?$<(HA-un0JXCXN$=-xa3DoD~5X$--SLPQdV)) zunmzT)1dm(;z0kR)dv7TZ>8&|%Qe%qT5*d97Bh-IeTgtW!(T^}T*p zn+UrLI|9_!R1$fH1HGH6m8>tSgCv*x6&$i&SGTF!rax+b!9F}!m>pRk8OjiNsJS5O zCabCo&rBfL7AtrE<2@ z4x#Acy2g9;@yxQCipfYg@wi`%qxka_C?`qd^If&ez+RVl zh{)!S%JI`DIA+_U@^0=LCb`0H4_&4_;}S)YawMNjiOKaLTzR?fWrdJUPE1d#=}zJJ z@&Cu(SHMNFz5OqZNC>ikNJ$GKf}}`^3j!itOG(Gl9U=&VveF0&(w$2#DWK9w$I>9( zC`gz8L9f5M*BjpWz3=TAfu9b)DBDkMm)fp|bYKe5lxM6AR&*DJ3c-V=rvr_j-*<}Mmd&a;h-?=T zW-x!-)-E5#?#y2EI7$vWeAP!<EhO z!fi=dtDXBR`8^rFGQn4)>;aaX?&OFU3nD6#p^XVnphGqp)?bdbZ|?g9nqe^C0+Mh3 z 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

@12a0V*aT}C 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

?vP#LQ zt|M>7$^OQ^Z$AOSP5jViHuhXHI05fif%jWes%^Wom|TbrVzs{$YfFOrY%Bi}T=vsQ zlat{@z2U&Owq~~$`#m$_!9;L1ZeiP+b2;@SZyeUB^4XU=8(;LEYV=s!uo$y}Tjhi8 zh_LUE8V~;ay$#)8nA6RVyJ=Bx#v>F@E+s`#_>$oQ)RtE=we}%zq@}oWZg5YP=u;%M zj+TDRu0+CcTy!#GW9`VpeRogZ-o(NVEB-**NfeG_TQ<0Dceo3W z?-BOE14sbRmf+>K!-=WYU43^$kKH2=-nBrEYj(vK~ z(_KVRG=66g7i-h`vxU9~9lPzz=R8~-t<_Dm(65uE!w2##RVk`82&RX&=)%)ZZVcfSSC(Bl;i+1`^{IXZBk z&(n70jR`$t3iG^T#2NVE_LW}=hC?iE9N449#LgE~7@R7{jz>m@Rw+j@M`Cw}leON4 z+n1w7bIh^Xz*B=#FY+p>zrxm5SI3c?eTj{_YZ?DW&&+!Trq>C3FX1&S9xrmNPWT*& zdJYPvb;h@o9o7>F{;FLwzk}4*w!GZ_fzAMH=3>~EJe7s$y*>vQJ9&gbLEj1CmUJia&nMu1$7ytPl`C&qG zP5TU-dF}YsrM9pAPNjk0d%=c18@DwQ)PtD2Zbx#oiCWm1oDsQ%jYy?eGW!K22YZ=& zR6=NflHy7cx&vK&4Q{;RAI{%SO%)y=K_N4p!_2V#rg_G^#!T4zK5#6)U@ ztMAcH^I`wy*tq0oX1hW&t7dUI2* zZjECjWBq+?bKLBRXGa{0$`)RQ^H~BLCy-olI08Wd8+3|8e8T0Y?M6!4@6= zUpV0(cLehxxGFK|<_GWo@9qC@@v$-bC;9&W6?z9peXbpapFU^kQJs=JdHekNSMnDX zcjfV};VFK77+Rhny8g&GrcRQCkmBU)tlRgazcNtV4{><$@a6M(J3XEe^c<_(IZGN%mHsb6{*fKe>SOq55bbVkU&a;hL!*+2L(xr_n^@AR0OND7mR741FCjl6Vb4t`!iC@`l=Q*~=RJ=aITJ zW*eu5RQqUe=GqTkgWc z$;rvjzdc}8+1lQ&Rf%0DHnyeh)d>v^4ZJe_A1+2lK8gYEYm>g^0ceND#>T$BzH9#7 zF{~4uUDegc?YMTfx3|Z~-?jG(WLu3?eEM|lQFBX+Wai3>wUt!4^SY6#si~8b)1yaT zRar+}+g}qUQc_YLHyJ;9@&xCNQ8_LjD=Vvhl<4913BFZB3yW55zn3qoF7`&@@H;F} zsP^kB@)4vG*>Af%c|zLtQfgl5@#DvCZpbfo3A_CK z`9s-Lj+U6%c6()PqCS|MoIF9qU67BDPf)O5FSL@rxw#oZCt_}CX=!DZ5E+@}F_LSn zASESbXgC$cZG7g;nILL`aly^45l<^KGlLt`E*o=U8$wMN$jG`nJKsb^Bqt}MeS9qM zeyBX$o$t#vmhqNB&>|zFqt`Tqm^PP3=*Y<(*Crcta=0D|*^GPf1s*puGn0^z$jHcm zbv5wxJQ^sp%8*@MUA^a>^zq}z`XCyDr{B}JMw5R0FuAc_^<`xx%f6a&EbjGdC3W?e zAv;KypR=2OB^viFY;9kETAGDJdvoKZ_RKeK+z=9qk+WGEgi|Q{IQ)es`ud5br7=4D z9SWj-JPeV2msC_#y1KfMIlY|&*FNCkbdp}*_g`DVshJ$R`p(_my_6NP3~y>;qDZ@R zZfcAwM|N%HXn#iZ|Gnz#>+6*Vn*;2X`=~i3kMv^_4<2+jhBBF%n$FG7DH*mPLf*@FWEhuH9MKl}?1V8fh_hGubLVbH?aNlR;B zW4_0|xdxU_>+s}=ud@@ZJ#5;VbwVG5Grz)#v$HeYEIFI@r}XrI;NY!^$>r+tag>?aym5lN!$cinGG7-XBO|2B>ReYE z+_IY^%|K7j)<%yWcR^|Czz-!kxz>EMp8K1fDa!i#`Z2^mrkW!R3=FoGhW4gotTZ(> z5BJyGTUn-}dV72G^71-6JIBYztE;Oa@_zn&g20AZ*XPfl*(-0Ks;qK64b>z3bV$l6L~#janr z5GMlt?%kECF_Bz|d?Cjr{@ZWYtS=9r`UCL(JJdVobMT=zJUkq`0Xyq69f$;0i5 z;Es-t%`|UsZ#g+RwM<>YNRm|R5h&AbBu|as9w@=mew2-HIvy+HuF3Sk*HKa~ySnlk z0>QDsgjp&;mX(*sY4;Z*_hYOocE!87qr*MV!}SF062Y4u!nW=6!_Dm}#0lC%?OLB{S5sB>;Kyu}v+M5v z>`>72*qMUFLho+M78e&|pN8=#hnnL4b5^k@8xs8bdy3|>nY!S-4)*m;Nlo3I3|08L zRqIP40>>0Z*tQS%mIwO#V>M6i%RpI@rgQfSGH#1)Y-nSi*oU5J!uJBTFNdl>=)lK|w(fm`$+Q-5FW|Dzu-G$ouQoww=ie37Qc= zL{@_!sy@Rchqs;-U z?q%1_1p)iHHxY8#qDTAddY%V{2Oe-|!6Lh}HSBc~^78VxZ)2dRH8(YJadShPgzvU0 zr|^W`DzqBWj0mC;s#7PMc*d?OA!TlUqwZ_~YQNldYui!>MNdvjdQzP;o@p2=&a`Gg zdqYFflOM1BR;$_nPDEwph0jeja?0se&P67Ef9@{+^#7yXtb8Rch3$YhI*p5q7FXk~G6aZv7UO@$u5k2*{&DJg-%_TM1i)3HQm z-qH0HnoiO*(4^@#>dBp&=C+20O+@$d}P1k8`nkZ&yanTZBYL@G*koAJigV`)HFCa2t{^b zVF6&>k;%aZ@6DSxMMP*%v1=FI*V7Bm``o6&=>Z^#Q)Dy-6%i33EiGMITDrHlH#0Mn zF@kU8paBR+S65e4vmd?QKrBQGHSOpf5?KYyNwwmu17rs&~kJ_bjM@ zPpx2A*a|5At^A>rdfoRnZ%a!927n<1(Cut8Z-F(fXIhMIbz)yv=C--*No@Nj)yT~c!L2yB&3 zU_ihPW@Zy}^D^r(arnYTNlC8`YqANxM-ikGCn}i3S9I0YBcr0C5)ulRQSmtDfw1=l z>t9~ripENZ|Cg!{*ZQ=*MszYs9pTK+?HaYkg7BnUc#TBDa)qJ&S*7H%f9;!ik;I=z z>F-f)*qwHOJAz$;rV3>P@G&5*CmB61F9hUGf=`IvJq%h%Pf|}KZJGo&qZ=+BXbcM< zm7A7k1}NIl5L420mA??yB0D=fFYhLx&XlCjsC}P>*QhddlKQ51ghih?-v788P&0Im z#F}bGa7(Wuw!UHm43F;bqWX{W>h#!;5P?v*dzXcUB{efs)bnsZMLD@ZMM*R_HyX8i z`_7$4=;(*5!Jd~@5}>OvqDpQe@;MAo7j^s7~K35gde z)M#(-zRc9$$y%weya0^~`dw+$gm@XjUv%v0*v^OEs*^M$`BP$gCD7+M6(AbT7Om@fFep!>3ShVz8huH36V;RQ^EUv~8f&^b z^E4<1WI}Y9n-4~#kR)t3Zaj3psiUQ3x8-QzhOU5;Q0G2uR&x21f)|NFre0-1+UUtP z6l*R@M&>0Nf8--YFitJ<%H?2A@mB`yWj0R_h@M^>U$+W=dS&G+fx()0_L8Lpc`i{^ zW94VKF?&;7=bbf%VM%f+i^uBkjx$LKtzB`CS@YBmaXlEm1<0$=y4{@^9)YLLYD8pXAwjHnaZE0!Q-gfF)o0B*9D}VAsNm*H0 zLnCU&G@B&yV!Ov?pYe#tUPgH<=i_F*f!+NbyL;&TR$q6IiiKtMq2*R80icoIHSl6Nkv1T6sjqtK!tFE8TolqZs}N=Od^rIa7bI#V zp~)(J!EK_GSysXX)%Z-)0##-4U47?ynb&jAAg<9W$6En9sB=m8#*Mq;EWsfXN=4PL zXWT;awEWgp4l3F_!B<6e5s5roqRwlzwZweu4{EajfVQ-@-ahS7d#Rztq86XUyhsp% zi=r~om|YpG(Y+|SAo+(9PFTgDMjUBHkjR#~f!FBeq9pZDG_)0~xv358hMp1R=l_Is zlb#%tm&?WqAO2XJ_&--e+po%H7ZmVvb9ao4jEq(3o*OB3#F7c%1;7cQ z4L*AG0qy*%puGH`Elx;BN9X$W>)p%fb2Q=)uV%uhPc$@Gvsx?_CG|oM&U>ZG$q9*y zj`a8MV#xI#GVH}dgWcKLAv||iR@MN8iZz|{xKT%9^zz%lfPbs2i_1Ne!Hriec5AAV zl9G4t-i3Z>W5X$5>mF}VRrBtogRwEwvCY|U@1eje=M}J zET(9mo0yoWMP8^PrO>yrSv?Zuz@^~~&w^yGp`q10Uqq)vi*$Ob>&C?tVl{2U#h688 zYik>s_2Gk8q@*08w0HeZcF_bdSxExgnZz&O2Ym%eNJzTbvKCC*oKe?_E<<|}^O2+B zmCDLKIdDv3Ol;iR*7kc`(6lTHb!Evwz~Qcv()W=~>+{c$H+xAViO`yrBrP)j^rmKJ zeU~V{mUucjMdD0*eBe63HNVm!@IX=V%dmoi!i=M34Oegdu+gK!vmmaKn8-9soUY9E zYfCxv;Lm>7#DtARL969g-)<8X6s^#>OT7 zZjk?Mm5}_*%qgEf%?=jZ0Zz|$R(oHmuA>td8~ftFx7Bfsg6KhBK|%L= zA1~-2fV6gjOD+$U8XpN?z4{?FH5Gbnb~Yy;Ur#J14K9oQ`DJCuSRmGp{gLghs909EbDGbDn@zl!71n0;OKTgNm zy1ICzGjU1_kx1={psKRrPh|xKK6W$IXV0E};^^oI#Ajn8YU1r6(Z!2?BLGG;ZZa`3 z2@BIuzI*>(hrYfLg;dhVwPc*L=Dh5cx!6&M!GuLb^z`(^bc|~2g#;WxegF*m=Km5C zFxv$uBlF@3UxV7kW+cyhyzQ=x%&knqJu2i)3~>vDIuK;2S^Up$(?QJeWv}?uD^qe9 zd^~Zo$~WD0WmGI_?K}rm|7l;ZpmY&H4FdzsEUK#mC)5L+j95j8ctk|vrEyJtyuB^9 zqYWN#WO5s^4{V*va_&2fVAuQn=@SQ9{@B(-yG+Y z7xi2cdsuze#JOQKy0i1adUc;1&2d(TlmDfVI}og`08d$y9w?X`11Qalvu2&c{F-kB z{*oppvwAShfiO04ZO^;jRPzGKi&=V$q{eUE`Px*2!S((ldj3=Xlu$MYy%B{%+1S|V z=nMgE1_kGLrv>USC?sShXq~Ewsjt^7dGf>aaK=-;-;UG6+WHqgTgYt(;%=NQOXvRc z8vq72-Lgnna?Soh4Y};3uTBsl5L!Pc8$)&Fx2IdF7VH4ILA}`*;^IQ__`o07vc!iF zbWm*^917-R*hb1J+Rv8_j*PS;r?1hIPOe)Kq=^Ml$jHkx9tYS#aOTYY1ibx$_o?bO z9v<-&b<)$`8Bhdn>=u&EU#d?r0?8IM8^E8*)T6Z@K3q*6D1(}V->q&pOso$g)i-Ej zU0t`U21fE-Rz|;k|Nb5R0boUJEOpELMWp0HD3gNqZ05Q9XLuGjY#qJ4y%W`ddP+&1 z4t-C4xz@A9Wl%ynUBC~2;w>o&8yj2BZf|cSny)VUqYWL=b6g-R*~uw_uKWyUMn*a0uD(%oA7$nS)zapK313=V9s2lQ^2Uk2=cOViE+%V1q!J!T?)@<8P&$gRI=Ds42X zkP%U7GjZB;)=HMP;zcy-1U-Vzaa4;|{_}HSvQ`?jL9tFvC3#`a{6XBNpbR|o`nRBf zx(M)^o3!&Akzz&;rz!O0()jW9AdHhwdrJ${hP=YU7(N{~P{P@o z<PEYT3ul3s; zJFBlaFRH-?xSW$SB&$A5QpCvdj4Pers*(R?MA9ve=iRhvpz~i-S5rfC`U)Q({&Amy zmpQ2>ruUV*A3H?t_NlIg>70mIN|fFepnY6iuNPzE;sQ&vA1NvlagI(t0dhHw$w@r7 zUF{jou#$7IQ7XTAlhKeH75@75Yd^m;-8@zpdwaT2j)Bq9OGN&OyL)@ilAsqq)V*%G zc&z5YiUz(kIbL)6K3lj!?)e0&CCP#lOM4(&1?B)$+LU!l2$XU%xbDhHt2a_?hu*V! zX6Vr3w7sGqerp@5O@+t7#V;JsIfD!d)tXNVZ1N;ssyiQ+zb)Rfy}H;tE^+IRf`m*U zEj{JDouO6eu|0;iX#54zg%L~%eOZm|VYixU=I7^qC8oyUgp&{t#?p{BC=9P3bh;Ds zEC|HIKREH9h!J8DQX15WSWuBeLqlU?n#tMIBmv9on?tL=ckiB?TbVOWVux^AT3UO8 zs3#<1oRA~-5$P9tL6!!joRH?Nmz?cf9{9Jv}{09EWSo>;nS>dKGRa2SJk{ zC1NEh5YRxhEbfRwWg7!_fkFlo8!0KD2#nJWBnQXJ>^FMSSfHbA-oPV3IRRZe?epj9 z(B;Tx`|VQFiQ=d(pyi6VLXdp}h|55Ps;&}Gnt6tPXHwvjplqPEsdK4(=k>yHqD@0S9#U)U+nL@i8tI~ z|A4~43s+Q#1T>0F5e(;9KEw;n`gV>M`Pg2T{(EO9>18iYR#{@+L0_j?Oxu-rUpr}K zVfEvxPJwuF?QwuffPwbYWsYfp?V!?oLR}r_M zpkUiEy>tujpdy6wdG51$mEjSysO0k;3$^fE!qS(oLeZy7Bc)$;L=~Mnbt>{D(=BJ` zVlwj^oq**Y4k|pMOr8*HX=6&GN`6Qvev^U0dnVrGHdhUiebcdb#NnHskMGLM8<`nU z#)@+|?YN+_m4OZZ&0MuY(d$eeva-$C#`cN1J02bS!`V6f(WR*|iVJB=wMgpQFTc}7 zU}I2lRTrjFL!ek-rO%|K(|e$V{%?`^;>8Q73FkoYs6D1vhJ5=3gb*SkBI#h-*0wg@ zWz#3ZuRv<}-0QyzdiExt?Kr{0c{;j;SFfI$eonq)(E#g~a>RP$Mz7gG%L`LH4IQ1p zl-3==&ow|S+P??W3Y!A(0TmIHK+4Fse<7SY_nj${Sc$n%TXf$l`N8^802=eF^DX9=JPCqz-`0dycs1|X5gtL@oH%Nl$dyV zuT%_pE{CGKyYLw!L&M8gQ8BWfS^?7Xr>`V4*S*IR!JPA&h0!8Jso|YB5aIL~rZgb0}MaK%o&3O&j@j5=OVMoP+Y$I_CmSwkF3=*HHTqrLsc#zx=3rJ`qha$y(A zv#w}$SxQ(%qkwaBGMbKyoiz*Vvf*q3dUNG!f_kIwB|cmmeM(+68=LHo@T(%(qKJf` zpmVf%*UXC90T`9ZLTj7S-Af7d>5KP~u>9a;HiFN(1-6_SWg|X=<5u z_4RwZyGue86cmwwn$_Y0_0&n*Vbs|l%r9QQv*Wyv1t)`pEh~TmWT&#SIO@hp-*JkH zio(3jmeAJ0!2vpJL<3X!0%iiHJjW?c?X)yDW?#H}SU{ohmAHIX26^eU*zou7&v{Bp zOIcIS`=$ZJl`(9?WoXk8_TQcEWkrQqeE;@MUu8U7AoO7i03j%EN!85Isf|WK*_=nY zU9G*bS#i>KSy#P&`gr8lK=c4i%kX4XB_ApW z7s@uXq+>{ebsE>3n(1e2gZ|UqZemVb+@bxPq)sq3M!RNhE5AQ$M;p|Xf6lF;2LFVs z!Isgw^%~psNH}uv$@p$KR+pN0r)|6Hw#tgAPld|S{SnkEk}jCbfX4Q(vg=Gzuj6GQ zp;8d06BEY(B>@7JSL-63_nSfOm%cCs&jSqo>bXG6o1NXcK|SKP3bzNdC~AN%mX>vQ zKN)!N&4lY;X_0+6+6NQ6q9Xo1KMFf@^MFsc4%*t}D*z{IS;Yi`zK|t(+rlElS^twt zu%3p7^X^X*=vq)Yp(18jLx1xR44g7j-mDV>2)s$=do(<(8*V^)9p$;F@*piW^$Kao z1$1I}+FRaI3^j&Pdw+O=C#-@Yj>e1%vW8L=uylc)3&)t!3@qx6~G0@dbIkiFOe zVdyh~)4oxZ;?~pC)8of$4T$HRSWc9Hr23XT;lzm(4qN&Tc83>u#pKN#LFO{_xDgc} zudAV9;zHU&q%D7Zo#V@o={z;$<0JC0+FHpAH(quv1$zWnezBvEIPEn21~Qd&+z8MG{j7KA!*Ipu0IWaPMM#d;h;dg}!q3f_DmOe(PUkCIMj?Fy{r$O@$ua=@q^IY}qx;W8Jb-XD z{V5S9LQrI(+^@TWaYJ1ExT2z}s+3G5Ntm|Y$+BN!wI3f4^ZGeJ7rFBG)xIF&)R|XV78U~>{vs6> z{%Md3qpK^;IO7|#{Z?xcdXZbd8xL>FFxg{IqaFN!^}6;(+G}ZQo{x;oE+7*VPe*xP zXa$K$Cn&~OA(wJ-$|Ak#6*SP@U6<1(Qqi9Nt98lKgY4p#HA{XVQN+i`tK!xckoAfM zm1}5g@B5xGr=q0%A*lVI#xWtxgK;#Z$8e;IHbEim9=yX@J0>i||MgQtj0&9wiX8>!om#Y`(V=} z%*8lGU@|mtL7<_v6~i9M$Hiq^qxNN2HNX?n*UE|=RK>mQdqD3lUFBd_RMgcCqS((# zjLpr>1;q_K6)hb6{4%kTAEAlZz)0g`%2e)WGAdxbFZ+Se_Vo#Ha8#XNcZG?c8CYOO z$$#ErKTs~EeB#5w|2>sl!Af_TYXyR z)zeB#skVr?fyq!rrA;dWKvnbbs8HFf9|h>VKwj~dT=y}QMG;ke(S~eF-<#dy(u_8X zR4WFYwC&>^1m{*{wY3L*mUV8YK;1g)I^WG2ZX`ZWJWh7u0n0$s zfb9mRht`0B&)K3DK|$|{alck)*FHOYjU_U|Dkv~e-`Eac6kuOxSJzm_^XJEV_&hYr zfW{G!_<_fRUOe(^EYiyi1~wG_AyCJ+QS!Z4eB|bni|ME|{l`VFUd4lY!p+6S`+&Pa z(W|Z>uvZ= zs}Wx|FDCvdZbrts+)C)NAOLA;Y4yc>3Fbt3zP&|cbc_8;;EDquf+ef@{+X_H#uIK{ z#(kGw`kh_q01sR9Iba{0B74;fci%O<=!Lcb>9h@|gvh28iuPXF2sQ}Nhi60MoE5(jVDK-3G8Em_<*5!5- z=cc6iPOYu450yV5+oR{!nwZb5v;?^)KE8l03TA#3%exMm*>+Hoe{qX|txi&^N&8== zKBKYbj=9XI--SLcBV#BW8GAdVqYz0=LPQLC|8Px$Zq3^0(upkrgr1fbeFj8`qlMql z1KPu|6M!Unk0%XVz+5~{g_gGJ&ussnQ~qIT<%M`**K^=s3z|zwOWT`$9}IgI`wKa0 z-4B2{g|PMLEg-=lx|y4&+dudY2vf&uGm)Ya1lWNAAQC!usIOpT+hA-hDk=iR2x>R< zLohe=^dxI?G}hL7r8rEeGQyOLHzLd0$cQl>N(4g*%urrXcTItLB0T&;w_)ecpLr^8 zZp*uUdAH5L%G%0v_Uyv*u&^*dlJBbVTG;P38>_2Rypy_pTf^#mtsL|dJJz}h%Z}Ms zv9b5I6HgTe@^c)eR-FaBs802MYG%eRcfM3I?gQ#ZDY3!3OREn{Zoi<8BcupDk2xn9 zjcX8H6Z^IK;$HVLS$c#EXE%$VUHkTSQE8HTSzSeu+YVRV&;4q>`47EqZEb`KpRUX~ zi2&nj*!g~pswqz_asmCI1s1z~9F^!DHEj990GLPv*20*IWlk`j^vHwyeB zfR2R(1wr9}qzoC+7Tgr9$j6(~~LlDpa<&6l<{`m3bML5Ad z;}e%nQ~UYb_Fk<#g|WDHiwH{XBEp4VtNG@m^W31*$;62t%3rp?l~%`WZyofjIxz5l;R@)tX7z`Xqa0xTy0P)jyrXhJ zVKi!^zx$T>-;&f#jHTQ!%+9`UohH;lCGrV5sBW*dW_`hMG^n}e&OY8UwCA{J6kiNF z)T`7d5Lliwf3`jk1~e&||A!_8Mo`!)80m(EO}Q(K0evdwW?`9wDHGT{Wo2ZnGw1*u zkhyXm!jHhyl+PBW_WX)E_%!a`^^4FU5(`?J1KY>fulGGYE9d(RfXb;CRaDT*K{J~e zA78MSwDMa`N;Oq^ZgWg^$|Dv;Q1dua3?ZO#_573+{L1shw0`wBz@aC350>dXt&@Y1 zQJwY~e0<-aAfV$IA=n^w`i5`EzJC913&uc8qc`>yAu6KN(_mPAvoUN*Yt2%(wYeEh z!6AGNbd2pd3rsLYg2H?N+w=4E^mZ`01JTyQL&UYVM*QpoY-S`lJM-=y`hd#-5I&UP zu?j$v2$e-Suu_Cq-CFbUIgOObD{?(%`RYAIaGqCSyIi(b;iqn=_6gFRM-;v+ujF8 z52(G6h+~Gd@@zBixRbbH=+KX^$Soiv#l0OMBaL4SKFQj^8Z2G4Hi453jsZqrYJn$F zt^8Z5g|Q9HTEM?LH97eJ{-~SZg zlBg@uPmC!nqKb;XWRf|4P5=~;ae2klR{s@~F@@C}kc(wCMjQC5#0J+if3g9L7A zWV&!mxq>80)q6OOLQ5k+0XySrj$r3z0W~Va{l#-|@noRN*yI00w~>gZA@X=xvFa3)FJP59=`&W?^;K+!yy z(?}Rr{hQYcy!*ecFoKRtu|F_BCrS=Y{SLrcXE{=F0OR7k{QOha$~V>`-n@DE3Wi3V z)XkH^kW_$x@4c*m(SFf@OSTF4Vqj1V2H5-)+UBCNEojs}h!h0+lnVyzQ?@5U4OD!9 zwz@j~NIsT^I&;z}zPnpBIoFK?10qDW6pRHb-v;>}6InELJ&vzNER)2%DI7;?MmAA? zlG4`BjtGB;6Z7l@E|R*_tM3~D`B_53KK73w*f|5R*xAS&o`8hGyDHyHs!p3NoM*V# zO}Yo7$9lNdP0WX(p&@`fUh_Uv4%2r)>nzp3=Wqby3NcI142!Sb7bXIA`QIplnoD~l zAU27jT|z-FyY%Frc7^RMJkHxfyqJo=hc|_`F&XVOBO`aRmw6D&3kz3U0K7Pw`VE=W zR`eyQyVA;+4E+DJ_7ErVzK|+V9A?@R+FM&UCQ3~G>@gBBKY((mUGB0$ceIT=XKvaL zBKy0C3JQp}#ib=$Xl#*@91+i7yZ|Hk$_pIbiQ#c%Sz_X`G)pK(9B+R>gR!CPTL9({Hj0?m8omK+KJ4s+L(@?Ux>D~` z>3?%ofXfLQ^7H44Q!!qX|#(*M?pV=@ZRVBB)XxYq}g7{7EDY!sRjw_%mXI5U&HMhm{At`B`KpSS< zQL(WL7f*|f%5e^tUJtf0%o zmy*I?w^tP0A6Kr7yYpdCf@u_bs;bjt_tIN=F**Knm3Se(!uSH(pg^=EjYw1V@2S>C zf=`5NQLLq=VwzY1r>xx;Y@C~|MPV4H_)t|&T_(&KroS~Am^f;^LYJEP4LwJ?;qqX1 zIT15fbgzIS!y2ivXB}qxPUVPOllQ@FSjeK3OdKZn}*V3j5LF0mSO=8Ac?#=vGq2@sjLx+K80`zTG{1Z2P#ZUL(d6+Ie^wLmKAq$uG zCk$S=QU+$nZ(wfMx>4_`83Eo~3K?V;XJHO=w~NI*)R!x~`UXM8)p}m7U>FtLa2HF)#?0Qcz z73hOP2CPT1dk;Bi2m1&8V@dqqwvWzSc>$aWSkY8RXK~4k<*J^p?$YwIF?MnZ)@-Xx ze_T_T%F{j0#cb#2^Q0fZ%+I{*`}eh#F^M$Ei*VRzp_g-^r3L03n@aEaFiz|J_vabn z)nDAI=1)p3$;*302ullu4Gzd~p$lC27X$3UIU+431%t8Zm>3};p&bP~W+XB;@&-FQ z6Y|vsdRzg&ZU79mIQ^g-^&wacE`tGz)yxmnz3bo$U}gqCyVNLz3n;MSaao+pWEgjI z2GYxtiYF(GA3Z7xF9bVn&8>htNU*wK6Pt|#*_3`Tfy7+_L1dhbPBA zIA3)Ib}Iz!-AYfl^71A!R`NMJXdnhE4|;(DzcFuydEuJ%chv7o|~a|pyprDr9OS6KE(k7`*$-dUkg<8a0+YZEp*m`2Db za4nG{nBd-*?{D_OcgmVv3wOM0169h%C<*s{TPKorqgeS(!N-rnWYVIv!IU zDF{ufK`~DXsaoc`#r7VI80n$eFnGV8k(l@_hH_S4kr8XbBqyW zI=+}lK}Sv9A`C_)2o%UZtZqqZSr_AVZPiHB6}F#RE#C3rT&BG6g>;ddH@%cT`Se8A zpW)@bZD`2g>J=Cj8ag4^ErNgiJ-N8%QPCIjB?JM11bc1PaeG*0A|ZPEn*EnbNIUQj z^(o)L8XM<5ye4;ExT_ZezlYJ8jHMc|f}eo@dNTFu%LexPRe3Oegn!ysfQ7jq57wIx z+612`*KRC&8Jy0ZQ)6zgOCZVGT0hic)vd=aF1ygdU?_fhP`58K@}=x`7+}aZuTI1bL`&=3r(nby(;Z11)n*OpLrdf!x4vp^abZ z^3oxau{8*#_{4;PXY8X|5y;^bo4|MSqwF)q(;z;9IFM@|-umk5Y6hv7)-_%bSU`u% zb!;vuAVB@Cq6FhrF79KbA$3B(xH&n03=g;ASOo#Fy0iohS5tHI-0Uo%Bvv5b%|J`G zMyj8&te_7!d3-uo(Unx(LOO6a6d^*8=`wd>sq4dQtj*d1Wh_dw9)!&5=kMPaW)=cT9w-dQZtGWm z%MY@_S%Q51@v_h{opCgP*v+iHeY7t%F=YNCp&^sKO1-wwQk2EhK!;Li`y!`4f{NXH z&T_ciL{NXeXvn(O2`Xon|B`v-2Fm9$5lt()+3*79bnu7)w<$n0at}6ksCV=SC+LC~ zZ=82)u5JwJ=$ICE)73qSoG%e}gVh!0eL9ud!SSE0Y1>B>{Vv#)kF9|e5Kt7*e?o$x zYCE*kO*E1|FLB+n05=-g^Gxw*%@;hiQKV^{4It@)a+{ZD0a}RGbY(8GsHkd~&I!CG zt)Sga28MCaW*nN@fTi{K&p);MD4_l%|Kw=3Hw_I<4T)DCOAvtC4ULVd85ss)@P0u_ zk&}~i;Uv>lYow+o)qBq44xF;yZ{BboS4hpuVg~}o>&q8>cJX;M*9mW6H%Vln1DJ9w zsE(F6<`1km{j8UQGY|(*Au(rZep~jW`N(|yG3nm;$klpZ8OZJ8QnvU+so;z<*2hvM zQN>Lp$KP0oB(4TNgR+)a{sySCdQuT`4Mq29YV;Gic=`Ez*?WOF1#>EltlZtrc;#Yj zeDkOmF-5Zt1Oel+1g_RmMYD@jT&EqcRDkHPwNvgLFxwUnLRVI-KM(CDtFub`(9ePi z(fx6NXZJneKIWbR%JS=NK>*{CjQ5SN9G?9jVfn?4+EdQ4-tWU9>;umPiv8ZN4b|3f zqIMJjwt(o6wevPPAK)5lN@idGNyy&|K^n}3aKC{4Em5B*A{sbk zmerJ%0j$+ZNt~!J$)^1;wYPA7c^3vm@2;iw%FOiUvu1GpN z3m`9DzPuKn#X(hjMnWItEY(nj#0xv;m6RB>6Q6<}7y>G+xt7;R)?yObsYmIXn+_7S z0aK0^ca`P5btqJxJQ;gBr3Kp5s3^T!&0-6{t~K>9T)A@P#B1l*%Om9D&;mj=rS5;^ zuGB53kibXN&#%{9t%=)-y#Si>cL2UET;rXH>C45uzdo103hD}&YbOU5#9m- zjGkS4CSozdF=UK4ZWzH9R+UhO&He7y>Q``7bAamW0vH}M&Hl=_Fa9at!cBr7e-FH@ zuve7kXecT3bl{a;or@E&^|A+<0*IGmy?`nPcnGoxbktm%VCzwRiOB(NR7bP+xeEX@ z1qXxmtD&W(hB=GJjEI$uZ4?6)Ajo@Ds)omYKxBg@A=e6RI2k%YRZZ;bfLp z>3!wvjEo?CdD^WZ$H&E`>p}=Vl1!^HFYssN8beniE`Ho2*YqnnY<7Sk&r3XWc!~SK za2E|&mHX~Y%9()u2lvKW0cWhB2o9Dz&Q74Bs`|9v9qwjS{*K<+S3RcG-!grqoNiC- z@2o*}@XL^h$`0%{0%HkeBzZa+YT5MXSDx!#>Wx#_c)oeY;hEB*Xzrt4^guRu_+xAq zB0W31K6*-O52;za{aJktP6XZD1l()x0B}AFXu%-2Tz?+JI}T#KO{0gNo??0+MC`2w z3XWSTpuMSSciDdh1ls=+Z|lRW$`sy*S{|^sb;#A;zL2Xu8{~73MtZ-u1w{X_-6RWT z*a`QB_773vVt-?5)amFoAQ=zuU=pM)7o7g78Xo8-Yc7LYn7h>$*cCAAzQkE-Lsuy) zFAo#Oo0@<+2Yn?}hnmM*b47eyfKm_zdJ8BRFUn`~xetLRbNKo7sMgOkf1{ih*aTcr z8%3)A`t?D8i6yc+C@3lh`}yUey4`Qp*-{;^udhFQqYjd1TWf1y;j;vY9OatXD=RsUT=PGt~y_JL4cp1;yt}7@a_*p?S5UX;!H?lNaqX>0ZNZ4hBLYJ zjTx&9#qFZX$~X?#P(8B3U{iB(bp=^-X%6}ilmaYmpK;XP&bPmR ziOI0UQ2Iea2j~QSs9l*+0@kVfUTCV8{=UO7Pz=HnuER3zw=Zkrv4IlQ;s&Z4hXNE3KDHkQfPATtAI1MKDf}?d zUzO^1Fff>auel9|(bltqn`H>lQ^H0AYVjD@X{wln~x5RAXxsjVbhPByv3LlaLinEGr+lWX{eGlXoYgce~+1SAe@G&!`r(tmidB68Bn5M{93&Qr7EY9TfCV;Y*w1 z&12)^%``tR4;ow=ha&6rsZ%~l2L~Qry?d9`iLY7TOypDsOnqkvKqv&5SFiIshZkNtOAOk*-;FO4dL||9`5zS>+TIpy)YRt|o%n z0WgCgy25~hoc#Ils_%K=8Gy8y+JZU;WXy6(^IQhjGQ{mL9%fY5S5 z0aabKNg4*WDhMM$I$n%e>g`iuP&L?w5U-|&60m^bB)uoZL&mRuAv?|gfwRbT=fwGY z4_R}^Iy>JDi2_;p<{sReswz3L@o*pIgcT_X6oogGPn|ji1MPcy;QjMP0ntx5pA9kO zSv!Dad#-+c36Q)_oT|LbQNXZ2?|y0!bi+-&*QPS_1nWRZ_<%#g@bv&*KMpIfU#o<6=_7>DE1gwrfLbElT`wc`Hd{x zKlbb4^nnb+xFf0&8g9n_v+}+dBph=+GbzbXb9H%WkPHo2lLX@#_qOUrTX6mY0N8fw zo)F~fE$pFb4)9yje{$lg1OQ-bW@2)PBY`vClzm|c4Y@BDL=+%kfkN%emxiU^j(X^@ z2CF>rC>@X7pw8UkE)#>^VoM!k<1Z>AL*rj}4^_hC0_VS@c+C{?%jBkk)nvWmrRybqYK$Qx-z!m7nbhCM&X!nr>(NaJu z(2D>kih1mBr^I{Q{|u}%yft&v6250#0lsuVIV!{nYk)uu5JMEoh=$bA$lksXJjIaF zfcdj`bS%a_fw?k|UnWm|xrWtq3rXDEhujNdTnEAFx+4 z+MTX8#c@z4%Ifz7dyyZG z*gmCV&l!84KKMWwUK(YE`b{35?wd&IlDs^<{(C-mmGjm7iIa13mSI{%smlh-Z723R zh8wzTFk?XQtvu-Y=6HE{BC$o3V)QK6USfUR?$?$JJ9>Bw&j?(c{kn+eBYYI1({f$m z?asS*BzJhS2O0fhHpd4CscAv#u?vp)g{Whj0G8iTJmSg~XVeABt^_ZJ-wDR)_(f1x zWFgRXHVQNp3ONiO`zunkG%flSFR?GSI0SC8v#WB6hWtxY{oXq`C}{P@p`O}+?D}tVLKB04Qgrl$SF=B?VeS zDCGZu_)ss5??KcViWSszuCDBqao}zX1gJsf#&dOc76f4 zd&_~@gAoRst$ZWBM2hEZsH?hqdz~hm!qU=M_B8I1H#h@pS_jwpdawtW6vQ;wg?=8) z(VRZLeW-OF1K@Na6p|deyu3Vhboe3-P3-Jd%sm*b0I?VBd|sc%-opL_h<+6YrGVsW zQx<4eiIY*Qkzrwlx?IC8%fN~rV!&U(-UwY6P`dz>2wWMwH1Ul9Z0Tprf~0Rj6@K&P z_5giSYCSNHOH)JHUu_zm1)CDp)Ye9lcKAf*<>f){-2Y`qWTE#RSUk6`&dx)!7;z4S z$JS#t0EqN*xIMLWDcpvx{EU+U+IE^y|E#O)7eKBue?3&($y=i}u06$PSA8 z+bcUYFHtm9;C_9;5mWmB@--QcwlhH*cf?rc#8Z;7br>%dw-<`>0KeCs#w1v1ZzRSD za>m?k0Nk9s!hS9sXNA5hMfAh)^oh8_FMpeSw10LR?rW(;I7Zl;1Ii@`7W*#&nmjlh zhT{NrG9Wa)=FmpHvwBAdebkdNXheQnRMzfT`F)k29L3VyBy#*NP8;M5E@7DA!TC?T zq*4IzM?CVm09Wj%*z+(kCI8DSxw3b&E`Jx&AS^!UgF(U%olq~3d;*ms53APhqy z0_E})X(%kQp2@E+qZu%o;&3n$u)ZL&g0z}^I0r|+>chKt-@m}xQ&Ukfce<~lqeGWS z;fg8bJ-)F_}G_FlrVYBCx9{gfwF!l&|fh6>EqJN z<8y^&ur{6*n4C82g$=_M)2ip$x8lVq4fO$KF7cUW$bFzn0JSq#sMY_q?^l@k0whUo z>g%KVISHb;bxak=eyG1sjo=T8m3nhD&r&G`+%TI5uCVU?X_T(whuN7KUDknb9tvTk zKHtoy_66<}NZs}u?FoVTBOr|lXngR%G39a^h>r4_j}Fil$P!s&IKSzQ9Z5~Y@`4^sfkId-^y>Z+;2glI^H(Q#BWH$ z*$Gq@0-xKRosh^|sjn=Zx1rtJuC{{}YQOd*3bL}mO+5Gvp%0W1 zIQagsxz6BWo>qG0C9v=gZ#aX8AE0PE>!)_`wSjy@FIDcX)YCm4*>#6dI@o@5ExG>! zG8|OX5Qh!tU!NudC$J%omWHPF6IhJ7@?f6Q(|Q8uM%X%FrHmjA1uQpKn{j86TEwNG zynG+m<{MMuvHfN_}*T1VgE15CNHi+{ZxgE{p{)Q>^lt-7g$AJjNlRrjX#pF z-9B4DPc3M7MpC`_^XJbwIU)88^z^)}0^`Ytb3-sQKVk4;p>{kaDXF*>$?+3M;;9^L zz5;Ep{eVTZ^_EPaxo;AI2$A4jDe@?SdpS)^+pibu&ML%k0nS+H0N6R;!7`1}ohMn9Y3deouyi zDKGEc89NsoyW=Ms&1c5OXRZK>(rX;izaj8q8Q?DnxUj7uncU^2J+^%;(m6<@f=7aI z_me#UCl(f2N|Dt0_-Qe`?q#sgg6|5=IZ+{RpUnLPN z%a;qO-Z<0v2}0AMC15I%vKgVBK^BJN=8nxctSIitzMy`nlp@ab9UZ=Ibu|_v~{ce z%`=5zpA^wD%?f**B(|^I&_W zio3yN_UNKCZ_EjO%7In>C;*3>pWQ28(P9A>^VY4~9IDWFP+EPxnQyI*GCCugslkU>NqmxT@o_5PlD1U4=pg&mrD0S`fihkqJ^!u7gruN!3f_i?`$ zS24-cYEXumEmHC}Rf_?cYr;p@ohEI2`CJVIP31T-Eo`_Xi-EzmE^U z-LFT=%49m_sXr?Te7Kg5a1D0L2R?-OC~7m|Bfv%Q5=ty1Bcp}s^*3+cPzyV80tYNq z+FCeo)FuaH@ZORqzPW5ucCh^mEK#U?FX&V>-4D=Xz1>Un^X!EShL2C_u`{h4NH88( zN+7Tu^QoC6m+FR zl=A;FV0;yK-i8rl;F|Oc86M1rDWV^|UEh1>3k|+)9hn-Pug7DDV~zPNV$6@#)k&Jx z<6}zknlS?Jdxz+K&1ch(ohdYDGKjY3@QAxt*3b%A&#enLa(8FQ-U)c^% zeaPXuLbR;2>S5TKy%)RB*@T!qm_QQyO_l~!A3cx_sE%*rkFk7nILdzT_c2gZ?^li- z*}C}WFC3x${b$9$FIQ(EeB`Uh8$DpfZEtpeJ7o@L;iZb)< znls(SezY3mRT=0)49xc@n`2OOTYKANBQZ<9$*B$q+h0+3QJY2cCRxL=HG#>RtkcIv zt{$GxQX+YHhz&0j9G0?pjjY-Big)!$Ps~BGR$cKLD8>^el&}RzX0F)eQo1ROq0?N7 ztQeuvj7uhMmMolx#Y|s>F^o_^%?t+PI0JVcL|gKZMIWe1i53pqZ|Gua9a<}qWyz_{ z9E}_oYKzS62Me?7Hw{PZ%?WF>DoWQ}A`3)@#;ix?9W!+rmoJdO@o+CR508s^rq4}# zaL zN3f&Lq_NBAA_+`m@pPywV}rKwXhe#$hcKDzkjhM~JfBPB9<|KId}30*XF_3b;bN3a zygx$L75Uy%+T$D92#KHhY;~6JS0uJbfXsDa1TkweXXoF+gdX}uHzYNaYdX8V85Q%) zgN{vss*|tpGr@#yy7@G*qr%AD1Ljqgp0SbL0oM7qmSO+CkQ$BVZdVbLt1htf4!>$5 zrZC+MGeWEfr@}rt@tl_1)72(TZ!R5IzMwQLI>9-&-DlUuv$w5racy%;DYI{I$E8s0 zQhZGIp2qRWkxz3XHs-xrlr0615#g7=ZaFxieSjTpnGQquFxLQ zZ_c2k+4l5)qrmoH(FT{}4_b#AL3?N8HI+0w=SKCC_y2ISR9p&c|9ZO!%$I8Z6gJCg zSPSjhN!b`>N%bPdft2QuwzTl6Zqw$DWLu8v7$J@6vWZ*RIBZ!~S#safECRb&R@Q3L zu!Gp<9(sbnA~csAiL>Wz-mDVPzsF7>hm_6dbNUu$-IcR=17;T5* zog~(}pKH#X*lHx%#bZ$*EK-)`G2}?6-H%%T$lGi&-uOdO9abQ%L#6@izSO_3P`y)p z)+g?y1Y6^79>uJ;e~=Zd7vNP;Dm8mU=FNOReDa+@5&xFH9h#8%o7Q-0XmExNKeuSp zTiK$#4-JF@f&vqoa(v320h3e|pO|=W=#BSa<1o(B+CB2um4f%CoPH6a%Q8`)I*{&W zWl2nzgJ`!FnzM$cdnXG=)(>_vJGrUU%+e5~E3Nu%$i*Jz`E_}P@X7cB1xIm(ng{GV zU5f5>t>~S58I@NBo=)ratpA8%$E2(+JJ5RjpdSPj&YO$)8r@fTC^hChvx`IA~JIz#NcZmX8pB;Yvk zfTgSzb<6P~rlt+U9zDpSX~Dx?Xq}sE9&Xg|&e4kw^$&}ty?L}Nsef${Me;+y`!U08 zRCTuPXDWsy!LUISv9^@vZRV{i1*PsgvfMV(SF{~t6EkE33M;3cVsFpQx`Z(Wp|g#0B;hrgBp;!ayNMwGEJHSVSORPAI$meP>8) zKx3_pxigE{Dxd(lTe9Ab|1}Hx=qC>PxUrY zzB_|0u`0fh{HKsgzHdRVj@UpYn@j+dOq_oDI*Xe-s@TIm3MU?KkUT zMy0+}p2~Ug;gOV~&(ovL3GM=R_3j4A3@{fpX@?m*rM}jAS#$P{&ep=UPnghUh4}LM z@kH}*IQ_TLu?p>&J#B{n>iGL~F^j_k&|U;KIvsi8dZu<&t8Vm>oUH^*8EX=%XPzcr zyHUMrC_y31V5apf#oxqEM|3abJBIMwuyTVrcY z_1+`1uD-av9lI;TyQNDh1#C|m1gK);Vk}WyDY@R(gZFbwTb$g4f>S)Gz0N>3`&{6N zpi;~%lkvP_16J@HbE^1)jVF3B;=QevnGDA@SzZpfR6R#CRK!xfLKkXnmc{pWvNz5f z6SrxWZ3f>TTn_yG#s6o*Qx+iJn~5QPiCW>7c*K*JDQ;&Jhe6?br@tUgM#|UMO5@q9 zBlL4iAKLrwPIf&*yz^8kynagd8q&T(?lF7MRLQ8Yihcfx(}^$g&9id9YGpo^G0^|E z`wkg{&A0K%VODFj?lYf;6@wZHbvr5UYm9niMw2kN-W?KO7rGW_lWy%npR|_3ESA1T zx{YA4G2>ufct^l7U>oPkQc)!P)|@@N^-_aM8af@HPZS{VW@I2ZehuYUN(nE`?A2mZXfN`Muu}A!o?$HdS`|^hGU%5Tw|blmxUr_ zvinZJ%q3!u_yX%DwuTvQMm^CWTa0o&BiX=W;zEfD=GLdy><_)~#B&jX=BP*W2_jQ! zk4(bZ+UMWxuyedDV>ww|T2-`v+*9D+S7B@7EcOu{JA!gaxi&HMWsZ%ym3D$3*n1~4 zoLS?8ch;!a{pnknFKer=7+Tb832~#yTbT1)I$rhBZnm=X6)ldu)oU(WHrHknja6aq z3CqHk$)G&@q|PlPM^u)VByRG~>Q4_cX=au#uW;AQ88+RHCBC&(ugFLyq&AZ`^S*e^ zsw`l}Z)Rs$ve6pDs}fzE8ERlY>oB9tF49zLSZZd*z%ww#fw?40v+9AJM{nPh?z2&K zA*NZ~%)+oX>&PEgmH%^N?>p^Ud-(TbN0k=S%FicF7YY)M518ynvuSU2|G{$C@?kLjGFLR9lJ` zyO6v9e5|CdCPsQCHW}6d`A8EC=KPy(Qv%c28XmwUy zf^ghL48Qn*jq#iq({GS0W=Ym}GEmkYDUD?tZ|U6W55^?LE237qf>YL<7VABkW@6N37Ti>ik1){5`f+B6CkHT5OU7 z4>nDyES7P*t$TT6fhs#0GL|Vr%d*;oC9f_HcL2C(aD-ZI$O=V^Be3$(}cv$ zw`*S22VmUVvip*Zc`HI7AnSY|r&!3xUDS!&TVd0i!x+k~<_^b68B4>POVW%dp{ zWn^jb+V;wweHTj6IOy}N$|P_TDT8OC>%4InEx(!SH*Oe*1_&bu3U=6}%`H3v)3DSw zfpOT4A(^?-P-pq-qGXK$#<||%JCk-ZGgX8WFT5wV_}V5TESf6XW*RJ>+Rn~}n>>u4 zsIDtuEN*FAS#4j+Ezd~Z;tD#a-yG!|FXL(_$STJ%yZ+s?FGW9Tu{yzBq<}7HXzrT( z9S-ls9Lu1cinlX-U$K>9+m(NBklT5tBWu&mWBW`HGkMzd(Q{Gx)-Si_5N*vY1%~fz zJRA$>%vp)M*Fv!00L$q>aqP4E z_?F)D+Z@syc)R_GpgW2J+XoJm5D?rbB8sHQd8H;W8r95}idFQT-*jDgiaW@tGTXhg z1g3VU2QO1`>(Uq$rofXdXTP|qFpUR&CAXD>D8FYQ zs8V*#a;=sqO$>blzrZ+>VkmYinJqo&fmIPYJgHmrs)2bin~JHqHp;FoOkt)45r^<- zBz|9};SkN!l~WP{@ALH@eqr# zk+jpkZ*cZUJ(VbmkK~}EjM~1XEqsImAxbFtAjNDiD#(Ixg=*aJa{TAu3Koq6w!dZN z(Pma$=G?S9E1f``o_U{jL|W2_eH$VZHM1bBY5jv2nA0rHpnGDoZ7)>7ImUoF?Lq{}g%e4sNUGj;yN9h$MZ&hagc(Q#N$KQ;gRB zdy88OY&J1-tA!&|#G4zgRQg;$n8gHbW4dF@8mB3x|YozC7zp<%(oyqw3A(LtRYlm zAC9jKr5#u=`QST&%W}sjo{jlx``5!~Gt7wadQiHUi|3)F!`!G&!EDc&Y)_g$j8DmD z7e6mCr==WUcf(s)RAB1oQw!HXV%gMovCqUaS&fM3NXb^O^U=!(!?1Gd|(bL9s8QnZn-U7Pi*~W-nPr5p3rEM)7$smFy;(v^nv zR?=n3vTdQS0%tSwaB)r7uMHS#uoMV?#HQtQTShPLKfIr! zSspOGew7ee)ekC@tbxH0GJe{*Na4L6*1Ei9RNMABDi`do309y5@&Zv#e8{V6M|?ov|J z>>l4)&}1wOKgGh;*0MCptXsIY+PFGtf|$IT?L%vs*M!UNP{EHT;bwAVQ?gCSTpnsh zp~ScHG#`A{*)uv>8MTi7w13PQEjOb+qa?Awpp9onDOSZc6Kli}T3-wc5*@>NbkJ5< zjvcw-SWmkubShZDoURqK;?-iP8)#>s+|$?V_-ez`@$Z4A|JRjTURg0@m)@k6sl~5= z>-RJ`xa+BG@pJnS*CsdUF!Ln$yzXlINoGM&@!Y1m+R!@BJS-E|B=T-yze?Ex{=v}p=zw8UrH(q@$AkJTX?#bf7I+C%^peQj73$t?F$Eu4t_DZ ze)r2q`&I`Bro;QzL$lt|O->5H2}~zEkN?3kJzo~DJvrEI*2J%{9W$k4NF{&WyRjfr zI>3V}g`P#&s#UYUXf`VO{QjqjN+i+VuTrta=BFn@AK&sP@%eJJ8*Mz_c{!T!6ZR|4 zFyIUP$9I8nCHaR*i+2x3IY@8H<_G|X9=lIm6R>Sr9)lCfgKm`M3ZlmDjkl8FEWGyZL+a`!g5kKXuxpinB+IyC+QBt3~xr z2n3WA*e1VE&g@j!6fpf!QPm@aT$z4Xf?L2n$}AmV4Bk79a#r4X8P$Hfa>RqxL7R3i zuVKH`1kTElQJ(Z}+rNq<2DDKxjdwR#V3EDqFiit!v{2^Q8WwsI|OW z`B+!eltCpbwU||#Iu-U)v~?x>J9%~-l3n)L@_E?5s5lSCq0R?Sc;h~yEzZ{RmWJ`x z8|j-0#A+6OPC=GgxY+Q{RhNq6ElID)k(wNNA%gP)2V%vcY+Bn z9DR|_uhnG9&L$-{Y3{n@DRdzT?LuMeJFm(ZtvJ5bU9a?^vB>_t2Mumtck5ccu1+vQ zy5?ZNAGc0Y^|8OGoY`JzYNPp=fwP5qhDrkMKfA9*bQRJgL`!Vx@yng+In;kFhA6Q_! zJ5ua@DD(!*7ScNE`?|f|wV7?OW(mCy8IzHP^$5E>k673DRWuX75`UtV*eQZy2uaer60DVxOL3GoR4@B+n~VhN&~O+({hNa{2Drx<_`<{MTDx z41B1F;vza#S1emzo8Dd#kd(L5**>k?;(tvd5@$%gCrXc8QHVh7jVA3`!R-45$QmvI z^mXfoyTaajfs!xres;a9Gs62Weq*!2DWe!>nGCU5FHd(Fs=elm9S2UHGnIi)X6=4; z)S?yFT=(@VKCC8VRu?gYh@tRyjE2tMjqxglzhxeeBOL=#$mdY4a7*OynCf^Jh~&LC zytG%4`{8@tY~YMuF28#tr7B~$8hKD~aLj&sdZtMsqS|w(HgxT+ec@abyAC^z9NM3$?)`8#lX2fsx7SHEZlt+_=**6zjb1NacJPO1woHX)-3o_?r+~ zBQs%rT=opV!R%gh1Ha!D-!^XI!{;%XYpng_D!wA&IbLMLcjpUEz z&FL9x%Y~lYKc#v&zTqbMMP~K&O9OJtO>){#ONdink>6={(-NzxvyGkZzx_AM%TjE~gs=bD^GVCJ`)Yw+yF72#2l4LMW1t-ykrXGp~JCS!^;I(^Yu zLEM?**g^p{bxYY6JQJaMxOF)@7k)>hxiD=6;a`>iPOi0mM~wfrTD@x34hNNOp*gE= z9~b3#vLb4%p|_#7 zZtl}URGPWX2?w=s<)9dOmrE1Ze2R4MHgYW!ewZNGV;OOY;7%E9MUpZYER zhgH8i>p3hR-=wM<>F2+WkH-#)X)};f(PghRFKqONmw1+=H-^yKRh#Win7=7~+WCwr zrpr5#CQh;S0`!?PYlbI#2QS{1!{j_a*0b6iAxvfaiSt!{DS>U|GxT#)+aL!@R8-5E z?^C=PgAP{^8jSejrKlL6z{dPv&O_bai^U1O*aGRuTO&oqTR<#&>m|N1nYSgLr}T?W zlv@NGZ6@iC+I0Eq>JCXlud$K^iguDZDpe)~T`nk-wn6D?p7x}II{Up{=963K_Uu^k zu8v9CN#Wb>?lTK(o7wJS-zxqD654kMA3X&FtK#VCHfPA1gHo!nGaOFN*|HWs?Uu*U zy!Cu0CkD!C(eZ@vB+&6X4g!Q!aBJd7Y67?M&X@RX%Nf35z$CTiP4*|vx3_s?y!pq1 ztNk|QU1rXFrbd2nEb!pBFt~{vVIdFe*(+EUPuUIyKk=dyV5l zd=cCd-P)$swxG7x!@X`56&Y>)NNkqLnw+}9whU`_;K>pFW|G?Ufvm+@p9P-QPHIf% zbdf-{+UBG0*^IN;tZ81P%SX2z`=wjk!Bft(DVa{pB)0|FNvYD4teu;(vq`u(Uar2o zN7pHdwU|=>Vi!{vlO=zds!1~g}~(nPss1`FQVPm zmdcU~II5`WQEMav3_R%K2e(I#|EV+glEl7Om0!T`7vig`v=2t=58~mMb`Dg*zfx_^#C&BVaY`08z5KHhU24-HL>jP0&+^K+i#xNl--`^eBn+|u02 z(!$Wf?kfK|jt3@Yc7`?_56pD!3?&TpEe+tRe|~+WYh!K;ANk0}(7;6B&eG;87tilc zv^Te~{p;$#KOcT0D#{^eXki4O%Eifjn-hNj*H>_gnXkZxQ)v_xUOsyDC&DFuoi(rD zG2Yfo`{C66_K%J~w!Q5VG%Ma@t)Hk;h+kyS`-Ktu{F12T$bH)d8lUr5U&?*f<$52Z zW0>1Of3f#@W+C=Li~4{a0(evaEpxUv^cz%wK=>KmTrn zNUgp6w=+j=e_BeAq20}}ltDvw)EnHzSp6OKzg_OX|63bH&O#E^JGm9cHFC8Kk#EAJ zpEervQ*RdJ()-~&@sIg43)<2a!u7rGCs<@7e|rC$yZdvwki8cVwZvDWwfU|PwHxTk z-u9iGsWIb?@_Acihs--*cW{Qzgm1c9>)Td#j78a+2Z^xTCy6D~__fubG53PAZCi{=~ws=v64=U7k*Q3*0Me2a_y6rNixsjr?nwP0*9o{@!pQ*>C5@>K95M5aD;u z*~nq;+)uv3ePQ3#v$EMi#d9)+Z(nWt0{Me-wJPL<)hHq%#BQBwRY~s6HMJg$_4MFJ zbDh)_B1*OAGN(S@80U5qm%0+1;59iK*fL4}1xHWq;)J90y?oR~-_=F>#P(uo%}V{~ zg{KYMkLv?Mjt+V#*n3BIzdj@HVUuLj{IZHW?BnR1At7Izdgb`!JUZ+>Q+c~v!ZKbNXv^tx>z@AXz0A2d)L_^%uos#)fj(s*aEgoNwg9__( z^C?Tygug=e2-#ozs{wo8lWS<9bo+|4;u!DEqi=`_-+sTQs9@yL>R0goHEaJ&sRDMv z!5dA@-SO=9s|V@PT-BC$CfWjB^s|MoZ*xurj^?bdpDMN*Jdohm(Wn2xj6rIuZ_GB$ zC7$eOiLuCbyw^`J{+Yu*zM!q@=&oqR634etE?nqY@5Qh}MIUV8qA|hxb7A3B+@S4# zTu{Ifms3?#CzlIR*X3q7?oSd1aODO1~q;pi2l{^d9y3*Tb`u z*O2SLpVI@c`UGqKk(ar5B za>_v)yVv%8IX_VyPHYdDFV!nvw|M*7Qet{J+$G(=*pb@)j0t|6-7;9$Wzr-u^y1UE zOhYRYU-C+fH8V$*sT9%~yxG&f$0s7qe;s&LGsztrsv)8zcRM=uxSiRfcHgD@C;P&T zxKw*mYMQq09leO;FWa(K2Amfu0-vLeim5FP0`@#w;yt6~RqVpEY7<8%P7=I1`^{`t zJ_Y91-cww1uBscQN=tHMqwz*do^mmLs7S@ewWNCb+ME{k`o%q=vmPt@h#iW=mlr?C zOK?jQh~H_vw7ltcj$=ENf5i5+q)bGx`zDXG@BM}&+iOfD8KJ;9Q z{4%<)Tl+bM_O&`o+9ClVN*zhzA=S>jQ^#y@x@nQ`}pxll#cIkIBQiUFPP z$`)P$jBfT8yk9u)3K6d_*G(+jJSz~&BNzTSc{e^avpMJ69Zup%gX@8AJc5r^XJj~0 zg|uQ9!j4nn=wI=D>Be%rpO-HXOxPO^iYX>Dox3Z$!8Nv3TYhV4f z06s8_^MUxNFJ$VzLyf2)5pq*OPv40l z;GPka4?gIre3v6PUn-@mtIfGeisK#1JXPzcPTtaQ+=fL2zw`Vb&N-GU+qD6wy z>JffKGdEZqroVIv^CRO_1_D*FXyS1fd$v!ZKa>T_gh_QGrN{Wb@fF1`N+$*Kk;}-h zKTVY!YBmhr-9(=u{7(O|F^N9H=dGI?3u)l+Zk*k+66FGWS-xX`uZRiMlM2|t2Q43; zG4jjo){%M{GEpHSrCH@~aLVulgF}BM&UrLc5l_~wF{b_G_Qz{m@D3(w<@?K@xqO@SBb(iby$E!ra>^hFnS?Q zaIixuNccmWHbH=osE#I$!3_OHT{iW2#f)~wl-s$|SueI?Rr}FR!fh-I&r{~&)o9N) z-#+c=^ic5H7CAA4sesz`4?$8nLHdyqjWv0V4GV_1S{*LuUcN=JN}4fMB%_dXUE@;; zt`3gQ33?!r`H0;l0lOV3qxrC4Kd3qXPNqff@V!@WT8`=#buUI0lWv?!bP?l|y=oG9 zlMf>u`_NNPu4kW&um^WHIQohaL(|d|* zUZ+GP9g2f5<#ayC^CtL|t*Sm&Dqzit&F*S{S~8rdv!(VtO>>S$ChLhuCaJsC_e5mJ z$UuXhd1}Z>q((!nk!^?aVA<*d>b0&}QCX9F*Yl%AT{fIiT(`*11{b}ub##yvik6oQ zPkvTrtjKB>7tPMPn$a(ClQ+ok41;-u;B$GZsV!m6iED{G=EuKr+KCuOXZyWIUf0(( z>-m|fZnT#A>y2VI;+X2R-$Kj>P46Tok6M;K2bXIb>mSKKkLbSQQoc(WSRZseeRE7s z_%?;Ze0XA|X-IbP>;)jT_YTr@ue&Vcj4tB}XX3sZzj^%7ws zDN6lt=^P?9^4V@^?Ls^+p?{!W=4r^Q#ZQ| zk<+{pG&mpNc0BSU$5xk4B5XfQZPya*WE@*c=j&qKb4fkZ$4!HZ7e zEImhFqB*+F^k}I~4V9tyn+7KiH`k|yUrkzm7FUTQTkANvBT~cqYUDQE4EkfWb9?F{ z+y>LlsJpqiDNs2dYRjr#k7;}~QCGcriJ*O&G?<*Eog9;%pYwI?(GjI#F_Zl=rEl%S zCW(EEUgBvwMDk?m3`d@d#`=nCD&Wh*U!qUGrajpG*t=h#vsa=sBxc@4i4fV?PIt|; zs3gv!CFBXDKf*l`uF1`GZE@0cchdB^HH-D6E&aX?w0p=6>8R_Za`!VBpg_&J=JR?x%i7i3bkaAMSnluR#=K3G3JNxx?8#d++K z`Sj}Ve-=r2m|SMyr|{zX?BA~QmW_{{I7ZgIyncZ~*3_4YH9LFHGfn0@=?uZBW6_7X zpbm0-h8e!tDFP398y2g3Dg1=VG^}o5Yn6s0ezp)a{cyEB?|78Mv7V57dl*(^R#=<^QZdmeRHy;i+gHVthJ7~&ER_En^#x4ySw#Px8GK7EQ+jX1z~8mWEBPf}z>avf@zZqy z`cZAcAq<~uMAmLIy5mjP>`h4ZfxFOGv;SaFKZpOqS9d8zOup=h$`ML~a+4h9B6agb zccyhdx`x$bb-x7$|HZ1D8Bt8@m3K-}4s~vmhVn6*c?I44GoWpE`M*7!927AI; z>H5(hG$1rYp$vuReajQ(vEm))cenOl0=HAb$o4)RDgrd1%;UodFuRnsDb=|X&!rXP zr3b5P^j&$cPtRGT6Ykmw-z=>{|&)oD2%zxeQ z(Z6n5PLTFPmB5U`Gsux@*Oc$jPpnK28WH5SeVI$0Toc0KLUe7NsqaSB!Q@Mg>$-h? zV0g9STcw*GcHI?({ImWa#HsQsRifU7ERw+S7weivCyf;iQs1!=?; z+g*)QTdlJVIjK(vaAZFgUw%FbJ=vWsa;AA9H+TE>iNhb*?Pwyihhh3v<}VLE2iGCn z>xGkkwR(L{)t)Z?sqZ?{d?nSMqsgQDyTe!6)AxpK-U7yir?Wx0R7GfZ8;198FH@2> zjIP@QKK}QtDwdmC+tc`6w~e;>zKgfK21FsnS z7x4VvqNNoI1_+k}Sa3Do}>#ro!8|9ArJ5iApRh^a9UtZrwOq)BS1gR!u}e6@ImH zM`9KJ(7a-9QpfAAec1SnEEKe%p*P4!dt==FNjsZKc3}TzID56!>KaS*>Wn$FVLTascL4*_BfDiFPR*@RN#7HDy6B&Xt*rr zjC)_hsBGciCWv*c|7F(|;=992(jevZ2>v%=KPQy)3LvA5O{kv0n~49low_6bABx*z zLWl&LvrWw0Zw+t%xiqCk_1wM1M1;+@wheWFhH_EL%xC1sIP-5sFdu=EYur^45*iYR zL$#w{$f3Cz?y^ui+H9wBvs3g4!13k%wHb5jMi*v2(ibBN6{?WTuI)!0jIBpz`#DS!};np#91_Ml+TyiHwX+44opUquh&Iaxw%m+Ij7>7Q6JB|82PS- z63fDY`!!EFV$d9y!F|`{SX)cF7Z28uyF?kS2}$n6a9Q(wk-&yw;c5{Z;owp(!uQFw zRs?Pr+tqHWR`rWu#>V(|w2Lpe*f1svgUaGuMzft$NleHXH`5YP`O0HSOhsUfD`ESr zQ;QLg_)TVW8a9lqRfb;aXgK-La56`W5JhkKB2gV))Mjhj!O8hb6qw{z463nfRv-%X z_hx;*1gfcyE?<)Y{#F|kqA;fxIb*`WmK@Q&gS^NlHi9tJXZX+2gX+cGxGtkdQi`Wyh&or}mt=?Ec+&{@_+j0Em zfY*mbj{<5oFhE&=%Yl@N1&ZJLS?|ZgYd?89k+t^bUH*I%I*h4!{jH>3A_ihI6MV`) z^npBTw!7=H(@>U@Dd{CUclg-1r;Yu%n6Q@(ga&QTyX$dN$83X!A^S!;K1^7`V`K`H z?miqa0mm}jK1AE>(`rzkrqGOXVF(~cfg7QPv*rmfwp0l@h_6gs8Szfd)CumyeCrtxn zmg>0)E!rG}BO~6UnP3vokZra!(W2>j-A0IBap=R}4_AA=|nSCeN|0R#~&@o~1MFkM&h+Ua-)0A&70^R<;xzsZ3CU;vD;GRBNwU%C(h?obCs%Dw$k~|m9=lp*LEcjX05+H zHF3~7KPVkN=w6`4Is1EMknrX=E}ZxYmUpbs`OjAnr)bYrU}nl|4zr)*$fW10vmag# z&g&)l;pIb6+?kRxfqjDHrfliMWBKd}BIc+)^&y{Hy6Dy*_&`D7qQgInAR$eaV6^{v zF|z`_(plH;SuuY;nz!L%@Y}(H)6V(RS4#f0A1W@@55s*!M48-tsN17KDjQ=#GqAkE=BWy#wTJNK9^#)>Mgv;i$U8l z;Z~qzc?-IjH&0G#L+^TWuG>xtJ|11w3A;&bzYcX{5_za!!$H_9e=hm-6~XC88#4YER}b}7l%+%og`NdS7wGBDRZC^0B^b@1mt z+;=;DN7_AhyH7nHniar?S?wc$>5=TU)xv!FbG0*Ny3c+L=;;gFQfQklxh+SoOi0Z1 z%%hBExJ|{^ewf}4W!jg?t}_H-f@%@0EqP;`2MWn5+)jT@_hL!c%R{DS*rx0=Sr6b2 zXER7?`{39$Gv!9hTyE>=S}vy|e|Zq8iJUx6=>lp+gr*4-f$#4$ulfw%hO~^9QF7MQ z0{T_g);^_DsHcfN;Y_@2j@nG8n^*vcJZ38gM!)*un8M}9JdwF&y7~En=N7eOX{cNz zc<}k}(|||4ST}mAf`rkSCLvUGHghEiy!mUsY?`lZ)!aVe*cq6c3R)j8&Z2gQOJ~xz zvZq}^4{!1&PI6L~&Qwfr2qbC}T?q%R+EZvimI8Y6uiKU{w+c1QTVLm)I-`$mi_Dp( z3}1y*i!|rBh}9JM@DYr(406yIEvG*vACGov6(}Z{gLunQnjOc`(Mht?JKdBc&VVA^ zzMlBz*mGNnWz-;c$^kgs_>FO7bD)9y$t z_HWf@AY0^r_%KuyN?!|@6P0hAJgHdkh0QRWbgkN!fUk_?RHbNsU-k+n{Q!KQLKUW= zC`WuWptV!=H81>dwEX${g{@N(^Vd6y4nZ!(vHDe)cEZ{7zBuoh0)hx|{I-yRbcZgQ zk`0?%>cQ5RY&-i~%@azW#j4{RkaWFUEhU%Q(>G!3Q4gqva%kL0N%{vmO^HXSgPbG zPcV=CZBt&Gl@?!^M4^}WcL3Ds5F9fo$Mi0vhpnDo*4PJO_e*qB;xwYb>c7xIh7hB`buB>QLZ?&Ug!bZ)Et(^zWhfApu$s*e> zOLQaaL9-daMxKjmUAEUMnE0|(-Yu+jl)yk{X~JeLjY)7Sq)WOzVr5%V{nTWz^!n-F zCFYUv*t7Ys68lNxCWzzTmh*D>OB!n4qI{(8xp^kY1pm@v_KTXZIDTx5B8REy#~8D` z)b^>4K1qQpu<#GAovJm)+L&;TG)zV2e(P*MF-(bV;n&d9k!iX*2P1< zX5rz$64XE^TWVEs6m`PtwjuWL)U6C?%-$u)3hs7D`~u#_OzM%ol_*8cnzYzxB6Kjj zq={&fLgn&C5G^Bv+d_l|Hw5LR)5VxFd$7-t5gxV^8ayrzJE`Ln(4)P{p`Z}Vsni(Z zP!8O;!PHu)g-vh5roZVIZZ!TDRF8e0+Sv_S40}F^_3CV;6k*l$`h6OWn^Wy1?)zy7 zEGSsThG8Qfm&^`U>t?FwgtGfldOgn$xwFM9(h&!^OWNvLIv^3;L>_mta-kl7YYt%$ zi~OkafBbqo-~X`QpgmRO@%3^6`0!bOJ9T7eH|SA~_9hGq7AW0T>k9_JUIf!kFVo=f zrVT$^Nda|C*n=YG<8uVqwP?Nrcq-z%CcjG*QT@JqgkaJ)E>4fA&yaFq#W5&Qe}*$) zC`m2GSTLc$YaL#X^9cXm;Yb5x=pdYq8diB8@lp@1w zJfXO)*3m1E*c0q?fEbdb>Nx#uz~_1n4mvFBQl%8y^zE80Xr?$4N^Mw2td7aXcUuje(@eePhp&kB7kC(MiwTQ`JF2oxhbpVv0 zGUH|_Hwh3Yzs;p*kGO8eRPTu%f)X4vf%k!Ra>wYoe6o)T%B98f#3%+0rHhaK9(M%3 zlx(=KPub)aXqvwsjzwk9S3XjH7#ni}=KpXB935;{XEbbOky%Gbu}E`9Wd94;=@Tmt z4(zFNj9T4%TZWW^r^pNb^1=`2aZ0>-^@e!9i3E59!Rvekg-6Z6&|LIbsHS;0?Jm z+VV_WSC@;kz*U2;4TFtp)tX-Ku%wL8NL9^V_c)+o9}q~?w@sOquBI5rGBezEyg}8# zjGE{RCq?$FN%N^sA*v_*qEcoA9Pn>*9}a+Ua?q8^_mQzL>=oQkMs-T z!7AUL%RXo~pgi}U)|F?9OvZr3qqD z1WrUuTVqt^QxW<`vyG20@lB#%-49XiBJXJ1{i@a(U`FDmM?QoeyZ~L<%T&0wnp3uq z+_@Qday=EYPkl+t4I7V|2vIMABp97q_ZgazeVPbI$cz*FCek1M1rNf(J8$f_n)=6N zw@JT@?@rSr7xZ}yk9-J^eWG5AHb0Kj&XgBzVpP+%<2DN#n*56$XxPYSgK54dUy}n;^eOdk2y_8f<3B{HSB87EL2v1IJ+N&IhUd zcB}wvZ8TZ}P;x|mNpm4qTxeJ@O4+y2XS3QTx02ufvo`hKE%7aG8Ny07|3rd22$afS zn3t)s;{NP_Wt?&>8Suv;8&znBvBMRc%7|{O7o){jE>@^Twd51Z{4Qj8h$AN8IP8S9 zy;Mj#>FI1|sZ9N-WszQ4qg9OEuu|UA)s9X-9zFU{35C_j?qMYb& zbSwf!i4#8jrfCrp`EQ}=qL_$r7H(c@tew%NbeK8>5@gJeP86`TrDJ_=8-3Mrzw1~bS*3DfC8Tnu!3J)k+}3JB$pf{N zX~grhc1HNh1l;`i>PjEF7XECHmMlMLRyTJcMvrL+1Q~u|(XmLao~UChC+}0(t!Rkx z&el(T9u?f?weh5N5f-iLy2d3nQ74MQ3V97i_?#=zMqwA~p&ha0%(zF}?|EdUFQzgV z`SwhaV&>=P4v99(Rz*Vb-7V?K`yPsLEuN|p*0hn=!b9%Lwj@{tVruc)r|*OIbFr^* z4+?E?CuOO46Jv~mCCoZ-C$l%|)9lK0Lr1z)4`e(Q&k{kLx>gvn=PpY`(Uq|02E%E4*(+x$v9r{>m@VA03 zzH=K35(~NajaDrsq%XrOF=Xl3LgWUw&Hg5cF$3!ey5!3>B5-c;=eYKN3+op7|65o~ z&fD@gj-}0N)m$hCk1+9qZQNqZkZ*~H>p#lfRMEoKbs|v?><6Fi?VokXU;H1^`g$oX zS1udjnDam6ylb?H2_uj6<;X=!q3;P9FH`U)qvT-#=^Wc}6JC6<5-A`pGHS7#{-jV+ zFkFkk;pEAiqaYDPrz5g*zQ_Yzvs3e1p*_vwI4&+A*yOq%6@v!sgP8t!e4cteJ?_{g zF(x(^axr;4RRro^1c%tJr_jtk`Z9as8J{bS3mXcr$fiqE(HK4@%(c-ljahCjgb@Xo5o$OjDm)DX~iL>^HX9A9~op}fTXXO_+$GR6W`vQ z?zDlPk6N0pY`Q2XVaY)S`mq7MN}U~GSixj0MD5Zgvo0(b9X4t|aIl6(+$7ZERkUNr ziyn?6aNdq!h59np?+;=SIp5DmZD0LM0UJ)&CCfkL#@8>>e2hVdon$ZWl`gRhC>^PF z7Yw4;w#qu%_h>2|DSz6azmwj2B6#?7V%%!wJ}p0v zL}@3bL^$CLAmq$QjmH$LU&6mlojrynX`rapB#B6>E@*QX8z4ISSotPSv@Tl}N^d>ovNcHI7i$XQnDC6H+Oh2ywwp~9NDpNzdc@P_I)u~o6hr`*D9$YV& z>(iFwS)Tz53^&~CfT|w;UV?nVwIiHXphu5L)|_eL#g(Uuw5|81p4m~)gE}g%@LA8| z$C7UAQO;X6H`9+5rl**iVPJm~SiHAj;z^A|ZKl-^y9J~Wp(CI`D(pxWOj`@)q_wIg znwBV?*{S5zI>d~t@4(EVjJ=AsmU=6?-Yrad2Pg(M!8pt5B6?V?Cl3Ax6>?>gpvAa* z-06MCB-f zdqAGDAmz!75+i@7jspKxKK#n2^$XUX4jtF{ac}e{yhbO}bvk+~`Jhy9C};hAg>jo- zt6HDcTW7VgRqr*^eXl#spkBPW8h|a7QHfZ``XSV@RQghbY+jzNZe)tVSHS9N#->CJ z@x_4qj*0mgl1jh7CNR|16|a6TAE0)6DSSMVq8cgiqspXJGM^v#{nv&C%m4hxwe__A zKjTyauwq{q*Sb%7G^%()v1XWt^g`0cdY#X!`6 zn%kFa6aBL3EMn;3w?UY^|o59PY@q z_B0k_u^HzlQ*U2Yfcn*qsz2H#+O9#BDWFjTnr0D=VdpAf&{;T1KDyb^!Z0!_8RzD< z#yqqwl`60+I&3&7jiA+=0MK~U%%9DBOfp$IKYctDB}BKt&t9rl02Fjna40o{QeAhS zug1Hr#$lx;LG9R{Qe;LR|8hrXW&72gA6;GGA&FD_A9(E!FU(Uty0MKC_;lPvap&B! zZlShA>Mc?^#-fZ1GPqo}19nPJ;BEcBxtJW5#ibdxKd6{xU}(34g7p1Q;Hq}U+Dm3; z1=^M!0#93X<}!gz=&=87qyxY+KOMSZL8`UKN5Z{EVX37dBI3Fc;G)i%grwCh4IF6q zZp>^AR^j^r-qn+&4X_);npUaYNEcg(I_pp-aCIDa^($u7at+v>Ma>9pDlUg{ZMbh_ z`dAG5P*X$r>)WEpa6rz-=l27_m3gj8ZBi?FB(ipOpDmOa1W`Qs@*jZy6qO9DQ@J(y zZ@ha3jDK;V0Q3m`fI_TH1+XP|$bzQ-#?JK?cWExd_$5 zRnf1*(H~+ne+?2mU4I*|Pt(Qp*0m(Bcz!JT8`h=`omJ)&PM*Iu7)J~T?|yzTOKh4x z(EWx(9II_a|HZxM@W>3O^aIkxv72j&Vikx`Wwt3mE(WDU?>IT2Z;yiUZK~>xv2Hz_ zo^>5_^EAb(S4{6r>vZ8#*4J3pq_(tnK`k7uX{l)#J(6uCd`mf#cgTLm>W!#CFALR% za0!xje$dD5Ob;jX`^O2DOwseVbFl7bC(7s4T@`>^ z=pn=P*_LW%%%7KA5X?=upXgCny)(`-VA-9Ywk%mKVX16;LB4!#{0MrI`eRPTTE>>};fFeS9} zQS$t@-1QV*_FTd)_!iPbAMH;36AN$-l?(_yOS_YGMlYEufBRm|U-c2H5G`MWF7)-i zim24XqN=f(V>65da&W&_Dm#-swd;?)9D5RX6vO3ei~bD`*~h8>lxl5@Md z%cPf{l7+g-*zVT_@0vt|t<`m4a{&;!+fHVlpm-VW_TDKa)Ia2<-^qWkReTZRsc3-S z;XnVDC+j%uX22=g9I(}|G%-4JZr+0>enyFu)8s?{oxK@4jdFVBGNM7L=w8AGO{FjG z;Lm({-aJzE>coqqXGDWVvd_xXSB$*o zo@lHcs{&3BaQ)Pt3sH&rO^0R&yHdHQ9|>d$CtFv)teazOM7%xw*2~S-=Wg!R$-UU$`v1w%_7VIw%J1ut|9(&7b$G zn7HnZ-vo4_)5Gp>b8Q{@1a5-58f~ks-Um{tl`lF$jvKTf^bY%2cCfnjpuPBb= z--EiSevOT5zj@9WK3+yte0KLe&QuW4Sn=+uA|=lZ=hv2eeo?xav2t_d6;$lgEYqxy zlVR-b1dIo-VMHFAFrXmJxm>NK-9xXq#b8*hw{JmewXIC*u zZ8n>h>1KIh+O4XGUnJcMyMMA?z~$i3d*#^1xg-Y6K^ouBrXmoUZ&8#)I>C!J*_lvvoD$lp2#4edKP)-h9#)gF6LPOyGQu=3w#v`YkV@{`B{z zF-Pm-mu;0gVR>x($H=8iD!r33v#+Qd5TvRn24DL}FvTq&gnD!uqa@RDf9kDokr)lX z_)iC8DlFLSBH#^U)-e^GUYQEj9v9hY*V@xc#zP>d|FOL@`0b)}GELqz|7^|SXQ*21 z)DnOSBonCO=;uf5D9AqG)LU3?70L?EX;=Jp@m^7q$`HC}8bB6>4lu?WG$*`9S6~oG zzU#A6iC&5Tixg8!rj;(Nh$z-%%AcF|HL|OUPLbxW_b>1S`q$$=gFrY@G#4e;tCM!&F5MU#L!Iw0B_AW@d`R zMaNLmLCqkY2chqmDSj=UHDL50tup*Cw`$!yfXI1muj8Ielx&vgJm5_Y;vVR z%}-9P0pV(?1Q~AP^K{a5+!Siig?`b4{S>PhU$prXfVq{{oKaip!y`>hh!bEo*?I*-(jLf0_k6oFPt#moIBVIYu3d)%+vQD3j;v4motM{1fC?yOP?&55`}=zv_QkXu|(okzv)~ zO=tem;ti@{x}aw^?14?x>G_vVjC8OZ$^W{*0n6uaD&^ zWrb7B1|d1FX5B*OZd`~*MnzO}*Ld;W)8FUkyX^>T7P*W3<&fyV7unOF6RGcCOx2oL z`US-%cG1nRLfeE;x>EI0p!8zK9!cQ_uMLoHL?*H#K0RaLt@d3njk(1ycieGJ_`fkP zHVoVWXVnk6zn0BK#9SCetCU^ir_&UGV)Ku;`Arqyi~&eG7v*4}W#os(>dfBZeVsJ3 zU5J@W%HQOT=={>I{KB-PMCr$8yKNEzQ-*9!ZX_&vA8VuxK$|{#4AD2bM)z=p5JdZV zVfFkC>|B}=?)5hvh?Z`)D8;IPCHW=rZ+$RZUud9r9=B{RNa0HJN zH=u!>y2nj@%egjP^~3}w6mWc>KIEf4n>1&go=T5b*fr?UYw+Ii*F4rqHW_KT?_w3W zQL|y2l;HKl!@__jMUtErggwH1*wTcX<&HFrZCXRQ!!C7gpwX>?-vi*P6;8dzANFmI zW~?68^yOdArI^_7Tn+M;gG*@4%gKr?71pCM#D_1>3I7-eT^6YGZO_rU3~0TtW~hbLw#;}XMs9E)L_tbSJUd@t{N97-esqz4Arnby5)^|9VjQS?B6wZ zcMc8+c5(2m66h5Fz81WUy~BaoVIBEP7R^t(38Pfq9>m4+ZvJU4HHqB$=dzU>%fCM7 zxu@W0YFo7%{};EDt{vdhX(n>Q>-D<{L;78)*LD=S)(N9R=Kyd1V|K*@NA0+IoTy`Ts)@ixI1%(9$SKuP z2bR<@IM>H3WPh*xRvjz61H5aqeAX?@2ufm1yoaG^W&P1OgQ<=38|pD70`AT1~2>j(Wd zy!_>-9G{tF3%^lha4|vz3YysQ&DPvN7#Ek*{o$Cn2a!S&2nwCB?+QOBtgh<}i{;2% zm$*B{zpa@VIZTySvp))}XO$^&^t|kgj#=Xu5W-MhA#!{kPeaSB_Dp4A(iz9$$!!`W z3+2l33!(~_!C-^ZG}QVsly(D%F^BH1P;9KYWA!Q|=VPr_{a^kJ1pzJDiV?~kXXr22 z90C{bzSYujFk1RXvvQA4_P5Hc0T%I)u5||8L5dW!t3y$Fvd9%4%P+zY)&I8Y5=@@& zeIIgPCub`E63S{p*N6jq&}cnzVp(21Yz=Z`O_Qy*`EV`@C6lZtW~A^}&)3ZEd#tF> zTmkewizh&i>h$xNEeG*d(qUU%)uP~iqRf)+BLnh~x?ApXHF3KtUMCN$=2?LF{)gzSGb1JOg6Z*?}Cb6}&N2RRG5H6AoX4UODQC&TqE&Sm;bxyB!V|v(= zyYwo0Pd$w~VZ3A+t>4hD{MG>>F$x?vtW0|&B!mU1#TzgyYVIS9=O<-RF;;*L*8;Y= z0~_=dgnr$De(>z~7RaoF;ST^^7~EKg6=5UQ7hD8gUJ4+MHBz4sIU2ocZ`keqP3>(X zWp5Jx%lmnaYJTTEj&KjRe>%ZlHV@SfK@c@M_*Db-=Gs!~>^;ICm|#v^9P80s z7YNs#O?(I#~NsMf(b!uV50jg6yR(CPA9l0%qY~?BB!@pO`}A)+SZo@-452 zVOtZS!Te}Rk8;(Qn%c2gC1TUKu3tdTNfjs~f%c6j9;lp;!po_SaU2s;NcLN>{`-}I zrVThIp}hSE``#6TmatTES^h`0mIDnN2x+eP!T)S*e&`*n`ez#_=X0!W?20j6BHvkRhTeFtE8}cSU zz4MGnL_&Hn1+sp6a=)K`l?rM$X>79XW8&=0>w<_QVj7*(RP-2rtJq6^KWNFBKetwmnNb5dYH{$THmDc>RY+lDR#y%;rWIPe z?N!*ABM7T^=Sv<7`#V?B0ODdNB-SZL6G7IA2^Fbr{xy4SgchM=6usJ|_3m78E@&Dj z;j%`8NVw9zo%i6*>4~zBCo@SiUbVkjpY2N-lZFD7Oa;!vnGD*8P`n?4Zj{w9Jcb!wx8VSxzs}oJn`{$3jv}sF`H2^_wxoOLi&^r)tf!m0=(%xt%yWyT zj_}Pogb2jXFrZTzhU~3@1r1YSjtqQvQ+%A{7=_+oTAC}VxN)6FPg9}U~c4VAsd02d-pY& zDB}7W1H`rpMVoB3Df0GHVA%E{P->j`qq*v>_HN_Ch>x`EZNU2cnHEzRlac!oNGMrMbUiK&1 zgzqd+MidIO^44*E0#^9_usjZoJ7F>|D;Cq@YM-B_e=P)`rxYIJpbSyngWiGT$S6ZcYkujMCYVu^BpsPt3rPHNllD{mgF} z(g0YEdy>_;(+)Q}`;O^`K4|7!)>G0=3D1cX%Aimde`Md5QhU`Ba?sUdocDc+Y z8s>@T!dT?k47%{e-VU>LOSmX#l3j;r@#~JtGak}q_(Ix}a;U`0(fm*AbC0we? zj3ordzQU;l7m&0cei<@2c1N^EcvK&z@^J*hrlmu69uq71Mx0H=S{{U2+ zwWum`0W<29*w1se@(zzwiZE$07e|%Su(zq-D5MT$nek=+k)3Cp1?%>z11kLD$F15r z8*M)OZwYU-Y=a;(u=xJgi8ARP;qg$|&2+cpx$X!1!0M0UGi10}Q<3k>PC&g>L>zw< zQI#aMR!m%f z3VvRdi?FxvVs?^k@orMcbu5`V@skxlJjOagyb5-c7m?Ea8Y#l0%G!TQcr~^Ha&1jg zw={?9d<~e-y95-tp#+VXsVJZmZFq>UUfAauy^mcF9Fe7n1hOWAM>BpaO#VFhpJ8xW zs=4z_gF51W-H^0~hLfiY?yqFszPJ<&YjV6cYx#AkbWKLM=ec)P{CJJ|@nWHK|3Q$B zsu=e`h=1Qe0W{q-;2C=`z{S64dWMlkYd;?k8K75Fa~iB;lrp{Mre{AMZqXB|qHUPZ zA@7+##w*B~zV6}V|6nb=_=s}A|ClJl(^f29NN_+v(T42ucIHrppn+d$ z-~TK!<|cHoz}>tTVzOA4_rw%>;p&g-e_z3k~z=IF%Q^zk>Vht@XDeI8v}QK`JiJ~*$u&t+36n0 zb}|*FW8^Nbni?Uc7O#h~s$~3IU|^^RPht#Q2j2;I+oqHCYq_JxZ10R{Jsvm9iEtFyoe2x(C1T=bg)rwZF_k-4>+dai z?d7Y9>8)ww_al-#xgt=n%yoJNvnN$zSsfD+Y)9n!Li=JbpY0!(u07B{72&|mf8*_0 zLQmH?MOR#faLEU$(~)N`KUoX~EHC=jD!h8l5m+&4>3eNEcydI%L?Cfp z0LD-$S3sP>D37B)DKqw;_{k6F%mfH(tjx(8WX2B^b$oh%Z1NbMfw0v!c6nAN!>#1E zIZT)zPx-SyNmTXME3^hEC{;T>Vs~o7#HNl8y8=d?FVRX()|~Q4-=ZjI5!|Hp+6>vk zyyHY?O9bwQV}_Q5S^w&r7aQmFIC+uU{574FspDiVNhC*bfimFsF7KVM1kU(EeRJ?6 zB-?;cT&KJqHR;$0jukDG7lL!inHke10tBIS7cVkbPOi?pny9mW*|>wzN`)GE=|kh? zMax-lb6J?vlG+mCc0R05V{f##D1gNMya;?;iCS1v;{xAn8z+ovw9APA09(h4)ijP>GHahG5h>f{O5I9h|BVBJ0Vz zWph{=CN)~b0XE!c6>=F7oAp22q=q9i#X+Cz{1=xsifkuxBq=asf_>Ub_q}dI(afNG z4D$U@lb@%hz0ID+$qTge)ehzO7HdB8ThW*IxcVgZp(Z78vt3it1buD}vovM-q8rsb z$&pMWhO65{BE#u$H{nsnatjR88z=(rY3K=+P%2H-oHp_N+9)LC3pOV_*2O($+!{Vz z$MgW21@r+9h?|3BD}mtGz>^QpwG}6zqbA1!Z{oeM(-^wH45yE&&YKQ`M{ZG>M8nmCaQWf3-y16eMr`Oa&$dRAvqq_Hvbh zsdeA$6pN^2QQ1HwhGW1paAdG689uo{;S^mr5USj>yD{|D)w|lnr?;#0;|{*|hAmPS z$j@2H#=x_*L?0pOFOa#&+y2L&aab4{u>G}cztKyYY-14rfmtacjQfus=Xy7xLGKwZiPP<*U zgq$vnNfw1wH1!0C%;A16F-Q{R@W|o~MH>+x3N{E!8fPpL4tq^eRoRHBhMI0Wo+(yH z2SZ8eC6VCpIFyO+O6#u+5La?kDJ2rCyNOe^={B9}Ld6j~3W@X3A*4fH7p$D&F`L*b zBx_ZU3oXAww)_t$KBWeeY^#3POJPCBLYC$a90o|_^xn=|91q8~5WArurVB%Tjprja!3>QPLJ7`|u; zMqB7|pKV^;?}7KJY^E zCUdNs(aYZ^hEu%3`BOyZr)8&Ni(z=*^l|4z7O$d!_`qQXPFM`xvk+bw6;#ci-RTj# zwBLFCgQpYhu7Ka#AG0Zqc-$N1dVoGJ-nB{d)5p{8!vE49;TwR}&vO7rn4|tUSAm)a^{FD@ANh$Ty zrO1Xz>pPd8-;uB5m~x8V1sKd_A{6HZ-yE2?7bA=vQ6rLm!O$cCbv3`yk9h~C0k zcO{?q4}?Gy9;!lbImmhcF&B;d9LbuAXOMD07VZiyUFL0wzaaJQ?aY6(iC$*72Cbb> zjnN*5G}b=>miR0tp;C*o{H47*v}+A|P~V7z25# zR8Uz^lRUpIH-9q_SM$Bp(VCIqez2DvJ6i0ao=YcYX10FbwCYkWRp?v)m@b3tL@iwO z&&DPwk5!@)-^vblBMWOTvK1J-1fL)FMT4oz?b2wK=DCu)U%KBp4YUy{z4N|rxS105 z7qX)TDuU&y_Q9&&VtxuaOjS8%Jj^q!9`&P=+&n)z(w!;* z(1ywG`?H3`?dfvlyn-U`B0T)M@WeYTA8Pn$WJ$ zm_=Xxbn%Psg2u6}%!I0PboIJNtk_HWo4;)l-1}Kh5W6tEQ5K6*cKZ75kgRTOm^-UZYsf@xk23apcLc`LlJ<0F)5BvmCz+LYS zxbl{^M+&@VPS!8CZuGxmLhN_?E6y%tpGxZgoX$D}kvPNJjN_A8=(ADdgJ%c!^w+&q zeo>{P6heK2r+#tIR)-Lp*(x-$B1N*i`_j9^`XdsOUEm}`kn{(n0l?kABELO%Jai*f zU?wAmRP^Uk-vO|c8pNs0(MCx007DY#2Z^=fsnwXW;+$){Vzk*Ty73$W%VIS3dy@<|vFPzzkjE+cBjc$pvqpD>Gs@ z#oHDTqD0xYycjtj!ahVUFw4SnBC;hJ8)YXaC$-tfnG5_U4GLEHlYa^!lU>(78d`V1tUYUj#H zRpAs0v~PEfpj811u@KR;A!tzZZh~JwMcAS{T7r??VyUI{u5soB%nL#}{OAY}tluCS zRO7$BmCDQZ_75=hi~_=0fW$pLJA$a60e8p-ow^v!_xTS~Vo1QTl7p|u9E+-dgXkKI+|bw%+lfieDbY$i}OS4*6?Z3UlRszNm>5Z zAAv75$9o~fyt>tcV>G*%umCS7%W8Oz{Mp4_B_o3o4D;GaQDX$Clii`%Z ztEGTtAME#?%6IS4K22iE&`*NJ`2uXOD(90021{%SiW~vfJ!ch$X;_ECT7;`z0o)}Y z5nY8-bIhF%H5_z2O~(RhaQ1-eZvEY}unHg+V|MOXv#-yfKicFdN?N=|rD`qocjpol zWs@LNbNz*E+O~LNy6BrV3I%=~>Jr)*2X9tMp60S#tx1OdpW7JUv!Be;R`KrJ>T331 z2XM)D(^dpRu*z=d^w8qN5Ffv-@hZ1%B~sBy#y$Hx^Y?7@kzlM}$}|%DgjCl2gwE0KzrDO|LLf}sOJUXF#1|-mmxK)pjfN+L z`Ya;k;26tRn=rAR$Xxn+dTAnE07i>c1=>oT-h~>XmwdpEjeqw|&Fa2@j(Vy4XRZQX z*qO(qqUBNFWP%RAI>m3CI|;D@YKrN8+RE(;^?Y36fF`tSIo6#nc>F%Rod_9Gth?E^ z&Z8TT3KBm}fW_U1n`2%6x{*em!I-{CF>Hd)g}j~e*N{DvZMe+Nr{GP4gXi0I-QtoL zy}3BA^vXHuyV$H~A93H};>Oualz0}*ntzF2gY81A;X+7du~|<2?#R0t%`m?mUARCr z+t$wZ9z1A)vfr)d+>en7^^u9LqEg z?#}wd9eTuYwa=>I%2J~Lk<}Y&W%DXO;_`9uM#x&^ere3F(AvKYESvM$sMBt^prP(eg*(Qh z@bA?&{q!KdtgW5MX+y;JL~RMqHq7sXBY*T3pFgJ~E;&RT2f>7dfQ3++yR}&sIE$@Ao3`Rzkq4ICg>g|iiD`3B%3Cq)bF}Stn zC4pHyr6f{BF^a&{m`o?oD?BEXsY44%@_mWbp!hRTno)+$Zg&GboY{kI!tHsvQzo?N zsA*>YOte|R-am#hv#^JKL=tv?Q0J`tT!yZbFD`C56AlzZT=y z_^19Iut>HsEB)4#0@(pw#{vtPrSr|LJ&`R4WX70yrV%urh(il3r_(#tNOxkR@de&o zr3ap>8W1teC6158jq@Cgeu+xU z-n;=&CHo?F(Z#D*q?1m1d)Wou+W1@{3n`nW<(w2Hcche^^?ay{iF#VG+*a?i`rpxJ z8=Ox)Rep#Tb0@p_Oi2TJ7=ngUMFpPXqZC~uq7#NW;-1w-oBrL&09Lz*e;c&|kYy<< zKcf5mOCC?@3bz!<8VeB6uFqzJr50ez@U=7y#p_)Tsp~s>)z|>1<-6eEH?7%b%0H?m znq@O!TIAscyQrVYJY?6v=eqgXaKK>RrcAaAQ5#M z+U~y=E2odN_y3dnSw8Y<`gVLBw0A3~BOl8(YN^Uxd8eUARF_GmK<1Nd;N$v-u}}lC z;`rL1{?(WH!?8s|!nCg1Ecme|yiHC*(EYStL^zB99ot`lxl7>#DV^64cB%u`B`>2g-hmPxVVZ3hULSr_BIr+#AfjW-+25 z81hv_rMbPAfCJ}eJ&fITX}AOW@3%cN=ki27KxMh1Of68_AC~*Qi^7W4pAznp0K3zE z&Wg9zz_R1YN?#N8e#N6!{3DTpCMmEr4`KCWKK6Kwh>Rz}d5YhuBt-h76JFZ?3}V+SEsZ*1yLcRka_N2M8_p6bT#h{(p6_> zD+?H2MY;8`u};mX%yv6ZXEOM>M!GZFhF1?#WAQepM$LPL^;vf?07x z^w3e(#VP*!vxwg9@u4p*ttLda$1$=JJ|2cyQ)~NVEmfv)wa-4omgN2C-#3y*H?T1KTX1ylS-gYck9a5_D07gdYhc#Eji~+M*i)2bzYyYs3LhGhJ?IYp4Ssx|z zF6y^YxH#Bk9-T|+rd(9?n*YP<{TN=#}Tap%nlJE*Aue55Mbgee%3K z>kK{=wvh1t9CM2SHWioK>fTf~Q!~y1fXw68i%Dh3sQDIpkf_r>t%XZ#hTph+DgBY& z^$=XQ(pf1NkxrAH{o?Cy7R;8{hEB9*n*1$gCntif!PdgF?o&}go@ z2?2%{jYDb*5!2*wDkcf+!2D|x-Kq`PSabmvZ$Z}DuB|^S<1Xw>y(QS=zWQUx|3)+UVqqk1be%=YY2uEiw9 zNrf;xy)<7a~<)A(_MtKcW;jnUGtw~0@7B>)^Xz> z7F$nP4GZY?GRBD0oXQF^73+4*!`SDy(;FbSaMji<6lRM)qNSldSHQIM*Jo2QH8zqhH{Am*@G*JAk?&H)q0#TF1@9zA=zA-Tf$6}LiLH0kr0s|S1@yx)0T zY;(Tnu$Z)1SC-qR_=LBf1eik5B;R`GH&IOM7ZnN=hsN0Vhbk<^B2(qNmxWpIKWP0W zYH>Xv32cXc*ocUA4%rssx*0!?k$zl{QQGR$R$Jdr{Zt!9uJMS$;dslX_wvonI&#`a zLy?BL3(TPKh7yhCJx5k8r%?IK;f?I#lqo2ga4l1HiNYq`{A6|F#sv1H$7GejIf(IB z;lphZwJug-&9ei&;l0T2_aCg)H$)^K&1HdHba%r_;B)0&Y4Os~o+SATEWj1gx{G0c zVUlbv^>%~cfSG9ua9eOGu&}CrU_%)*;d>M`Ft2|cW{f!d(ZIvcn*Ih=;W=0Vx#qgo zl9JUsfI2kz-{S2Uj1>C{OdcjNVM89EcOSBPc)>Z?cQ#h5b`Mtn8u#g-0cD7MymE5|J7a1&jU=|G;T~uVtaOUt-|GayE!>&5_ABc;5aUT)Mk# z%{ie}xiN8g!qZ+S+Q3hM=i`QxCkIt~c`-2FyQCPnTn7g7wy^NDR2sbnb8Z@wCkNX& zo%N@2)aI9k&;}KpqeF0M&uPEn6-iF$-_g63hP`s)L^=3=Fe&oViQUGhm|G>hWxZX5 zV;x6@SB;zD0%aRYNk?a)=s^Z0h zA(uuiPZF|HX-8Vcc6Wn3>?;ncCld-xB8pj7civocXDLzPO105bpFauWxEs0flPpWet8Zw)XO$R~PSOg1>Q7N@)8e?3p;WB8R6HUpOe?!gv9gH3d3*1i3;YVP)^ z(Bi(<#)IIcv5aFe7ytmo*8Tns4|w*ay>+ELtd6VZUL~?LM$i*VX4|q}lDe1{v6Hrh z4czy6lVWnx7wgZDUO4y5rMXa3yTikpi9_Vlm6tWLr&&KKyIa6QM#}+~Ix=W>{E_}F z+J=NFDhUOFgHF^>fQ`Yi1&Uw!z*t%Q&|M!7u=|_#t{=Q}4Ct;)4W7YwkCMjt#OnqV1fa zWPZYal-q+#Q*-<$4c;M+Sa})i4h$AXMux9Us!ZDZnXg>L;s0@ZS8_e4Ted8aMM}Qy zYFe|Cd^0gDiDN<$KS23|ZShrKDV%gL?+Z*15AqzEKi;Zep)F4-MT10|RAwV_`NH}A z0jFsRu&$=mnn&JiK<)`9PdZa?+vfY}mUL-=Iz=h*7;b~WE|q%YJPO_2uJ+X}v#Nc0 z9P%zGBM;y&h~nTevH2IndTLYzDAPf4Qyv*j)fDy&1&AgzyYqGTG}Z zs?nlAC}khyW|BC>>)7Z9V^xF3=0{;5-Kz>~BG&JE_V4G#%jdMWvf|(&nYV>&rdbXS z_?T0a>GzgE7(gsKM&TksAJ3Li(rqc?0)ptK*@aZKQ~v=aov{MJu0goBtiZ}JA6wq9 zciIAA7viSYz4TT6#WDpJ`Zg7t?O5Q|8%L9JvL-yZ$+-4@f-$c_T~Oz^K0#y!Lfx#Lw*YC7wCS>BpI)l9s7C8!7w#7$ z`gwnejIzKY*zjy=Ck&B?zsjyIxRQ^6UIEf%`&J)y4$O*Vt!;G9=&3;ob1&}h4r2ZB zh)aF%^zzU#D%^g~`w>(iZxgI7<(CF>Ec>1QcMR2&-X}6RNT1yA41_2lnmVg;inkb| zpXS!gu|qie#xb>J$!;^_A~}RULJDpZ06ZhPDjde-cN0Ev-Q|n*&2Zvph%Z&aO=PO` z6mn#c!SVju&6zC|4k|wdQJr(oHDy;M{BsH~1~IJdSX40-X7kJOmSn+V>L^dqCxh)l z5X>3oo2?UdMjK9)+tuSn_xu)o+(Zv8Y;R3`*onc-8HNOr(nEO{pph^!2N}kq?c1mF zcz_;*-Sq?x6EtIYE|M8pJX-&Y#Rld8nMk`oA@W725QadIxS@QuH*9qk=R6(T=NQ9; zaU31-0jrxG4}^Dzv1|o-p60Buf6#}nm)=?F0D{ExYPNF;&oD<(lq|`*+L8hx1F}aB z$S6M^Adwk??hY9$oVNgoB3`$3=xB{?^Ld}4+K=m`lC;Y%7I&J3M%K2Yp-i@7-QgnS zhezsIS!XUh#BnU>J6NAv$rrIz+@G0nYaJ=T+Z|j_=UXB9_cr9qIrr z&tsatzgv-qME6eIU)PSO%pg#tS(TVL#kTP{hqH-SeM?GK$3&!eaOuly*vHQx;OxxW z2_Q0RT2r!Tmi@Pt9YCQc>ka`?oNYwoNi9N_O%q?M<7C$vd8J2`($##2Ww^TuXj0J6o~ib`e@s#~cRKGpxL zXNeuDghlkU?3?hA(1y~QRo^}0-Ohfd!wG%;L6-i>nc!M7n;3jJlmOB~V@~wug3YC3 zq6kKr!f*4tQPk0SmO8(2v}o|$JZUZ2c6RsK^$;vG@LrF{w?4n%TrWj|upz`kVskK2 z!b$e;SlGFF`{xdHo$3mX*??dws`)c@jWk_V`!GU}qz~J~An?$ip}E@t-)ff!ZXz>D zq?PlP3@iiIH3c7$ce1KA|3|lX#AFuTov0V&uD? z+}fih2sDT5YzqF*QT`wE{6*D8{C~dttN2iSm{So0Ou(2)v9m8XA0Z8 ziY}iCg%JIz%dH9RlD$~5d79Pd-%snbTEPhZ8QHSdd{(!1^+Es+LRe^D$!I-UC3D34m_=yV?tk z;mZOmy=MGxA3QK&CMpaNP5;bHU$SyspL;u?OUQ>svEyi%Ou={=4@>IAXJzwc_e&FD z87a+UscrtX99AH56Fu)@S0di{-zpwtheV+m@oQ1IkNpKRgLLvMwFtkW* z0ruCQO!W&Pumfzr6~=FJ#KjPY4PUemC50a*sU)5mFLnAzYc$L5*e;=5Xw1a_c{Aav zR|Fs1qa~_W%cBXHnLf8qd6J19dW3*7XH2R!i2Yj#$})$*I+(8W5X8ytc`TkLnk zrBWF03N%98)W2fs!8)oY4xpfUy+tj+;SIEi)_FF49>%z;qdV(JULEzno0-n`Gs3RI z?Z!8E=6fPlCd5?e?m7FNIqj?cE-p9@Sx-f!!E_%3+f?ZI`nav6$XKI}q66%eU!(tg zVc^(b_iHCrga|{utqIX<otfY$6WKFd!Vr?GDM(T87$6(DI+ZjP#<8knIV0v8ngd`53qr9jjVAAp1h9je?~fU`=^-0?Xy1PPkapI$u`_oi0aG2&B&1^->IxQv#2}Un;mm==yv6=jQCkU%=ri5a3+^SCH7;9 zt77JevQ45yaX~HQRoUF&i63gVksm!St zJBTSw`p6^de(lH4)lphp+wTlUfhi28PxapPd*mxGJvuCg5sK&klOk-a;>aTN^5$bd zZeFS5>3#)V2!_+SeOtm|e7U+yMy%tyLFyIb^{Z7ldRaIT5cgd;sFgc4Kh;21A@E}VJaj~kUiChh?=~+Hu{A1$BI+>Tx8P3 zjj@BWOI$eEJNorvX(Aet5LLQo#N95fKMj++q!P*7`y_2dQ0X8dTrDoG4Fgg{ayeSe zU<+N@v<`wW!n}@Y_!%_VCA?vCGE}oPC6281kwlBsl$LsM)S2>~1w;v(G5ja%ly+Jc zUFcZzj0Ucr-^Rtkz&i4+WdscGz3+LmXL?LT=B1J^PJzepQ+GNh0TzA;hh3)b39w`u@Ls zvJYsW(S5oU5zf~YR{4ea;!_oIl^>ZjE3DHH`(Y4K>WF%`h=&qB{Z<}$@hl+%|K!c4 z=Qd*e#>n=)HNoP0YE_n8;#OHbgmUH8q=f4!q;ucX-Y&UV(7+1kDqQM7xwVspuEAmn zu5z0`2ir6Lsn~kF&3oVmTJ2Qct$)I7s9k>wm+$yDN zpDq;&9diqI0@9pJ*9)euVdu$kkk;?V*esf?2HMvycc~SQvoZll7C+&hYb zlky5S;;Yed0F8r-ucXOXTmV;EiK0`6GN)&(i?(pb^5N>bYB^s1PUW;PtCw;NT-wD| zJF=UYai+#r=gfrhY&{Jc9eDc*e;-TL>AYrxFX=u*sdlv@ z2KF~hvg;B}Jzy$WEO7rCZ1@Ns3y?TL^DYf6!dk0svJi+W8gDOh<( z;Up;{V-*-v&Am5TqNG%eq?E1=;Y%P92GB5iIlVRg_|}kVq%hG+a==`) zwbBp)=QxIY;!8gsu)SruZNd!BK@`lxAV#}u{+%})DC*F2YDRdfL(K~{*^d(6HZB9* zL2myUlQ%EEk34XM0H5^)cE$V&48^**#dv{O*OF>YNUzJZjjnXLY3o9`DfCOUNo#?? zVCwzMBo1fTEKrXt;R>z@@dkeIXPuq-@z)s;6Z>z{i;2S^s~q#?=u~_E2s!+TTJH^< zl@>di88f9cZRMbdp0P}g8%58^!%R3c>Od|1zbB)QaF$efBCH3Qz%^*)x^>)f^X|)` zyIBI=KG#sRyEhP{OBD5}jAP(JI~Bd1IV+&7Yc5#_UT2SfxUJ)KLT)Vt&N|?>5H;G@ z?QP2z!{QD|LEmOYU?#?VSuqGa&Ib>~N0UoJ#jVp}-I$?=jBVX|+FIeLG2x@>9os(Y z4<}a(;ie+4WS%x~at2=(y-%?OY=w@&p!Rx|?n191GasbI59DPJ*9a*%*mBiSP9G;S z#J@?;Nm&-*4JM6#-Eqa-hLym&qPr1FMF3%)6mlApDSr<0zHJ-OCrZ&TJ2kVUv22r9 znOJ~c7roHy!O<~rf&AyA`>TO!^?&gpA4}ARMm}^*p3=i!<20$kd`IR26Z`6MVy7?F z-QqPOK4DyX6L_8GINId4Gp12hmB~kGVduqzS>(^LM*CT}pxxWO{A=q20-dKF|I=TV z%Zd(0cB|h4Lci^gA1w|y$N;eu3kVzR*G;w1s`lD#D+Rz^yV<{g;=_lYKwQ|!0_duK zlG-Z+2MLM;VkQBoy<&?6xlV8p+v5jgAwr;jl!=A0JyjD*J2q9XL>EofO3N5I@+xw2 zxz-*lrUGrqrE?FzSv9-fp^4g1nA$0qg<38=oHYmFW~)PAalj@yo}0*pq6X(3#vx3A zzG6m>&vgd8sV>l&hBOW(Hcb(6Ck_X6yz>p<7fw-+JA9xlSS*%!UekS5oTgjw!-psc z{OZ7^6z~xaMlT2P@)>3b;}oeLv}t4T2uSum>nSq2eYu3U7*DZ0aN;M$tQxaDU_aml;K>5!NhOzVZhM0N6V{mPb@baFFuM=k49Uo zSWeTf<$5y3xM6t+G}yT(+N>Y6JCb)VVIFna9EQ(?p9TLP!2IpkkBByYSpmz(g^540 z^O0^6k$DA+UFm$?A*GF@$&AfJSZI23P%pTglsBT1(wA6@Bwx<3Z6hKJYT80sn23o_ z_Wh6hrLRBsCmO#4D(_>V6C!go0CKT+SL(|jBg;VUvyur3bj8~V`C%az{C%BjDJS2PY({f{6%(BVv37FDet(bw`$*Tr&0tE0Dhq};2q7u$Sda2F<2mU;yV>A^uZjA-b zo%_3Y`^4xjtaXA985vR3j!I%+*5(w^^RhfX#1D^=^72W7tqgkVr+7%Gv}CY-2v-t4 zxn(!eCgV@~pGfmv%OEvFX>fhkuO!ZK$QY>RdBgblgK(bG`jy2=>{p`azBA`}WTpN% z=y1^KtNo0KkC}_2C+=pASF5gTGQFCYZrcjz-*!4 z`2=A&LoCyEA`FdCGn<$Q?uwRbpRK<`^RKpTr_BVDN*S-8);L+szHn4T2j!gjy}4U6 zi7^f}n#e@wNVuxg3_NtW$(N5Z&~}koRaw#y%mmnATXbSY?aGE)FfIjI!muY|tiIgL zaKFx&nq9G5)4UkM7iMj?2kLj`i>JT46$Lr?vc($o}FcUgQh12M3^;xyiO#CblW9CFQ2Xp^CNtdFH# zc=b#8T-B+$CoZ4s+(AGF7h?20wm8@~mvwAP#8CXF%V7>ow(4gkJt}~llpI+VlYv{5 zLu<%2hmhN~MmMAiZEb6yQr<*d^PP(B4uUKDpgaWBgx0F_^Uw6b zFHQKtr2F|KbSVlnlK$3O{Wt?Q{j3=iDHLQHDMhya1^z!#ezbp+6@&|`8<;OprryQ^6Nw-S^-bH+W~^kML`I|xWyHk>lb)avHqS*yY3wCiQ^Grv@7t22S42oEat({r zJO}0p--Y1;!wq&|RCG?i0mW|5&uQY6x!@kzB!v{2O2>Tp?F;qV z_&SCmB77Gcog+hwdgMW%zzG*2@N8e`uyG5jAaX=c08At9Dj}}UF|Hp^P8+tNpEsYJ z*~K=zkm&OlYq-GxZ;Lccj6zENMDXB}N6s)iXUPlWa!ixJ#er?GK15t%V8}WjK^!%= zLue)v8{4TMvW=mw=ub+;(K@#A65w|XnR)}QgjYuNl)mR2O+bQpkrJ94*IlDuW7Fs{ zX)`CBkC8CjB6EmF_SAOpB0XO^s{WqcbYKQkb4CVU268?_c5|ykRySr8}%%dyr+~ zJO}(L)}DSCj`mnYZ!%ojy%7L_Y%x_jo0r)|A-UduImAs~cZ4vTb_j>-+v*gwBgN5QR86F6>sxhXa;|#t6^sTj z;^rqV{Qfb&^~gFxVN{&U-w zChpr?W2$d+vXU~dYUgI}D?KBp3Fg)vt!qCj!52-PyK?cLs?I!ClC;c4uOY$g6z%3LbbqH{0l?%>Z2<%&P$)4av(Jx%F-G63NK1PuOl= zE?}-*%Xftrb(Pv+Q!ipfxB*t!JpS*ps?&?*{v!mk63J+#B*^WrTd#*V>q%qXIvMuK zhX+;6EKB|Fv&vf?td`M+VGz4Z6!m6Mh>znC)kU6IB0;z`?x0$IB>SCXoEi`YIHz>2_&Ia7V5*mq;)~+iW%x>8jsV~Iq?y>!JmwNx~~bc zxCX*xCj5+Cw}r}fTK&@Y-|E!%$lrngEl0gkJ^)?pI1FHH z*gn#xg6lcFayGUOyTrmX^4o7-Z1h@Yspib>slifB{I%xa8~~}lVQQ6LQA4iSzFJeV z0R~D%4qTvBcsCynMgu&zC+THTdaSFgjb=`sscg)R>9_fY&P)RTz2# z640Am@E({6)-0&IrljAmIyzUZ*m|ukM>X0XBGkdb{sZ5vTr?v8AplqVvtoS{e*6UP z1LIu#0g=sctx}($fY1;kM$$m>Q+W^wb=s|n*VZuaqx}aQ;LMFZtrxFoLwYhky|l-W z=e0lHVucFCT~03=YqSpRp|yyT7rggRjlA&=dHoufY*3j#5suNqrL-M!J4DbQHo9yO z#Z*e^=7C}wbRI5z**djdQ9r3D_Ad=)S0x1GP)W3PxW)RSA*b7I`;ESNGAycPfi`v5 zTB@8}>1PQ@PhR$7WvTcq8ej9d?&hcUqgq(Xk$aOf- zGL}n>+s}R)AEDDaw;&_h#qhv@x!^YsQ2#hHowpLB!XW(2ol#l;7%7{Py==IkYW<()ONcXH3sZr^Wxz%vC2?aF~ zVTXW9B?D3Ev~Aiuv13oU^O9gCaKZUuvCi8+E)2uGnYaKamExVyMV#G={@+Vh*{=By z$Zs-A3SmF%LcO3v6-aQ6*zf0Cn`pRGdIfp)m7KD0#%({=b4!@!m;JH+b8?xIV&r~_ zuxq}4b-$iUNn3T(93$W6ta3vJR7_Nt)?!x7q%xucwgl5ByNfaGs;MV_-L#6lr3Srqy<&6eBe7K>@F+V{o;%H0JzwwF7^SjWkXjV z&|W!-*p9nE}c{5!q4b0m4Ow3Ip)IpsK-n?{5X%+lzYt3NaLoq#t1 zJ6IONv&vz>D8P^Z6#zIUXT1Jb0Nna=j#ovcJ5KK`q&iELZ(En-lA1@A#Q0H=!1z;Y_Sr7Fafdbsi|^J14WPIuQNf0t{t8RD zW=K6uH<+;GIS6Xi_J?(YC34D^bf?9l$Z??mYEPDd!+ukC_9x2;Kf$6_WSH~^Ouy^t zIHfd^oMj*$-8@TK;U!wAL|<8EukGNcw`^V^*-p8JZv0@k&7G3|WP&jvGHBQyne%&% z=7czs@q2IAu!FF`g`hRsLBbz2Zj+=RqBc;S5jvJqZUm#OLMy$2A93+J9Mjp)ibw0Ua5@59L1=b1qHq zIYw#|p96q^iJce88!k|oYPdvZdc=lXJuP|;58=pWCB&h+hStqkK^Ri{z>1|wmgd-| z`%;Ce^T@f3<4R?vF>HR=Ge7JEM(hlU{B?rpY|dYC>f$iQ^wmS4P7#nj3{+22RH>6W zCCMG)&yy+}B6rAwNz1&}Na^w%1W19((rlt^E4xbGXBh|rk6T6I#7gW>S*}{7{_Iq} z0JmSEq)5ZZ#E0Bf6}825(AL@8zr-}q@$5!dN5AY4}xOww^y=0%B*yuls6LLio&aU4aM1G7vXuO&Me#(7j5 z77ljOUTf`fi|Ouv%6WmzEOhh#O;)9!)2l#1-Uv*=)7tNL$tYyTNJ0vj5$N679^zo- z52^3YFB*5Cv9cfgT8b^^&%bQwymH!vKw?1EA8#gG*4(;db?V{A{; zy9WW2njTJ~Ct7)P>w%`dd@T5nw&mnELa$p?gm(^1QpWblPH^#k7`Y6yxIAC@XK21P zuAX@M{j(nU5r6`C=C|q;uKAJv^~IAOmRnKcuVcxtua=n4=6aVft`Z*CLq|tfhB%7M>QDGdDw6Z*bxYZ}flkU;0;meGZ^9nRC_LP?& z#u$I$V9z|OjDTR{Tq7);ntfZD!~)>KN`C=R8WZ5l8CXnLRyuB3w%PmYnKJ&m|CfL@RioJb*2m6BKsppOS=`}N# z%#;2MCD7hP{7VHr|5mBpx-anXt$idB2TQn~e2fN(xjeyl40$lacFz#M zh_$8W{nU`+LD^rkxh5G;VnC86N{reK`L>Sup-q}m%wE}nU$=^eKmW6Z4{S|~=_&0= z1L(2urwRF5uAcSx6XP(48IK=O8q~1LtlO8r`6T&tCuj8^=v&S3|Jxa%<9+&=PeBEX z<9=e`eEMZ91&=h|O*pW6-|{XsQhY}Ks(x>j#Fme`p89IV=qtso0P^-HcEc%2#Jt1T zCMiC?V!Nm;DLG^z*bQn}?%~ep41{nX&4cR51jt}m*V?0slTH)yMwA}&b+7|QL$$g- z7J{z*ucM0n;~?hKxA%w`!rolLtg8zPQ*jT1qV^Z1n>XTnAPe*6fZ5kKMmklGj}^iH zI-8K8z7^UuP~{L2k#0{#njeW~)_IiK&9Q;6pnFG#93#CbU5pTtMHkmX>m}5vHVG&z z8w=Ni^$6r{ZUZQ8P`nL%vKtp!1?-)=_0nkzmK6-X=NABR{Nc9Hd7z8mC=OJ-J(LhS zNXSKT75VFE?{v0-?n=cQh2N)Aud8f!myR7{v()y0G5;P%#lUf1q#=j}*;7A12m7AX zeo5>Sr!m#W*+POu7^T-T`>OF}YYGLOnJOexic9XPpXKx%Uos0C5~x&fFQC)s&tBXn z34BDrOxe9&?3rZPSgPgBGo){$p{1qq!@0@Tq%sve`c_v+)Z35XnU2KO{1VOMI#Spv zgpDR;@)9XR;(zAQWDwbWVpLaQve4i#FxPfw8WJ$si`u(5@|+2ANk1YnXOa!s2^!>q z-Gf~V@~}^_SRKjUx4ddL)ZZyc5m?R|HU7Ag$^gsy+x$zGoqS6FsKWfbWPM*@&w{Fr-9D;I?`NrW%Rb($Cg%G0%`+Ud8v zyXCoKqKC;br?PG-zF$omBf~+24F#ELCCgK|l(Hm5gK44mmR+YG zM(}NUV44u`5&m>D3Iw49@(cglxvUYY3r@zwKs1dl02)&%`I>blOJt1fS_}EQseIlL zVD;L}*vR8al9M~y7N;$QI{YIB9>I)V3X1O$?lY+?y%KyW2ZjFm_1;&!Em7Rc+$zI# z|HQN)Xiv}!c*gt5QjN1$Cg$_PFNA0yV2>J%Z=0LOvEdf`jR+81{mC}u(O@`Yiz>Nc z>o;SfBOx{tu*+S*A`~I~`2! zPJy^F10fIxc3nTgY?3b%Z!6XLJBYhR#RnO=R=+$_9Q?ULF=#IM%|BhUeu?IDou*f^ zvTr9+w&sPC0PcVoDI8>5?WxlA%a?_4n7TEJDYM{B_1r_$>QDT`ct%g@9DI4Ef!19; zy(hhJ;CFRjr*)#?6!}?CvnZyNEU+^a4aPV895OSx-8`1qEpPgxF${(y0+VT@`N@Zp@cYi-tN`xnVt3q$f$ zUd>c`)?=XRZ|C~@CgEj5wciNUcQ2d$UA+e(9-7v6LuGMibO-mnZdb6HJXdke89h&f z#k`q%m&|dOUYClGG0{|i_pg-|JB3QXq~NpUFS@3k^%ghqU=t7WUvyd;j_2k16bI=*8N!d=BkD5{7OP=L@@HGpNVXwG zwf5kNFh&{6hxyqTot}eee8PV%zNx2q(Q`iuh*QBg+GAEkwcvkr60(u#WG{GZ3fG4m zG&?pn8FnwCJQkWEn99lS8`*F7TO%Of^VhNRM0%2PXBfHx8E71mp84ODFu=-_Vpo=K z&QuG{rqj*___aZxVT{fOVp+7Yd!p>9@%B?S!*Mq+xbJ=L@ec~A8ZV)`Cx-uDATxM; z*ZbcR**7k_dCE>!u#N!;)z#Z)|yuZQv?9iQgzQD#OYZWgIT#w#tenB&DjQvfxTdvl2M zh*AY8KuY0poO4lGI{^4+!CUz!iKzr=jVZmXbGIE$5y^w=lUuyMt%>Ew^XSzzj`r|pZIF*NX@>lugFd-8PWXEwD`?$xhE%IXW7y#Y;Ga+;`!sFRu8QM z*yfq^L?*s=ehXNZi2_u3>gV;E$W3wPr+kHJ*$w-A7cR0mr>vF61jG6G7KdOqhAs{^ z??S5HK#zei7`Hs{`l>8BG;uMYkJ6ffkUL3hkh-Lk6s~r0#U)w@Qbb0?H`UgE5(xX- zNzDtRclPd4T(;3;kQpBGR9gTn=B&mVGY46k7{i>Ie1!#sK!Gf^8z-(ZJd$$rsYj)X z_jO3T74d0MU}DPgJ?i#N7l$c9ZohtobzvlTFMWOO%v^W-a3@6x7^We*YpdEf2y340 zlR?E$i&qDMz%W^!)tkM(xj~TIFx1Z^$OR=9Xr}H+5!wpObVMgo?&$+ORNGi_2udP2 z=zJ9uH~8pB0R|j)U!P)nO-`=;7C5#tS1JU>!Pc0u2=4_5pSXOr&bKEa(gP4_Dg>oY zX>MC2)&&=+4T>qU4cnyS+0U$(zJj;M4NNjENeHkcVqYw1`=*pl+7{N@(=x*aLy+6i z0kPI0h{Fxmtc7|obXYJ_Lg@HNRq70m&Q^m57~}C?r~wlWj+UXXNUPk>NiA|aHV=bAYQ__#s(4ZNba`H zQVf;U83i-Op4VJ1aueo@Z|583kWCQb6W;uuqb6@RC?S8Ny!}Fl+pfp^gwTov7ece3 z2Xy%sK&J#I;Qyihg|JS)q|fbBrd{#-R!Cb+#;+!`SIVrqjve}fMKBDAFT=G##|DE} z=mQ{wt%5KZp014WVZd!e|pzFts$18l;S^xO+f z;_0zEn{fR{?ibnK$0=r7aH{^ESHbNXCF3Y8v@@z!Mhj?o|HYsSl?PPqHLKvrOx07j_?#{Od%Ro5sPn zR9+TXOtMf2esWg8*mS?yT^9Hu0Lq6#x`skl0yw^ zn6dpxfKVHqMKKS1`mPLFhPMHS@(xGVr&ZcnvGv;PA|3n=%@(;@Rv9oESa9hqdHpl=e zNVEOBfnBe9&bAKf3t@hVBB_N659w^cQ$PW5k6i2jaP^i!ZH8OdFiTH7aHvN-SH~S!{2-V%szDQZvF^oyYpBDQy@kTWen9`!3hk~je079<`Q zz^UfPz&O;Hqj3y@>r659h6W|DAQ6}OS7bkYPbNHKrf)-<=^|KK8CIUEXky20q8d4mTv#4`!Hpm9k^62=Y z1d?}0XSG={0onMYTAQ0F{GiGHU8#df4GF*b-$pPz=uF(FG0Qdi|E^qpoPGCEpTvca zWbu#8;30=uHVN?;smw^fx%QaBGHCa=u&(er;(L=Q(i6vhun=v!wkwLc14&rnQQ~5| zN#7#bnnQo@_lIa5Xf}J9+z0(^rS#QkUJ|B-#@QW#mEa_piU;Pl@P&M)AYEuzJ#u1- zU*>%vvQD>5AI>!2xZ&AX=-+#iS|3z5p7Akc^wDqWS!0XdK1HT;F0KcJ%?_n(zhcsk z7#I|2fG%xA{}3DKG?_^IZ%-xjEQ8iH-Ruu1bv2XN4b+#a5oSu(?p{)2__NNlAOf^y@GjRcqixB%)=m|E zXNRqGa~$Cae5=r4Vo(eg$A}%_JUk?dLaoa#m=6J;hOcG9kA{q)6gWBK!@7F zvXAF^D)!kZ%A{ey~C%=((>%lEUo3 z6(0yQc4WLrKeg1(J}BCOR(&{0yl60n1p}Kj!M7VtL!>ur`I#|dKKJ|~eL#ndv^x94%zDre%VC0MvFiw^qPzeoGEJVy_|=3D62@pSF)Pb4o9 z1saKvQ<->=@bQVHf+e`JTD)K><3p$2m&sZYMR_7?u6j=&lk>f*{RzViZFFKb@!^EG zSF~2gMG-Z|=sbi2nvs7}asIF3PZ_H~Li3TI5#N+G*WS?J$jo-Sy zGm00Mnh_|*MSW~qip)-FFkYejLgLt0+N+ro3^|xdQs-R%8*ewBx3DLM7aem{*JR=5 zM1_sAP;W-7xsA|pQ9!UjZ{x=yl-wFxLV6u(UM=*@&7#MY`lWxE@%FaeQcEG3%KId_ zy%AB_jSiU$1Iy;`rEJ&l*ED(`d^*g2$fh^*&$U~6cn@xZBDp|7^L>+645!GGeN^iN zty4~TbHFRCMfhO~2>nUUq}Z6OF@Mk`+Ifb@z+5UxNxyfr@eaVg=!V7E!KUHPSFfqO z6KF5jj83M&By#j<)>C<4)xQ%r`jU9J69!hJweEN-UE5n8t&v$kcEv4PBey}hM*^;x>qtEKLysIoylnIP8N?ob@9w{J!&!p=xE@#gpAWAKEwIV_Srr; ztPc!QA1w^d+xhsD>VB#ghJ@qyXQcl!ImJoMQGZ*gG=<86?J%1~BkgnkzO^Iuuw4qS zPX5?1HK-|yya_fqy*6h+zm1s_>LtbtO*XpTYyYOW=C5sIvSp}D(g|>HZ}nVMF$#z8 zHeWCpr&ndDd;`eF8sDQ`b0y9)Vox!?(=*2z$FRWoIyZhM!8KFzj%YGoD_3a?Qes(FY$MfvsPrRjT9V7hLlhoO^iFgC& zTMp>2=@F$C7So<)nb^{T>5wzfEPlDEgGKbwu6>4(no$I3K3PPqwQm(jzRcC;T5n*C$&y0LTkK;UYuLYgor?`pv^(#@%A34yVoXr#fnP zf?7SR6(;uDRs=S0#||;t$B@I9#+egJJfiPd2lZcx>VbjXqH9 zmFsHT`Tr!>U;O>ol*1s2FuSwL`JK$n4ZC)2?i_rC7|wtUch_TA#fE~>kBIs5>;6KV z9YYv~od>z3H7WELhn5y|jDKRAi4I~_FYPi?3Y>L{7n^J!f5m#5;r9t6Bsj?V8td=2 zPhb$z%R@b?I#-rPLP9Nn=WWY8!OI2L)tdcChzz?LJ=H1E%%7~Ldy5ox6`|HuGC`?X zdmP8yk0g;S=1GvHd|UqefdLT*BOw9JT&u2cj%3^neeM&)LRJPiPuc~d9V`5aV<1|8 zBf93(#M(D1l$;D^6%~(V1gVd*msuE{E~(HB3cEXVkc#+o+^D%#?etZKWzt*vW21Dc z9*$7)5p)-TGVFD4{W7(?{OHKB16+sWY%KOnH|kveYyQ)ESiNe?H+-$ZS-+WKmDu^J>VN-c7mTzDd1SzMrG^7Yze= z1=B$TfS%qrsKu^KPL$K)Uw;IBhwqS^)w9m5eD~XfAszepG_YLqR@u_dfH-mCK-ZM? zkH0ys9ks?4V0owON9xzV?s<%P<9}K3ZwuStAm6)SncnE&Aw7n=LGrUw9Ri&%Va8=? ziPvfTwZmaW@0G`x{69&tIp%GW&=xE+A{L~?Xw%-o87Y{b~ct8%TvsP38RvI41 zw&~;Rp?)V>ZK4luchSua=Ldi7o=i{=^S$`oPpZ``)JMI&*2Rb-OPqo@3P8ND?NmSZ zi(JAgVGjjN>B}iCQ@Zm0E{w;^OW-)JfU4Z{RzbeMMpksu^&j221Dr#|39@iD<5c!9 zR46ykQc#dV1$=*DMlYJ0xbog~*`i%SqgrUJkx3lb$>i7a4+6aC?!6zmxWr=MNh6Pf zmW;D|jRH^wNLLE#j11^#!FQK&OJ^lgdHJw0_Ua9+N_)I60qfD)_HPguPl=PapcV)J z&Ncd`2+J^4@fC}^^F?V_EMrd*NEkvhzTd_)d;i-g;X@a;1VV9ZYd^t=0=l^^iCnA9 z_}@1$z3c#zKRh3b;=t9Pgx*>OA&V;yhsN6ak}Sdc?C>=+Mf>&;_vNon4RpM-53V0W zyF+hIt6@Pa%3W(}@S#vaqXy6cx)2hG@s&^&OA-qLOZpZ6*LGCKh`zO#WDB_;k=oE; zBHT-VTD<5ObU%X*d}qiSUgA~Nv?5q?4TqVWrKN!5$$q7qszn2-HmB>WZDS3Us(vgX z%-Mko<%Cx0OWT{V=6TZ(_Cp20y%2V>Pc{AEG9_*##Qb%XByAW6QdiPuPA45j)LTpw zvr4aD6hyT#my%3JHSr&K9(M}nqytF+pZMmu1h)3stBv*Xpxa;h?FL2%zV<`KvIWJz zI-7QyKs;mCUxGW6B;NrZyO0eTY)<}Yg|xCSjQ}%`l1w6AGYUXpfWnSjL!yMHj}NL1 zVIHt@SVolRuD^sOcsd?=>$0jPaDY~Qf9k-FK|8ef;uRBEr3ooNtFPcxZ0{C!4?#6M zR?C^RMgNXtW-J?$SE2Fm;Ai-um^!w!zCN#6_RBk?ehWI~M;RRNqOy{)(8b3_C7QYF zr&o2S27tVz5Rtc|Dcuxlzp}C=G5lTDf{t`X5QoHft_51fw8$hsj4vD2b%Zxci`zZ# z-lQ2$PQYp1?|R(pDhFIb9Kb3hOJq3)J9;l%ZrZ6v1UCd)Px&eq^aRE8=&{}BKydf8 z9tS=eK?l(qC@%U(66xG>#cWMwd|;xq51965mO43 zw|xfskms9w$vY*)*5-FmM9cdTkIGlp4PW*#cgsRls>JH;1?0vY*UGZ2%HOwm7L(wvVxZ#!yZw0_M(b9u3qQi|%)OTudjD#u;gr8__Us|s(kPQf!0(nL&S(W&37E`aq684igdT4hG)WX$9XA~u9Q{=vJ zl_dI8*mpQH1^Hx1OXMV=yVCf#zNoqK~fAcmIdzbG(_b24(4t2-UNC`FMd6zn7#9|b~Y zH}nO*fcf(%DJaHOgkCSQ4W9kQa}#pL=mN&md$ROzxI za>E6k-Ya@I*N8jcMS_xXW%T`7p>Mmk*R1d}+YAcU#Xj2s53P(A~Ih`BxpVu!4l%u16v_1)eO%FDwzOHBv45lK`PT8DdU)=F% z3CvF!h3`Yyg)tm473Miv%JDW3Q#>&OX%vKj5vEmgC_d7qa&mKmL6;hW8mu=Ub<{aI z<`uW_IEs!59}C}5?ySYC|A_Bgda~$Q%2CrHgKaa1M#*Tz#Zl4@z5Fm98Ul2QGWNNs zb86XRFws-S{sQ-v?q@4k&mrd@?(TA$)yZGl*}uoRCKaS~`5)`|6UqOzfX zS)89d4PP_qS@b4ujDRPdPo)JQ)`Eq<3EV7Cx}UmY-S$sZ44y|4@h(4EpJ}4P>R*cI z_$fy0pLNv^x;;U*2?E%%LTmAkTck}D)U{*Zq+5e0Mc+UoGVU#HJxgylwiNsWXqh7Z zRKK*8GFmtW(0oIJ~3>HV;`Nxh1WZkt}=zEcpeWl3VYG|5KOb!MmkT z`C76=+n61LTAfN#t9U#O#j-5+T0SspSu*qICB&_<{EGm)WU1k+Qq^+s_g3>w*<8>b zTW|9~Eq3eDukh^2z{>Tk-Z-*WHx^H55)lv=#&zJt8;Ht3-2?G%w`krKuJ7wJ&8hWu zW4lisH#pdAD$Jwxp`$!~2bt31x$$bTBAV4|dh;_8*i9Xp(TZ)=Ns_i9!s^2>s@Rie z=_~cVdz5Wwc{3YlvqtXQr7DY^5Ccyrzqn#R0)i%d>yiDhn{pZzp#hkzht|<(1RqSx z`kG7X*}lZJR`!8{<&vvQS*!?EiEyvhe0d0sRU-bVsLhaYtx}^w9FGzAy^vuu6cj}2 z3S0FtSr0DL9Q9>eF8uhvFWJIk6*WU-r8n#ZFCo`Cw!-4f5Tu5_LxF_=in6D|r?7?nzC2GMTauf$cF%()oqV!0cyEA}-9^L5( zzPQu|)WAc+Hr(Qv18f!|YW6uagl9wk33i4Qe`J7Y-sY8JgdowuXN>-4l()#%5s7^$ zrz|X<0&xCZq>%hz=%MssRe9%b_MbfL3Df2a^0EzKuKq4b{`*TT_}0 zS!a>by=*ioZUV*3XnL2Pb`er=_r+dr2zfz+>#GNr163$r}GsAzI#npOhN6AzXx=9hMHsR!qT3?8z6QS>( zi2V772yS{__ZCJFibilub+aYow#wQ;Jc;(c#>r}WHhg)KPCwT$ST^-D@2f#a?4-tw zqCjuMX37w`yY&t9ve=2~f|>3SuP#c`uj z#QACftMofC;>VS65JW$!P7jg?v5&H0GSU-aD$$u;OH=fhLJa0?aA$EiPjhpBh9C)Kp=;#^(Z1FK&JcRYY3Rxtr&qFZU3Qks=f2? zp*rm{z?(4MmzjkqUpgfwOIqUg(RSzQ2ev!T+g8Hd>gp}1bk2Xq{+5xw1ql1a`V!$D z+4`EvS(+wz>UHC_Td{3Kof!VM1}Q--X50s=^2r%|iSksf%`R_r_w)_LOHijUY-){< zXWDP2%a##AESE_jZ>u1TQMK7=P&KyGUi-t{IQVPM5goYW72JJp!#uS9QXz+qRhy^?>PwCRBe$fxLrC3Ssh4 z@M59qT__kvLRkQEeY-MmGs675i_uT4UY3Ra5{vxC43BB;1nVY`d4?+U?Iporfp_>~ z%9c;&8`S+<4x^L}0;r=gc~#bq|8PaYlBkKpN&(3K`46mYqR!O3VRRF-dugnDMcInt zx{I`{uRJ1U0&jOzrMKgzjdn{?oU>K)3 z2Zi7AeqC1GrR@I{yZ&)C#lG2KN}S4iwm2&dmHmD<(Gb;y%(TC!XD2{_{?;k-x6NHo z#@M9K<%1DEvcg~f(znyyhv*`K*>Nc0Um0Cn@iq*sy4)T|uzfuovAU1U@DnRU!=^1h z!06ZWZ_yw|%8Ez{1dDdDsD7aFRB*@4iS3qA?c`1ivs?lJNHN7iuzT~`ML)lw+{AFd zeUVv>dyp@?_XzI&ogO^Exd@Aqmz>`B4o@O}l=^iN4@$pc3!3nEzti68ChmucH z`-?3@T?fTLtMOThX(rw<6#U5s$Wya}^iYFE@FQzF8Q=*QoPfCFJ#MgjW8c4&&f3he z$@kugZcjAD9LqK1;cpSIw>?hzDnt6KO z=rR?x=iQY0&xfn42j5FCNxy7$(nnSr>Q;9D1|F{hsGTzn=teY24(!hQtP+`nZ6wfs zj&E2EGDzB@@YgZv(-|$~2EUCih6|dNN(+bk*~Uo?Mg$pm}AW2@f7ZLYRZ?sxNzbB#%Rs;p>K`R0&nPmP)t z6U-r>QXQW-Rz2ba%YTzXAsJYcx>mESl~ zA@%!R$Au~tqH(Y7(+<@pY#QK=81N{{2eTtXzzsW3uKkh#!9t8Uu3?Q@)8=205r4s! zhTdZlMW08A*%BABfn4QS5CTX>zPr}mHl zD*4`8C%6P7JgW(-I2vUsA%`^eXMIjn2URlRqSbpQ)#Kw*Cr3!f_~zMe7aHOB+Y0iN zZ7}5HvPW8fBUyb%>WE}aCpTf0FAfUl>(hnd=$VV+BxOMg82{cry>~~8I&T^w`}ttk zVs$-A%zm)y{06p?%A}uOg-o-Vnk_iXwhA&qq4P4Z$?+J4{)}F6Nl|6B`)Y-gIoc*M zx$F^iPx&7S@HX~eC22uSoFr_14AEemwU2U)U@2TdouxbpgwSH zE*TN%8dn)ZHyD0FZ-)bGjFqkKHra(MsC#SF2opc zDq{~%s`K=f9XDje`BwcGK@jjwqX8Q-ztot5PLC;n6j45&4BtXz6DU@~cGIL-4Aq}{ z3hlU5vJxJ`psS!I1zOOS^&3xpg6k@rryh(DkDhf91~sas(_Z`AeiUo@XX3DNOX@2x zyVE{`tRafDBqY<@ZdMxYBG;)a1o(GBeyyaN)p5MF$$1ZF8oA3-A}LdXEs z&`&l6^pXAatd6(CPgpu9J)$f`1R+akl9ObtrOicf!Q;aANhTx57baIO7QLFtgrv@{ z9vg7*Lp|#ak-t0D$z(8Cz~xs5Mk@z3Q=iQH+M&}=#olac2)VDP_B-N&mQ9?sD3Q@R zpH+VPmA`i&O*vOxs9>hjxz=+g%}rMy3;yalUcTEGxbY>34LZ7>&-UmR)SITp<&b3W z{)UZMk&O!XQJ|;~b>dWWd_DSXINFK-%jEsOG*o1Odx#P$@MJ2x^+flXw7H@u8I~il z#&@%2XK!P2r2yiO19Y(cBaI4@s*2*8Nm7{?_y@mg5Iao^>Z2?sCjNKAKB9cnn%kO1 zNMF{Az_T-a4Tj@mgI;$DB)OyM20xG}!w6)%LmZ@C^Eci?x<=I)9A_EECCAkoaqqcJ z3b7Pa4!V=D{?;<&IrCV;Sdz{~H*AH;3CYaep7SzHKL>Paznm6;hGW$$u4BgsxgPzY zhq~k}=!Hk+BM-_?aibTkHhF{*~ zvAqDaFCzvIZHh8|;UT==I*cv&_BWtHTLC2R7T_8RK>{soR@;4n8R}0{S?iZP11qwu z+XsW-7Ai9%jWN5+{6}OMCzCZxwD)ZipTr-s@~?wAtVa_&ETrFe*#q?!%+2H$tO0fk z2PFX{-;tBb_5IrtolJDc`fTbmXmi>AJ%HJvNiKDsw(0F+m}>dSNny-(KW--owLrm~ z;qgpR`NXAwz%#j*1&M+tX{f3#rlBI)4=PQ?NbMqk3Khn`-Osy`>mM-@&1WWlo~jgY z{KcOBmGlN`7Y1g|L!WaC5_m}ryUxx99IjC`d_R~;B(C1ku3S5iodtz~rb;JV)k_%i zWgMInf0YkO-aP*$>_{f}I73f|6zprJ-ji0Kc0sX{gKC(*Lmb78cmL8RJm1#uJFZLSz@|)U(1w0)C~U zn<Vj1r_7 zgv=YXqeVDE_^3$Yjn^7KFvAo1A^c^ZTp8bVb<;uZkBe?a{UGz7 zEBjHKMru@80!l;lbeE`ojtQQupjOXr?uDw#PPjtQ@?__-YPAGf=lyCZc>23SN8;uu zzJJk$Uz?1(t?0_;NIQl@=kGtkZxTgqME;9v;Z3Oxpwg)5ZP%D~j^}s@BT_LYD+a~{ z2IAs=X6Ij1HQ>p`&FU4?$w4hD3@1iWk)i%vyAG3Ck@bbh9BxYpm=L(q{+LyOdSR;J zQmSuiX$b@1%~ps7UiA*0`(uVn3HqNia%pILJu)J0NoPmhkW6gKG)*(Q8R9t0HJG6}7azuC z=*xKP60s+W_z}K9i&FU;Lud7xL@#IHy5&Tc>kaz{!nhE)mSra!ihXl}%0n2@i9k9egiQM$8MH)&y0*FmJaaw!op=2S7q2NGTFyec= z=S$osoqTAr!O%T*1&=BFMFIXTx%+KNc8}dFZ2tv|Wnr5vz0#GN-J%mz0MC3+q82IU zmhk!P@EX|9fQk{hp&g4)Ymowc+&{iJO>fQhr{i%VdFI<)YWuSvs%6@inEWxjAFliJ z=1Wz#cSEwDf3|)1s1ssrXCd8d_)EdEoZJ2MyqSeXZz`Sxe8nscUFZP(U2LTfcI;n( zd#e_R{}i2{Z~us|lfk+Ct7M*a*=n~Eyg?V!{|~Gf9MWr-qGb){3wa~=Hsa~&7oh)z zn`ObbR>tl$M!WwL1~(jivL%&C9*7A_Pwn0~SlEAvOjj{9b}h1fe?k@%`!~WF7SN>> zj2>cS4o=?bV~F|lN>Bh|=Ob13?bnQ}p-Yb#kgMfZr9~96R}jMQ7-0%^+u#bBknD8s z-i>AT4W3nPcqx~L()&bIEaul)j6A&3u8LSw#lFCs8DgDq>|8yT`i)nm=EUG**a4Bw z)_lZ>VPsYe-yn^3BqhB4=oFQWwr%P7UlSuW%l|&ZO^rw}4G`aP`#jfN`vb(l>9!-l zjNT7P+d}LQYv?qk;CRS1smh^6;sU+<|Cj1OG!PSM&F!9U_4@QH486G^d4{ zW0+j5XPD1ij10@nK!}LWJ@q76=wx3^-i9(gPNr#<`)zLDh$zYr2|R#mbQne2Hhb)M zZlde2Vb{M-b$y$20+g+9Ld6uYiQ1Z7zTL(^#0jekh;bb`6>t~dZ>AAwl-y_rNq+Ak z1OW7`)o~`^`%kMac(>&i)iG>zRc4B(t)ePSP{>4x2a#ZxHfC>uMPPFsfH_$X3hZyy zV1^En{2GW&lwGq>#x`AVFmO%^&70du#n{i6RhL~xv4okO0F?&aHxGiE51+Pv80pM= zKaKglsVcQUbp~+idaV0Vl*3vpZ~DD%6}aq1=>)z&LX6quZ>K0R2EXNCj^0KCg#HB` zSmkk`RDD}wUO4aI?M~aAgU(niU0vmcrw3@Yj4QcO_r4G#+r<0C32 zdbfVVHE{BO@A-io{6F4vUjH_b1(tIRR~0P9ES=q7@AE@>*Y!}N_URYlupKZtZT42d^2c?7 za?yH3v-5m(J;@ds$;d-w_f0;uZo@ZZKcc-EqOL?-Tzc9^ihmAaXB~j3=J~>?e~Er&E`DWvWw#R{K!-aj$%A|IHrs* zRxEcZ(__5ox3UZw+>_Wy^qNq<@E~_%c%E`{O@Zz5i>WVR;86$P{Oi>voG0l2K6Zpr zNvfugpEbE|=+8r{AZQtc+4uVZr*7U?wJ0F+FfYyE{6!jg;_Wbg2DHO8)$`IXs#9-8 za$qbt^;E1~4dZHCIJ3T){II|+EgL*UENv4C}9P&IHVL~J}hhYB{qK%t(bGPR#1w03+CjcfG z)f&Wt{|CF{w=*(KLx*e3Q+V^a=cEhOZ*`>p{m-0KITXlGHynanzq8lZP`}CBG2u@J zMM#91eF%{)dW2}9x^)h}@<^%YZp%-hN(EX*-={0}`x;E!A%DDXZ-#g&?bT3xsSKnh zp}hj=5F_{sh%xK}& z#cSooD^X!9h##E)ju~3;AQ@8REac^!d|#ty5u`}-8n$1n|JMc=<_>K6T#Xw)G!=B5 z3x}AUHNfpPmnD~>tFiWf%KE3y6*xl-B8Q%E(z2J2P4vdYu7=8s|NX(sTK%Cu`wQD` zLq8ZCAc086#&Ub4fa9akW~rK|HGQOB05UU=U_*l+6%-UpA>>#4mUj!V z)Misa>kBeNQ)ydC6ZsJ`1Gd*kbVyfyvb&aj5Si2N=Q)wwzc(E}c&TC|oI+XkVuH?X zZ)PV$!ONb_ERNP*zaHiPepw-6@v4tJeUJe?`SzpkJ9HBMEN~0 zSR=T8(cg;&;=8IljXf&?Ir5HWL(n4cQ0K4g6ot+s$u<7T-f?uv0y$cig5YpSOCMBQ zg9zJ}sAE~vZ`WMd5=d8AJaN-s3bF=Poyz?qhW$FIQm5h5B@CUCKVV{+jd2T3rOF|9 zMu${W8k5BTd3UxAjG)|xGXUFaC(z(mq6RJIUNk)j)}>v?lhs!Xt(GuwB3CwdI{eKy zYZF8TP@Vg3)=#-k1v+QV%$mG2l7dF<4@JqqKga7&>;s7av7{V}>doj975*vJcL@l& zJxG96LAb61*&@6+`-!a0wh|~=+oXPF1*|H0A%$OU;?(0AuXP_*Ec}bD#8ciM372rL zY{mDnHWv=UvUACIv{izMdjinUw;w~m0?S(xGffLW#TU!33QZS)qcm>dBt^!4WuA#V zSa#V5$kd}BGHg3k$2Alj6y%bq21VvfVkNp6VtkWJ01(|;R7LXaIauyqvNn>tNsEDW+l%8fnyv##FFg?seBX@*X`OX{L#dl}Ni^){JjP;kgSO;RV z=+&y~DN$ueEz9ysroCgSamzy6{)DDAVEu906TA1_YRl3ecFh6E zy3*0E;9_3bXCg&J9blTK7p~vQNilbG&N0LyZ+|}1LznJ&B7n2Jb62yafE*N`pXi0D zlS##{ca0Yc!4e>6&u&rxd#1;$3=s;|A-41PGaMB~d0;L9sI-VkvMg@6kgOA0%yG6M;L4!wo*f@9qyF~D*D)zs3jq2Mh! zBuG5m;5qHRO9nh)MuZg!_MU?rcJYN|9=@cf4W1)1W7x^@?vTM_A{K40qwVAS_w_`XNCACI@$ zxW)v;os@vp^b`<0Y1(&V&g$7%3VJUp5!_*(kzZS;MGdacu@uZ9&cjTUqKrN6rTkMG z=ifL2LA!}F0vM?ngeE$=Kg{;;WUF*ZGAJozMfMD#d}-w+HpOYeNH4Kb|6&+*umHB(! z#lzQ{)J-t`%}~BPL3ZluPoUTehu6M=eQl;dqr(Gs;(!eMhnF*AK^hKmX+?5RKcHyGAW1e{mKflW(Kp`J82ee!cM& z%o2od-e#Q})R!d7Cy9$8U^A*18&k7;w;&Hei89EG>Dk=9dB@Yf6DdLXBj=c$NmYrf z&cXX5sl}~-nLiVwPW&OYHi@=Py<8}w*vJTX25{ZUUgMlE`>Cs!CVKrLb_m(+EmF3w zuh^m7`IgLO3+mcP76OCOg6Pzf-}0$wZS$&Z`@K*O`Ts2(=ZM~^7arH6s9Oi;BP51z5X8;%pVfeAK>HR);DxR z)T@lb)AI8aNjwL>z>}O{aM0sc0f;0k6r9h=oW9}$Cg=iZ4ik@8)AlS{#&`6SxX^4q zo}6|KtWSwcBd_$*i@rQk$c_Af6l`EpN_^6IZBCAq$c+|n5M7dV?p&?x7Of(LD?>=U zosnRXq3d7b3P8y2V>{Y{L|DSpwianmXL=7e8V{RJ1)$y7XD&n-_$cCY^=&s$^kt%8 zDG>=G{)7+Y_>=tU40YG#Spmq=KV2Mg?~Ge^p5AuRb?f%~>C0!oF2$biil%XPk^p8F zLHyhC5)R{PY^{<9o z>ne;+S}|gwn}?D1B23ulYLxFMt3-|;1U@-HuFB8#IR0vqhmSbEVPZ=3N?oI>_*Tv`h7=}$v8`|V+D7zji@PGle1*C6a z+9|R~A?}{Q7e&qBK`HUxDkKzy1YKZ0*_%RlKIt}5#gA1XcV@}Gix}U5h08@M8Gb`q zT^x*xsK^tGrC#>$e0~pyYr!4$hQDS@E3XFyb=0Ws8xs9tCrf0o%5Ss8A;! z&NX7IvUiO8!`%cdf}_Qv6&eJI8QT>a&d#aNgrTY#B#nwHq)PW6;lt}?cmH=d zKEw?i(7cY1Ft4&qz_q3m^L2t@gh?( z^RoWy>{HaorWyQYGr`48V6Ge(|#;p3Cn=r->pRSBcAnm@zR&^tOM>#2Ea z(e$vQkSVH1c&Ome6V*`XIB&7;F?imGfJHA09Q3RYzq_~!9iQNH(AjTpguf2^R%Ov* zXMQo2oiq+ETzw8V6zH_1#}Mj)SLtLpojvx5w3TOwAH)oF_^LD|P1hfmMvgfe^&p%g zq3g&+eqkh*kTK3&N|YzRwV4>P@`31bb!c)&VHn#V3nm6(FP=X}Pd<_&-Z7@bDKzu9 z_hD-0B_7utw&L9y!9Lcha%_`uED*j?(#E6{XDpH~zwLqlb5z)4GbeZh1jknw4*&9Y z@SVaQ`xlMRGR&C8i{#-H)DH5bMZcA0C>zr9^2LX5Dq-p9RemdM!F0*5* z$@6%kl>RRedl&Jj;3PV=u89_lfU0Y#+pB$TXtWVH<)1IGN>Mw8D9V*8BpUwen3Mmt zOj3^yiMKZ*94!UeZG9UT{5lz(n&~S%g6ws2hXCs*OTF0K{t`!-k%1qLPEfGqOgy$o z{b}#D!K2Nfg8nn||H+v6Ke6n0tX`-vB4og$Rc*byh_a-6EQ@U9q>#g_$XZs1Ca`Ll z03BayV5D&g}!eGN`qt42N2Ds)!}GrPm5L@YBX%E;|}TvtWx4FeTM61`{^YGkYN)r z`a<-NNvwMCaqi?3mQZ^jGrVnTQw*)lPhZV%oIJCYEi|&b6&fFDQipWi!2=eR2ZSXl z=1kuM1C4}VI~OWC^JsM(nEH(7H-yUasu{}g&B;Fy4h(upQs}lM9>XyDI74}xNj{#v ze9q%Sg~?pOr#b6r5*?x}&A$)5+L5u$0{3UQrR9^ppSSk~M8H;^VSjTL>@$@19m#P+O9gjB<$PSK)7zp77l z!k%R{zkkx9DfHS#p*~Xo-se~bTHe04Gco+wp+jhq2(Ql?WlP@N+q$u$`S6QDYebR(1Ad+aLh2FGUA&vNT`Z7PxW2i?>BMeJGf3 zF&I2wOX%;3$s#BM--41Z=!V{*--LmMo24|(W`YE%?p%LQ`J@W(Xw-`5+4T(T8pDdD z!z-6lRSpGB27nOktB63VVqsbo>l6*G)vkf#DoL>E;$O~KlyGX?189Vq8#Km&E zLSPX6+gm}Gk~(6sZG~U-kJRZ#&;VZ8C;V%5I>95YQ^t}U1=60(_-*MNDebj?2Q$Hs za3IKelq>Ot(OsM*^0*sY9FKw|+$cCTT)fXD>C$D{f!D$hNg_7q{vvwp;0(u3g_t>f zJ3QE*6`m5S{%-9{g5^gCa|x(0`FL4>g@Tg^p}YUG3@wydo|4UMu7%|2-xI^>bq_p! zncS~S|M|=c{pI67FJ72kO%y#1iGpl*>GG25Zc`H$lFXPZ2=gr2+eHr~ak8HV@YWKX8uGPgd7mHhMt&V~ z<0Yez-cxbA#q#PqKfgy4WwO=uAtS(Ca$u{MP@H=SJ41lTe|UvTHE-&#S^~o1SEWDu zXZ%DTsWdc`vI%5c5kSB~#9nsoYypXX@K5MOXkfNK>SJK3HV6w|fCO z6e2F)yoB;1w6|mGaJc>Tqb-RV0@6RL6@Vs^mwPH&lEZFe<5RUercdmS+Pcz)#}=}! z<_`o{KuOw|KSS)eGW>*s!R7eHrO5usJU(ZDiI2a5&`2x_5zBo(5Xh+RU9{K}xakvL}d);3c$soe~Z| ztu{q~Rag>rVyaTRT*re_PiycE2z)!WrZPq{+n{T7lqs_s5}uqET~!zpn( z<+*y2|IsiX!{hRaaxrJz1rC8lQ*k7jSZ=??=j^B=VQ=6FxdG6(+He5uy*h$Fc78p> zlmWUOt8hWb@$a93$puRh4%ZKEDp_FW1Ka;c)>%cx87v={Jo46q(Y>l_)|_8WRp(9Yu8zR(Jabj$Wv=jb z!k-hW*LYoM$B!b2L+LKAeXZVIsTS%ROLq|B<80wZtM#2X7aG!WtFk!ue(E#yQj3Y( zZz*-47Xm>ly)Qsqmuq3;*X-m%q4zbr?OQbUO>*Q@P>9*tTscvNe)1(UIV(u{<{D^I z^YID%v~sS1F<`3d3=0IIFaQn>o#lVzTkPsXb~GN4^yS#G-1rN_6!t`gGD8D`?DLB^ zy~p>1jG@#67ki6}sF7n|)LnwX$oX3m*aRmFJ8n^4u!RR_(uq1fA); zXvru{THMa%sYeI@)1J-wibRkd0+3LQ=>qS*oheq4~DXeOtHB|LjG2D z^LC3nBIo@@{d5r(REicWThk7FM8sV)a|UkgbYZnjysyBm5;X5$+GYAAe8w<|TfJBW zFL8}CSuElLqXgtG=D)H*;mx>@pq8rl z9ij>JrRNANi%y?J47{UXj&ZYc9Htj_)C-w~mqx9pC8t;L@=lX58JtQ6q%qY+EBh22 zn*HwdN$7u&;5xtuYPW{~FybquhrcO%A_puudY2x+aOnK63hE34wNokj2BHY|1Lh8~ zhJhIt!_*^VL3xV`5-ME;G%?zennloG{hWi6USpLhTc_)jbJ$o}#jPfyq{96Rj~abn zuO+vn>!_VGgiF4~pR0VL%F%@h$5<&L%iox`%V9TrF$k)?oAc)(2L5;%2BX!pFm-Jt;U9X>FmB2pwkW1E1k8gzy%3&ORV#d2^!r@IuTAZ6%=M3*l%9(~ zxIw&u+NgO?l)hPq(-qCDpKflh!emK_`8MX47XLng znkJ}z&}_Cr*e{+fF+j9vS4ZZ{2||YA!%N_8+fcDVpw9=(-bFGU zrWf4L>~^9j6Wf}2e+2mcE-B=V!6bZwvA^`^WYMLB4U#2HRf)RTIAD*@y!T_^-sx<% z%zAva?(TLU7?b%;?t#l7UJcmC9QD{DIUzfXN6X9F zrrII}1O$GwZ57Q%HgABeASv+t=rt&ARD+coSoaru129DSyju`a*C>W!5{+9jQGNS} z;CO-Xr*!5o0Cn4|$0aiIH`Ra=smhKs5u%$n1g3}WLWmpn zmkObsMxg%G(m8#`)H-{)M4jFwnt!W~FJ5=`fI$jb# z=f-0w9(iDhJd0n>{xm+&8Ma#BMun6_`m6|owC(<`y!5Sm_H9M87cevt`fy2V7Dc|p z*FYHX($@ooEsTSjO@PDTCi%G#5Jb0f@TZhj;wP)fE3Mu3TXsoEwpqBAJ^>phf^vzo zw?MxUY&BZ_3)wAgPjq`AOJFzmhbwzgODGLXrc10e-Eg2N3sDev4oi;Ng$xluG1iw* zew#*u=97|~sTAt}80?g;-^iN0l??vja88cJ@$<6YY-v{gb%gJNy#I;;-j;-xu2N8#78G>tc?-73#z46lC_`5v-B#Xk8+Y$>2!S1wy|0 zW-AR9TRzr(Pzf)LGc32sz6W=2Kvj~saS1v82NJZ`SH*1b$cxH|$9hM!QO6UzFxnZ7gsZ zqAXf*a#LNXKkKe5;%A#MAq9`fKkp6n{aLcwdWFoP3^qb!-&n3RIO|)H(1L~I>keEq zO@YE+|8e-4y%7bARl6~c47%?Q*wE7oW>oE((6J0eB*w} zB7?eLc^tT=+h?BScM+%SZ{`Uu(SiE7QZpQ{xCV+z@sNS=a?9}1dP0MOmi;dF0mP;9 zW-KZ)L{zw6Z(+AbQai{z(6Yf3yut6YKNmbYznFfe<;qyjD?HyPhe5ya9%-A;_$Pa@ z*!U4yL$B?4MAc?R86xh}9bDvU&4skkt* z9xsy`@y$ad1KEx39BoP1!7o<*t#C8?2Rwq#h_QNK(}$1h4nf*qy^Cq7XoLH^^l58I zJyTv}KcUVbr66q1I!WA5?P@;V{jitF+V7ohDW_yy^UR5$ei&${VZ(}Za&I%3Mip@sNm91z{p!bSG`cF?f+s{N_! zo%WYfLe}(Rf5OQ>@g0~z~c`%{H53}J0t%JH07=?1KEf9DJ|FkS+)p>vG8L}#KU%a`$mLy}scZ0XO5RzXcndt$$1I>L??V;cK4Gn#*8b+VG`y z_3u4PvOLq`m58v`i9m)uqZAc+L0*sj=bb6oSjs+K=M}e(HLvuYT^@>%9OUb{nS_X; zL4SWC^2Tj>GA_Hw`gIrkKoIVy!m39=CviPlhMXIex=()OjfN{N(GAP;XG8( z&VcTBweiF=Fja_BW|hZV?;RU8+CthdqQJ)F1aXs(FAbT#TcO}{Kt=!DN6dvIv?i8~ z#*3o;&;LUL#vwvJqs;u0%NuRvjGYmh1vC#pKfvNtr_{!UP5$&(RlrnI!d zT|*|I`%N1}knxSnM;kWQ6 zW56ZRU$lNo$86ka2kaHWX=~_7@Xbc1UVyjbbA4o#^$^zkhLzkl~ftu*ssweisR;C~65fYkm#6P<07`MXG zMc(h@$xnt7A0mXK$sL%zV$g2g%~gmZ@s#8C`ogk{w4y!?sN78we zX_59?V!U1lbASU&N|%;Sm3sQ8Gh;W7$mU|@{`p% z2p=P52=nb+wK9aN8tKeU>@Y8j?S>HqK|T0Ru&zCZAp`-=VaBVDQ0SLt83SQMN**X( z%!spfEVQ+Om55v|tFjukOrKqtGSw6}B4NZpH0flFPv)QL0-+q@ug|f+wy1F=!L&hl ze^4KPf*@zVXG$+$VOSgDW9lU#K%huxzW6H8^r>Hj7fRQ~uEk-z^~3{RmDV0}^EmFa)6T#9nEubzV2Ep%RG;eE#Fqi_hm#3jiN zggkhVoJ1VJ9VI5|fw&ofp>{;SAoY%FFzo6(!Ux&qsVn6hJ%fTB*dV|=ZhvPmbdgIq z$P80hk5F^!k-!J+RB!!(*#kx6k400oP^bl^adSowh4IoD!Y`kpsI2OxF0Si~QXHWf zjnsZzRd&vhOx~ZS0ZFuT;wXsE`sd?n77xJD{AD#zT>aDuayg>=(7U$( z0^Ut5)R#4AF!5wk#<3NL2;=7z#44-z=wMvagCM2AhTwORE zy;ddJAD~sejP@HJ$>K~6bbTAdPkud(U9&_MD-eKg^o)iX?|{U6MDeG}$D3;~>o7zg zqQ5L**ULqHgtmf#OY+0Ce2pGUO%iefta0~Q9}!)@s>wI+D(!d{K94*M&1K9VJ8%dl z-UDD;yXQR?lF z7EMEfXE6W0F>a8zhrKvS;2P16PVt6g&N{cA!`MI)9F*vn;~^TcqAYy0MA8-NGDg0@ zp1DB(E!Jd$fFGehAocaxAPolT#YLm*-PGC3fH;#xcGX~Fn-2p@DKCb^GrB|0y5Tcw z$innS{R)3O&^2W$iJEPPDPK@|b_B@$deO2xuYo=2sPL@9+(~L@T**pM9SOI$x_%N% zDGU-OG^Csr9?-ok;pE42bfR3a;LK`Hlp>1f7tpe(Ci#--l;hq0QT>#{e;w9GsIKLU z>S0Utb~z)QTs!G`<9JRNXttK1MP=y0K_-PRZsqXPi3Uq)Tq#k}gb~=^-gdtQJ@&;; zor8&s=44gD88o`>>|6vPk-8+T%EO-UU-7)ev0;8p`R+dbCvaCe$(5E?acu)`XqMw z*M^-l$E^5WCMGOX>^5v;s+)m_ivqe|rhOcr`;*)3PYH(lV1Ew?{F$|wN9{$we@8@? z!@3Wa=>u_w^SqA*M&pWBnOWfsp zM5;ZIq}3h9kf62YOc#~WX%#x$M@GEXlz{p&Bs=iRx?II?Fj-F2NUv+2G(?1v^Pw;B zhs)%Ev{q6^OxJH^jtY#$?C2Gvmq$Z&4!G4i^3VE)E^zKXHeG9J6l2)4m&&OZEMnq%+KY@y$eJJph@%D6tSE}0XCC0KyMvNR*MU$+E1gxf6 zQd9D;<~TC)>ZOwAAublR^vU^bqQ11&HP#uMfPa+*Yc7IR;^3I(Yr&sm$!mHhg0HxG z!6N3B5qnn-AFSzREQBty&UTUbR)x?=cnOgr+08KPwMsN?M!XP0s!!k<>j&X8!{1|0GziS+U57>_U=g75T9=Lco) z4lay>9}Lt7Y53ZU3pW444$=A%gb=Su+En$_wQmefJ|nxQ9j7)VTO+NrJz~Q^@uL3G zyg0CCbi>8IxM=%zG8Zlzu5~%9bF3e?%|EMG^sZH(=Hg}f6RX#ZaZ&@KKhXlP!mxms zKqC0n9Nd)e-IVU%lPYH+l!3DP+puZz z*f86ld??IXXMK@T9;fLaIpW=q>tDFndsn5P$zt}SMAS-Bp3d}JLXWW$J#(!wNC0re zJz1f|su;sUdqjX5t4{!&vKHly6v#sX!(vtYwUHF4|FPZ}ioIX(LKTSEPRU#V_~pop z)oho|+yN748N05E^qM0SqcJBZn8UTo+-xOEL&(Y}=M8^6nG7JArjXgtCrQ6(!t#CH zg=u)tu%BZ?@_|kqmGylgXFv9LP$Hu(E!qFQZq)5QO(moNXPUKYT_<|!#*??Z=% z{YAw9?XJ3MlY0JjnbVnaAwzUn;`D5d^2T!wW0#@JhW64b<>Fh6V|f7pxF2~qw>bi8 z=f<2|;{qnaGY|~&Y>lbw@Y!!NZ_MY!=R?b5E{0{UK%wq&@DQh3d|T%V60FJBSu;b3 z-4J%l)m!CU8HkEZgY=C#JRiBGB1nOiUTM+7$vv|s&gO<~zV{e07;wBsu!uoO z^Gi@Iv?QTkWMF>pae6n%&8_lq#PS{$Kcci04D!>`?T_nZcF1JwT(Yty;3#X}uUqCg zq{YYHZ%lzYII!{Xx@FVXx)@l-nTis}8;{-*5Rm(1t37k8*G!WjXEkUHg^bKzIb#T5 zG`{0Ebob*IElwcr|8h1B8 zRZF}U|14&tdiyxx`!y0-z&2vIOCk7ieMC>()!qWT;CnC5_*`EU`S{OtR5as0tnm{< zlzj>cLqdXiNt?HV6{zF*c-kU=C>tL)&4)hG7)vJDI-n-Jouc?Gn+p>LCR^5ccV!!9 zqYbV)daEyRZ(~Js4(a6L=d9t@7fb%*XrLo;$-ZgA1-E5sMw9SWCI{FOPqhwYa4GvguyX(tJp_8V0_t z)!psD>f7&Ww#(;K(zq^hv;d3VZ$iofp}Z1+4UuM-`UMR}${ie!4EByL||Eh~LLNC89+koYCfuMomDFum7V; z960tHuI}Ghj(kF#-5R|Mg>e+2*Z4+ffv>0Z5M9t%x~DqQ|FB$0=*oj7KfTaYM7 zjT1sf_vPQp3VlDIL{b}qSb23_!l6|yb!NOdfrLCU3hPvQ7^TriJtf;rdE@cG{DhG$ zXFl@Nc3zLoWvKS7ODcOPqBS+yHLJu+AMKgE_N-=Geeeha#F~PetGtvXNLAe5P0AM(X7V;4`Wz!6?JDcd97Dv&L-4HkYl4XaL> z9`t}r&hkMxnjghD+WVeS{A~d^-L-Cr4l~XhYnncRef@Jqdo%_l&mdv75Z<>S*u`xg zMTu$*G6=ujcR?Rc>fh?@l^87~34TGAPYx6pK`LAo5p*u}mcEyoh}j|iN?c%;DXn!! zdFi2m%yP9KE*HnJ*iyUq0TFD&M3kF@Mz5f$Ck<08)m&K6aIe(-ncq;i;qX(RMS{?$ZIoE$9xN!> zViz`dWU!w%=UXh)F0LY{|F=g{%6PwBw;V|vJvI*{WkwYWrnhviFn0#rJ+*s?N%E+# z?R3FZIO+8*p%H@2l;WY@Pn#2XSKm1LkO$pGsZ_W`l`~NKXK=F2&5PUiZp~$5Ln$sp zs)dTzPCX)67x}~?^cGDi(>yt-^a`&%Dg9(Yp;wEiR}rXmLEG!W6Ew^DC}{yoEVE}^ z_$=SJaYb36^hB;4?l{hu1<`CRN>}O5E7sQ0+2)iTL~*i|_90+={3tO% z73yZik-b#sXCYF;_U2mDRU?t!!ACy-K8_uA`?k{M->C!i>+Au|5erh;Sdv?#QuL`&RD=0 zK(9!Ul~aabyQLK_Yi_KI)^@K{qv3w;Ebf$R=v?3R$`GLQliI_hzoYAU&$o)N`S2hK zd9oco*|;+6TnKYj*jYfwUU`oU=X`6GwjJg3cXQV^b(y5j9lvSgh?xC{TEt^c_t+v& zC2tRqLm-ML%jc)MJSZ#TW;i5DN>)jz*JaYk&KqD9Fpk(vCsE(g@TaPi-IzbWTiFh< zV0-jt?U(Dg=GowG$#BvAjBoFzxhY0lAGYz=_vQVUI8+0_3e4M7i=2RZ$GeXouD8~w z1KzDS{SM#24rkSEEoke`i$!#;vkl))T#Y$S2hnyiCtyddQ@&dezNZ43u=gg2P~k5| zA~N4STapwV?!K#w0B&4Vhl;oNfs=`0Q|7d?cnjv<4Pp9r?tDgaaurU~0y&xDyARpD;0-b3y85_=YdcpArLRR*p{=$Tf^OUrT4A{APB}=CG*-W7;xVPh}#rT z8*8AaSOoGc3Wqmg{{CE)fDuI)B*|_}Qc^C~a`@Q@u3VA|IEntHw{wCZ?m$QV)H0+= z*l3m>OL9OZba}psAD>#odj=sSk$0_NuLVvaEO?@AN*}8=1&`S zKy1iQmrkkA&Hl!$jF|`{q9`LDgKa&CTOCcd4$FGfF!Nvp`1j~OSJ{HGi8W9eqGzKM zaDK1KenWAtj`JYbI%QmHUV`)YiO%^Miw#&X=q%YTv@Ouo;i}X{cgtiX!lzBAs)Cu7 zHO0`U1{&4c?|%{Uf{Q|9<>c~Qo8#UyQHn<#hForeaH#C%i0$e@5KS1IUnusV?vTn6 zj=tnv!s1yWONG%bGB(_}E?^uu?m~=(lH@+h=gMsVBV&AVO(m;IVEowjmzWc-l8J%HZjpaUcpubdi8Q84jg^rQ( zg@V6kgwH0;Sc+pUjSfkNSa7-gCc}=?Bt@jcL#|2L`xjVkcO1mW(!ve{F5%36KOCHk zh;A@0=SUA)6=OoGjb-BbJaqJ4=gFP^;!!Z1PR{AdA!46p1Lp@=8`|NXt?^d{)*05z=ZBm|sQztd5+N z!CI(U5D7(B{glX_e0BoZ|FP^DO%}CSOtj|@3VW2W>kAIt`{}Abi>}MNw$hu(KBLPp zYU)L^L83PUIkZu-WsZ->`?QMyywFz8Hq24$n^&2>zbpvCr6*liqj#BKYrhl1OF9PWI<3PdZOc6YJj}qi`jS=_>8W$`+L{>3Fa~P2Gn+%48!C%Xl3Zt@j#Wa60l;CB) zeecVn<$&oRYy2Ug5mQ0Uh?(mv{q3FXApJT$QamqGqL+6_+q|6i&_Wji)YMtmt0}~1 z%kG^XWV(!8RXa@Vfuv|?`)kNpIBxNHbd>8uq&@Q8K|dP@zTwwxTy%nk#!7BBbGw$&Mf74~=r2Z~C;~X3mPoElh=HLiKZ4tM>A#$!yoY=> zarVTXM1c1g!Yp^o+h~0f3zhHQBf2fcV@S|v1c$BV@>SMfFZ3Ri!$WtZpl*H#C5chO z_&8O~)GoVN?ai`@N!C04gexp#Q!?;9JjUoVLZ0Y+RRL1fk(HZQfwU}{oX-fev6bU$ z@`PiRfe%bp(2a*xuvf>t=E!YIze?^P^dcUb%__mDeadqn?E#{S= za1TezyNo-L0&X#=hiXu6p6_)nW7J7)K`}E7mi;-B5XY5bYw6`~v|%5AMc;|aaBk6k zeBeu1eZAL+kw`-Hbj#!l;m-aSweSMgQg|=qH^yZB^amakxEAh{y{?-Bvo5xxIy^^d z*79xL`1Ve0ooY}E=N+%CJNRT7TH;P^n1M>qoOoUDt6Ah1{`}etOTezuf%GujIF|^#O_YS0)w? zx&_wqgX)bU>Rqg_$!fI%p<(NEt9C>n8fhFn9@0})aq_%n_XQ282iYjPyRlE{id|Z&$tN-*L5;yi@^ZT#jhyBo*@Ere z?SS@u3?MrL3_irC-Y+Tt=A@jWAgsy~0)$jW?Fxs{!NzS4bS=(#?=L(C=Rf0OAfp6f zbE(Rs%rRgHN2VZC2$ti^t`Z(UNgZv_(8PD=^ZWpY=)YfV59DMQ@u0gf+ zCs(YuG~}>Py&Y9&C;SYy5av+#J3)&rpjm!FX-=jQF)AZl#s*>uc@}uJS&6m#;L+22 zp{y9B7y4)6Z?fpz=>5^d;PT|>$!a^ilIQI?rl0V6=?q4K^?OFZ}5zVmz9_Uj< zJ0XACxGnwUyB1~b0GW_32rqpDr5Fp&#Q?XP)=aZcevLj}>ecdn@b*$PbEesn@E<{z z%)GqvLH*!oy6j({TuyOTf%cM6_3^6)ABQf=Gbq-47$=>aDoC)0s+0Zko&cgGz>Z12>F1wqS3LK$Urha5^!3{2E2-4nj2BixGbS?=+;kA!WHG4qyZ7$T0@WksQ!{ku5_(8d($MS82$0ogu zdw{Ev!60h4foQn2-fs9NK(Jy!y?Vl_wfY487%+dOvU+_h16IW;mpbINFpO`_^0Q_| z*eQ{u#?Sq3?ALVAjvK9HChI{%-f&SGLGxF)ob7f=+-r;m7C!9^@o zr28-|Utc0reUQi{)P8YVNFG33mNC&V5Uvk?9hog^>8~@6R654(^Y`3t*C)mY-xgBM zx&0SQ-e2PXlw;t3l0-xAsVB5`V7lbXb*U-LrkcP9ZRtcH#uM|=&YHaXp_%tCF%0C) z0-(^A-7}|iBZhnvF?lSvgWapgug{U8wd2rSZnL~N%^&Ut=ZAM|6&rtaNS7tNt@C!i z&PO{rmXvxWU8JWC^NX0^JzI^wR;!tMZUV8oqq_+UzIB)BcihHzgaIAt#@UIhVaIOQ zJbcjiVgCR*NG=G3NbUk>@tNK5$~ zVEbq*n$GR~A!R(jDjJHZEspyPQs)@|K#0CyHsD>syvIi#*2(HCR|zc~Z$$G+@ne{v z#E~Py+lj@Kx5=vF0LDxB&jn(a#tB~MdBFh^ z1XWO85gOoYi*VVmaR(fTEnFUnvx+sDOaw5_WCtHYTQB18ea3#YIaSYLSh zT%&i#w&+zF!tlsYMZg`&=g^3nep|>+B&{QL*f;*5EX}PPicX4)d*W1TE+_4hTTR08 zG}B`BkC-ZC+R#?-lhe-5^^6OQdutC)P)qKRLRn-0=gL#tT2u@X*K#PuwYSS~;3lT8 zli60rP=DiY3k?==LwK%mtKmC4O6AR*jWHsyciwVcEl$=z7Ch~OZ72R9Iw}CK`FN>GB+fM`(vl^IMUb=SZH?b+S6!T4^ zUuUJ6Dp2Vy-iD@o$OukmIv9;>e1@Lyozrh}2>w_hiN|)#COWpb-J=YX zqdwqh>e~KvI}1M-j378#%UJT;m+nVLdt3hyRfvQaagPG)%ppUA)pd2m>uQcK+Z;>l z=#ny@Oud$u@0R5o4v*I(_v)F+4ifx@09zvFx>lZ$giN$m`TG?2*w%u6rHV@H4xEAO zz(bBM%qtZ}LL;R%S{O9bAaa4{Nq|WgmMrRtYN!0CoL;pqtV5lrsO(X)f+c4|;M+JH z3VJ+h9B|fP*q@FPT{5cwk|NyhL92gz$+rS52&!-OIXZp*WoSoVpdf6hJ;;xfnF8Ye zQUSXx^V>>Uolf!)Z3ZvJYa^5LjZ{>@3C2aT(7?3 zYeOc8RWO8Ah_!X|G?QoRrO`%ZOi1${n-3w!^OBEKckRlh)1Bf3#V71Mms%ij^L=P)PW4iHp0BUz5LGh|%9WjLpLHAqJt| zi^Xo}DeSZcgRSvOtE01)hRoIX3dj2vw#pw#hkQh%cb=2uxmDw-@B?%|_kY|xQ?%lX zZvU5%c4If6B65Px08M#0F2Ju0x)}p5J-g3DiAFQhs2L%_CG|J`ONcg0 z&F8swjQq=4W;U;2plHpm;*=utXaa(t*#q!!che$fWumYtrP!KEL=INT0{n70{d+#CRM(}s6$*d1D!xe@_fVa^pREigo+u@j`7m)H2aE0n+N`1%&!tsN01`6|K{WhGeJ0pa@4~0F z1JxdQ2&1*tveMe1tNt7mxd;wEk)mAuEO%rC^FRcJJ-5v>Ti~WpY)GI);0qH~1IUxR z(XBXaw5DEmNT7J(*0f*Jn6Lr!?nf_}dv5U+0v9(J!fvP?Zl>1Zj#cY4qvU=0v?3?u z5`m_Qc)6E6R@1XVzfYBKzje>0jljq;;l>8A8g&2csN#sy&XgGOd8uLg>uvXPHX=s> zZ;cDu{gy8m7P<6ceStsCV@QA3@9Lhl>ORM9Tya;TUiD5f;Ee!MMbMyQchv3b_lL#` zH1-mv;aJkU6Jnj^rTpEu^E6P0W-a;=5uf`%KTj|ahjE7rry%syFa6dV&-&&LBZ9ai z9AH`619U`SKrpf9CUqQ8%R)KyY0Hj|7}kWbROp7^WO#Xwf!(bmtNB~F*4Ff5^3|5t zBqzZdkGAg5ZODjFmoq@Fb+zNXKJ2=^tU#Jzhp&)C3R@vC$-!uD6h*+J^5HM|tA7~2 z*{>KOXq?QI*1Q53YKqAEF%1$UNhy+vsouF|+RoCJL;LP7KZ&j|YLLxfV}ZSp9Z;M+ zt;)pc{e?8h)Kwv~J28pyrFd2+p3B2JfgcFzLXiy7e0D7cSo1l`aTahf2l^E!*tH|( z-8k%-UG+}Qu&Id$CaYUM-9^JaMAP`FuVvN3@n=gzGNNg-FNxW$Vi{$YUB4`^^&9M_ zRqdoArx~8&NveTx1`T2O>21?AfAO6r{iSe0{Q0+`*>5$t^gB2l(k#-gu$)9kI-`SD zrN1S-Z@jxSxbxMxQT$!3!2DZ1QArppGWn)tbhQR~ajdkqg(A}@o6qk#M!5kly!+{* z%IVCpgTE7-=olyr)Hp~XgHzAlVS$!nW>IkDZT^|*^%Ku)w9e472ICBKD52v~?3I}L z&fvT0gFUteIrTiw*A({?#}*mvczGKW@m+M3t7zx?2V^&KeAP4M;%UMd2A|o=&~SbG zZ~VsI7Hm?fPonD*WN3*CA@>YdTRGime*vlED(P9rw+-i>2vDHLOmEps+~~_)eqWwW zAJKmB$1|okR>S6^1Jfkc)h8ii*K;b%eqX580K*YfhmWj!hwFEf5;S$VB@Izj;~id? ztiQS_n9x%9@4px?BJRvca^bgleCQFDykBM3u738-qL}rzQq+tOqwP)2dlLg9-IX#3 zzYdmvE!;FN%+r}^396#tB(C&X0r4JN>ril%Rl)kk$)>u49}v>QEL?^tL8G$hmOfim z;5*{iy<@qToo6EswS{J+6i!uf@|r#VV6gAbyi8T0AZkmF5!F`~HBkmj72_)%@&BOA zG%uh|Yb6z}zm!=lKWWeIDf))Pv7q6*Qn+kmix9gI_%YjzQ6Z2`c~JF~)uX`=>@WOB zL%&9#baPUYn6gPKDauvRUuDX{{8?3jiw%eKb8g)xwbd#t zN}>DUkI4unfE(7x-Q|3;5N*f%NFOGrQ!n@?D`K1(`+*NbH&jiX0=RwI$rHEKhZan7e~6IOqgMQ94NgP)6uo>^t$n zBJVtA+guv+XQD^unR5-wm^vGe=CCpI?7VGz)-&t(&L8Z@gh@6pK{aCgO)j_6-(xK# zx9c&j5EyvV*OPqu=<_L=V@B9gZL!;grJGJ~5W}juJ^rhJs{Ze2{X?fDWZ=70GPqYh z|3|4ok4Rv9J`?T%-nA`beZ5^=2sc{sZ8pgWZrYMFSIZSMA*?fXQ?H2e1^Ln~^Han>o7LGI|n zF!58^g3lGQNGt7$3Ya~Kt6d(Q&k5}XkHerf(Oikd%ENfO)DW4!mysLG|FYrZx*Ef2 z0off+FA>2nSHr^PM}y`c0Hi4`(}C^EoAuJ|LpP)^0E^i?!e|v5dG}tF$e81A#3g!A zMiNe`(A6D8(cTxMCsHIoa|N?q-%h7Q-d_vFdG?Z~%Tni&U-kXKpbYV34iPN#QwQG1 zYRtSK5*DxP3f-C}m81QSD4vljmIFmb_QW4y>;!fmYPq$p1*Ahq}g z!1mb4IAbi(p4^M%9Bm6!BIxuawKwTp&cLNmuCs{M-=7<`!v7Ro}hY2outd*-V?julKMnf{wd01C^MpR zl!4BRn+3SHTZA1onlq#TA~fAe?t&*Kc#0^3sq3*dSGz2h1;27@&FxxQdiUv;Cv633 zf*;k1 z6`K2AuD{Siy$V_-x&c2?T~WOUi$eYHW!Ee+@JAVE8Sar%2=z~iod@ejaD{sXq?{bo!p4@ zh8}55AG&=AR>pc(LS*TzI(1mmZaepk65kAQb*0%NFaCj%x@__LP&ORWt@CMVrPrp; z01^pZ1T9z1NC`7l+HqBLAJ>zQ#YR?`!RkLbV3efgnB?nV8lB*R?Yb|$lJX8yuLTLfSeb?V4Gy3JSITnOcqZA{u=QxIzDs^cLg*WKOgb07 z{eN7&bySo8A3kh?h=Med3eq{cry@0AAl=B2?(XqXln&``29lF*kl2uxZV*O|F}g?m z_C3#Yp68t3Is5zmV|To-*Y&z$0&}V{fURV;6Lr-B@+7_x|6kF`Ih)Z4_HQ?Rm{xFu zy7aQYjJ)@6yxrmHli2%nl)IubB+XPja_jNsy+ho}9)e(XHBa%@NE0@2ep68NIa{j>gO;`nAA6$6o&S0CSM> zYIQ@01iq$krOQfYJVK6J@+05N9BE;acCF8uDGV2p|3M;HNAXyXn)2R7TXv8j!#6#d zed$RtrRTjW54s=d{rGTrfESb2*L;t8O~68t-`gE1sb8qc&Q8}N%V(i5VaM`I*|$sP zeSnPMUuqJU5&)^q-^U0%)VBZgmJ*#m`3&cENi-}EoXL69MWw0wyA>G!9|Lg}!5&Mw z7%?T!-_OL0%uoNfnR&EK!^0(^$}QLM0yA($`EVk#aq-tk+%SGN)k$IqZvISMCct}w zmksh#7o@}WMIOtsSSjG zJ4PMK(1>>X!>wN2J?**}^`&gSRmos7iHx89r>ihmz)58@lqX@B6@kwix$^AuL{cZn zZNlcz1r1;H4t<86ygxw&9$kXS2M>t4^@of~$GS}Le%GyC|Ia(|B{0J;tfPG{bi%1W zAD8=vV!ejQIQ1sPS(YcPbl6|o4jB?)+=;YD6KX(@yu;+NtQr;@h{x_>0=nb?y>5+W zMb%0?St<-8gubvoAEl!aN)8{27c}&>nTQV*6N-DB!3tc<&?}Q&pRXMg0UUO@kg!)Z z{r^54_tyVAB;Zy|vqHHMxb2P0&jX4p6h(L+_EBRkjyCC2lKAOl*ZwF1RK-dV3 zcoT&WF~Kj$f0aitx&BRlQ9?$W-$+6@w=VJ$QAfc3VmvK=iJ}3yz#}%Iyg5cyAdqi- zYUE`6@V<)_sA|q@HO^!}u@?P9{dEPUrr;awZ)a~p!6)zSdcNpn$(kL~Y%$ai-R=>I ze-R^Iq=VPa2og!Ye{Igrlr_3YL>YjOn1JW~b%mFHaJ3UtiId8)l)-wvHSf`57BztzO|faTB4vzEvG{x0VY^2BM+(Pzfic z_a6zjhDmYLdd`SfS9-b6#y(T|fv2n&(o{ZOWF5k0RwuCH`VB<&iq(07n z7GIOR7-5m>FMdDc9p0eZqA#+{Y>*i{@U>!M_3#?se>P<;ZjBeVJ<)u6l+%R5tA-7@_wadmi9*YQ(|uU&w;Ks=m{I;;9K$AOA6GvqYEk6{wjP%&-gP{s$aN z5-Ugin6=Bm?mk8y6~3)@Z~A&Zx&O3{x9LNm7KHJ&r+u_Hnba2t`JRKviQfs;iH#I4 zKz)Y2;3TPvil?HKOs=v;2`O0{|FvELZ6cd0ilN(1Vlh|WK6Iu9NyOGx-GW{|(+t59 zWBBr0x^HJO6qG*;yI%o9e5uuLJlx^dFS@d}jGs*H*xsLJT`wnGz~nnO|MVdl&9IrG zetNF(z<%z{QUv9sQV1PcKOmxlR(APKMS}MN6^qrvcjAZaMVi8Il9YN?VHPsV6kx*8_kx+O z&qF*N9}azb^-n%MqK5k&F|!rF4CB{(AXc4B9H(13b=p2Bjk_SC~AHaZtpZf zd0WWAR&dj0R1c7r(!nsVV`cj}Bq7?Y0`_7;&l)mfeez4iHo1k$2=qMk*9%Fpzf!A2 zPnqPq*XQm}i*eB4qn(^WUv{;aky>BZWcW9yD4ss94}kwjUrYRXV3DP4bC7DutC7Ku ze5YA~(7`g~h*OYO472{>$bE9YHG8Equxo8RQ<9~gSd96O=+3X{r=Ka2NerBRdl^QR z^&`_8OQY`pnM`5-D)2g0)E8uL;d^cTxB-ldUwm}>p3Q*9GCwi_zr*`aI>~`O2ax@b z>PKb{KZgZ381tR{qpzjcTLzA;Ne3Dz(N)F@7~uPsm%)2u>JgOXuzD#h>7=7InaZE{ z9qa71&LfK9VsT-B?{uR_%zHZn6^m?=)W7^^%t-BMqhn2sWO#NpZ4Dr^qa;EfS~aEo?HTyy^2sykTU>r<#FDGo z469x{7Z<%7x!LFpT~L(U%I7h*pZEjv7|zxykR50yp`kh$SZF)d2SYtL9d7jUAjFp?AvweR|hib zX@KxLY_<~)dcQ1=hbucKiz>g4?&%Lak`CLC`e-4xXr(9kW^WiP2^AGU1Us`xuMdgsJd_F4L)o){sr61jJrY#(Ljrzgr{U&|ozm8`hD0#N|;e<~Q zBi`E{>^OiIh1Kd@RqjdgrZ5J$O>{gio;1aenZ9=X4MG&gLyFepWY?%iIY=n~s8<}j z=09kug)`&K3YH9*A1z?EA07{&B3dtsI-G#5)A71qUlH0MbET8@7ueMLuz9ofCfC53 z^qBj#l2z@?Y}ys$H{LDnW}_5wS2TVr>xGC%&j?8AZy89{&BbhCqpxkWz7SIs!-5Ea zOw-?9%s4i*4!qoq4+mtD08PO+Tko#=A>1NF-Oe2gaD2pzV{Yu*>Ny?TApS#7NunFI ze+maC`y}OfS(M8;4?cWq_3>zm)}3FPUtL<(tUkAi$jV-=(&|Y64=!)1vp%@eY`strynnvYLk-t5^rR1-B z4PiZsTZE5l63=4~NWA&$nT`Ag1;75t4Oe;hf_$t)$cFL9lgCxnUmTY78VTaH`5hQP z5E;xs~E{Xa|Ir6Drg=5{R~->vvXu5YYPy2gkW)%HCMlDNioXR zPV<8<0Ue^Q+VApgZkU2zDKLHJ>}c0KZrDWc`sr2x@of*H4xO}TgYj* z9(xzrM+ox&l=HYr1&b`Z7DYx0{%JrnL>6d=>ZyIb20SwvrpNU}XkXS4ssALKUwipP zDMP8d)EbF5@Nh(_Jm}q8qtL6yXJ*V-UDxA>B`5)9)X%7j8wj6hHtn&w%sydp?arnf zw$0ro&)@@X#_-yyb!{-ab?xZh&N+U3nQyU`_z&>P|I@vnht^uJX^(AQCp;bekA#;u z>D99re>EYJlIpAG%tdPN^L6P65&YzU#K5{A2I*1O+7(M*9`=G1DUQV@^iox)3yEhwhPnjIR4?@Eny4USr4bDt!F9$50>N&{`2Y7|JME% zc4G$5xxTD0!1x4OFAhtOpP`8G)oHrfn z_gfdz_=XWpa=T8fG{G%N^9JFl{jp39@71S&h%-(#)%57t%S1oCp>zU<0W*?bD_p)_^!IV zw~YKnv*5DNvhA4Y!4hfMK`%i!O$Ye}-tfzPzle$4kH2?9JXhjMYpnZTsHc|wnu?DG zeTJS9JI*R#LG9z}Egr7P z^h?Keqng<$`!I(XR7SU!3NhcOo6IC4UDbya%qCEIuy8jz>CxeQ@<@HbpE6Jgf9T5( zKe(R$QVFYM)>KY^MV2^i5i+^0Oe*L4(aCb1nG};7>(EDoA4##J$7*?TDhy?B4O=s! z_|(w%L+OcKcm!VD-rm*v8L~rJy(8r86#p`a+{a*BRw$#A(K9 z@Ya@sLS92j;lx)@K20yv-|KpmP_rmjzA{q-vLgFUBwZ0wJ2GDyw8_aLTSS*iR45(5 z$#r(>?=Q#&Y)La?D*Rjj{bq`2fR$oPRuAC(A&~rwx>WW8mW@lS;3S-* z^N+3_DeOBUJ?2n`b4fK2)jpJ5xKQfeWYy zrSKPP-D9Tr*gZ9hC*Kwy2L~O0X65%%tz5KpxFJb|q}pVPANLFajux9`q%%AhoX>OG z)K}MXnJX3p&T8Kv6p7VB%${YYPUxQ9#@4mE#ozYS)};h}h#MWvqQp&D*1A&(rt=it zZf*t+u>x)ox(j250fNu)lSXE`k!WVHENT}^MGN%_^y&C(3AB%$riAEjHfZCs4u)8kKf zJtkrtq7wC~*-81Fyn!@7aF{p;4K22OR+VaE3iIXkJC|JZtEHvyS6w%TOUt;ykSQRN zAGl;NC&A8jR_IWBcYp|BNC%*YEUiI@=u{IrB?|*l1n03pm3TBz@q+ z40m61t(_e9H|&kJv8Vo+)A_xqNu|-PPC?^FBQA*q3$LLWHY9i`s2OH3|o(U-9q*nK=U4AbZJOxC_hr}kR-O<&!=k@B2vfb3-bmRGQ z1-4_(RyMHNbPwHOsKM2_kzxjagBTH$Gsxj@{0(dd1pLg~A3*Lk#);p#-Z?Skrj}PG zG$m@gXbqP{SQ|YPnTgAaOEs5EvR|BUJ^y?RkDFdQ-zt}e{dD5kaszLC_YvSzGciqT z=@7Z>+Nevh-JMav{AMCoKg9ZHoh$_=7V@GO=IvmQI^10Zpbp3?7)x+z3U+^wH_#Jx zFdsa+vUk03&U1Hlvw#~FZ#1%_!dWJc7T}3h%e_vf8OOCc=#8(e)E{y5zoP3+?~YC; zW=8Bf(tW@>HpN^IWSV9d%WSiz352%Sw$#(#@PPf>KHF7E`mX>;J~{3*qDLl>C~@g> z$wqj5fF;-bRVyh?f#2QPNO!(Z?DFB3%y!V7qor42E+zdwbBXlSw^mVRr+ik4Ziw6AGK1Sv@o zX$SVAG5xST)IyA>@M+gzrIw06i*Wkw$M^%zi zq*DIdrA}{p!C}G9bW;i5$lSRcYsTQzF+Q63Gi8gDuK6Cm&G7D|f851+l-UUD@8xk` zZbET$dt52*P#L3V^tWN`ry_kvi%ha`?xq~>)2(KIwH`ND`(+LO2ihgByUtA-ZaM7)9|r@W-SZY$S~{709a;V#AG zlY_)|a*931iA!5_~Txfff^`j)P@t8<$>o61^_W?8bb`kL@$HX42bu!(tA3zUoR zU4WC_(NVmUgx;>o4jHCZK>M<%?&l#&e8C~JloB&Hff$e{VIy#uwBI1g!l>HGF4BUv zx2f_^chkW^!R79sUk=YlglPT=Ml zOu+y8{+{Ckc{75--(0(&+{uswMS%JG5wEUw#m>T&yXW#YW&rm`kNfoTkMKJ zL9yHA+VJ~Y8J1<7&Gq8GU@q}A35R0}KvAH(C41;1?PnyR4&XmU2{NZ!0bte5g*(su zsv|UumEgCresN)(c}8xuAuoR^37>vYg#?65MyZJA;iqR0>`t*Ubt(SMj+{KtKCq_! zQK@ELq1B6&)jSrkUPyJQtohNcp%$5)ZhxZR)KPnIIozXR)mGbN5cTPm)a`(^GQ7UCWS%@)Fh9}l!fI#}fm z7T->72{c$PWeczohg9wYeK~d|*(UpXYj*fOu~4s%>M^>`+{ddB(s#6*at^xbVCqDd`0ed90kgC)Q4MNeJi z2vp0laYo}V#>119k2@jfOIv`GSjOVTr7Xc0;07jEWUL62aq^~TOk^0UwQC|QVE$v? zqc){c%FXjOnD%I%HZhJQ55Gj1*!{S9|=5b>cm>K%h*Na0=gk;x8 zLyYxXxcrg~AJ~57Gx#c>`DgDZ`qZh^t#K=_y47%% z@l&0Sil`3n@ml6W$aruH5|(Y7GK%lKE$y7zcStsaHXSl(eA-ORhPR@w&2n56U(vOC zTXB642ACpGadXEIOL|BXPrQm+hK5O)^n|#;oxt)dez3tMsy*5E^{GF$C+R=AyVZJh+J`me94Sd8QOrkK>mQ{iKL5t!1;i}Lqn*hs zTka@(!L2gT6lThp<|gVfOA*vI4d8S|#(?|cr>!H|+~$QCY;wP$^;q&wV&48b68K?3 zHNJm#;7Z<2oiXghkIuRgk`n`M%wXmmkT+?`k-Pg&cJE$RT#>=Od&?yclObE$lB1)} z#RI90RSZq5^Y%W>=QO9#++@hagW@H3V^+Q;(NuRfBJSFejR zGx182yH8k*PbFo5@C^ET?W|jA#%9D=2BqUB#$0?Qb+g9lciLVfVI3^_Z`F@6<@$OZ zxd;rZxgcd0U^MD-5@sW;xI=gC_-K&mL{_F$%-@n{+jVBxA!d`NJiXkG6r~WtTmhdf zOj7LIw2cT4rp^jyj7L`*%;1g7j=RpAMszUb>R4vL4MmcRgSyB-M&{|pWfJJLKSt;0 z{#BQ-S4E783u<)`%WPg;oXlO|w6&gj-O#M%D6qv}0;)dD8MBg;YN`ry>?yC;V@L!p zt-vXb;ak$0?e-%;wZ?A~LS4-K*JmT|uPshuO#}5j8~1aa1Mfs=weg_ zO94Kr5~ppRmZAzhn&;3+yN#8C&Nh>!AUwM6qcI-4S724;j7=$n-uQF3zth^)L4^zg zD2q;_;^3oVBsqmj0*!Y!Vac^RkvA9ke}{R-v7kB#_xUD{bh=|uT*7Ap^1XD(Sae=x zgeTJN-*j>kO~Coi?&(H9BJmhj08kRZ?X3EXBxgBFd7WSFVh6SLmAI`Gk7GNSA1VZH zhinepF{66kw@07&pi2QAZh2a}r_C$HplZ9IEqUDO zRAGHE4!Qv+)icjA;u1?PF})hDyp&I;)-c;Ink>gToaa=gf~re3H4TMs=N+TRdzj;b zf?MOk+l?Ax`03|x{q!;sGN__jT7a%Vykh7v@*KBa7<)C*U6EQmc$g*UNAyR2?c41^ z;4#!p$jhOzb^`RcecETfRPeJ|K{d4QgQv^g=&6o+NzquJ0pPT2Lq^X8Y(>(y_&etH z`6Y;lM1kR(EfLqTb)jiw+onP~p`=H$nF_x~G6ZOH(HBQ8*DBg67?kIwaD1_Oc%|Q5 zhs8h2@L?#_<17(#4A6*ST9?o!%{eCy&DP;MYiy)(Hp`*o0~)eV@8_P@f-Rpg>P6nP zwnp6@jJaYl6x)kxomzfUrxO8TUms|XF`e|IHXTxY{$pz7n`yN{rw z*bcFII!jB)b;L(bjT&Q^mZRa2&xJ7TZ1zK;oVadh-H-8omdJ2yTw?}(ra?o7R-yM5 z(OU;VTL}mA(N+G^ShKsQwaFi0l#BaU-)AIYd)s}kC-}2HSV9{%+Z=rBdAKiUWFnU) z#el=9XN+h)#+;jQiDe8|qB4i$U?Yp8np_P+vm2nCi4u1Es9LUa(c(-}`0ye=kC0wW zuEn>uBU7&^D1qr|Lx`tB3xfo7g&SmNi zMWY*T)KJqfv~3H=Qb}BB25Y+xjMvDeE^AniTVw$Z{90@N?o<;td*S8p=>1b`7g9w@ ze}6R|{Yo*d^SX)7hTH$j7B+jdmhg>ii+?REB4TIg0}533LWXhmWa&h(hpRvS@G5zD ziNnRaKvpI&p8QIiZq6CB|8vvd(Wc)V-8prO|GCnQbvv>?FB#Nk-o(e0538$Xy%rFQ z9oj+eO*Gn-Gqn#GMrU%71vgSWwDZx7x&0lYvSi{V2mGzwS|f4Te;RJNCD$S8V+A#_ zcKu)iz}&2cP0>0*7}C-m7bD~EjLLvP93|ivl!+6%4m1E`u^1B*|N{57;6g-({s!E!cDLw z^EAB_xu$0MTJ{ehy#Z+cX9%2~AWk7{?ReeTY~Xv6Cqm%upADS=$COcKsp7xhTCmxb zBK&*Bgx$WEnE=tpojUBx1~Vr^T!wDWyp7zTYA0UaWP!+f#cvaUa^!#J)IQD|y2K#q zGCh)KwMsk)A0T|pkLfJEHu6a#B$J*v%^DBp1)-oqXTd|#-lFIqtavup)Ty0j`-AGq{RI` zl%swji7sF~9f_LN$BcOxI!*dDy6aBP&g^G3~DC2r(Q&y z?7n>9-cmXGR{B*#(TOUt%|+Q^w%(cB_<wernQ@l z9&_y6p0Sd+D$|J!3OEB*14YFKPvda;Gx+1@cSb5OL;B>ck-?n3Qe0F%>)OH-oF%bz zbKg{~4v>$rjW^-Nn1W}EZ)055@M5zVz4p$U$#Ky`x|t)tsnj|-d6VU0%!GrRES?jx zvj;MO;=K2hY{Veze)SElnF7rAfW=;fDxd5k`GmRW&?qkTi*PN6c`PD6LXeA2gQ2`e zN{JzI`!S%b?{EBOan>tiB<%3AKA9nJc`#XNzl3-z`$%-m%qLh!YAe~=@8g{XI>J3) zT-?pcPKaQAHfOdECMm9BBC@p9PnU<)@Jj#=b4X3 z$jj%}EXdgZ-c%+Wda@S(+AboCBk6Q6-4dut*f0r4>?qxe|}l7Gb*C zv-4ML7oPgrM~&n_Ce=wSG}ZiAyKB9~HTG|E;h|da7#gy$wj&_sC{DA%cX}~ssV{_Q zye^tmA|K!ThmXZMEfM&^pWks?2_*fXR$hOZyd%}pWwXP625PitI{7VZcVzx5LDlQ!}Fu= zCy6zA9-Y=2clFv7rT==j8nyEOT4(xK$d;aiB-(I5EkfH#j*-m5d4WnXU3 z?-Hh#6tj;sPGd`t5{7T;5i8CO=LF5ara~Mt^a*^*tdDmB%olTTC!5#FA%_1+mT>4w zsreCLu(#Z2?Uv3iTl98l_8^7>Qg_jTK&96kQVg98&Ezl_~?9qZ8mrnS1++1GpoqU#UyTm1klTP{9KZLAG^yZp3woQV!yS@i4> z_URtpzvvy-!)<_C?t9!JtnJ1nNo(||-!g1ch|||=nWB5znpTHZwY3RrhIsJEKls=e zm8s<5rloacSg9w?f5{uGu{)F6Cz=_9U3`%1EEiaPDK>*ZpAj!^jEA<@fj6cQrPBJv z6S76B+GE!4K}nX#FEr(qE=THpG!D|$Y-8qfU}7P#x$&+Ivz|wAU~4n(VhX%_QJA^_ zpV2z=mdcm3v6W2Sy*a{@XLOY~@=P)t;L_yiX#gY>HLNw4GiR-`I?zlKcFsf44`;5t zJMd)n*Xys565~1>59AidDRgv68ePE_Dw7_+=nNp=vUTvVadBr!&chuHs6Eq$b)Xh? zEV*qI`Yr=nt8u8PVUt0RV|1pET4d!jXK=|oP8S>2l}eKw)wy+mATs)wZ)l`Xa$xz9 zq2t{|jD&MFt8wLsaso&$z*4*-8lDYqk(3=%p29hsf_>s$Ow%Jf#H8mWxEfhc=aThK zQkCEhYord%%1)vJ`bJn9TYf9Ii9nh=td<-)cf+$?p6DsuJspV~)!rMKw+?U+ucR;< zO^zvuTQP{el?%eTgFNg=sN?s&xiQk%61dNv>;mVY9`Zy)Eixw7j|c98b2F0>SFZ?Z z53go}UW{QXXOC=nDz{JFdLaUEfz+gIlUmnx0()mByHzwH7h_Sf-ohd_>2%&wQleD(f>=c7#)@JemMJ}n4 zlAK(86Bxy?m^{l%qn#x!D@IT7tvxBeGwX=N2DCH&Md*{AR5-1~27m9L z7s5w^T;6qUR={~Q;-7YUt{v2uZQ~i@Guh2y(f80n)dnAF$$m=?v0V$#@%p8ub}&PX zA~-at@l11BQot=oi#yet1M>M|+aHSj1QjAk(OwZ_shTb0@GBn>*0K7GA-wCeQh0`H z*L>fHzj2C5jfU%X z_|?S6uFkh|AV`FaYVvgK2;{#N z$KvAz2aA!uey7;ok00jA&I0dvWxr938I8CB@i--zkRJVLqvOTL#oePW#^{{1&~S-p zfpH7o(Wxve>g|nb1O5~CjH$G9{FYDAC+Z%1Xd$vcy)-$Cj!M7OyyU@wvBSa*2J>z* zDb6DOb9pi?pQTC6OEI8d0{h(RH}Xs)CeaADqrOxwfPa9GOJ`&3(r%KHLFLFghcW1@ z5hy!%UqA|Yb+j$%W&m+Ok^dW3lwJ#4S7?V&y#x7A`Oh4S2s z77iQnVyFrj73&;vsc&i4cRwXj+J!ylS4+};x2B%KI$^%k>C%8w2lckfjz0*Ck&<%B zASuoylY&BpgQi@$LW`kA)sygvu~nr#SBQ`A+vb);-8yQZ@+S z)qQHW>-%ii9JuJ)QNtJ}i;%qZ=Y9`ALV#Q3matVMCAX>g^_u073bFd+@fa`ZkwT*p z$Xs{0SSh+{6nP3nm)pA}=%$V4TCT|&QEIX6h zAjee(x%st+uVPe7y#q|Dp+BM!OiS}e5#@dsDH2w0@wA6d{zoMz{q}5TBBF-&%tc)X zXH#fII)%fRRCxDV%}IG5W<|~{u6)wljI-3_s{cD4>;a?yA1Z7)Z(6tit5KTW=0;rR z@x-tNY}U-I#o4m_#-5Kax20yvxkPlc%u-8cv`UA86Q(p^Jp>lzA1)F7D==Jg0#B4H zTtYizJ@GVC4!mx;VjsD%zQZUyL(Ngbf$7NrpdHqRy-OJ-YJNkk4yb&&ac+Kcx+6_( z5`a001Ji5&mbhh*YN%5YIc2lZAfA=2&DqH@GtOx1kn#FC`GKJ-Ii`+a57YHDEo4;Y zF#ME2)K=Rn+`0_o$^~z0mI(Ot`r;fSz2X&cWi36jXD)J+8IuB0j%ylX+@i`%$_cyOC8iux#cdu=Gj!JaMfXjdX7b620|B_RlXb zMa4yB`#0CrrX=QPmTo)VA+^N!!E);L%_i!?EoxcCWAl86`3sfpjhI7rzvL}FM^zVJ z0ijB{=9%)TaV(Z6iee_Ec+Esfx?<+c#oe({%E1^bj=?t4<83t#ng>EO8R}@n2EpaE zCpYQKR&PJ3yINO*``fk8l}<2vK>@vqvU=F9mFKbhgO zjD7VxL_1`1!O)kWvf0K|Rq);lhvcjye!=0K_1CeWtBux4tXV&q{w|<2#RkL{9cws^ z%Ss{c4wm`OspOm%sDoCOT%*XvP$bFEuU$6gr#~d_iy~o>0FASrpM{_^E}X3bgoW~ zrOIU}TulBhvdc?4PI5-NKW)}_y#Wfe1^uxV(L(-qH;WXX@wYQG1r3Ur_Z#ZDh-t0e zHfp$QErISxwxwqd_@m5Isk~6?o9^>Ik~yf@u{$!VJB+3exeu;=2y&JccKUqjryx2Y`Dl@~v%R$O3P z?cjD@!a-NK-_nt-Cm453tM0%t^=|`8R)WzKS>?;cJ+yH9*vWVH8xf~iYn)S6VoUO12Xdt^q9cLE%p8RNhr5vykGtK3 zwUl9XH2B#T^|g!*&^~7q(t^CGXTMQ@5jv(oq zN+^<^Qrp^gmkJFtp80v(uyK^g)+#&Sf4Y(6)h-k8X=-U$?^yymPl1(-uP6!XxS4V8 zR#Whfe@LvDn(3d=x z(9#}%zoFNCB5|O4Wz??&(1sKtnr0aM1vl(fa3?&&puxV)~36w55 z)!1;1%SyAC(I&e%k5^?OnTj7 zYk|PTBVVwSO;2UyC8rTuQSQRcH#25lMY2PI%b6~5W?W6pBhl>=9c7M3vfjx)Pg=r#yZp@Z~bHiO*Mi>R? z87s-Bk-ufhC81zY-793VLZXFmXyqQ`%@|Nc?t%RgLX!B?e%dayHVa~E1bB^%Uw ze4#rM>Qd6X9g$Qco3L$&rYYppT`hcWGSDs&y0I#)Bp=PiOQP&}mr1$3SMR|fwCQel z@&JFz*G0YJXb>xy*nV)_CtE`cY|csOZe%@(#iP1`;HK6CQf59_!Ji3SqK{|wY$0y6 zVNX_-?T4zeNdm;<@zBFQdluQGh49-1%bbYA7%|vF)vgS*`Nq9c7t~!+UOWG#)be8T zgRs6_>`Nd)JLM{ad8ab*jwEIte*6RHEiC)(N2jCY-&_BXYQ$6-!4k&V=PbQrY4#eM@5ara%%&GBi%}ZpwZK?dA&d!$CxbJvn71=GDzP zlQ9!>o=!q;RshpBrCK2RN<@x@;EV%4A>3Y_?-skZn~IsR@EnU9ou~#`s6g+v8Z+|# z`ODK~{EY&A_$N)RJA6Pna{bY4;q98Dn%||GCWfU>qr=J(+6TbX$ zJVVv!^YOo?6KBx5%ho{Qp|b~CwbS#tyIn^*{|UJKQ--#fGyp#;9%`95m#~xFiSiRc zIBA6!lhqa{UuKr>;z3Zea1KMJLOEaVkx=k=T5UD|0e_YttOuL7=ksq%c`RYzQSp#O;z z6c#*A{d_`Gj#eET*6Xx(2D0z#vM^;1Z~TUDIqVz?2Z*H2Zs6rDxg9E8sANwzV;<5l z)&DVP|1X%Tb?3-S*{2kvuW#E9tao#Lypj;sxUknSZ*@~Ku}_xcL*Eio@wbiIqbx*X zj#u0>?k>%}JgHNk2r%#;N;WNx10lnB;@=;e|6MNtJ@Ucd;=1E5p99b=~v3dvj^(lIHy-jdMg^)FDFsajeJ-RtKw?5)p%5`_@0dJ=H36bvgO?`0J!B&{k=Il*m5BPQG=~Dr{aH%+1Mafhp2T)MSi+>_;J4N zD!;V$nUb9#muhdUvstIC_{1|`*OIG3%|OkUy`iS3Z^!N7<~D#h4%lGdmrC)twuP?R zUn|XPdDsn|gd<1fn3Q$jP;|2_17m8z&DMBxdo@Z+stu;gEOly=H8S#(0cCVrXDytD zIs?z{=2oSuhCgS|2CkMO@9T50xa+n#{tNDm?zWSe~(dAX;1jlkcz|Aw)b~J-OjKZy`hiP`)cZ=4>d%#ip2{^Rp)7@A$ z$~*_zGpuI^;|h9HjIi*PtSH8t;8PsFkUvbasLj0-Yr4k;V?!mWi^Y=uEDPa;1?4TI zh@+D^irsm3#5;x6vh8T28%#k7`UJ1{Y-Jk~to0K%CbTU8R~y=XPHsEL3m)c+8J!I> zRPx(BsS7JIW}W9EQ_<#2_Nk)1eOnNw+1M_Ul<#C2Xw6Adg@%3mV8IAXy&m_m!At5& z2H@gz_)|;E0`#U5NU`SO@h|hudh(fUw~(VE6InSa?CHZ_wyEgBs&dURVn=Sh`V85Vgrq$~Y5s-y zeyRcX$AZsqc-y^=G%Q^_Yy{|5u{^@T!9J@#%>0WT89WFQsMPHlIx`!Gry+tH$oP&= zyFk^+?}Fz>&76w3{x$u$NVBXLme9*~uZWdV5gJd^wo!BY7)&eaT6KIZgEq1j@6_Fx z4G*e&EH)AC{YwYZX|W}^c|mPJ&?CYlI^ngQhR&1X#F(-4zvB#86cG>a-3iJ2IVZvJ zhP302N`QV9d+buzF`acyah&r>XQ?eimgcz9)?tGP!eYn|(g3-=Y45YX(d+~`zuz~v zKOLDI9;A9#@BRu*>k&l9O!nMMS{9pOeI z1>9yBC-Q#UyVY1^Y!)0m7h1M zrEYNL3AY7_3&>7_;#GnV1ZbXwQD;bOeh(Q*BiO30HuO69W9}fxm?YJ8>i#Zu6!k%N zIJvK*Ej5>C!5-_hrG$VqvLBnc+9F><4RyYbgJab~mGaC_q_%2{wNqFVElKbG&@jSu z_k9wb;o`nK9Y!o!maVgC*tqyg_l8S4yyitfrTX5zYZFjq-YRxgzKpFJZF39qYUJFyxAQ5xbu|WSX|6jit1*AH$`@AXQ#*j$`aT6N8vrQ(Cvl{|fm+78CesseWQU&@ zh)Fny1cN^|tZ(P&X@Gyq>NRIik23wt>hLKnxyUA7+!f!gT@nVO!cu~`ls2~`=3Qhg zh2A0CWP(pF9!hugFm*cE_$~}66Eke?Gx;Y9lRV}S%>?ydOZW+o$dN=h{9a6s3-13V z%p{wSyPW8Yxp#AtH1?sv;-Q>#&lS#V-l@Gda2xMc(lX>QtCJ8u%ry46JGwk_aUN0E z5Xph>1>U$~7dYrOwD}6o@G3g2i}Brx$1_A&L-2a^`rXk)3-+b>ry?hPu*M_F%Qvwv zC%{2dDwekgCb=TjO!nzLVA(45oW+FEdhO(i(DPem-_Wu1?2>(9usq5J=@FyKrtpsg zY-4jWGQ8Q&Gv{@AFURSY@uYM>(C0t~@LPq#M1_FsdDA?wvLxo1b!lBqeZ$nU_83ga z;r!O>&7|bQh2Qd?H~+@u`BtBB))lI8CktTU@`iCMX)LcL*i6xU!G*Tnt=?TJtTz#v zYj5SMqaoK|L)z9?e+dE-p&5i{`sJ@)Zzy}a7urvbLl*BY4#)9YA>ZR8&j2`nZB~h2 zmMjH#oVr`t$fjD$=xgnMX_v5>kd4Bt1$j*`{+<=>$#_4&7vX6ub|pd(1Alb>4|{JN z7S;DPiVq^9qzXuf3eq6mVIbW|45f7EP(zD=lF~|wFm#A8^bjH--QAr-cg);_@qWJF z_xHQ^dGGJJ&;9-Lp65aLnRE8uYpuO%@4ePOPSZ##543ZIf2p$A0tZ#MP+(lHgS(A% zjjqS`ocg;afr4dxrXHTo9w0J;|Jcoqw60dnccZ;?QU*2}o`PU3t^l_AYL9Ie`tp%# zv(CKCN4+I^2Q20`_A4p8%8{W~*#fDJToSu)RtN97ABnpZJrbjUQ1h6l)Vn2j_?tPe zX3Q`rLhDP$POKN*B95mI&khz{$rzb@L{4k6+D8q14~Qa>)Dp*l=h*F;?q)Hum#W!) z&Nk*Dvaou%=^!Fsy-uDnTmlFer_y+^v-G1@@9jYmcU9kb&ZeUZw8Z@Sbr2}xKJz`0 zUz)s|N>w_sHPvN%nU?^#2QJypUYN$H%%FRtMX~#_h3JwU3A_X2)@EbR@a8WMkIGSWVZ? zaS1gY;f=s0E~KF7!o6a3`9%By!}d0@@y-Z4^QwosEHRg{HP9uZV`1s;!CPq}lNnrv z-d?)w3@<6*D3+$+=}a)PzScKB(%S=W$Yj@9IHUG5r>vpWL@=)Z>tW-3?SdOJ^PcuP zU#c*1t#c{!wvg!8sV9Z8#!Jy)_!Ero!36AL3J+P|)&b@CAdLuL)uS@v@1oV&O+ZrZ z8&niCBf_)Ohi|<#?Lf7O$gMv(ON^x^mb7m3;B2Flqes!p!yHxbQ+KfzUiJP3a(4p> zM5vry4s@-s7KWE;nq4RqqwL;4#!fM263@|4DH`dCO?8j_>&lp3BzbKw5jpp?Ryu?r#iX7&1Xph!pqzC2ExQ~-9CmQy%guteDx+5s>n!Wz|ulbzZn6ZqdDc|Ighb; zG-J4Yc+`UL_awaR0HPKcPfwWnEX?xzmB;VI^0rI4@SYZ< zF5K61eGPSoHnboj$eVb&Sn6S>^?mMp-Xn1s>3B4|uboSRzuf!G*Jbv3vaO-=SYtrnnus!HMqfwnRDGg# zR90x$XjII2!%zAN^3KxWBG+@$=4?eK>6MMSXCkH!WG_(ghrwUMc99x)D!zS)HZn(V zZ5dsMRS-UEF0zIDdQ}}xEripi+KYRamX^b7N+-IgS3Vj;r;YjWN{!81(FZ5a-bWSd z1RVDx%NuxJ)S9Od+z^B5T}vJ$doj%)z8(nq*f~3RD|2oWvq=XMfvIc(r_iMM>g6Ghk4n)fY>tC! zSm%+BS#or)5LwQ-metBTh3*;hU{ynpkXg2tIkFiWJbSCgH9q~7LaC5C^(0F0@m9f0>2*oM^S!x*F#gO1oScLFu@tYn(%T;+ z!eUxof*Tu!PIET5^^Ys{MIi3-YBm?IG7M5ua|{hr&-S{%&&=r8x_DUG7auq6cS(q8 zp8}Eg8;3_q2GiB_9}o#opzb&=lLun!n_UYB_+(<~=CrKcJ8j0nmqe|}nCgojEf>?W zh_$!(?G)<8P4|`7xf!+Oim2F*T_D+cFyeu+?v<~G$-={_j_*Wvmg5|G7Ea##XdJ&) zmq0NgO5N=EC4wDaPv3vIFLg@DC?&EG>Oea{N635LK8vkn$F(9Mw@sB47xnrA;&9~b zV$>tt{juoMAlX>Z+gI161@OOfkMQQYELtT>ic@Ug2wF?JfG0&Bm5I2X_XrxtCx1K{ zH7l(aoT~NoUfz}fU(63*TqrCcq36YfBlXa-vy-8tv!iLd8ePpvp9<~SsVtPE&p5;4 z*aFNMF()hHew4cy8!2cxDzRSM{N$WLJ`&G~{GF;{VR^Z$2ofHkaRvWyZx;|XlMm{2X|YydNf?F@fF}l2)m%H(jZj7g^7Sv=Aj-rfboLD4aF!q^BP!q#SfQ4z3x3 zQ<=XDeY*sKc0#Y18U#W!Lu%q&vvu<|&9W)9?lDT#iJvb8?BmJ!puegENThkxbadpzE|u+DSHCxVI^1qnqhW|T)h1FEH8Bg4S^!0CL(SNpPw(4H1CZU?Wa zYH);)bGqPxF4$KOM=-XPl=%dm4KnkINoNkwckf3?Z|= zIV0ri@A8DLA3n%bz&D2Gxmx<{wE*D|;MAm#p9-WkgwA3nYErU+NFC7`uM4QTsdL5D zRy?>l9NeCzpKLu@ExJF}Rn=qPJyj*lL&*i4r*jnc`5^LG3w_em9?4lz4oV zj7$T$46q^u;O1z$*7I$6{@}S-(M5eF4|)k1STkbINC^i3+)f2P>Df3g5IJH1d~LiM z0cDpF0;*6?8MGU19zo$&rjD-j85=zH=MHlM70bn(%FTo53uLzz;RqVY^g`_eqw4w` z;|`vN$q%Pw3n@=e=IZ1myU9x4!@k2YWxLL)I&N=E@i-{5xF>a?r%-ccuA|VNrg#SM z384u1#MTzlMFb&NYLJp-rDu>_>210UBpJFDb?fOS7evwz+HFC6+{<@^&+~yuLF8Hz zatdLW!66Lb1?rYlV*~!X2;ay&cq@l6NU<1>H%p?`PdeRe3REuYVejN0sThwmu=hQ7 zUzpzSGPkb~C_kECSzt7!1~trt5#P*&t>lM8U7+7wy)D;Elbj8wbt+vv@>Giv+Lo6) zUJHQVE>Sn>gBZ6$x@<5r4?j4h;sioM)W$b9HN?jITLqTuD#g%%$KT;hB<*`L1m0*( z&;`P+3+%SakLLsX?y~j~0CWy@?#d610X8BzyOe<~%OK9NF{G%WrT4!3Wqz==gy@7< zX&rD@ePTGctPNe60=S1D4(_W-5@@G_tuStKLlYYJ-ptmg+QZgzePP2AHlB~G?m4xU z0ff$okJX}W_PbtKn^#P%Wf2F*-gvkH0--b^HI`jxA7{)TZOA)!=_Z(qU%ooZ*eETH z35ORR9rpl99^ZCP4v$)nrnd~*bqb^&(_usrJ-4YEK}wx}v>A?Heq^Wr>Fi?p0>~5F zHb@eqkSrIOf_DKr&LDp(ynLvOmGt?B)v&cX5qz!ftkdM-wE4#!ijvjR3K0OIlcU|1 zfCOD2_$W!l6A>$|n?HogI3@-#s{Bmfd=22unQyVg6UY|YM~v(8r2u)~+R9x4pXy?Df|9 zR^QoeSU0OtD;%`WYjzINaIZ|D0p=t5>O|r4`&|=SX5v-ip2y>zhfBF_W`$$!2?s+* z25z1e`>q+6J4?d|b4o%(yLzy-?H1%ncx@n-;|2g~x6*I^VyAq>p}=cZsvh1vwhTLc ze}XV5EV75E6>eU|AC|=Jy?T^%2vvH!cG*9H2db66b1U<#c&Pp0xwlVN36PIh|9}Mu zNv$)O@!o@;FM;!iw)i*TW*HQB-pKelLNB#T62IkG^TfcL$KC^M0;t2OI$>{sA%E6wVzz__pXi*V>P&bw&KWpV`Qr^MiRil60m&3O{q*PH+O4-<8kViJ7 znEv!S=2MJrm_a`OdakN|qV;s0@Rhy+3*D(<(t_6YVf^_FfiRwR_ltAJjG0ww~|N5 zWlx0qW-(HXBrr*|T3sg!7o1SgDKsyygCBdDuC#3cTirElh3l3&0bs>n z(OB@2NyCCT^Z+E(!URZ8&KuWFHEkAz~wOaw}Y#@+3zubpt-th2>d;eS7pG0;41&3 z#P2&0Y3fzH#@~xW^p~dkbF1h6zv?h0k@#GKHEx=-=KbI5AkgD!X4w+-2Kul#&S0;@ zj^UptVNuaWjON0~6#0QEG^%+i19*>LCM1sZ3bo%?L$L-zNQg_Qbi{5cb2KB)2;Jjb zsF@!JE(GVIzER@*eGdd;%oSjy=vqS@9rZ6x`=Yz{&?jB6q=f7aLs;f0dI^1kUJri{ zb^fMVthMi}%6&Bizb`+-aG$vmaK@O0LYXW7J&Ho~?h*{Wd%EWj)I*|Cmr6Ag`Fud- zXyS=~qhYZW+@v`R=PMj)ZH*j;y+Ba3(3;0V`_ z?{AMFP*{$pGuY+~0Zy?vu+vXPAyWc5?R)eMK5n9)7mu9#qLCi?Q)5#bF6t~c@VjVM z#(x9Xs$SEkKSztBOWDW4lEtS>k?%~RcjGX%ZVX_gl-Dda#c0ld`ntf;kVY#PYJRdA zG|QqGAUb@3Kx;8GA0>=(|MQZ&{r}Ib^M9RJ|GUG#qyK+Q{QsMz|4q_g6!_n<8UM{R z|L2%yr-R8*rPUsRqRn5DK!2gc0_|99Qs0mt%2dnO^c};$2J$l``D4y6u2oL~bA#-m zEt{=PJ7k&LM2Z|d9_1+)eb~$gcpVJ*<^7?)8}Ri`6K7Yb5%ddJUqLJS5+(pFc=?e0 zu@*bH7TYc(6|RQGw)NU$?`8zbT|MDY28Iq-sJ@{dCWuP2P}7>(VErX4BKLhu|KuPX z_Q_hlG}JjJrt6Fo;R3ip`E{+1$^}76@nRPcGehwA`TKZMm-2=EYOpIweDU zaF@e`DRBUg@XOVl@z9y1uJ_A}i(B2pL#OY3FAmlve4H-F`#U*n0s-o=UhOjg7eKw3 z5z2b>(b#sqZ{3vbFlAQ?vTI7SW}wi86)soI!f+2X>!)$QTr1yoV`%z^iL(_n3o!vs z-n<+zA3>cCP>v*+`~GM80UpK4WkruK`f|Su0Y;43*xFWrQ(P^Q^ znLy-N-plGkXtvH&QnHPLqB7h~w_^YeoIdh>vOH?#^~cIa-D69gZ<`9yPV=3En#g1H zHC>TU3XdXePd~WmlG?wiJemQ?s(&N+VGRzRVf@w^MfbUHDwc9Ug7?5&dD+LK_HmEg z)vQ4Bjmp)Ez=xP8j$~3|5(jU3H?W?NE%Az7zUbr?1>9Q6y|Q7G!*0Q0mo9F+R&J^Z zUi_}!LrM;+t-Tg`7n3x?zDQU`8;OAP9msrTt8=U}T z&l10UFLor>&Qfigh>82I(Hut_VLJ_3b2#3l5kSKocQ#s3mW;f%jQGvabn3Tnuhyix zPsl>}Fr~NgpOuuFo{udEJ^eKSx}ARIgwu_zVM)WgyH%afzoO>K)U90?c!?=*I8seP z)_})$q4Y%gS3NFLTjwPkCbNluEM`+oV8L3+k`Jy~`L1HaS$6UB!4=$(t;j;)c)k#r z_V4zEes%7rhnSj}EJlnAjfq-N35fO(Dz**{%9T8!;(7(lkyi)G^e95`o9J-fypJyB zeR;9fxEKR#(^;O~9nrrRg8xACigbbt3vwkdB$=)_vGUq)xZSk3FRDBa&L;>x8TB~_ z@dgGVVhN!`+$DG)0i1)PVMfktv0lW|{sQ{kX+>SAGX7Ft^}4n1b6fYXp#5;?cQX%v z0V`>@oq0I15#VdPNy|4xQIbA``<*Tu6=@dK0dz@g8BmYcRK_N9^WqEnWv%$Rjkldk z9kkT6N&op3Omu%5dGQ$fZb#UNL9Fe z|NF$Sa3lRtwhqXCpkPG!*Zs}iNr}|XVs?c|$Sud?+gEu1eD|9#e#1Iz%v4VFsoK&b zrF;bc%}+ezhe}UN6j}g{WUnWTU2IuW6qrRLT)wruFAIDqo9SL!_*HGmKTw6;yjnH^ zu@Ik6Y!ITo;9AE{ZjZ_Bf3%s1vI0;2>PCrNp1^Fkh0m8R_FSH zo;xAU=D(Qp-^td{9J6a+fqg$_7ihWN0j520lPV+Otx*aS-u{b&fwRpS+MeQWE&J-Q zO3z>2oBX2JU%VVVnBv>q0p0SWRi!|Q>7F6p)tLDGft380)PO#QVFQESV!<@b@AVY; z+B;b=CJ6NJ?KGHNi6-C8W+STqehT`(M2&?c?%^>qMaqTlU9ILz2~ySiG0?2@FSZ47 z|56B`$K-^-Dgpk}5;E+Txsw+^9I2YCnAFnhcQV7`V=6+jRv@RDmd}mt17s3K$PJ*PBwL6iEwrRfhhT=6+bFF=K@#otk|4$JZGTl@@^^g$p`35%5_Sz_)+ zkX&vV7f3~D{dOVwWN4!#6=L+;mC91z`5|2&&UbH^s>gOX{D}V- z+_SF7PE2xWahoin-J)?bv=uPi*YBS=@=;a3 z{oaV|FGJb*YfszcO5Pgz>-zmC7MlDR$$Fso8bWiptOp*PP_6B8-R0Y*mdNdK2(EtM zm-LkB-a>;Q)$x#GppjHQWvz$>dd2(l)XaP1>%iW%X9Eh)%-ICQ-B^h!8T8dhc$<20 z%DL2CXgU{ZyYFe5;Yy8kPCzp#YsaiFtA^ZbX2flepidy`tmD@NgZ~pGUbbzqMpV*P zSzeHoRAtMy1-3(zqus15x&iV_AJv}tmm3Kx1BaBX)8^`od=_t1*JRhKvu3K)&o-j@ z<60E6c8WJbECao8hpx>&{mTTVgv~*!o2OAL!FxIe`HsV;#)XX*UA(*_+R)shQaMeT2xjQTy3L{l|<>Ia~b#hQ*|7|#%^g< zFU2hNuiLyXS|1OngY>Uo?iTHy*HENu&zApkC;xgRfT#()T2y0edbZ&#aIttccYS@w zmq9#!H9{$Z06eEhH0c%StN5wr3;)GAW$q`>hcq4?{jMkI|InQP=)-$6o7s_h_HEW{ z2g?k(qf8-}kE89CVhe`G<`-c7O=I6p+R8ikDcvr2x(qfVyUsdNmQk`5OIS}n+u08s zPBzPT5E!S7AQpl!mwIS4@QT@r1U0MA%Q6FyJ<6t*0m`JQy(H3o9OztJH>W-trxljh z3hAS4E^(KGXW1E0GkVT^DNmQWorBkh!Et+fLyoq_l}oQPj=f4zHDKm)A-rZQM>U1Z zv#g%cgdi-G{FJ3TmO%BfvYW$LUulK7gUD~k?LVA=$YOfLg`C!8nL?Lrs>eFG+EVXp zt$Hl}YfwNCnN1r*CaBdb?#U zZF?g)JoQ4vmVz{x9$-DZa%UojjX8zgnx+1j=Kei}I&fJxzJ;kto%i6_sAb)_tsQN- za$;SWO_MgqGme|hk4hByUdaUEYju&qlnHywdVIe;1+!o7wk?&auQf3pEV@a8^K$An z*H-!S=)b|n*_bePhTnoo{Lm+Nfs8u3N5dWTz7qKRLB{Qlb#nAA;5;zQA@Je+FCld+$q=1Gs%dGEF&Y*N~igI>|;Ig3qHrT}lMXK0V~ zU)61Rs~L)(E5UJLCUeLLi#uitv%OUo$O$*2TX}HgA zWE#}|SeLS=iv*6vH59EipqUWoB+sY`kLK3;+(1B>Sg z*^gXY-uc+QEGK+$Izt#9EFl?P>xGV)Q+yFcd7c{CPr8M{qX&w-5i13t{+7_z4qL2NP*m;4L@6d`xP(JNly5gx&5s9^S>l_mr~;AdoJ+1bV0{H%!txsHKT zr$*jzRC)%Jo$E8^A;7syLJSYTUMYhuyTl0XO$au-+Z91Ah0&J*dxWf}LdAVu;3*ZW z^X78s8|3T46@0alvAdwwg%Q5 zUb32IRaoV!ESt0$7&4*CG%sJnxV6Mel_lPpG?aS)&g;nJq&+gN-Q~xr%H}H1);ViC zW7~J@9_z|+YpUZ`GM(WQ1!=~$mNkU1)`doLk!9k=J8^A-qi^5oF@EwGj@-zG%&qB_ zM6U{IO)3uB&os`%4IdMWeA9BdyCz&oE1HBQF-PF2t`5AL~*CyR^miOe_#k) znMRvy^H$XpbMXrQc+Hm2$vRJ48j$}s69?vubvLSx0vUIMZ`{3pu3mh2OEumkCDg)~$ao(Ha zNtf-3JcS1RbyhKMeAwpf=Fui`hP@_N;%Nob_VBiYjXqiDRT@T( z*vKbDy@tJt-^;Q!h?P+Mc~h8LZ^|4c_|vFKt-{kTAK%Xkj6@T?UEK^&8X2 zle~))Bc>ku!7U!!UO?~GDh5_z#h2fR+>*00m?Ah%NBEB0GB{dUZWJYGxO1)^Js5iI zC@RY5!A{MM_b~V3jkOXn`~GmDZ>KK8&X({{EDp2koI-H2=3`8C`HaQCW0T;F@mieXcFy z|LidG<$QX|=av)wu7l^ao;|_WUBw`UQ;E2c)km&q^hmjeQlv{_T7cg*2|HWACsJd5 zkZikCUxJwOhljN9V}18(@a3thi*3;diJIt~IOaJ8S9b7th_0 zW@gK=sfF$i!*bv8g9(FK zY|GIH-KN^(_+)>bRV%%8ZMd~daSER5etaKcvv{hP13&S^eg-fH-6CoP4z(3vy#B%O`MtD!gr3ZRBeh{y% zY_RNAm*O=hX=4{$hK!}AK}Z>=*7Eefa+3MV6;dZdDMiA&n#xB)vsjNZPW$`Abi0$5 zUo~ov=_079hQ!A9o^^@Xo+68?k@9l$+SOF1z^sm5`V*UO%TMl71YL9oD>HhBi?qcd zmX2iyCY3R~8-}w}__Owyl`HqJ5xf)_3m|6%@Lz$(8+hq6>-J?=4`0}GDW#%lI zIxMp&YoGfItFTu1Pz(^E0jUs&WcphnCC?Lji3gO2|G5*+Pdr+1g?_UB&_o?oifiDljT+4eh0f}ovJu`$L=`fH-`y!m)`jPmh% zwW|Rc9hB0-&+;i{JlZ|vIh^HWX`q!E5ag(xGQ5r#p*JFf-VLzmwZnVwX#SrTy&{Y6 zhb%yzmVmzwFNZ4AYStMtb1E(2CWw9&XP6iPqX4Vt%fHc6K_McYV#moFUQ8Tv*fa_U zLdz~93GiC{d=i(N`zfoUpy!mDJ;y>vv_ZW=gYaV4Z@IKRF?nJroW{t#hC z_|&kyz0y+Vky7n>h1w=yMqZZFa>o0B^L;8bfVuOK(HAY$plrr5wD|Dc47ud0KCaIa z1RO1yR2Gxn11#r|IOrrhC1m67J*BYO&a45>88KuQlfe0YG63uI%LmqduNJtx0bSua zxO%x;hw2F*keCsOpfI=_f^eTDj})yk;Lp8Rco;a}V?9JmtJ%$dx_t_)+H`jmwscG_ zZ#mYaKBs?3-uq}fZ;^b@%1)+;S+9d>Is8+|L*oT$+`za`Z#G>&_9;k{w51P`w=IR? z-5eUgbfvIAp1^kL*$A{$jiFn^iu-_Ke3{PpUYp#vefBvA>!PtwKl{?qUN$XZ0+p(d z)p^eTb_E=eTvve)>t_>AOMP#uKRJAyicMd8Jr&b6y#-$aTcQW^;e$vICk8c{csKpT zZV3an_SSw4gLP-^%m~_c)6mU})AJToE?8WvZo=>*FG{0NR%0G0w5I`K1k zscdBRw2z8fzO0Y$=L;C< zS;LCZOGKc1Vtdn@0yD^p@`!4>Zl(^ z!QmoIU&l)aTO6Avgg4vmW_(v=3fr~L?#xAbR%AwG2EpF5NS!y9om-TgSQM2#UQ!@N z9>_iK-kmLDJsh*Zb}DO&X0WfYiaw*}*rm*udSh%^FyguHs_qhL*t8$8cyJ@#WLD|- z9+k;~?|XL{UK~?96K9B%>1*4olD&}?4i7)wW4fz?s3@lz7Y_~>4{)yr6!~zt_fH5)!nE<;rAPn>b=oyFr2Nxgr z76CpU{%t~nJNM{G?-3KT~}Y{su2vr+qdr#-D4poWziAg7SZ|NzR(SzJ2x?I5QJc2JOEw0gMoPm1N{R; z3&4nl@$0&R_v*s9hIt+92KLQcIJm$I@Y|qk7?_yXu47_hT?b;GF}#82pzC+A?%wBm za)U_qHTDBXVs8Ja^qau`TqB8E-wr*Gk<*)7IQK}&$SD{eF)}f;@bd8s2nq>5doJ}t zT1Hk*UE`&umbMPq*u>P#+``hz8RFvV=I#LvcpDfL{O)~7bWChqe8R_1iC;1@VOiNZ zxq078%i!e|l~vW>n|?I6wEk>s?;jW(8Xg%P8=sqBSX^3OSzTM--P=DnJUTu(J-fmS z1BCe-E#Tk(SG?{3cwM`G9rHT&65ymJh@SE&8M?7xQCoBvOk{Rd+I;581y!^8jv5AzO40(6kb^u-V7 z_4$07f`pgKb^GIR{$w=BeZcBHPPA}DX2=J+O2NRoxS#svYl+q8X@`UdMZ$|dr*-h= zkX6^Y>L^tyk{_-&r&z!2puA$%^mZ3DBhozBt8a%!f%~GvwmS2r+WDpBncw*qOq>j0 zP7wL2^L4HZlqxj2YUW8hvMEtjH59!!QgbbN>wqlmPEa3+pTngC`Rffv)hfMg;nG)1 z@I3liwaLo!11E36qFK@6h3ZihHF-PtqL~;mL9EvOVd7wad6_9D%#2=LE{ajRxX`)X z^KaG`2gPc^4Uzm6E$u6X#584^%h%naytDddQ9I2J;Dn}Ks=JdfW+bLD`Br%|x5(_I z=tLO`U9^)w>(r@7;0w>l4{{bQM3{UC5(6WeHsgb1a8}kN;Xq>U`zO@9l3VV_@4VRg zqob->xho8<*2F0dbsKS8+5Gi(FpAdChAB5RgQTuU`RfJN`-8_1l!=ohZAWkTiHQ7^ zLY6kA#kGR>IEhXSy!rQCs(FHh<`Gb~Rvh5e<1RvC9^WF#)@eUcdfoNUuh`I_6kAIJ zlIp?D#mdTQawsMczrN|}yWi}~0&OKWwy`4d#=>y^VZ)pM)5SeFdQ_{$(O|;T-}r7N zibjfY%+|T`c@4r*d97hhlBy!qi~U{(uHMsh{TB|bof4&olpf^95vl=Ug`V9`k39_K z!p6Zg3an``4Ckg-{l(iHQ4A5v9~amSisvHn8#BSdE_jpLmD&crwI%%=XF8_s$z3AYB8t2iQ5P%Iamy zG1-_f;+xB&hI92u3-FxJS(v|po(&%W%|ig1$autx5SeH(?1e2m;Ukise*ei`N_`29 zno1dM1(I$8WfD(=9au|Z30YK{o1WHJT-}$yz)^BfPq?(Y(W=l(Dp(veJTTGBm>dXQ z;7i-3>7SoJ#N$fPJ1Uma{t|krhIOXKdt1IUhwS{*Z_Pe)`mmy5`Lv)5PkPvD&^Gk>kHSKhCp!J9RSZUQ7R=W9&qZOd2@ec2eL;gX{C#4p9;O~( zEYdLUl#Sa?+xDesuY|PlSEuX49sysjJ9Y~puOFc^-c~rLPP^DOZ1NiyQh0XjY|4Z21+#~$gE=?y!trCdn8O(56sZv=dQ<==rAU*#`1TPrO{HuL7 zk&gysJ6&}#HuO=LGEG8!y=iu_ccHGCpPwj2ZmU~lVPhsGSc^CkK zw7@(&sB^{^EfUh*^A^way*_>om|Hbf&lAqpnj4FdK`^cQA!a^pUM2M5n6$-Kl3yvIV}CLF7S9mPjvbGdjj5ld={ai z6Dmkn+jSx|s917kQUx0{%`ynbI5K2N=v)viifo#ul_%NXa(q}XdQ=!?YL?B4^G0Mo ztA`9J*$!P#=*yC6WpF2HyO1bPonCh4j=P?0R^x<;_qhE`jZIY=;Mg>)>tc1g1(!}( z39=vG-cYQiIfT9eUif+NnSi#zwG{VL*SdL3g^L?|W5b%F_LoRNLd6HmFz}Jd0>eE- zIg?F=4*N*}cRYT}o3mUq>)4-kMMVT=nxiBYrhC5HAoiG7ydh86e6<9jyEmIwPt}iz zi~aF(slOyn5;cZnKBx^wY8GEhsR_bz7{T|R(~aK?kSp?mPX|QAj?umGJzS+a54r9@ zyOX%?S$gDpk*6!de4*}Ip(Ue|-orO>`KA@+&bXu|O{{_^=`S9O_dxm4^|z2GAz-E~ zx}0J<()dU_=;LO2Nr1-*u9;Nrgm+MCcLa+C3ZRJem0f+hXX4!Uo?J(RHhP7QiF>|k zqd`5_FLKBmrk;4udkR!~_r;#q>{}aaWtG z{m`G0X#AVVwZDj5bNZK9ufCP4#|1v28N_SZIS%e`_UUtePkp)qhu{#WWa8Jwep;Z; zWxCVg-qOEtZb$p={+&g;W;Y5i*?VaOgE$i}tkm&1oFCk<2fID-@Asqn%+=(?+EZ(6 z>3CT|IClHpo`6x!nPm{EP!y&>AxJ9wN0j9bQnIkjEIZ?K!elZL4Mu?$wiZNB(tQO-et|f9Sn}=CNc0<1k zBZ$lddd1kCGQ{U9_Y;mBW+Z7a`D6u@7-H1UvaWx0&jy1iRcV&cPbz@ep+|K^f z)xriDmP_7DcUJP}FO^3B$Uk2SVkN}x`7wDo@d4iiCFKLBS5JN7=pCg%KW-AON&YAU z6aZfY@09}3BMoP_do=Re{X^V!XML1q7Mb4ibG+%Yo3;@zl5X0iOOZNwf9pf`V6?C( z1z^H{=`Y8Lo;h1(+vCWuca+5rGi8N%UA~4BLkwga&9sw4JSXJsVi?vlx zhC*%!$(mk*AA9zjEoW|$D;4lt!ZZJ{R3_#GR`*<7k@XKScIu4HZ-u5$&8b>;IU@(! zAKLZFwh>LcAJNSdlGr`H-%R?{Gpr>9N`VXyj}m%(pK(0%w-)neA_MC-Ti=zY@Y8se zIO}C??Z{t&`y(*+PM6zh*2gQQ%meMc9}g-@!bwe+l9vWpE94abCrC)rIA~ET&AlC9 zMytQfcrfsX1ttH5ztY@5wPl{peL??_gQ(Scjxyd_gM2jSCFzh+4mZ3)E~5}}BS6mM{e*h%SkQQSe;eF1 zS;0iSDh@pqdA)dw=L(pdbQenHse>HFKZNv8#vde|W-9fVftZTCtPhTl8I$LAW+r2d z(f{@g@0pDZiLwgwbJZ8l6j+S?enQ(sCtikaM?gl_BF;){D4bQ}T)5$f^j<*7f#{;G z-4mor(l6dqhJze(=L_XdLXB~mV%|7vpQQyCv-1fuo~Ak5@vT2??*hJ*`GlH)PiR9b5~NvGe8+;; z!X8MH4ojYOD~d?S83$b4U#tfEht+UAVfqL@ zP);LXqxEMx~}smV?lnttPUg*^@S$&zJh%56QrdWpHwXT z-gn>hx|VbHn`#r5siz?xLF5D`l3g20tB-|MFr|c{*V7{DD6%3f38i~9JZG@ zeqr6SauUquEPS1wxtUIkw!`Wv3_6mC27PZyIuEM$#W@Lt_f7n#HeGVuuEt z_KIRTC<|ck7oCmgjeM|0*0~2N~3`bec8Fb5RPFh{B_?@W2u+!VGG?v>T*ImSQ)ks)} zYxhw^V(KXGiM>KJh~VVi%#wY*>y-azf-q+}jgX+T*Y>6i-<^m}v;<)8)vWN3at*>J z7?RWmEeCmty{3ID6HQn}EWTvxvOI77LogegU)JsVz{FysMDa+1ZZ%_adWlC{+S`e? zuwjTu#mwSMZJqL%whTt z4Z5{{lbZcB29nMKY`bq}mB z3U~G<%B?eI_iBr+KrH27n|a@Va=&lY^>Vm=5ntlG3}cz%UbsuqbT{52NEtf)XMFm- z#OMtty%pWIesC@OC*Ry5X%wBL?T+TF-GTMD#?ae%@XY|DmQnPKs`~lXD*2m53Q%JA z5#@wSG(Xn6MU6SxBHX#nepz3Kh{YVnYvr|4^E{a|tsq*jUTi5T?xBlwnPt>YmrMpD z@y%;7{dv~Uiz0;#fRpRp1Af?M&Pdx~PYV_*K7HmmHxhH+x9lgx8NAoUa51mN#tj|$ z%zd|&WO*7N@uo#LA*#VE8K=Z?fm%jsUXbjwD3uCN9g9{Wo3FbT&)oK1%6YZ(WBXBx z_1j*J!Bb*@ZS)aJv^e~D-A=>AQNQ30-*6z6$LS}o#Cb0_H0XYg_?H@)m2=ME{?`|G zmi=SP#0V5w%%c{k$Hd~9&8Gl+E9%jM@7G`_a!dgymD zt96Gn41S;W=B$z5j-w=vpGGlQZuvrN{+XAYp%3yLQ=gg2juvw8`TCa-W`8Xm28c)d zj_U~J4oWApK3Q%lNEy5dFFwUoMj;*32FGH`+QX zsY%HDAvmvW@94z{DysI6`u`*T9GPAS&F7YC+ zjz-tD3j~3v?M!CV9psG%Zr;1M*ospns&pu8Z~mAsy7^rLp~t4});^%>5V= z6`wk?#*>R#9ag;SI*JiCBxL_dhp8b>JG(A`<)N2&!)^QTlB4B2ZqjAvK$6arP(z5L zrRo0mY}9y#%c~XHk5b1+yLu7_ea_WR%W#~d6YGjqjS>sr^j&U5{c zB!unHv>6MX*&ZO{EZSaDFX=cRwaNp)O19YDH!n0%2pH+2NIK;*yV>X=aY;~$j&QF+ zJXFsQ?N6~wE|`_=uObH||1mRYbSbxfiXllE5_BJ9@4V8RlMPEN-So;59dMH-!lGy7 zwKCb{U5df92B9Cv!*KC-xvDmYGWRaS*;cxL4RzFk&?Sd3XktP#ce1{XCww{x`yC}K z{0*fU1qW_+aD*h_&rZXomU#&2I<6Ibop$YtR?<=?A%;-Q9yKLvY1eaM_0;-`d|B?r z8_VrL&1kSM30&$N;SJqfKMtAviCFV^oq7c#SItEuK_fwFrSl<7tK5O(Ha*FOt0zAU zFL$v=Vg)sz__EYm0UgHZ`Jll_atMSG=za5WM9DOW>|I4vdD>JR{*Lv+21f)bLB>yzQR!$Z~1lS30 z%9-`n0_#0&bs16Hi;zH{)(|yyinQlkovrSVST-*?P{lRiPDmh0q7l)3+NCD#;`^bF z|2Z@KlOg`QpOl=(B~}G0dV!xrfA(R@_a(-9WM%5;Dp5fGy!1&YD1L&X1Dq|e)}eIa zs4dw*)gW%bV@|pcW1Fa@d8CSWXIK!`oQrZdf092-FxS$ySv3@vkY&w^z*Xn%k$U2s zQ1_bprj4xl!$C?(Zc7@hyvbYr>Fg*a)$O)+jl88i*N|8Ubk%&zz$ZvvPejsHe z(cO35_Ij6+L#xVgOSM3}{}!1?27)(snLsce!M(R^3G&s9FJ$kO%jmM??~z55@8sD? z6q=?uQN-}SsZC~GSE4Y?mRF)cr~En?T4Up-BmetZ|No1d#Q*=9|8}1+%L{)&n4f<5 zUWijiU7O4_F1l`-do4>n{}W{)Sxx^n&4HW__iaWuRr{_&wS&7jLny){{{7Q{iLF9~ z0~eS~W#DxJlHp9@y1xzok5l~qiJ@=0pbRcoQ^$l4onQ~$7COjgcTo!_5?|)!z;p5J zX^E1$ejKrL2Wy)u$|#i;h)a)gE~tv8ilq219S$-2UvN)9IFL)_JZAQm+ujJ2g!FA* zuD>T|U3@a#*~p6Wv4YZ?9xkk_3Mnx%ZA?3uh*KxjT034S zUAlN_nKx+D^J~@M)wYyn9A&Ssl?CgyrrzqN3?D*nuh6n5i4|hjh8*I+Wv)!7A1G~& zrSm3j7ZNTyN?%#I*4U1v`lrPj-p5 zZS{>==wrf0%+iVVq%3d;?6@4bZ%^LpgENlr;*1@ae>=s-$RU4JIqBvSw&Ob^BxU=t z%r8jH(rI?h7M7|aQH(l{?|u-p_(O`tqt%xHtlIKU{nR14@JQUHWW|-xeQq{#y5>Y= zwV&C6bR$>|NszSK!kwi_S4r{-&iniz5GEoXUmJeQIE6NE2DTe-8pQm9Hx>`4=DQGA z|ILs%D2K8p#1y^5x;Nzw%JN^{?VFEQ#`w6wa~$YzlyYtp82X`(R3=5Lw+$)_9F*iJgv{juZ(rB3<@zZ@NFaj{5Zqhi*Q2CF+Bd z0LP#!H+q;8N^8Ta{h`#hG6wPsl4;em7n2g~mbCs7;wnJ_NiaIMrLtRPkE0l^PrEQB ztT4w%O()EKx3I6vz^a^Jnmyw9hrp~Pfm!XGnuiFq?4sZY1T%7*z;&D}ihs~$-7Q9zxE>_(2MPAq_hl>>NJ>JixVXZ1; zgm_j8Ng;ObU3bORR^KjU0Q=-fnu{b^x%mqcYrwRIC}EnQw9@?jk7A|?3cT$P;9a@k zT|cf!`Cm={dCxp7`WIwY6nDVL!tED?weaLU(k}JD`bL2Mt+?jZTMtwVbtAM(5Tc3% z7jfAU(~kfkv4&fPIy^l@l32GS5mYCSnybu3#&VyM4<+kg8Ln;-O!_t$Edo-l?XA0+ zk@;8bQ_sX(9Gz@K>3hPDWv?*7N=`;OB`kM2Lv}TiTgCRdR9>`cddT@WNk1M*x;h>9 za)v-V3zHs=73kh1s2(~F$^oZ(8hJ;Gj|m$2Z36V4QXki>WcEtSmRD8Pv_x@AIDaL5S}GbR zJL-JnkxnNjT+((H^MiXCYh;R%=+sr;GM&NpblzZCj_y-IXtaK--?niFU;JZEntVq3 zjje`shpLtW<__GX`BT>PYdVNqG`Ahf#{~yw%A!Ss!gb+p(C*U}^|G|@Gh`Ww^kkAo zm)QFbH1x?6`JScm2+mmCq(4dhz|%H>Dq{%L4^{~(4`s;1SgKeXN@McYP4wvIjoRS4 zO#5VdW&hsOHdsx+^=OVFU35e+2r{o=W zaP`Qf5@>KnZSs#qZMTyzNs0L|h**q(+;=1i|8Ul(b4I(bLHHJLWkugAOAwm?8zpr& zZ)d5d?Sg83`j6rlpBRHHw4+3UaktkzG6;3?iEmzBcDd?C6Yk9Hrt-vde&A{Oqhcc4 zs+tc}j^2iaxWl6h)JsP73?^fW((lKVb;|wvF>_jsk5|>H+x1jLdk>77JMY=NH=ov= zVP=F8wx@5=K3?Xn?pKpEpgCPc;u6xajzM4jG{Ty>vuAM^!%@0OwS#go?qt)_cjm(( zQR6NJ#z?cPQz>?(bV7`1+o*K?)q$AqTWr#Z<%M66IHS{HBi@buxet}?^huCaWdFO# z5H^9=JlEL`ss6=00gX^39T;WaDl|H2j%4efpj5AXroR?^d zAEI2Smj*ulnMoJgwN7y0%l9tPEJdx>2CK^h|DG+qPy_sgM@Aq%OFn%KkrqUc8(nZO z{#MY;&9+RNA%{$JMgC+0<;f!5IJE+mOAeQ6a`~tpn|n78-%C856i(F9rXX4m!t)kv zU|8vqcKqP-byDoj=MiN$i}DYi#PzQvyb0!fP}drW_;>L~T*hyw*uo_bf(wWZQEeQ=<(da*LcBH|_FP+X?5FHnX}7x=MU;$`V3 z;vyhR($}Zvf-ZD*b2#8Yr3b$bCctEB+E|qMB$z!4<;pjsb0{<2-VrH8Vj-UU4C&*_ z*|~g-B~5hj=g51)XTl+E`TN zDB`er(r<3myncw+vnztJNc#5`UN<^YNQO6c^K#H${9cWIaeNBNZm%F-O>zjuw>4zt z#~V|1O3V`E)8DneKI&$+E{UA35Fx!3P$)OTR4r3sq`1c`Gc0f=p!E)HoW?>esEn1* z&kfoYl)v<2%FvU~@AlUL_SoS=aGWgp)4AOtuRfBOHR_5S>jGNBPzHZ^`;@=HtWrmz z#71}cNOl1muhT96ILp@saFM4C)O0Y!fxqg2vurk8DqLhm^^NgoE@P5RBaE4YU z&SF~(QcquSa3M+1!>@niiki*sz97FzD<`EBDmW0=rMa?4CWU4AWM?^m)Ar2J+v@JH-R3LSS9D(VdBHmKm*RQCAxJ&>$g{CR8=2lw2DS zmtsr>sOGRBUP#Q8bboz^&iz)1?|KZ5rw?S8@|$7+NqWYOzDgpt4#u)}{~PYa$3lhd zzS9N~T_07LR-m7wVEO}|7P@pWLQj`w$|XOxk+LT+M#Du_o|F+ z5hs(#K2Wi8Qi{so4Yvjln)mr&P*vt5+dU!Cu3omW*Eh}k%C<5xd)luT(`T>GLDZQ2 z1_wp3rkA8li_lVRrZeFM8j95i63H5=-{o0+MBDsj6HPqn;N2z|(mJ^Qc#2igkaf$4 zGxv@j72pmB`j&!B-^p*8EZiHYJQ0QPUKj2AwbN@fGnf?>1tjZL{b3i!831t!ict{2*#G(V z51y!m5^b&-#BzaC3pxCPM{myOwQj%N>$l=0=nP2J5sLBJ?m;?fWs7fm?toe)nXVF- zo}Uh;uGY8l=OYlVjG!(Eg??@M4jQV4a8T%lu-kzDMdL{IW_lQU&`BdC5w3AidmElpJmSt2EDH-#9XN>7L^k9Y_U2(ZB7G1g;wWONk zkclm1ISQS+;);4`fDFY5Q|v1$3&6BcKIFfs`C7{@X*9$?-y?ii7Xk64c&$c50bp!_ ziwN(;fe=t5!?H*e|OG<-{5Y%Ggu;W^`a)n_soE)x<#zJ z2>oqFE*_<`_l`fm@1hPBJKJC|T{JKYaRQ&dq;|Gnc%O4?Ql^xIq+arqu(-B(wi*q2 z6JLIiLRQv!Ed9*EnO}Mk6bv0OMoaM87N%58ZM+4{=@q8JR}ha|*g+jkKls7}IZ}>9 zjaMxwGi-p}&LiSt6D6|Gzee{aCIW!W0F!(U89{S$&tCMPiilqJ^D0IuB1B(17{pKV=Upy za|Us(-sL>)T46F?2uJ|f?z7eQYTL=~J@W`_H zC1)S@0%#(Acja)1?OKpCdqRpiqn6)S3&lpG%ZWl-{P<~} zir}epWq|_HOHhS6huXkTOkr$`Zr6-g44|g0)2TOO6q6w+m8scy4R^Qs;@kKuP=;2D1!_kp z0Rr@Qb%0{u^K#zrYoO3vE`QUiSB-{zQ$f5m19Gg#(N018V`C4gKdl;?)%) z{4v}kbRyXFf{Z$0fV6*gDV38 zz6_K_tghyP6;n@GQ3Kv1d2Y>M(|ei_!1=V?2t(OWJjCwYZ?sg1E?1F;^?l-)J*zeM zVO3|G(cB&2XQ@RQTId~I;Mh$ST=r|*wmgEa-rS^`swSm z(9E4|v}2yn3?`s7cFdKn;*Py=W@)bnD~M^)p`qi9OK=_8v!ClQdPytJqxj8Ie%$Xh0K)f9ThXRs`6SWyTMJ zY7ckmTUU1|qwh@KtfnKj5sMlP<>=B#K)yroe2I547Z3a$iT4`!XU-Tyo_{lj zaQx_96&>-TFt7O=r5p^d(WN?L5QZ|t-SjyTyS#l@BLP1Sd%Ad6o7B?OQAc}Qc7Dtr z>kEJ283c3dlmBlFuev77cB2z28+a}2!6`<08sYHg4ugy6<9cG9_75EBxNMQRSwyOt8^|eSl(1Mf4MQs& zT{`Dks^2b2ZaYd!ZxrHCjwUUyO&;AUO&o5xgV-LOWu&Tt-CA;+Sb@@v(|s{B{W|Mw z(~~&6ZJB@3myC}sBhrv6R75vNWe@55(zfE;>^%G~u(KAf+v&peTGBWx-fkv)TIq9rvPF>ON^Z_z z6g0@R`mv_a4_%+OB8^h2|0cWRAEZkBT~K?^9P1>`5Hh?i4lzn4y}WGrbk8#=JZ27; zVrSDb%TK8|v>25eJJ0B7NCCakYTMdWD@9x5{YlnT<`~{I47=jh# z%O*%7KT%E^F-+2#OxCA-4v`1h{%Vo=+MGQo4iYuB>!dpOB!1QswtQkxHCFq$?~IP- zAP1VmpHaC9r&rYnd>IwRU$lV|ZCg$tNxEYX8wN8y!N-lgVz;;I(*`_`U%#VMb&=M8 zz)|_xKIb)RdSsAJ;xbn(<{NATBq5Z9n=9ibqPpidDwqyYBuaV$h@A}p&vv?_v2=-N zs}&ZrLHTaO>YOy#M>BqX0SlRnx^r|Ze{_dLP!BLr5MC+0Y&|AJjX#TSEOd)5iaqn) z+w2aEw5{r)Si}N6;+yof{y|zB^*QbyA8cO{gtuWJZKqJ$khG|w6 zg{#otZ&dbK5cS&Xru*a_GH{sGxz>Eq&XEu;jpw<1pG26`HRXdv?v-OsG;7@De@c-(5T-1yzw!m*pjDEdLXP?iAfNVkgSp8TW8DD!)}+;)UL%bVvtSCH3*o>gr8g&zLvQ~?>`0t$ zps?C6S6o^l6Hzshr$Lf`{rK+m^2lSpyVF(Iu!@QX?958$N-jkXxn~ns+wd}jVSs~=f_=bv%Voi3~@Pd zF{%8@Pp|%jc@dTZs@~{vtluxVQ}UEG3c@3xilRb~XL;j%JS3xN!2c!y{L_&A@)rD* z&Um`|y(}+uB5I5(WT@{}%FHxLRz~@5$7~lufj$UWp1nrEX^OT$)HkHv^_i-ys)tUf zTQ+S<9*@X+jnqp`w&R(*+(#TqDJ=MI%>4KT>8r!RJC3kt)3H;vImMNDk!o~KlKBVYnamp!!c>Afc-K^-@S8}bFDo@hXqr$rhjqDehxa_FTTy9T|5z@_D z_0WEoK>}aL#dG-1Gy6kkB`h-_!YuCA$2`^?pHwwnzb)O$iy0d4f9U54)rHzW1;2lvd|{p*}(A z=9FS!MwFAuPn|?*hIC@{*jK+>9H3n+q5B{LdZcz_k@u~$8`n=!QlaMb-ki2N zX62HlhqPJVNa65tsH_!DD^^?5OS#Rpi3EsO_3nVqlDi5o{6{6$U=_4IbSOO(7_d-shX>T{X1KG@GrJ@+H*hF^P3=)45lJ^W8oxex}FIXx6}jkP(wy~ zAcTNSYNi$!CQTbTZv#@IE{ONU)?n>AIBBTCN%KYcXk>exeq>BLAKLr+9=0u9%IVsv zyg*9(1F(@LTsEV6-Y}5RNz1sk^+DS8vdVPB zpw|i?@w&Wz8jof*yeEl3Q+*oa$!m;YvB3(UwpFnm z5)T20ercMx?vrJ!2%ee4s&c|~ozl(AJs2YbnbYt~?H|t8ys8hB5ij8aATE%4bj)IW zRFn47Ghx6=B3RPNcWqRHn8d6jwkJRU1|M9gpk2!g-|PZQT6(sm_7|n1*iPkR1FLz% zHow>Qyj5i77R;j&9R;iU;%rq>1+29d_Nnr=)LmFCUr;RRnon6>Kfe{?S^NIRedA4m zD;4iUpg6L}QjPXAaGLH?-w8SHK$9dv+lhesGOBkc~3 zjC?GGvm?W!!AL#CER=wY=C&A}XxBlZg4xayjPWiFD*BZ>)rgZNR)ZS?+dYkZNGp>V zNv|Mi_OnT_FXzTwIY7dO?KaBul0Ep|r>TNwdfKwX9I+3YTorweybL8ViURko3XVMn%`{j0-s2!RGy z!OnNTJz9M_5SK0S1gWhuo6UejokhI-ohIq zBka%8Ecs6?{b!C>dNCTi-0Qh|6ORKb)9%m}L+KZy7ZPVjogU<0kwAqt(Gn~fM#w&} zp+P;=lAn&qdXf^5{?q8SJk#*%Goppttq_@LEeDW11^Vnoxj%IO?z8t2b63896SnEM&v*yV zK-{8>=7LNa)NH)TLm63ZN)3NzD`Ip(ao6(cc;mV8FK^mT3PNgM2DlG1Z=^szh_y%rfeay6rgA&EJnWn!SWxiWA zIb8urZgLfKE`i>hw_y*i%64-l3KLv>L(}R$&e8iEEAYO5F%vrhWI5PoHlV++D$2d( z!?5IYuhpjFHb-r|m9DpWA!sJR+$nSG!V38f3HDti@ptRiYuIjO@NIF=R-3>kySITo zHIHt6@v(0H^38;IEQtF~T$-C%{v8{$@Jn*)kS0Kv)chIu5KSUB*vu|=bGYBD5c0-t z!0=k6JFHNl{6meNG89##AIdE)WNAP&t^*FnWFL3Sntq$uMw)={K7}_n1`FKtdFh^T zsT8LtEV& zTeY1We5akDU9#5E!o5Sb)t=8UPfBw?p?}7O^|Wj=8o7^GqVS1EI>pG%!TrK4&ldsq zXc(1g)t4cS6y>`YF}7xMMI$zrO>B|^)=aLqLL6cB98SEt(E}vZ)74Ve3#0Aar-Dh_ zJ#@LUEMaU1A%2&W!A0^w?mGoW_evVaY3IP33TMh_VI3GFw+~y?JKR?_C|<&8Y%BXg z)<{<%mQx9pmSG5aR@ZSck%ndgybDNAelKh9fp^Q5WAd}rbGaH4=gfTbgty24u54Ff zL-_=H<&Y#tx|IMUG|ypCR~c@CipZ!%xCp}Igdhd$Wc2pi@jzWPC4*mfRcV&AjQlApTr_(#I`e&{Ds`?j zz5c4db*@YkU+?=iZBEM3E9o|IZ>e=+C8zUX4%(83h)<|>Y7({5~uSQ3U&Y@K*0^uR#+sX%>=(s`{PynSJ`$4cUS(K-{ZeL`;`gg;G-sx<5uNGrNd=<&ZJ9 ztxY!mGO9i_O)?tfkJyc1OO<5W2SG7GS&N%1o9+1~s?go;eyBONn$;V@? zp9uMEw%jbL9rn~{+d$2H1(Ag^8EJph-ATZEVKN9xRp9)(Cdl#%S~>EKfDj<8NmKQV zYJ4v)J*6+AX~;k2192pTT$|1SQ4;l3Gy}A!-4R^cXnag@)FUtT> zDKZaS5d*eF@>bYP^-gu!J7zQa|G+8cJ@H zO!_#*d>6UlW>(L*$u#=DVxlI#NVJ9_Bt`ekMB>cXpL%dK)|bm#y+AW(kgu)-1qjO8 zVv}=E>kUJV>pQok_$B}$A?`S%SsyXsg1$dnbV=}K?6KU9H#Hh5oNh~ZeRnh9^Eb;g zw`jlA&}cllX$HjTJ6>YyV7kUOb}5EiCMIEHvCJ-65cj0^r^%XCq4e%ogw2e^A8Ez9 zJY4;5el6;Gpi6^b!ySvhQNr)US9?^TTv)u#w1-3NaSu5>_ykl7Wz}$>h+1*r+{muO z9IpT3{OlLR-xkh-UXhFDq?16KM0D_E#a%Uh>}@^YkY?$J;cwHHJWf=qv?S>qvx@vH zHK0D7HzA)hS|Sy61(3ki00~_6JP_wpl+|vEA#KwI+i4bIB^Ht&2|Y;(?f@Q1_Kwihm;T6cdE0L8j(T_OypVY%Vb=SfEcucv(bp zoq-w;rH%6i4?mz=xV*(IfYvSO9E{-UTf$i(_%yBFex6aUi-Vrvr@l$ix$sg|>=R!K zrV#AKChpVm?%Ro2UAwKEh_d;T=MI~j^RC3^8|z`u2CvD^;+ul1s~eR1@;{91uY=0A zT_W3JNvz^>4_OFB(PU6xvAGLE%nK90zFcijD&w4ROkR9cpZ;B9Hd9 z;HA!j8oElCf`qBtpH)O&lnYFZN^8N3>1n4g&TA7auiQ6(|Ivp6W0CsYcjiT{E{aG7 zn+=l+TzU*@O5?0BpP6zd?i7rqnyI=AS6QjVspB$fXjY+gMVC0BF>7T*bdzM-FK+O%#e9JZ4JISE8PbAB2mG#!%D> zDi30PzB)vi>M(tx4tpMTrm!)4M0M^E63>e|dL#MfuAJ@p%dbSP1O2KzZK&B?RvXkex8*)S_cMfpF-Pr&Ov$qB z?`c1D`5=-RM2xEkFe}NizQT%Q66?zcl29udV% zQ;rd)7u(~@?X%$o#S9c8i^^@|8sg~*rfoJ8Gudy)3Yu@YX_ajIo8^{-X1#9o!yc=vR^^@f z_vH*VYo3lVK%(lo?09wdT-0trbShIo!f)I z2gf5v*To7eQbs9U#2Hz;FLI<@^rRF|O-HR2;+FW&_~7E;dtsKKx6+m^mitAL=DWSZ zi%kgC$sm&vlJK85qd(6*_MpHhQ{ujUJu~~v*tKaL_r(mmuvJZ{ZznCk4Xwi#vfma7 zrw*Cy!}{cpR+E;f_MWLptIEHkJe@910{-9R-n$rxS>x5O4bRS!z#nBVGb;Kxx84{W zJ|w_#lO?GOZd`jchTGYY=L`&vZ|&llnk{C^iF{X6OHF(VkcR8z0qOLdDqV>rVI2h) z-yOlnmkY9+G1KqO-k7B~3CTO&ntn}q=Xc{rY({J?8Sje&U-tJF-S4mS;5Q&i)_>wA%CP2u~R(7o@L zm;bX5lP%{#9qq%CP! zt;*hSZRir-jO$TOmOCRyuR&gYIjbC>O^}|CwuRFz)9*h)@()>TI1j97^_6$YbC7&! z`|BU;=6!Ewet*t?KV{gM9^p*&!j7Jia2~+u`bYliJv_)ZKcrEl8>Y10RAUkJSYxJUNPKEz2O25IU zs5aI4gBK_iKpD1y%98fUgiZ0Y$w0g=Ev@Y;U!0P%qi}t-Bu-a)6a=Y6O5}qU5wkG4 zi+1}goGSJPD48BS1Z;GDz(zNd5H)I-+hTmY%tbT4)GTQO3G^`Vi`uz-`E#EHxL4iO zh$&v=mfOE1+BQ-OD1Z@EJaK7C5cYbZfhUnb3AXSUF}ATEemZt8X*DZa8vHAC^&GsA z*USF-E&RCn87>7ze_Y!Xhz1bITj(<2qV3yUlfp*gXTqp_9|i?0!(~ zbrQS)v6wbI^`;;cMf>|$p7?|wPa+|(x3XsJWr(Y~`hgf?qqA7^i}@Ox*$H7XxZ z=K|X4Z{bZuvAn`lMZ+Rr(vV4z^=}Xjbj~~{EkAAd+dK`@xWDpGz4+m^s2U%MNN%pD zH#68qHN=hC5s$#He>k|gt9`id^0AtfAmVRn27J?L0M`WW&<$a?bAos< z3J>!0t(sDkfv)a|spEf!rM~so2yG(gS6Jc+13!nZP7?ZX)cn3bKpCh)%O0j03!*Eg zFeAPC;HK{&Dz#&#daxChJu~xZdLIopqPbAE{{V-ahM-fW)>37Nq@|od4qUW=f2tn}^? ze%>n}n=EQ`z%X1fFRrNYR(sxoi#1+FU2p}|O&7-azea9o8e3s^?KKL2R(I~CLA8zG z6)+o5>tqsLfwlD_5i5k$H1gZ9U}q4%?ANOl@cXXKkdr3tpZX=^2yS>kkq~`H zP?VJ8j04lPtbhGV{s&^|HA{c>4bf0yrlS{VkaGo1mDYe_2EB>DH{x{+Xp^${dn2eo z0}uU?mqpFwp!H6=x+ew1WnO_HHr^8`Kco&IFj8rhxc%PS*Ip%;3j9_#2V4<}KFiS`AoOLEx64f8H)cc4wIj zg8r38N>t9;Pd#84=Z$-`%VZ_)z#mOv25=APL3;dPis6*Kvj&i&g7hbvqjTp)C^18L~s3 z#a*@77a31xsDkE9bKMBg6Li9ImIX5XDo{j*0~58TzDk7bq$h=hJY3ZN6Fo)it?#=}@~m{>b` zDxaD*06z%huWfnxXHPVgApAZJi|C>?A$t00U-66ITgPKw40vnG4H*c<3;h<$lZMm_ z&xo8CA<(=^(SWA;aJ$Eqp7f7ALqNiR+uA_D??zl-RB_sg1W3o2wX>w21uUYM=(gh3 zxw7KcmLU9H&__U)`Pyli^-*iA6Z@?XLKOrL*8ltUOuq;!IM!)btZ~ zPcJzwimQ{dx45&5=pkth;QPVh%5-t6#fnUVNc~j}B>{rJcLYuZ5s;uD!vlQ*GvMUE z8}Ni8(A{0y#}g3{0Z7B74wQ|!1B_k?L46nn`k$F{A#qC2I>yNE{6N257Yf##F|17C z{{5F{J!gQMiAmgfe4+px=)K<;B>~#r=4(F(hjb#zf%(3?6Ic(Q$&xzr zXMITapU?blRw`Q0b)m%1r~$XfGU&9l(b^`57c*D}y}ng5Sirx}n$BQ=jRU?JQ+NI` zIvD3~^SSeK-iAn}KmziHumLzZ#C-Pl4!UhnJpD_u_*L}RgXIp)g{G@}vmbp?&%qUG z_=iOQaPliQ5cb+`;KwjGEq(_gcgy{S~N)ZYir|Vew%_KNqdl_wQ4t33JzCX1>aT0YJsJ zylLeKU5$q<^V|~bI&4-g5MmNnTsqkE1NWAFh+oojS-?IcQ@s7*urOk_7H7rUUC1K+ z>bFhMM*&n@b%uJ5Rng_cQi4RO7q8!aARlYK9513LaZzZ4i~N)Sb%^)q%_3bqIVyD<=;V-^ zt&OYk7B1m0v!h%;xXyn*RD4)WkR`Ih%LPI#I+O z7h|==jXXq-ZaICz#9F=p@!fkfIr^mN*;0;-IAxdV!F@52FZ(p8H!Uw*&6X~y@P^#2 z#H3>$Cj!~}8(rw1-keUTlyLE8y$I3UOib`Ycc%w6qpW-xN2K(Lj}-_Ub@ zBv2K+&_Z@dLPsQw*wFx+-wbqSHh{J&NC7xxXM=cPh2GwIu)P&lU@GkBQ-pJ4@sgYC zLz_ODA)l~QX#WXs?17i|h%*pkerU1U!bx8;4{QE#aG1Vqk5vmg5{7>GjY8$Gqm33+ zX3?k_-Yj}9UF|alk66Ux^ILf$i&zW&C4p`?Ii?M{*;?9D(0Zlm4z^9N5Er=qX1!-V z(-`Vqi}Dn32mKoJ-}g=RJHN{ySD_<&BkgWDs$Hza*Q-q7$*zO@e0VttVBD6R41bHRWL=kED?{#g@) z7vZ&6jS@M>a!R#nlVd^r_-)H;ZRw754;tV zCJ=5H!Ds`Ix4FIWWA)HbbhqtIq2q=II}wGzs^zA@*a-|E71%bFN5Stu&=4u;p1ir@A+MVIJW9l`K*pP)lH633(| zX?4tYdv>dS4c2?dihr0*KS37`>+x4}adUCA-}`7SA2n;_oi*0#nbQI|1{Ah%K3xq^ zLq+B>IE1U8$p$ju+$$4X*uWeC68&dLUjK^yYVV4KdY*#V6)W1_2guQ9;O~&tG}9rL zc>vmh@v8t|7A^(&q{&*bWG(#;;U0mHYFE(K%J}$X$}$3AxRRUg$6-hiMf9+}2eDIy z&^u$Wd9obbe8!gG@j2av_*S&A%{dmUzu_a6B&Bh5xF61Zm*O_PLA^NOMA_1aUBYAg zj~hiaqw>e8X@4&04wcz+Ji{RXIz~e$$xaG1hcJ(|szBSgto(y2-)*CXXK%6~ux0L& zrXOLsF_fSDC8w7sN%bvk^Xdah>%Ral6iTHbn$Lw(@+!8N*@N6RCEjWmC7=Vm_xTdxrPuf6nKoh>K9q@_GOKfpeK6Z_#$-o z$^g6D?4iA+8r(JOG5iTsOmUjei)r?89Ozebm{oqUOB z3BCY0HqKzThR%K`B2-n^#E3b_ys)`*_Sv$hHy?%s1;+O;XhBtJ3#GONuyQ_dQhoiH zg8~OD=oaCC(cuqN$}yink*2+cX$u$d+Pu)*w%f@ykJn&Do4Ch8Ye4yJ$FT7uy=;us z-D2fr+nlPo=inH4H0a)8kE1&jI7=vZRMv5fKBGRxv{kQqpF&H1L25v~^~1q&<*_|x zdW+(@>EmTpY$oO~l-i%${`mFZwok@(rTT=2L2Ul-Ak|L#SCBgC20^O#uOQ|5>^}#o z9u5_C$kP26wy6Y+ua(p^D>znl&x6!Ir=5p#&*+I+>&0dIdpa|g4=3qre6HD=oyv#@j@PeI#2Jq*vCBY@HO0V|c0bM&V)c`{_>t`nl8mo~oh5;FD zdr>HsmC;XtfDf^|9Y z(jZBpXPuYNmeP{Pe9cmR$s~=rDwKi8KGT)qMG!PvdukGMZ-z0u=Bn01Df@A?CK~9B z3@q;8At0^m1JZiAt7AoUPMqgAa&xr0PH@YoM_0|59lMPLm!jCr@}Ts^^HQlmf*(64 zvR_LN2%%3v=)={WdcUa2@hV7OnQWLsh4hO0< zW;cthkHQC5jzq-~S&#=Ge$VIdbhA)ygExY1Y4FG4{gxTgMGg(nTtS8lGrC;$i(UIZ zEcyVj0+~uqG(FQ;s)HxgUR?plcaV8{b4m4@7X!Ws26(E1$cX#NjAl0TTfg;lr3vbm zrh};_<30IA-iAzEhK==zPmz8}>i}5=-5D?|i|hZe<%7@J@%1O2C%R4nMJ{@~0=EbMSfm~XZPt|{)+!*? zLQQD*ubOGY{}gxP{$9U^e=L(lG@g^ZAW{i10b^(_n%z-otpXY7h1IvS&@}rC($6#Z zh%vDJ2l{~5TwtV>+x-Y`8}Q^$j{ym#Hr}ple#Xv!h!?f8k}Ux)HZ3Qs85O&G+#pV- zkk!E=HZTk3zBg83nqP_%H6*!w(S-CNPbv0+)_-V`uitT8&>iw$;NerLPo)gg7 zCZ!{AsMZKzV0TN_UZTRi(et(teR{ieW(hL6ps)Eqo@*czRkrYSEu^*0T1kf3E4!^D zdQ9vZg)oFr9pC~~<#ELB7zcTb1v_K~wtUmfSd@N#(wXoIDY9-LL;1N#f*I#r7 z-6KgkzLZ^6QK(A3PbAM-=1r?~e9BUkNcViW(wnmO{=3n5g7hYUgf^aLVFqx~G~Rq6 zOJ3#jzRg??nGGNeSl(LC@aPum^v@y*|F|r--6+QcndDzxuhq8QC#@m~B(^&6hRGz~ zjL)O)#z%FrgmR41UeF&P08a-we5w#XL~)@Tx6P~K5^SSZRXzARYG3Q{J~MG6fv|ii zl~g9WhcxS|syjqNYjOe?xj zCIYI5CIWUPio*axuUI6<_%#FXb~bw9UGlc{&YX7ACg&95)vU7eq<5K++-cCifq5NA6$e2PJ;xjfHe8PZzB6hK`+%Q+_K=?+|2Rt|PM%BoEtWy9MyvYd10*aAcJueT&Z`g}9ZP3J-Nb211e?^BA{6 z!yZP;YU|R3MA_N*%FaH5eYp?`^oVZHt@*7DnyN0%zAE)9)O{(|`&9ZPa@sC0Yg0ab z_g*kZOj3buMVQ1xGSc^0Y-m=%eTBnT(c=BQ+#GV?q1A9g`ctEhQY@yp;TkI_3Y6V( z6tO|LxPQ&;f0d>--+bk+C{?Z$T1oQwvY(i8IM7)Ml?C#ZioPjyJfx4SXAS$)L3;~s zH~k&!cr3kqqg1GnB-!A1_x$W6Yu?RUKzaao-9KytPB)SJEkmXY7~qJ1($ecHRbG@q^oCl)jkv6azUlwp%+R8nw8 z%ZAL((e08?>|J(~9NItcdu8I#(IotDn{8BWtf9;{+?c6n2dttSNJhw@Zm2=7k<|QD zX$6VCkm7kTKD+GHWglD`)05Hbqn|yGe90Fr;6(omI|yHB;4C~IIPV=*FNLsYiwzbwJvMqQ zlKn0;k8%7o{Wv!A@Sm1q1pYoQVvj&VjezlcSVeaKac|^?xk#M_vEsOoI;dFjtEmnQ zy_Vg3QBOuKlRuPp%P`x=zXNzu(Y!xXdAVyZ;oGPbdnf&5h7Sco?B<4dI8HvZy_p+7sL-~g7~OD^k4f`3 z8`|u(9_WY!%rC%51K2}k^EZJr>|cApENXN(9%ORRt^)8=yf_aFa%+`Vv(J??r?kG2 z?3Qjm32n%%_Kmk46;|57<%X|X==rG4+vX`ev;MNXub;7yG(aOUdmoOgpLg|sa{?GO zqoGlg-?r|j8w8vS%~%+k4-z7Qy#+ZM;armLZ@w}jvB0OtctdpQax4x=g)<500=Y9s zRw3huRw0a`)lvzZyY~+Jn)z>DA;b?vL0A+7oc_|pDCQrGy?%T`tDkTgu7W zyQ#$I8GyDTu2qlf?t!|Kni_?T?ySK>{fkK_kZXsI8Pdv>Z##%kmJ4j~b~hek6aD4r z%iE$iMr}WEIekyTar(x5I_bUa*{_Y@NUH`5TN%hePIpV}?pqv6v0h(2x$NH1wng=E zMzrw4vT(9)&(lMPgzs$BjYA_qPdlpy^t5WS#!dOv!cJUHOh8XdzBr9UyGwGm=RrQY z*aVr?E90_})6RG<0Y-bk;={fc5dc|y>_|b5CWq!lIBGrqqG!M$ot-trfQ5e+W4h9h zz=|^?=drY4(3z6pLl2+boR>}k-Rc5e5`LI%eKW}z+{L>&f_0S3r&7y2iQaF;A=hbe zSbx9_0&3HskmD>O^*cCbFnK>;7vYfZoR{uC{F;HMZ*`!Rgl`C#qy;yR)io?>9Qmf) zM|&-T6rz`tYTe+~2l0oVJzE(XW$IVkN^KM`jzZxesLVI)j}C&LV4Y2&t1o*dhM$K^ zCtm{PxJ~GsvhP+>jrn7%6u?ojN+zqG=h{A#eN;T_6r%`*>%Qong?g_va-T0pkw1ThKs^Mv1 z%b`PoaZ7t>hCZ8$&Xo>N8MqncCJr@6@cn?@$p0Ye5dp#w)@btvSW(<_?*@1)u!Ok- z3>BKb#upvV8CnPQFKnL&FY|jAOntoB9@~9J%>*3XhF*0qQ~*lD}WW7p9AAaa5j)vH1awL)OkX&9UaByjV87!;w?X88*a>d1gz^+Ezj-k$!n?~#Jl zFRAp|0Y^KS*YaMSW+{VObPMnSx@?IF9DME!{OaHXB?3SzUEH12>vkaZAkPVsFB*Lg z^O52iSxsMWX{C7oDHGKh0~kEP37$dLP(Rjb>HBnAy-f!3o0QFz8lVSNr9-x0I7+*z zV4ylI8@NQ7*2br~XIU6OU;=A)%{8hGj6>a_jBohaSIPPP@(_bdD*nf#fK>OfMUNgQ z$i+SO90HzWy>EZ1l}@Z>+I4dM>h((gC%F?1BT66V6UFX_pJ*!>Iu&xNlm#?&@-((| zu?Y0IB}6D_;=_QQq|ECHmW4`kFle~>$395W67EL$8Ob&7F$Scj4pYEHS?e<0TY22s zft$Zi+W|^DspnkA&u;A1#jW0JS7@c^iUOyLIY&SOibb#1;nASsqk$~N1~#SjOR*Jw zl7`3=jwtekZ66qVo`5}!IGuLHQ3)Z)&&6bH422UXwe(aEDD=6}dwgXd+()vvea>W zM9|*9f{rE`iE!-kB%8`GeHD${N}V;l$6!@JI{WZt4#--Yx#j)7rp5|C#;}1R51&q% zJRk^poBTgCKtiWolp4CRyRa9+$%*JbDHk)!SZC-8AT-fvAkX^$=cZ0U_z~cGZ@GMv zr4S-V3rn@aPkXyYJdyv#*+qusQ$_~BVEulGEJ3Zl}d0K-msFc z{I@;?{e1Q@YpZ-`SDh$(@-qDpIpN6y<_N_ z@+ZiMi4B%LzC2Dj#OdEs0?r~pI4Cc!Wg3T4gd;PQ+<%93o1jouqvk_3_e)*0C>!5o z;z6dd0V@z>%IH;?#?cYss0sz*D+ENsljE`h&BM?Pq`0Z711z!(G&NOjft^0%-|%!v$!I;Oq`yC3n0KBp$e0!+6r-`h&!QtEx30b%s;NI9O@!&&UkeBX z(2pJR4Ozm5r-i5bBxIeQ+ZJJ%KCh!#aW^|)?OrH&k0AaDZ$xTl(BQ@N0}h^gMmQ1} zfc-+mQ%6H!B;j$;?nf2r)wFz;w}vehtgb#}>7u@_^wH*;d*Yi9 zJGgF~edS8R!D7JU$&sX<|9fu_@+Rk;VTM9(xYnCkes=%+5aN(0q0j$kWz$=a8+xn5 ztui@eK%#{eia{sdr)gpcK`QfZ(L7Qmvc=c!X6-A~oMIU!U!cywnmq3hL3L<cy9#P?U5R``qWF_w^bWj0*zpF* z@vO8-&LrYTugsIs-F}cV zBss91Gg%S%@y1v~z>?90J-o?ed*TJ9lOq!Bu0<{^m%Ieg#u7 zsgfsRu!4g`^q7aI*L=yf0%JvU4VF05I<==td(azy;`NlLd>Pug9=L=Vm7UG^cz36$ z38nx*lQq_6`+ffhQ1bSS^|Q_VhC#41gL=Qzd;n?amw0} z5b_c+3*dhcyYi6is9?aZJqZq@62JEMO;002$I}jmd;JzF58UFX8HrW$6luip%*Knb z4^5$5L)@A5dhbr7=#s97bV;3>bmJx6&5^LdP$}Sm=t(net2ZZt%_Y$9fBwpcozK^v z^T&F-=md<45QUUKzKUTa;~Y!fhUd~>W!2qeACufb4wl*hZO@P0?MSzT_Zkvrz@Y{=*lJKydD7%o6wi-tfRlN341VqMVg|c2&`IY z5I9f~xX&Sk{)0DzK!<2RYFwF?Va^)K4x9!3Y5#JK0{VMed37mBS%`Xoqn5AWmo0n! z=9U04FVOJ$-KgHQXrSaKV+WG8mq#V+`uzFQ7VniuDhxqFEsSVJmca9|M`^PCIn_Z= zT!Ph?W-IFPnK=S+8e9J6%uz@szYtn2yKutp_I{}<)~x{83~XIQqJlVz1*>aH zB%%PznVDxtEE}g3KQ=o~3&A`)09q17$Gn8~URgUxMpL{Su75;yH5cJEHb+2E)pJh) z#jKtPpQz+b$-7$e4;Yu`8lOeeZ%$6Wzg!mARiac^E1>$1qk5sN;y=ItXP3dhmKFZ@ zg327>NkFYZmlEN2>#@p>G9-U104|)Is_|Y|@gl62D|4eNRNo{Zsf`d&^nYPO2=KD` zsR`EKT0gu{Shjlfu=*(r@fPDR2or$Sd@>WRUE&INmtrwk=|iMM0rv#&wG1&bNkXL@Z;1lQfe zHxXD_epo5?@76FL0>8?$;U&_1hnNtl_6}fPVUCh2uTJ-VoC*U(cMiTJbu4hIt+4wo ze|>HCBcbb4erMprXjBNO2C#_{MlOXm^sJ4@>fzjnhLFM+=TjGmc$hD1jFjQEP-jDe zZPI2S*d8082;Rivk=8?=dVMzEje!ctwJDGJ1?pJzh2cUc%jFU%wSnk*L zoy}kGT6k)csK~|RIWFskyomZjb9Jg!a0+GOFe7^EvMz;waJt6E^e0Tqk zOG#J!s7T!IS({Ii2^h~mv9RHqvwX^1hTd4{>MYD!*fm&NI6Q$O6fz;Z{zpAwz z-U8jZYW;w`g42;&8}0FmCi7OvG^WbbWw#P@UX(?GtDt5K@cT8zbKiw>E66`>`4xe{ zhkFH2=*918Gt0Jlzob5c*&*!US#;+2;6GihZggVt{3+OcnD;SqUfYGK#`E-Q?`O34N zDc5Py2gt=wxDoO9AHbgk3B4ISy;pTbgz)v9ZY;usaKReYVRheq`$B`FcI)n$N}v*; zisIBQ34IyOS-!6}SWKR>f0qy@tyvfNW++hs!tjKlFg$@M43Bu%yT9JQu+L|CX5GGX z!~!tb=&yFGu(&#<8n4pKKyUb1zP#)-Zx9P!*Pd0HNTSq?AX-tuUfe#jX5?7y3PZ`& zUmziRek5u8@!XSOav;Rnux8pU9tgpMsoOi>4n0vJKaJJ+7R7QOhK^ z8)3rMf{|R(hvFp-9rKb9?>HTP6^Os84B5r>)Z=Rrq91=??RImMOEIq@5Yy?x@>M*W zz|kVNXu#PxAaWYdUDn;uGZavqREosp8n~2bIoxf5TthEku{G>EVS}Z=P3M#x;?ML8 z4N2;ED$P>Ax?#4b7NjecdIfZ)4@AQoS>WM7S1N1=acK*UM40n)b7zx#ObAas!hnY=Js_4rq&C@*V<%@~h3V1sBgifGg30&K9*|TO1Ws z?w#hiweYK92^Bnci032KvxVPE@f27`BA(ft>>e@{5P;yWPp7^Ehd`sM1j24z_L;C* zV_%#Pt-uEirUd+jSz|zZl9`--0ztI0WCXd2;($QbUHo>s-i5>L$%JjClH~W(dKyY} zBy8v^oK?35ucSG?Q()4;s+rd5aid!GpNiyI2rX6;d}Qq8oZZbHx|wjfQY(rwY^DOZrK z;B>l68#rA7kww}@OK5u0OWg`|%?4(P=`zYUtz{%PzHVX#87a?tNpeN#bcG7`;*0YyoWCY&hFnVD|Fj?_3R~GQ_an)`_8uUp zw5kM|iAlP#p7-=Bsy z^RZ0EAjqZYJ6Ote@z(TZL@5fViOGcHb6Cq6efkb4yXEiKI_>um#2B?iBE-L8L{9rl zqK|!B(L3_~rXWfI`kq#xD3b8=4WR3+nU?P%-ooN+*$Nz!1+A-Nuwj5x+frt<6A}L+Gr{=;zcS^ENu?z zH_5Ye`x4~_sL&Wl;)VPQP&pjreDs8pR0*?vu8Y8#Kw`ax`%E{|r5v&<7ix7=uO478=YqW~ZxLWc$~OpSK-! zQTr4vvcU%*;hM^cwA*aInz^in!pJgiB-*5GzpmqetqFaQ9_)>hD>y&3@XZ$>ku>Ty zeKRHR$4C%Rgy1$A@7Zm)2_$EM#O89mpFoCVUI+@vF#Q{l;o{!_GTfaAEUN2|G}H4S0P)K1MHKS zhV9RToH5GJ(q^MeA1^q|fDye~>6}BI`}cr?(0%bPv3+shE1}Ol&5cc1cK7bG1K5z@ zr+32l#8hQWI76Ub#_hZ%N*otpT$)|07CI~2rrqRK7hJ6HK}d{FiUQ&Xn$9#E#C8Gz z8UQw^K=aYU(Gq^OSM^mSYs6D%_mP#aZ_tvV+J?styg2>O4gciJxza9XrZw0f=Qsd#zH5uvS7usL9HQA0Tx_)P=)1v7s{p>haV3)+ZoBMSUv@I?$=ehgySBp$j z_GiTkGdd1j(4DUbu&zOnmJhEeSkOrM=pJk2=XxU`#zv(3crAj08$)Op3Y@+mw@285U>Er#u8f4wpPhLSHeD$6%d8p*HtTG9glaCo&nj!Y zj-^NuzcJ*K^DL_TjK3tN{1D(Dy4VR;zT?k5K@$^a5(urX3EkO76rT*qT&t$RP|6&Y zJ@*9f;$(FC>AV5_ja_|{EjM>oFg}k%y%o5|0BepTiSwWT|EDs>|HqXZV7PG&tZ4M5 zY<2h+`$GoXz+H;`w}5oR=O(F#zI&-S6M$a>t%N?1{q{U$M)NnmHGurde*xMMszHil zV0oZBP5cE7$by_xi0UA5cZNXzCL>C>%(}6dBIN|>n2In*&jZX8{k*y11|cC9}M z(lO6k3+l&U=|y6qi}8d?7#X3Vw2`&}8?^ZmeQoYOWoFH`bsTzYCLsZjzJ39H6ng0Z z>&7gai&K>MvX6obfx)Hsij#`%^#!)Sh}Zquk0tFBLv%|oECJ=2_*mv$wSTB#PsJPl z0XrhyNkhBb$y0(z zoT^bO9NH#M2+ATys|BgeJ(|gctb9;^`3p%nr1<|s63%+0W|xKZqcK4H%K3c;aSF{t zRAW4Vt`J#Vz^fKpTs_HU=*YeAg)pp0#^wHr;%9}ZL zi*ST4_aqZnL6%|RSQT(UaLV!@c0~)3f8SqzmGZTO!4AJcj$#1q-Bdzp%9YwnY4rqo zqc;jYwJsQ+;}KK)`aYKP{w5ji$cS($?b{hAip61fxo|vS$-s z1YWW^0APW(U;<=FK%M?M*kkvsIP~j6=}mCV`Siw=hptzqk*r(RMJC5V4dCQ53X*MS znt#BA>#)3lbWimAxN$2WRc%L6&V%&XJ3|K>?0_HWv1=&(a%$V@l~t#0;(!lAunpZh zCgkk89YtYw!o4>OPx6>4-u@~Xhgp7OHHhEkPNcjl5a@KNPlDDlfy}sg;n{Qr*hk&Y zKBPdXZ_Cb938aGGyXVl@J#X^x!_geS$lZgBzZ%E zQ8mHE972tZM!^6Lq^`F98_f4;+j>5Jv4;eKm@4$`-8-pxG)v4EQy7m(q5yZ%w->pL zfBUpK2(+4D0zqNq3RD5VnL&gqd|vtE5*CZTf88#G25Mi>=uV|~yLNrS2DlLrg0BOb zYe<5bx|Fg-9Q6IY$?X|GARz{$C7@5JiuPUu+K&27p3s9)uoJmj2jt8$*B}A*gw?Zl zFFSlMt#XXbAOsx=aAmofe4&02m=RHM7lylGm&+W%5F?~In%7Sed3ACmRG8T@#5e+I zF~=-8Raq^W6^Z7QpL!T6rv%6)6~}sF)FKPVPP@NT&^l^g$UbMK4yCY%Z8H)tlG%#5 z+>d^SD{1Sqhqr+8PQUugUR;o1QhEwr0ZveYzVri;@i*~Ab>NvUVruJm%e#k6%>YA^ z=qfzZs|9SMB!SMfh7zzvTxLSxSN%Ok*=Wx1|3gCalM`DUDPQM|u7($+mJg(E8SxRI zHMu`X1;QjQ1wW2}q?U%4z8@SVJ3OL3M|iFKpIe=*egfbNN^qe?3l+M^5Pvq?tOJ%f zNWmQ15REz3EV=T0lkgqyl9n8^|Ho>)c`1gG4vKf{r=#H@7uwsX(QAl?+6^=AT#EtbO%ztP&P1td zd_H|>@0S+rALA?f`IBAtT8QB3zwC|?X!L9n2dh-D#;b&za$0DzvC74$B}7oC-%X!2 z;qtg)TnEhC{Rz2s)&&g&tNdj(B^oc@JlQ>Yc7-!Qt&^#U@~;CaK~ESbp7o~h@Az*Q z0ujACG!zf}eG3F#!4)N7KQbcqlu~>-hz*qt&>p1$mmmdvBArF z8&}>Xl=Zgwof(ZQ7J`d^_xu5COmsQuaPozffduF%VIh~eK3(g=XjkjjrBX;IpR)Ny zy007CzMoQm9^+e%)KQ{p4z$=r7jUbhmFqcs8iUFN2jCdaPp>(On-5$)(%u7+vj>n6 zKVXc2pC{BriJt>e;^%vD&E81m*G#Nv_29szZ|htYhRrNH^XaO4gnww9)v>85O4jcw zd8x>jZR8Oe%Eig|GwC}2fbkaos^6s^1Nzb97(1p@~6?4oZ=w^;asi_|@Y5~5$%pqR@h@IE3J`jY{9{Y8o*v+nfw-RB& zYm)(iVBXuwlHfJ+?@4tU5qiBh60)J8G9B*JI3^d2Wk0Fycc&E?rphyD9J zHe5Oq&gi)MxHbXa@>5Ek0>0jn?Ia>zPzph`vAErH2He27^NnmkZvE?p?f0GK?^98Dg6 zM4c-YsL8_zrKWQ^?wl3vQOThI z-G48G_0Q-2y`tv-s`Au^cEKg|hkIg0Twt;+(~}S*^J_ZCC21e6rO%yQ|IUu4+lbd=wVmtS z=wy@yXdJCtKiKiOV`W*Iu;DU?R)T)M4u z7DNaHDlvhb3;|?OY4xULcln_i;Br4szM0;Px^Vc7V{vqj73pu1=&E)mUDaSU^|YiT zWptM7q-!dk_pwA5I3z-fyv8F?tAL_roZ+=7imd5Tnd*2C+*#%Ro$aM~jsvo>I@IRJqt8+1#>M=Ea-gY}yT z8dr`PX|~qPW8rqCqc||`n&yVR`vJ2%a#vKDAygj4@d-IE+R52n8Ik`M1)Bt9)2^O? zq$}|y6UcMHO`Rx(`G%paHC_uDCI?@PY9w1KRRB7%jlm({38h}l?Mi!>&EM!+pbKF4 zyPr=yLg}?e0BkixA@f+fn}Kl$eZIos#PS0trCm-}7HMjVUM&M07P}s%8}yq9s${xu zxjVkMTRPW3xL~06Rmj(&DGO@mpe3z^aCdS*bc8u>aIc4aQezch(WJ?r9hqEO@=o{lfZDG>kBQkl7+C4b^a+onpbEV`z8n%;n(K+qstcT$O% z>vdk?hjlDl#+A8w*an=zRt_^oN`F!$-`DKMMw>aW5>~Qk!on)+R=3Z%atC0pfX|J_!56GgmMYgrV=9vkjv zMf-&C;q2=~ET@5l&$TQsZdH`Y7i}Y7ZH(ZuY+ACq=(>$rNY6A}LbRPF&~`FlpzaQd zV@y)(U}{Sxy49TU;Dl{=F-o#oS%m4jsQn3#eVv?N7?Sd5LPGarI3#+`Fj!R~U0EwS zpC+4rdHyUnak@BBu#J&RHC{WEH_H6A&N%0M)p1hO@g&7b0X&kZFqnx$Hfz&&L1g(WzkwCeu10fEG zj}Zs84BeEk2|hEP2Y!0_P8K(^I8lUyE~-@osmaK_5rwkFJU%0qHkT>dgncfHhU7O@ z8%{kaDPAq_!l*j4{~t1+OI2mHo05-5rDoZ`2~B)IWSXieUcYM>fu6IB2^TF4O?Wlb zCg_qwbvDjm{LK3sRdK7)tum^PoT;R8)bFeS0@vMHxQyeLI%l${#MPXU!dND=SK-qk zze*{qdLbbgZb~Nlq0rBx3C=Ge^px-v!O)is>eFeP=k5uOe1Cb8DNB^%y=Az2I$-Qx zRmSj|M2R&OQDRNnCYs2!6mw51E}$-5zZ?-G#tY)Tf5_0=HktzkkQ8 z>L6%bGIRr}<}>irXH?f+9+3!mcXNh3-Wo*E29n<>=bh#`ol!-KuqWDI>*xZ4f^Ch%TgrLxgE60qj4(l!RpE1mAc2`9o@elH?U%hwhp zNH9~#RJ+L_1=(G^SWeqNeG{?v2hnf)BrKe+EV7 zF9NM_4@v(J4|4t2d-*O1iP{4m_eWzL-z-=Fwe)|M9(L+NryRbe`_y&Pkv;!VJ3aw2 z$`~F@k14oPuA>c0X*wAi>_!P~aqrm6vW=CNHAN&Q-6dztR6$8q5nYlf{c0OZzbfmQ zuF>8L2W?gqkehKhvH=Zg7kp z(-{=}xwFbDj|^<5z~q>xp#b>GV5EQ~EodOqwxSLgI$y0D(M72bdp^;saV{wmOZ;a9 z$kcO{4?+vMJ}I90k|ba+wD>t7D&%dz_Ltin`zW?F8DL9m3dd}H1#MX?&C`2JX|D2o zoEas&zoaW%h|}~sN`+kT#WW0y6o#EIf2f?6>LXe>Vd3C4eebCx3K!y`ldx&f9D~xC z-aXbK3*t;lSOZW&6$C0^1}(^0a8T9_kG+}72$XVqQjGtme?OJjFR7;5m@QKIX{X?f%k3$ZkS)NefCT>d_4Mp7Wq`JFr5gYT z(CS5yCESSHkJ})NKhAU%sKNLB5gX-5;=if|Y9-Ya65U3w5tkZBR)`YusolV-N(rWr zUpIOQfZ&l=tYMS4x|#3RYD_&&cu9Ybc)K90frhQuRD{E?KfE7tS3YQ0Hr$oqxW3;(KhfO29W}AxW(P0Pwhk_=zcIW>FJtlcFLegPIoEE=*vpubSShQ_@*RT5yTO-Dep;G>fIsIK>L z%`>3XABkG%z?>5dBKn`Et2ywKysc88w@LX`AU&K%a&|Nv=Dn#5up|(a89@xO-5}7# z@Tn}P;{ zX3Qia&M)&MuMIi9M)*0{Uayhnip!^h9iM6*n3j1U?hn{Ns>>Q1X}#YuAtvYM$A!%+ z!=q!TE{94CIP8L`!emOk5}gKu4;|yHI)B1*+$cmW#%%62UCv2->&dF44m#;SD#Fxr zgl|_r1@NhwKegid-H7WUkZEzl9{RB7xdnk!>PpSFullm~S(6^X_vCHlAifNsQ9sYm z0nT9B7Ra4cfRp>IzZ$w5XK37MaUnI%cm$l-A4hFb%!Jae6WOB; z`A#Pp?Kd*py-sB+NOIO-|7`cteVXvDt_UH1znQT*4q{}<`MG^|VEsKKTJZS@gM$f) z`SEaeQ*TIzx?&b-Ik{|CZFkx9_V?9Bi8qUJ)<5@}q0hlV)m#9bG#Hu!w~kE7Uj@#R z#w=+ZjZWGgF9j(bI0!01+9zt2@}&02%lO4fAWeVy<#3r&11(e9Sqws$;Q^J!5uG9L zoUfe;NU|Fh8D}kuUAB9l=QI6m&*|<$BG+t=PV;<5)s^TH$jTl3Rpv%*NTs=-HTENU zTbl!&kRGLI3;$MfJqy>tE43RMiTC{*YzYc8(Rr(-pN}qUDaJijuMse8yf*#th@8RR z2T`U_^mTg3zG+@Acua+ z+0n;O{#X8=NhKi)26wQ2nXj30%6ZE$_{F4rx~T5>jC;VFDl+5&INAm|&j<9E*-kix zF%}6`wnz}&2Z!CtP`my^sGg1ujav8Bv9R)|Uf=S0K*GockHvH_j5>o6zNKxN1YmBg zOuRxVgayxi93?ob>880!Dwpx`33fhCo49rKZLjEno^9=RLcRTizHom~876=}FJVl3aZM-_|uF z*94qwHi7~hs0*Z|G2ZcDbn&rQvD~Oq2B^CX44rN{Tl5yPV5V!+DbQHJ#0#Aju%%+? zr9}acUtovvFLa83^v&4ii3#{?L9Jk)FWkHCCI%m2Wc%DgaqkBVhra9EH^$DY?nYO^ zs*(O^Dh9@lX={DpJy&(Y@SRKj(h?+yPQ@uaEg~F+mqba`VQ!VoXe?|Q>o-ohlsK9R ziV{ZWKB;+>T=tjnxj%pY&#?;s$COvxfqr3sdXDs5;&*E_XsiPk%51;RaO~iG?l$lD zO#~@~3V{fsxh%gv|L5a>q2vE6gT|k){a?Ql`=7j8`LA3l{rTB{ENA~Li~qW^Kux-gVQ z7l(%g*~_RS0|c~i20a-0+sgm?{&Wfma;sxFe2x%~KiJIpbM5@+e&Nsk!heT0aJ+Ut z!2H^S4l+|9wTAkyr&Zc^pM%NO&&W@B0&24QZ?p2BBmMubk^ay6{_j)YDc?9hr6Cc@ z;=m{Q=USQg#}J-{y}664v&D5g=#hh|4W5t?6E73=Kth5?%gxl)%h7^I$?m$P1s;#A z!%YWgEywF-7CaX%+^x+lG!-u3@#tEcyIL^`i172{@hDnYTUxm?@r!`R7pz@f)GeH4 z9qb$(>@DnFnMCn;(DggqVnwlI0{NIXNX4(#6;*!#`@`}ng4UJ9BEv;>DdwTmm^bZUU4Npza%+Ad( zEG{i?Zf);;+WoxuV1)d`$EUSfMZ}o_l1V;0o^z$2IeU~EHW7l z?CVY^PV)!gkY9*-TJ##1SwM4x!qoXa9wm$56ze8*Yp6T>$8Id}pSrW3H}=PU4Z{fF zXrS`oq%djNP9o$S^V^a$2?|l!g#EE5O$WK9soW_#cDON{=u;oUxcG4a_hc@9S zP^RLFM+rc{S(`comE35y4xGG+px5^!uZW7J;#ky_l!}%|pOPx+@C?1mpHifEuxb89 zi2_)MGd|FBeBY|Yuv2>!-HNX|(QztlDgwir&0btEh(#CCa#oP93!at9iq2u{V+G}; z8(B8A5Z-pIXl8*qG8x8R=_sbB62TeMk`#0?-_on&E+I471= zL2}l89D(t~BfIY`jY~Me@ejpF*rb*3L-`{ba!j-=yj=%1@b7ZGknKc$YLpGI88_OD z?7OdV3A0na_w%ung3@k|RR&y>%9Pd=k?S3xd^(KC43W|E{?hTm#Zf8l_e`P%)Pqxf zDANKYbH&IJ^QLNgPlLA=N73cAcY$FR&5H(7kO`Ke>;}+ys!{7mJB}o}ZtP^w&A=6P zmrgkkVUh-^c9V#GNi|-GWgP(vpwmFyTgNk?|A2H-&;o)J%-cW zEd6wXkjFhtYm@jcLCT^#W3|4NrkvqMZJ=O=2tAEVEW3~NRB_Ksdui{nu=%n!sCM93 z02U3Rp1`gB;T3Jed z&ZsZfUo!xSoStL4pcmdlbFnd)T0)!5M3zd-DRH5&9r8qx{X9Ym zf7{TKzRWT)uFJ08?s*TGutkN4xXEVBdSAjGCSh zQrM#qDu2w2e=E8xDtB&_ZAGKS1@rZ3N&*EVl$sa3Uh!Q~!Gfp;0$)yn{@qDBVBNTa zjQtD8z3lO|BhWESNe(_wZ4#O(|Ji+`w9N=hG8@lOS9TkHcNC(K#Sbs7v+_EidO3SVR3AJPd?6MpzM7VU=mwr%^P;m~>T8XeZyE#7c@ zUm&=`OiPcP#}E3aZu$Qvp%g04QMP9aZWyzuYeSHsmRO1aXe|Otc}zy^^vPcuD#|r3MK0sE zk(2}atUn8?l4I^d1(2Ji-+MpWQeB~jiTgcB2rn(}@f#>yP!(@Z67K{Z+#oFns7$Qu zw#WR$lkwYa>-Ii7{(vdN5|F^z3UdDP%T z2MX2+KZLn}L-{BQebi$?8Kza0RhYgIy+QA!B)M9W_030-WWNX9h9l*e`kX~*rYd>% zYNtQ92I_85{9}$48kgwj;s9}spj=EPX|M2Ig2*vP6$vxo5M4`6T7^0l1uJR*g4zJE z%*&ps40I`lnt?Vd7YfRUI{H3rKB(5cjN3T~(T$HgGodp_8MF}E7(^67^2n9#*)KPw`4(-?1Zm5Swu{1RZO44uti0dU#cTE3aqB8Q zysPa~eNFv*GR-;rdv;{4hR+0af@^c-FLVX1%OP_H)JeC#gd#uV8>(nokn%ngj_mW_ z%;%rDLURWruik#)OijUiy}?G}@nHeQ1ox_1z59%r&Ijz9Dpnr&cmxY2yy7o2y?cmk zA8)iEO+UOo@j~|_q201Ua7}Rf+ch*e62ow?Z+LrA!gp(e>%40J?TSJ~aCJM-k~Rp! zpe~KpalYLqE60Y!dN+zC5*|=rfOqw7Y+iWo9e+o5v?VD+O$yHb>fQrN!HMm61DB^# z$Qz#Lpgsl7EF;xLC8A|+);+iK$u}Ce^fpfadUHHj*<1;51+eXy-MhyY6Zn*a7^_m6 zz%!Tr8pWf)x~HjJuJ@lREvXL0eYB0+R6{b#J~5L4cEQ@(K`Ovcz}Z_m{8Y`0SnEN~ z0#Bh}o<@C2UF{3nbZ`ViTu~0WMUjbz^(O9IMFfjxZVSeMz zV8K2Jw>i@W4EKWI5M1&`R;__DLNezhk`gz0HK8`o0o{sMWwxH_tW?($VL2O{^Rc(0 zgzmxA4AzXUKX367D;QgPsdz2Cbgf!9&C^z=;zNAI8*=78bpb~g)ve)N8;=d^-H)9R zF4Kw3vqfv0)|^0Bf=->e8*(QwS`YP6*!`IK8AbXv_h5A0fh-c({UL|Yg$VOxNnb!^ z*HoYwA8YO3E#x40LC@LhBb#S5ww$J<9wI-fNh2Amiv5wqex+D9#k1c!ePBv&GEta>0&IYwd%jm6^n66+EG#AwfO24lmxC&XIUKm3NB8+$+D%aZ1C(2G^~>Z$ zJPcTl*I08VZ>-7R@F5ITwDCQgR>V9>(zImCKdgiaj>xc96s2A{)d zmHW&};US_0kwf9T@7u>htk4>OyTk`A&AK49(i<@-3^2=Pw9j<%pi_fmnguo4tT3?J3C~j%y?fXJbM4dOp6D!zyt+=%hvaucz%=FM&WJVr zda3ypYvBfJBiP1O+2})>>^`MC1zO6RuDUTD^DoHGASmKQ!i9t$y+IL8{Uu>JCdB|~ z?~=^8d2)obu2|Z&;n{M~)y?z6Z%?W+Sgn`(i`PUfT`s^IX{Nbnbh-nd<3wAN2W6S# zSbhEpbO36FsX+AlRA;MfA>0Vylo6RLfS|;SL3QRt-Fs=(kq$!sG5oN+N7ZIIc?D!x zY{b~W<%1serUT$jN0|~R_1b2qtL_<=+fV8MlLIkyf7VPqHDz9MO3++{-tGl8u3Ph} zpv`}s{^M%I@2Lh_p&)Z>Tx(Bj%5;N+gvC;EtyWZml00%NM++5Xs9@%SOM`U!vw7_1$yS63YHEw3r7*3kv_OV8iDeoWVw z6%+*F&W`r^?4DPk8P^K->$|x8m3Kk>{w{-JE#5HI;&txaXPJJO!H2g6k;L8jm@$6s zcw)yL59+b6QP^;B$%?J1piw0bR4aXt$yR_n<~bz>0fcb_x!pC1H)DXp;E>Q4to*4^ z0*D~nuPn`q%o!7h`dn~$ZMY7I*jD&7!}C*VomzpEzzv~LuuPZ1mJ*g+;@6zm)Rg&L z7M(JpMZ-uT)NQ0jSf2)`Jz=E@E*a5G)vF*BJe6;D@8fLyrrB|?c_3#^Swh3v9*ma4{~^#D)m~^o*>!> zjZ0+?;{9T3I@DRfdIbqAY=c>&0n;pynXGAF)m1gKKDZUYf$i5lasqvis zu@zm!o>8lfU>=%yA=HaG3K8f3kEVmR4>cWKs0J^o ze*o8*(m4y;!C>~-j^st#im`8{%zI1D))6DWhN6Q zK6kiMb}bkvhi8IaO z#~4loLqJgtd&z4<&lU}@ZWVkC0MuVyJvRlRtTFG-s-Lz|&)7*vld*(+H_GlxT-tTM z^Mb(|Fb|eXp@u*Uh?!?xPh4oHmPpcdvhX1MR9VeMUDN?~$k<>x{tq5g{H^1QzyEt8 zFsjsW;J5j9+}H*%n;X?%{q8!q2&8IWNYaG&NR(!P+03i(8<%xmxoy@);ax*x!g4cm z%t$0she{OkTKawOi+R~9{(TnbYp7zsSj2vH;!L2Hw0!~4O0)RD-MYm`0%O96(M8eH z2Nji&zn~X$d22X;yd+ImJ_*zaz_k$1C8#VlqQ>BML#^)-qB{mNQVc+>`|Srz3(@%n zWYB=&(*=fm11e515dSPr3^$X*uJ)G$py4>f=BXN1K=K0U)>N*WD;EnQ#7v0BOIp53CFt{H zk%?W8>#w4>B?RMQv@UW=g7!9Mco`2f?29Nl!A`;jz3InAHJn{*5@tDEYs>*i`0FOh z1HL{JSF$&+ac8If&o6V(sz9?{1eon8gwVk$6xiqiQqYx8w2NHak1`w?>F^K+TO&Qu zIVL3wTYD{9WG^D2sgt5?YMqR>pWP2ymBC!&>1Utyzf}q7e4UuY#zG2CQ|2TrpBoJs z6!ShczaD4>KXq}OuhLDQz*NBaY-lmHp!&${IB|_vOQ=wL4Zj!7IDb=RI9Rtj=vRIy zyZwy+A&>xm0SB|0*MpDl)DQzVGLLzVCb9_x=9x#}+rk%(~9&T<2Qnx{iZ-w+uYo zb8xrfMNR8F*H0+o`!N>O4}hl0RJ#dH_lNJapa?8X1JNszV@rxvYXh>DcKFO(HNfo3 z1-A2@TrA?G2OP{X?&fXKU@Qgw@!MhEVahA2;JPFaAL(qrrv6BBsm9E}CFh=x*kosNU^yh8l#LRp}ig#0>S-jVvpRc3tNXgTa8 zhY#3f>ZCB0NPRG8-iRpg8SY!L;Eh>Vd-2RrEtDOz^yAb6Ft?UtgituCN|d_uBi)I) zoLi?@L`rr3f}v9+pq|e)9(H2bR z;n!EfMl0_2TL=VCz_&+pJ&HF-1BhORWg4PPs}HZIY6u88z+azy!qgqyyXn0kynCc} zj7dRW5(GsSB>KSe8`8Thl3;22^v!GrO-v51=oS)B1H@U$>V;U{4dw^cd0HhE zFh8KcItACI%vLC%3%HXgw~vkUnlqIaqclxkxy%U$=V_$1zVkc-8zzbVC?5IR!jLsA z>+shhRclJm?BJJIMY;LS^ro!>swDK$ZJ$!FjrSlj=uxtc#k~;D95u8P{f7*dJ}IEAH-GMHJx3oxzUfSEYIHR znHe$g)Cr2Nmr!((!=2x`sT7wk3f=9Ri7aOYH}aL!8@bY@QNgY9(ZErFt1OHPM|&IV zrE(E81G7TJs#=oh1MxU0${O|$J3?(7p2S!q6g0R}ckCKRh`G~BGwtdVUQ62nk||)g z-ung~0e6HbS>#dolUu2-rt<$RQ6>n;70ur{AIAEkrIS(3pedcwyH@{rTU$3=Q4V>Z z&>siwUo%_2i8v@2@h%h*?T6Q7@_8;Ay0WX86GSWdE&q6;mW+>*iV+c?8fBT;?555@3>a2)ORg*U{vhMLF}Y?qeycD!%q5& z?=p6P?m!sPntoMgd7>B%X{D24|H`-0-Alx{7|(dB?tWDl|Ev1ip)aaU#_4~A$3OjRg7 zc21F7AaL{+m~TgOj%5CVB|HH0s73e;hHgGZ$ccvg}lTQP0F z*8#|QIrM7w7VQqTH6eK03(oV&QUj3jT*ig#N=e5g+r_Z`QN(;LXM0$4MHAlrd{SktZ!t91fJxL- zjQmW}5?|%GB*VQ68WQAtEwi_G}JTkoO_qTiB3{SHbeP$e``WD1Gz7HBN5ka8z;r>2&4A z7p5wvQb-{{pw?!&;8CgiY`LghQN=Gqx8^LrN5kVh!TjxzNS3A)kf@5}64SpbjlPYv zrX{z2WPeu9=0fV@TiOFTYJlcARWJacMaX!;gA~cT{&&i+BzGa=XS47J^%a~S`I2p! zZ`}(L{#ikmb?ZlLn1z-1hR%qB(tL`$$L;{-#|eKN+{yqKmMJ}7;dd)zuKA879ZzZQ zV9sO@-<02x`W9}&g<7Y6Y3Ko#hel4{1)i|f%>z75`plTaoZVs9BjJVmrH0FO#oY35 z6`OHh*_dJ;(z!JIxgloHaZ!K53Ycu1Cx=hIo|zO-(jHsDP|)l#5^sOvf9sg-MTR?W zCRN|AaHJM8$IaDAWbms*L|TmDkAA@sN!p6)moCvXsCLhgbI3z$y6=wP-T>7t16ee|t81DEP^qUTgME<0Sbek)5e%y&00qq48eA?VUyFm1MZHDc2a zshqm=GiBjH<|=z@^jmfUsMo`nLDQ0@o>j2F5fxc zK@pp_)t?P@+qe_|ZXrz9U)S8ln2=~hTF@l@53>1Zh-|Klq#Y-u(b3HTU?G0u-)1r; zM)klGGuhrluuI!_io8zf-BN#9bzV#0&7(1~c6T}%xyxnbT%E$7>)lR0J~Ns@4(Yl@zaQx<(sDu{N7Cdcq_x*as94_cpp*Bzw33>5_3i@W7(X!Qd={S^ zN%j)0imheYL(~R2me?Oljqm2+Y~A&SM+D!vdP{2pS$F_OL0=6T1+$*5d%~*k6l)G8 zg63(t6lW(hzbzT_l0J4bvGOCltje0uZIK?>snRP;)&4 z$oE9hIUHp~_DOCR+#XBKX9@dOBF17^EMGXr#C=QUEUt%{Cg2JWLR{h2pDwU~!gyw` z5_#;x%?LW*9dnr|Ng3Ld^lqQK#vQj@oil%|7*^$) z=w-2PITvQ``U<3b<-cIR8Ph;h3q6bWm>uMSZ8kUiMpgNJ~~PD;`=#8 z7Qpf@8*N^|1Dgn4N8%upJ&o@O6$&z~cm*E8vC<&Sv@7%XL*5^uuQZ#}W$2Rxz_U=9 zS%%QVn5}gUZ=gIPha*NFIr_K)uUURH7XDn*AYY`gEZlmHaqbm{Of$F~@fns8l1Fbs zC7#~vV^a}%^=-496D^P%xWJj1E$?GEf6SpHvyxD5Gdp@g1QwVM+qm|(v(ZrGx9}>F zLN*E82cVp_N0reCd6*|XQB-HT;E-Kqqj7~)-rQ?Zft~c;10Mj}HKdQzJ&2kzC?hWs zXaPGyk`l8ERq=gwZDkC-B*GPbd1Di%l2^!eTElTwW~{*8b!t~Q4x<9RUDAIL6r1*L zZ$nv}?*_4zoKZcmtcjSCWy`sd91>*LnEhj3d$h{oViFEMg>Qwy3-k0K_P|K=X$&=4 zux*1;)ZOlx%{7|ct8JA@Dca+c2%z6NH1MCz@V{UVI#}LKwEfIg(Hj>;A9M-!377d4 zn3#<>0*l(U*BE)v0L2_iQ+1sxIPOI?O;kgTwfo96Q4L)8UgD&>o%tTV*>2?QU+_II zmY=pqcQllWWrp~2KQ6W1^&Qu|-hcCmm2-hHH3Vb21xT{6#Us_n9J)|$GU~?2hg6p+ zpht`nG^t+!Gd~nhql_SH_<^heE8fB9lQ95_OBOExQa+NRjZAvg0r?$!xw3cq0ImE- z%+?J&@#}z^kHY1NOLS#W`w1BBcG5lNE!E8pSYUdOLqjq&y#%&~k!NJPnO+EIl+k*3 zzoEDt=HIeF1sMIaoI_jBZ}h+T4v>C8nh;@cipM+VmFdcr4y)Q;HNIY#KKm~-);V6M#SX_4eiXGVm#*bl_0*^&+9i*Hu=#Ng4sT}z*4|6anni}Ef9c--MDej1H*m=5cp-k zxp-n%|NO{u9e>XOR3xLP(yvenf&tCQyOKGaAd!YZBQ~lT@E42;9F-~m1A~3$$jezM zed5G!WL}--K{)2kaW4EysJvhse}{KQv@Le{HpB+!elcl=&94(OG*5o0-MXagM9jWv{MP3GsHvEWUN*f}vOCbmMDL)=-IiFhli7({OUV%F;_8 zY4BCB5Q-L2ltKaNR|&6dJAKs~m4P;hE8*=27*lwzn^=iYtun70+Ly{Bni6Fm#5D6= z13StmMC%uj0+qz$cmq?i@68Y9)%48xX2?H>o>L$%AvC8n(VgYv#jOLE;5+EsIQ0$- z-TlOfyt0ifH=SKi>JB&&VAcOT1z3X@Z$9{0d*pzr*l!t1ho7zeV?Pk?r4XCKE&6l6laecJ7=_2iOwnzB&Om+PfQBncKE_M%;& z|F@otD+BBDE+)5q=hqbqe5{@OaW_Xw2v&4TcH5oXc=s9xeK>Y$jyf}Ss05t{Zc)Ii z*20h9fmuGs@91g&G4)vA4f@_Ixl;+fpn@(KgbLz+!!%>NT(?(zNWVFn;*dT(l5$h# zQ!Zbs6n0=Xv^F$`iUq!wOLD>+of#B>S+7IUIxlr%d}BLe4JfoAIiV z0~-_pD`(HGa)s^q4A+hDbY!mLDEJQ7mQ@6qsH&LIHb+{mQ89lWYsBBZus{XdyH{Yl z{rtw!l%dJO5$wtC?)(N!HQb}V!N}@DI@OgxaqHTKJFY<&J^P#@+oGSLh`$_)51z{3 z4s2aF2b_bhUMNEJsZF#VS=gEMkWT%V4+Z7+82D>z401q7KEpGD8n zpVlmQv2)Pr+#|%}zL-#yZ@=S+`<29pS}7FWh=@6LY;*OEYIJTJY@Qa@G!gw!2qj1U zAhwFjg&B5h7bwf(e9u@a1N!P63nGtZ5+qe*hm^W+{nk-9ugoOGM83SOdefaH&J=5& zsbL4}QqClUCaRodcIzkv@aLxiatM=J+oJEADhIDjy`avpixtj?CES8BEDzrTV0q&n z|CXniXx>I;n|CSi)|Ioll~L0_;5(i+TLSwsnBKu%`mAC( zidA6v6M&(51p=r2D&zEY)4Z*@K@gjN>G4DKzY5w-M&N4dFa>C}mI_w{V z9XTgMayNQx9Sm=G?}b<1efvFZQ`DLa-%yG&v*tRhTbIlj>5Mwmy)4O?zf`f?&??i6 zK52I&=X*GhubCgPbswZnVNfCnhP;`gyWi1$y|yi*1FTux^0OYgzr)8|i?K^r9za2I z8svS<&dbTlPi2`{!H$`8<$x<=ntCL&yRjYyNBx9H7L%V3G$kYem*9)331~`~3(NX^ zjsE>I%n$68rvGd<4jm&Abfj$eZDMGMnpVq{3^S`hbR5ZC^9hzvKYV`r2 z_WAV(JLXTPZVWVyA9t+oZYZqjj8=)V_)|Mv8+*mNg70sZOMKM`MXd5^5fsK6yU-HV z4JXSUivztxO$1B0>D1$S8c*lukS1u2>K3iD*#j(vH-V)vetRasPf#I%A$`LqNg+;J z271tC>-!l^P?sz*kZGndd)ZHD)vKnbt3?BC7)ReqrucDb7daz~MsCP}>&AFd;Zr&wT%0%U*$LQOq!t zZi;rO995s0b|)~hTxWV4AL&19KTdqedTKAbpy868Jt|O zp<`ZND3#Ud!ZJ%3>XBUuPoAA7Cb0do*^;g8?rHOjPm1xr}=+$9QFzHhqzqrJ99+L*;2F|}gvnue(qa{H`0%wS}b zF@F4mpK#Z z??SFiW@vQLJK$|5?JMVd+ZVRJ62w>D+79l}-I!jl{;ZT78`F9a+>r|kGv}(IrI$5vd6|p} z#DXILfi5xo`bM)u1BPOPJ<(WI`MKW#!D~tB#36WQ#)d+aMyDNn|DLiy>TSMRBqHdV zkE@TVN1=FFVphu7+xL<@4Kgw*BaP#x{nHA=3?z)VWGl3)Z<~MCeglfHP|*rFd*cwV zbUzUCQkEb7D!yJ%y!M#oDo7e8_#R!Q00!Y)d&4a~_`n(+mFc^@^l37eRcwc8#t2z& z$rLpM#b`;T{k*dM&GBkyXJf`n5Dwv$@Fi)g50?7Fc~*z|mMn%v@`c9j_#OR^89brg zwmF4d52$3B7J_FzH8x>Qk>F-O158U@2N=ed+F9n^S{m5C>77SmAmn^&E295`?Vin9 zb-?VW2mYMWc4|jK!6NPp5s*%&xHP1TE@a<<46KNL|EwS2N`nPlD|o624~X49lkCS~ zqWhr#XgEQS0RQj)`5!f{IF(k#lQ@y#3v;;A!>yK=SH{=O+eeRXHV@RAKE4%50LD{@O=k;@J))w8n8VwLnwnna1*Ba0HZ_?Cu z3eAvF%9HD-lE=05@Gu9D!B&GVA3heYpX9=95hF=b7g5nMCu(6CF=vtcG6YfHyj_iDlmlyGks{e+Jq)$w5x}i z@u-VP!fzT@n=G&MyB>}!I7ZN_*xeH$kU*+GWpAgfYYt}+F* zFO?Z$?{s-rppzySm(pYMSH|fc%{AmtB&&OjHq**~XaW2?- zkjG`VD$e>YMkK{t-=jt{XFp$J`FV8w1#_OP4 zm)DD`__K3u)S0r!z*>YKdtD22dJ8mSpdYkD8;OQ@w3`Mo=Z;)K_C}0kDR-rCt|X>4&*{y41I3}*ePEhFmc_ySv;sE zf0qBdAO2Rz%hK^g468%n0Oi5#b*moBip`wyD@8z_6v-U4unD#R^*CMLshS9;i_*hjm+^~HtsJ!nirPqB$SzD480k%62x58 z?RVp>QqYTBT27gB{{9x---Z|G7w}=9xyk>6*|kV)ATH5a0H>T^g*Y&SY$SIXQIj2^ z=CZTdhbp?N9E`7mon~0sJV6n!&p}W$Q50;h!Fj<^lK(l5QHN-S#88k_fPKm9OB1sh z9u>MTI==-mg0n|4u-V2lYc_u3<~ckcfpKd$|Ni1<=SSdV&9cZZXVyRB(3g(sk2n{uWr#_za|J<8? z2gRkOhNq-pOA$!4LfPWCMl%m)LwB%1@6jTr5IR_u);jn7#0QH~JTZ`hE#1)F-M%;X ztCr>3$Fg1o5MWx%JfP7XY!^@Ye!h%=9SB>HZ^2>7@MX*BZugH?#9UR)pnf)jnrs#U zMF)YqeR|>7>RK<)Tim@>dQ8cly9~T2xO`9-x)7)VqkoLeO2UD+>-~wh%g^d~H&ha` z@$S+?o8@1lPi(-31ZdF{Pdc81hSkXMHtgXrclG8uvu#Dl%aA3)t#K8nauc%)?; zGs*!}6C0cMf*e2`;eZKrAdZz4`*Fbbtb5uM^DJJA>C06s5@>e>8ASq2h{eYR4V_@C z#|>tx>EB&xe<$$w$_p^txl)^T%i+SHX)si`Y zz{x!2XQoKMq(-h6F%eAvAI4IHam^R<-2Do$Ri*Ot^BYr$S~nJ-`p-j z0u2;VoTgEAb+ZyTgW+=0lX`!=o7cU-sfud{H(OV%n}T~;{Fbwan>_m6*-0OqK0ymP z*`#(}HTIOraTfD~k^PJyTFf*YIgxlUPy(T|SK-xXwbms9oS)1?U(T?vI`^UVCDh$S zoMHtcF+Nhi3^wePbtMOhkB81qbp?cG(il`1H_f+hg&lUN%@z6o`4*aYm$8DH9>7}; z5bbdbE51S1VEO>({dyO{3ETI;b@yd_Bel?mO_X*GI|w+dNZ7g{XH}>K3F$;Daf*6d99Tv*Ws$VY-+rm9wRaE`=f~8#xgzb% z;AVbDtmy^oKeL)SU4~!n-(8;y5Mk7uMG?plYpgwuq9t}}KIyjUH%I#>e|jgNmS-c% zirOj5ZyQ_ZJ9}PBQ3yV{60%DS`H@4Q93~6=^2otk=F+eU(p+E$9T=E%@w{-CfSoxV zwpj_Pc^uH8DxN?5iXD0~HYdj$EJVSYaUBvs^T{meLu*}4sxdS5G9c)J2GVwpfBSVT zNzOZ9ntvB032u5IH7)OKqu<4?1%+%KJItQm`)@i}pC6|#AAdwQIz!Z*WC$GD`HX-JlPG=YV4ZU{*e0wUd}3tA zuTO~({`$ahWQ)3}n*yiSG`_}PXR$F9phIALFv-T3nINQlg6w^;dmCVpt)wk9`VV$A z3X4Rmb}55;1!LZf2t5)iGni7&O!e&(g0BMAF5086SA__hEVvT#3BiMbUtIQ7Irse? zfp&j{>jRry!gv+fOc4Iun{QA8;TP=zN7KP>3kf&^E{_U++;rl~n|fy0{v+$zF4{oI zPWka5YKg+T_(@`muLZUjJ&8+U%&K3al0h$#;%|MGo)i&UU)7eVfI?6Jzx?k`9N41j z;su>n_bK7Z+8k3*tGqq4)R2Mhbp0c|KmH2uzhHk{Kji)LFURt_K=u7J?e`T?|9wrl z9&KZne%tqYlu*PnFGRTEhPseCV45AvZ$|Z2@?zjiL&eUUz%PO0`EL1z%F5*Nn5B84-Ug4Y=sbaM-?{@cG zB-bU?S3m898LU=6i&AI0Zedi$AUYi#n(;1T)A{+YmRrEB_#!89+KF~XYdoo^FDi#! ztFowO)F};Kw*Z0NG3fb%m)AA_0+hKTkR|HXscCZ&imUwckgoF~`_A!b%Ww^SoG;Zt z+J_~eJ=-x$gKTGwCo(0}b!qYHbaiV=jB}*Sto0kLJmRYzjN~5A@dZ1DJ%0>Pf23p6 zGKOXz5LX7XP+Vm{fKOECT#qqE#lnXY%|?n#O~x%*&XYd<(ycx4e7xNx>)=o%>D`h? zrlI2O7D;~6&nL@gC4k`wHePdaL%R#4Z0QH{s2LsI|Eq3VE3&8sUFmLzfJ^1K9{ga3 z=h(ai&rETB*G*-A@)t}m?AC)y9q`cBziCt8=u?&4(7^}V?fqjJP;RVOrSRpxfBFtl zF4uDT<@i*u9Z*BX4p2`1-uGofAId~G-ekaeg%Gn_!XMW-EfpUbrgE9Zhq@F(S0_@I zjWSQ5CY~+Pr z0J#o{_oBS>RgZw;l1s$0E{c}ZVbPs7EzHd6ph35aPBEcpaVJx6#C^)YU_ssE;Rg~q zB*6?pz>~&wW%AqB?%=))Ss(+QZgn>oL>>XT6I?rXi0Uo4XY?0i`f(|tP*?_)Cs?n| zN@6=pUKm6t3t=b*@Zw79-@IHo2Lx>XPxW$XDXs@<0YnrpJ5R;3xh%Qhxf*wn<`1QN zI%cu1(>t~N`KG^yHi4CbV&Z~eK#)B-;kpmsdXM;Iwo)!JE+$QS?rfHN#j?l3cL#AA z1ES0e*&KCeC+vjeK=E$xOq8ii?f};gmxsC2fig5$PS%VpHBFXyC=GZGD>FsjNj&C*R)<}hvjAhBstS%WOzd6*hjWsj8_~&qM zR(_~ai@Z+%Mu3X|6p3S+V;krNaKB(ar{$7`?26u3i39ILg8&LV*o-0ZA0G+9^T)gH z$CaIZWj(K#bu`2o@wnW%Gh~-4VwJ1;WmQx!ONr-3mb7 z=LC6QU2CPKJPp4F^zMtuXooO1hd25ZD9X?IZ{IIxvIv?#TI(m@5G(g;r=ptr3s#u? zp4pe3vgcsa(bcxPHN}`8l)_~FhRQFE!@3jf>L!J8V_Z{C^D{pAF3$j60}eYzQ_UBL zFVLz$By@A8X2{++lj|(9$4~rqM?61R-!(Q|`LNj3kUq!8(9!;k9dlGAO(HG9S;C?& ziir0#*gSSz3mrO07~@ktGIiHy8+X*ZQs=#$q93Dhk7TN|xmKp+8L35uapT2CP~fyw z>Bf`FyG-)ngA2DDA#3WKKNo}%xJVUYHV(*Axip2;b4BhRMB}md;$Jmr!~iKN(4e=q2ddMM4mNG zh&sDap`zt{g({mUQI>+B;JhqsZap&cmEn1$87Qc$w`%%O(zw0d11}q;X1~6q z2VJ=PM_d>0>4h z0d}%`bDtI)M^LI4cthh_^eiq`*M^l&eNutPEf^}#zQQst9CN+p=aGHWU~)1~q9>!WE7CXzLyUS?MpC_YwWGiKN8)lD=; z7>|8@f638Hkt=k)5r01Zo{xmWr2xVy;|>qdef!cb!ekoTQ4~l83jq@C+@@@hqi)O$ z(Me}t9kG)4Bu@lSu9Y$}_Gx{kVaRx}t)ijPMm@ ztj6kyxi^hij%ZI$c@q5SME58rX;?f(b~10UWAIT=wtAH!8Qt4RiMg5w?oUFcR=};N zvup3nui$koPmIR}Mr9=yT%nGr)WW$C<1PG3H%OD8XjoTqG(&s9KFt48vDv7h*M+e% zi)kS6w76NsbYQYrHk#iVQUmNs2Z|9a1%jf{o)NvxsFY#h1c%C{=X z_k!kUGrQAaUz+Jcx~##0-X?kb?dl;)n+sr_ItS921x_TW--X9lB3#q(yJT)(*TN;5 zi8@d900iTUwt3;t@+Wye1Inzq-x_S7>ELT$1sGM?1u&|XV0X?p@Q(psl%^k7r`_9C z%44?2d1Ozt9OHVmhB8iTPk3T%yxksOkt$RV5J+YkgC*~lw!|y|nnZ*8HZG9Us=EXG4Xit&6Fk zowBAruYOzfm`?uM>23BLeVf5n@YBAhB?KDyzVgAYP7zR>HLAdk)~1j9Q!)d zHx*MLXKE;ybDFlPW75-FWBj9LletC_XAhwZ@t*nJy>Fb_+%5bwbXae6(%9$wejDi@ zLnd;PJg_?K7mV6=X-iGd+nH9_cG=ygTX55 zh7H!6#tGr~D$k1dSP~6w!l|v)9Ex7;SoljC7aJFTN<|lSy2zTw#mlaR(t_qk!YM05qz1%1K&$U%oEt9YmW{ zp>yNsIGw?=7n}l_YoZ6!vkEBTMh$g-T!pH-`9@r4NvhL93CjY}r7s++5ifICP)=5_ zX2>zu5Uq*1T+&y2=j4exKzem+x=*fF0S|fQ8b=?g1>CW`MYht>Et zEdG^vj1^Nmx#emC-vD66!OIBGe&Gc4+Nb2&AtlIW6%%&27kD3mdLh>q&EQ${WmP)LebbnMgA4EkXvvM;AgR% zZSA5x-=OYClkZ1SDqKXic=v$!G!#ViVXt1U;abtkpl0&4Qv1ni!tsxf<_HPk;cg~=C)X5J~^Y!w)WY z0I1u4d~(={BomDPU$9{YT`-P-f(QPPQe2Bt1Yv~1t*v-m3`EK%>?l}hE1`fC$9eW# zXko2c1wJZ==wEQg*458xXNq3$8lkf({or8Dwq8?i)bUZ>g|# zhw#z#TkXt_$IAIw5$Ws&m?!RN2Cpr(^9D|y;IoY7gA1O`KbG{z;$4ea9K5^Vzw-63 z-v@@P4%n2zM+G4Qe&xwU@`5fBh9bEZAu>$*K^-_9^~+g*a@k=853hMWA{7iAEJ9&o zLSw}#Xlpl7$*DPz_auQx=~@ItWY%UO)jWQMnG@(k{+r*t7ex{EF@ZB11>u^>F+j4rs>eG-V@b#<^t3ZG-sy;i#2SchYQIM?5b=Y-xfcl+XT>p9I z2(#-=*tG$ash;GSVd-+>Vq1GR9jF|Fl9}Qk5Z9GE5hx$&7JdIxtQUJ!SIpB$B&nO* zxR|1$)Z?4_w}>_LJhW0G`+&nSq@qt3IL=f23K$5gj3qENHcn%vM4Dr=)F@Z+DE?z- zJ;}RLB`Ps|o2i^x0Ipz#th8|-)8)>!Qk@xK7Tj~hQ7Zc;CiWOeYB^4icDG21FvYNA z{JLx@E;F&#qHiLG;F?bopr{A>bSO1I@Mor9esq9-7Le@&9AjCT9}6cOV*)N=F(5ie zYwE$J|C=xMi=_Gg-&bq0JLqBozMJHfyt6hXgz8)V@a1jJsj+9h$i{qYmPe!iIk-!=2VEGVC1sNHJxj5^Ok#S1Yb{x{h;ClvIZ+%!tB}#Kq@H?bz zAU`9qaAxapprJW=Z7b;3uLH}n)6s)6D;j*Mv&`&x2w8GZvKe{uhK?fnC6WmSO^~%i z#UUX(n1(JvF?{k$Xa+4v^_4%TRsMLZAg>W(?nA+oy{D~)^YB{2(p5sok1#86kH9zz zD6WeoVp4&d#tI%bkR}F29^i8`UA}yEp(QWJDM|Ek=&f0dU=D{oc=p~Pp#V)+SR9ye zD9}HDLOO4({+o2(hNHPBK|jTv!@*PrYU?y3ABP2w_&`gN0~hboj93-G&Q559pxO@r zR9icV3uTj>PO%&|IFJ;E@G1XQDX-x)*P1O{-!bo5uym^QC)pu1P>7ga{7@Jmd$<&q zL1JTPmKug9+p^s?_~W@rBX{l$Mu-pcIe7Nbi?r zoMgheHUaV)b{_>Tu9IvhNH;i*m)?7E;xLb7!Y~P1z-U7g=F>8dT7|T}s4xN1 zxCbuMLo#Y;^3u_)!hlfd2rTb8kipMX-mPL#qCkNDrOlDVJm-DuYhHtwu1F};g2Tc?T#mo=tN|vEd8gAB;qc9 zjodQwHpVDQ;_JwcG#E64A_+2M>9SMs&@&Cop-Ea%1Pk6H zC|H>!ZP1Qzq>JPCMe^?=KNCFn-uXWvEAqW}erF z#nc(4(?$JI+gx8vsmGrHKz!JPD0Xznn{b4JkZ%Fi4%wQ|{!6g3!oC57ap$5NI-y$A68%Ch|A(&-v0Dtn zasMKZ{|lV_&q+IOvuxHSsn$TM1Sv<<`k#jN&!6~D{|!O44**nq39lFIr1`W13_VzG zX-rL3jq+|uWr_Vy{ttqb=w z_!HwU%cuZB#>w^Vhb#9)9UqWwsUMFGhAh_~dxzG@>z)3$kK_e|{fNuG^mGqE5JKqg z)8${D-I<1rNOD-Ep2x&%u{K_aqkl@-&rMpL!Wrj^v{}>SeJuIrmPQ?bgFlJcoLWf4 zgjnV#FfFCe4lLOqL!jY)D#}vo7r|RqdQS?VD!R;oH2x=tUiQ0QgL`h7JYw=yDlSw;J^6(gQUQ8mD9KO_dN+8&-gnsM#dSQK?yiqO9}379X* zo}%ObjBaBU+D+jGS0pPf{`|ZLU0}qmajs?j6(vu zh50=HoHO)1%}rZ;-_IKD^?+NhEr9pz*cI z9VQ77zSiq?yR!2l-eE5Ned zo(|^=0X)m{=!my_8_005AqPh;h2n`K3{Pm*ei&*1`tAkrY!H_*M|qw{^Sw&~zuC42 z#KWW?->qo|JZmBN2R*~V3<*kJTnQYf7Bg_x6>r5XI?m^2hN@jnj6hc_)?BE-{QVG0 zGcjXAXUebTIjv(X>71myZhb+cnf`7T4FgkhZe%W#3S1w8M4nEpzEyuq-dTkyg4f-{ z9TJ!jOQUD#S@r7a+X!x46)blP;UxbfS&WWFy=QZ;Ff~tE=kfm0Ms*Ftx04e5A5MbAXJ(P$mYyx$i!>f1hqXtpwrzC8N zA~!1lw5IVwp1rTmp~Fd}U}JB?GG7uqDwcmx&()Rxg#zy!13ql^sCqBgCeScPeV$g? z);)n=%U`t6YL@9inv+Y-RNV=Vc9!@aoy z+?x}?z2Tp+m4pz?WnO^>4PIUa-CpjIDuiEj{Jkv1-w!YzVo>sO=~70VBj51DoDPd2U5Rl)}Vq@1^74~=ks4UwyR zCOwR+r}&4cPRY4ixHt8_PPWQt7Gm)jy{Hcd?>m#fQ}{i^?|*U1@6Xi2=8H~J=jrK8 zZx01nUyVz{^Vu|`u6v)ZJ23N_RvhhX8nR{Olzq zh@6a4L;*KKQr$E}PX43{v9g_WnQI{iII`HsDUQEVtTZIaodGh6vm?-D_mey){K zY&s0$tg0-1-GYeBoi}i&M9ZTlkJgM9kGFeZ($GIbtkklbZE^Wd{NwO_aPrW`{Gzw< z+sw;j3r%$IxYJHi>xKHsz1#EMKNosDbBO5}fiv3$buy$N zbuR%x;k20+^HV@o9h)g@v?&t$%zE<1=KdFZZyi-t*Eala8YLx^ZUqDsq(j)qO^Jjc zA`%8jZ7BiiQb9yOTBT7^N~KGX5K#$9rAtyI1r)^ZT6=?fKkxHB=lKb(Z-9{piJ(Fh?}a`=0v%Hr00#z_E0Zp#Ar-`-?d)b8~>}Et#PC zvLpK3f>lwo^XJ^(F z^H_y&V;m+>^|ZN@gE#-Zsr%U5vZLY{YtD-e5pk=sRME6Gn z@U*-k#hkyW@K~VdKcd1T)krbdEqydtVh7J#`tPG6eKmsl^^;+e=@@r>0~;)Jev`%N z@a%UxkLGb9HMN%him?56+*InHHFXmV* z{185K`iG&I<~cTgw@aa)Ngf#G3rIj|M3?e2*Vc->gxwo&;5`|&N=Aau9Y~w=%^KKv zJ*7{aqY_((qb|Sc&&Tz)z5AE*Z`Z%zlpM)h0H(PZQK+rG!~0DBmt?TN{^Oz8FXJtM zvg#?=XggO{SZsCi#QU;YfuO}Nm97~r+=`5s2i;OEpS>3Ddf#%%4P#K=eG{0xW9CeKv1Lv=^803K!2I9?XUA2Q`C04`rw1yfaPe_=3JN&% z)3+qWn-QgfB_Ecdn)_CPVV1&$sRgNqYOwiHGS2Gjhy9X=k4fdPX#c8B{ZN~XECX(e zaEniS>}-hDL9|RFd*Q@GK&}+=}6 zXXdaa z8w%Wrxg*|~z9z(F|4sy?A22kj_p~b@Bfh%RtIBj8SdQ1g0e@Qn_-o2jcNVV`=~dSx z(-DP@UpzqG-_5a*pJAgEu&*ED-gE@136{I<47lG>08F36&Id7`VNTeAyQ5!Scy?}U zvyA6@e&jN@lhtDO%S$0WDtAV^Iy2oZ8$t&6q!Hu0v5kEqY;ibK!(;LE>v1xj_r+2t z)mo@IqT;?rPIwOyo$kG?F6KTMy`L=Hit$jq3w`4)MHW#aM*7QT3bzZ@4^GT}IR`|v z7qIY6-3RMPzXzVbhvxs?eSD``L>|r}6rxrin^fr#L-iru< z2E;oz3>t*;0|!Kc@tc&D1rS!^uX$crL_+?IU-Gn3%>AJoC+6*{5YwDVbpqpSR8&v3 zEW!!h+0nWh;SCCaK>kJgS~+9(R{s%!8}4NaiLR{;B9l>`9_s}UA- z?jKd-OwY|D_vD8dgdFvNMXQdpIvmbhzx(wUs)mozb96OI!_#q6$=lez3cQ}NNk z>kC>*syBeRzGSi;RbV{$;jN=14@RZ zQ}mYnc-1@sa-_>{_6;P4Ws%3^M^h*RcL4k+Q3Os7kF!$&gdDe|lI>zw*MY^~sO{Yr zT4GkTYd^R3Z6uiZ6}|SB#Me-~)%NT-Ecc8&j?+=O zewkqf-Ad@T7fVrAXBu+ToiS^Ul#q*C0O~yrm)9sznwGl{@!DaBv|ggc zHEW)lGF9Z+8JTh|F?QGk4ibPDj~+eT<*%oK0D=%t9mZmh3{(>e$oD@3H-%Un-Q`hhCZqy?s3*uSImOY$+^_*O3M5 z;$R$x94=O&3U=EA!+r_Zyj@7;FV+LYo)oBHEn*(;@UgMDhcs^PM3~$bXm}juclWlY zIsLd_KO?+Nx`KXlp6&Lb7}3|u_T=7}s|g9cvZHO(C54VWnp?ybTs0Cz_%uj})bBca z@hM^s^4dwaVs7F1##Cq=YZ=S~FAicm%lzmtNvaAM{KH&aZBA}v1(u}@J7EMnF0>v* z#1z-h|3+mDFHw2P?MC1{6USlxK|c9oj_gB^uQz_IHGkufX+y@4+a}p4*||$ zqGS&O0Fn57VD$gHfS~Dv!7UkRbR8!4v>?@b}H@O7@-| z8$v%)g;wamHi6_vCm~bGB*I=rKBj?k=HZ-(hCs=hH`$V9cnHQ{{3oJ1kRgD5gFLq_*P0Y+a|(#E zlDbt;%!@Wwgni&xX0{}dDnOUot~CoLn47l~+=%M9593myF)CW|Xn#SHIM1=?9KY)c z9qB?=)>V6s7ocr|Sq*x5O2;9;-_4`cBIds|56XVSH`cTf^+fri2sAuZDh7dud-OM0 zY^o<7y&XG2jrW9|YSD%HMpeEhfh-{66x1vZyw1RPod) z?H$+VrdvMy%Uep>r^HX$^L!pwGtU``kAKiGFHOERF7~+AfN;gZS7zZG2c5#vtGYCE zUF{^OyY8d1F~$$M&6@K&-fWX?y0|5PX+Y~maq#!!h3S72~Kz)9{rf`yi^g* zd`W#CByT}gDt(%(4*u({0v;XOMTSj?)@C0vOw@VIOW(3_yFoL}v`S+&!{W2Z zSor|WeqA#C8psDkiY@{gXXyKUZjhW=R?+lxoPXrmFya_eGIJ&ReE5Btpeol>h^5?* zhnhgs;n7Z_0t2r~=8p2?MvX!gMd12*WmlG4>B}&yDI*vzd;(^;C^uj5_cM1CUN~Q9 z#4g!#LDbGM$;tQ@jK^aQa8?eSS`7AL|8^WyV1*vhsOb678GRSB4}wA;(-G0h*rBD^ zw1Ys1!P$|ZF>Ap7&3A5|4T0Z+FZj$?5||u(`%R)n%xeU8*%FO6^WHNk-B+%omOp-q z+&N3qdn~0law8e5%FtkhI_k^>=g?_{=C=ZIi6WHJ_v;;?-J!~?D}I;~MC_CY%G1n{&L zWL>DwG!lz^3c7&U?KJ^1i%1o`+7W{TbOt{BU6Sh20aR1y8w?9_+F9R1PC0UpRX*Te z7K)^~cE(JsU*lYEUJqY1KLKIz{aE=`-18_{xcGFZ-QA9dsmYjzzjaHdY)kyrm+!+S zRJ+<Pbwi8@BeUqS(F0O6Petl@tDMOR1sWxKniZ^$5X2f({IbRIPdY z1joVIB!2MMX0?B`q4K}AQ4-lTfV}u;H!@DE?Wrd?i9YWBJ~nu4DU^mx7T z%`V6$*;A9x1s{~+`I?_uFV7xU*K9hmM}s_M#keXOqrPLgW>)$ z!nTg8%~$NxeOm&yo5cvO(+vv{_r<;$&Dz$-)~}=$eV?Uw)a|F z7H%G4mt>X*nJmw9Z6MH$KJ<{`DvXc(WRyE|Q%dnhPw`DeocrG08dhOECQ2Pnb)Qu+ z-*uZN5pdmbxc%tEmr@xv@)Ttndyd38bvhci6V=?-eJj|xaILxZaAxRKgqI@urPn7^ zlnpm*m&M+%Gv@iyZurhW|55Jl_6^@pBDZK$<=L$wQgt1t;G@oWjqa-6;Z(jX#bH1W zfFPq3KlBIf`%>9?US?Ux>ja-ZPnCmbtuZ=Jqj|_+;L}a#e1$Q5#;-w-^loUMUo{da zvl}xAt!KF=(B_3{3PQ*cI)GVArfM=XFSv#!Y3Fr6eJ<3nCprCKL~A@Tz_EdAigIrX zQT9iS^3Sc>Rv^LDXG1+^&06bk-6Lp>A4@2H|ouHJ%T{klme!${0;yVOT5?Z?l!vf2Xe&L z*Ostwz#WG%b>j%6`Ady<##ji~7R{}(foPtNTFh5b;gbE9LSA`_E6&HOg_!y^56+&8a8uu=>IBzp9Ze5o+ zxz2I&oVjJ(B=*hZ$eYQyaVU8m{Jel2>ao{l`Ids(lHp2S6*QLEp0LpiKzd&Q(hrEg zFKmw;S=PtPmwBx*HmI0>)lWYvQn;N}gkbTFWi-+pWV=O()UL+eqQ*5kTSf{-r`GaC^hmQjQo$ zmjA-Oz;u}=MrAzsq?fOUpY&0BOq;cEXXi~`#+)S9#pUyjQv?12kfF8;#BAIc(!#>B zJ4cpcf6=fBWcynV^-O*oqka_2LM;%yd1{EZn~=OQQm;|vg?QJ?wvYYGxtRV?RnzW~ zSTzQ|OMT&N_j5ERH$2p}mkwcC<#>Tko>k?)_DF=s;E~Nqy?XM@tb6otw`6(eB?$&P z35qo3o4L=u<5OdGJX8Eu_S~xbM^5F7Rn!9daF~#3S6JZBl8FF|#~it138d(K8{;%5PqV?@#ZE>&ZQyv27W}>Oz|5-yXIUr z5hlPwII+~Fh#6DIamh`EAPys^PZJ^jXtofo@t6swmL;MFfiz9pvLOS1gIs2dL^3tU zWqkDl*`=88ZwpR@YeWm;q1uUW*S|GPDN9T{@#JHp<<^P2^Gpq=!+>eLdi)4q$155D z*NGaFfHmPFU@_3F?16H}SwkbMU(>`QOw9t<^ga_KISm>C;Sqmb#3Nw2`6v^b2uU(o zHdtNAt~K^3HM)4bQF2L9my5XZ?jdp60`pei7UR?;{f7&%`5%x0;VF~`qd$sh2DEm# zqL|J<#1V`;$d1o0i_B^X>?cvp|sCayZ44Uh@SV>*Pd?u6uW2S7Ug$AHQ;*vp8eYOZ?9y4 zkdz}E#AL`Dl6v)P2GKD6T$`ov(|=E^rwZbbAFJG?O+-uwC{@RdK4bJ!E?=%HA!W>` ziq`P&TGiB+f@Bj0`Ko|T*m6+s9l^#;Z*!-NIye%4Q2Ejhyiy1`{!$>Zaq~cOjxxgt zOtu`t0`7eQrn0@5Vl}-bf%U4nY%hIRjhq&O;B^iWo0f`sLF$u}jntyMGIC?U7Y@p1R^#Xw_;(aQANn^g>OE zH)Jjb0m3&Um7U@if`}h-XdV-8fL`ml0&va?b~)#$>96sLSPc4K{%%b=7^=~(=gp4t z>w*bmPiEOD%CHD@=(D=-1&*7&Wp~g-DUW*^CYuE6pFpq!rJYAOS|61J1*`=omb>X&iJOv3L#Gz6w6veN-{*8j5 z>K`ZwhVEk(1bn#&&VTGh_y5*GP;U3oxvdz^7!MFR_Ns5<9Rlr-o94*r-+u>u!bVA`B2DL#wXj- z1lu&ER4`92ntCPAXH zM9Tu*xmwO2v^TlR*jZ>?rsW@1_U|l)AltgI3a{uT)2g*=cd>yo7fbUQp_<>I+B^}? zowoSJpS9?MRe3{(Vv>8_-B5{+F_O?rNbaHcnG!KO&?BylB;~y6mUPT}d)wL<${x4- ze40{)YPacH9NDCJ=GwghlISNHu;}4_2JemGH*8z~gtYatKihh|Vo(16uC3!!%xCZW zrsRm9hSd>RG3P2V=3A^ZRwNES?*D#1%mMTB*oPD&M!E0>v@Z7r`Da zNi9IS(RrqA%d_;;X;ZgSy~-j_-@?*Xkq$o@d(ydTd!D$BZ!5uY1m!G$U~v`6Jfv_@r2ARnU<5wF>Z95ytUe?vsf%>7N;7*9 zJ@)1!W$!pwCNM(xzn7bP%HxW_R*$QA%37UQuVX}yA9pe~PZI6YJ-Y{w4{)pG^G9ek zigy^H1daD~SZ(k!rS__|_Lb8YFWgmk*H9{5%%w0=j#BC2Fu3*;C7eQ~QWMB8Cv0j? zUUww3ryQV1FNL~mBgL=Mh6K;qhj|HV|2PIpXHNy&hso-?nidO~~A@ z%e@>pMs$gt$>t%TSAa(#@Mq{p(%<7Q#rhamfYI7e?Z>oT;loD$tSy)nWQ_F-w~F1fpF+js`yUz_07(?`!(sQK4OWXu5^nxs&JW>d|ZUPzmJM(mAL z^J4$j_&q;S=5V+%QmYcFQJK*FA?IYVQf|PJ{s0#MT4t4zy+Po;+2+@&Uql)7J#+`~ zpjk;aA62c4(fRn~(3v5*`SGLMitTX3+iwYc7?6Ru>4>K8h$6~yq6oX4bn=%d0)|3( zQ}UwhS3neT0V|65iPGko38!uD1DyKK*BE&JzBH|S3wqXP04&VrI(}!ul5`{ zmGKnv-9;O4mNkYj;jH8xFZrXx^EvB)GOGn{SzgrVIf8xcZz%Z~2Tf)q3i}Wf3HJ>m zODiVYnQP6H@?Y&jB&YG zD*bdUaqRG`^M5k{MEzj^xMMxJn3Tb3AsCr-SY+Jf6bph9dewErh1FC4h9Sqr)Y~>_ z4~ulk#L=k-AT+k9>aXi#w(&>^D=0qQ%vHVr+ex=e(Tjh%L5&^dS|0I?yLkQC%$lQ0 z7Pt*&m7TT^wx7vM+e;~C2z1^Qa^Jm}mM8qBcF#aD$Z&D2?C5Pj zvi=Z{xP@dmM~ZOX@nAonH6H;lz8^hg+n?l23Yhtc{8=;_on>NEDdVrUapQ5YP@Nwe zd49j~{QW*&%^b$phr(MH$fhwF%4^~7(H0f>*PJv1!gZ{DOU!eX5Nr?x^P-*dJb zs^vb(&Ek>X#|NU!HeXfG=@YGH>$_hr9y{Q1Wu_wf8>Np~D?bHe@r(jFy6@{t-zz{@ zXsg`TpT0mbZ&^w;#i`gY7U&9qG~7yt&7FUpUO0>~p6-MJow0(yy=|Voo!mEk7BG{} z@iNIZ{fJwhCs2$stWGu$5LTa4v&G^Ll_^Zg>-OcMi8 zPNsa_cB4_BW3iarsQMQy`?IG8{kdO@2F{<4yVY}ju_)@+F}zoRvf>T-N(T!Bv;f4_ zA+dIdGs&Sk&UM0D*+KqDMX5|zSdXry$tpLzo{`sI1l~t~s%1Sc&|39N5|Aglt*8StAMbp<^u1x^ zkNmm87ZxyEx8O4=@R_F%<`+wlXZQ=X;({{>_$RrJhVJ{Sc~+IGSRW#aijaIOUpG0Q z8cU?W9gs)VAmhNP%}GD$do)&uXYFkr*<+7^1rCG=r@+|&LIkrNkwe+=?TZvA#@SZ! z4%|~f^Z^DYj$n`}`0+enwJCX-8AvJl@ZfhS6d){* z_^QQYw!DxZgIzs7Bi0L$Otdj&8hw^zIVnHP0>vbHcb3Ruvhg7{xetnGy2_{ z^ul_idaxQV0@=;H!#$p^At!>*IiP2ZPeo~r3Y}6p_xz+=R#T{pFk%zPVb-naa`~aP zhmE+8;d&ZL#&D&noA;oKVW(8SWNpeh8(L^$2%2F*^PXKIxt+`r(tMI8iZyQwTr<-n zXm6%;J<8EdaczvQBO`PG;mcc|l65X)QrhB(#I$YMLj$A6HL!M~0@V2yiq!=!`m?;m zmA#v)7o#F+~Q18?4@1%Gewvi)XWMlijtpHr3H8_?y`Q;<$j$% zHmp$;NElKZa>h)m;Lv;V_(ZPnzRzD>5cJqPC@6Uc@O%}!rG0`~y6J|Cr6c+BTUaXpICpAq@;buA?KC6HXXSdCcPaTH%K|yc+sYR~8kqMF;A|Ye$n`SdY#hqAI2(ttLDI&`wvsUDge9v4Mkk&>H?(s+ zv=mMy-hMC!WE_x2XRX$0#USHw4?+hvnc`T@vm~LSOc7Bg84-@;6<7J0Z@g4dK2*%2 znWpt6W`~7Zpv<>jTrn!=*!T$2V2L`G@PMRLOd2C<#mL~ie(u@=Ljc{=5&w>=?S9ZQosD?) zRAjF(<>Ax2nHO5#FnuvLgL=osVY}<%IJt1T_bcD7i{sOdiz9>NpxwWdB}_yZtJV+S z*C}gaiCZN>VyFFnHV*P3xMD7jTwlexUd?y?lUUV@Zs7U?hbzn~ZjAHO27aaU8&L&JjQ*ySe;D8p2ioN{*Q!9u z=QF)FXhQWNcip`9;W~Xlf!h_AL&RM{&t@74B!~+#3j++hp3U4e(1}#C{B&HPEq&3p z@s`TmJmI$s5~4=(^u7IhLRSaPUJ?`3 z93_Ux-|_ZHsskfTp9G^8{7GF!YFX#nyliUhyGJBys`^wMP4cTxHL!EtD5!NvphMwPp8GKLJ0j3fiKha*xaMX zG4>G~W(TUz@GL)GDK3V*#l?_3+p`_-#hM2%A*!%!Xo7$H)(7CQt3Et#&}}}*zx=*1 zWUWBwreH%cjRv z1X30YZb!apzEa*0{|YVF!;X6<22Nm_e*gqO`4Xs2{)I}c})pMR`wS|_%)P1{sXb4ng(%qqUftoDE{UK3v`2luQu zk$!Rr*H6}koN;M%m$;j2Ji~PBC+bQ_$+=bfDlqjz?hYL#2%8#`*bV6h`(R;j06i8z z%IaObU!tIgGo)A6W$cIUWcLVG)_b_O9;V~+uf&ZVi@!66-ZS2>p4NR48oBNs@ekAM z)NeCRM3f2And=q59OvSW0<7HchF7}m2&Bykm(Z+>oRpJN1l8^fq4(#%7qMUY zG1(y+JYPJQWxM*ZzU-_(qoXO_CD*K03wet@2#C6qE+b}dDLI{^UgrZMM1z74L#=2w!zG^xlh+&MjsmEW4~Z==cj^+x#zJ{u{du&W81uXoe@?f+rK_;3HdvHkTJ zXui`(uuEJFzQ7mWe_@#dh`h$^A+|>j^^UrQ$B;|sFTdWGc>;kEH;-?2PqD#qh=@Qi zD|?9fdQ`2ylDJQcS*%h!8OYL3IwyXJfAsPjhri6?K5ese4QV*op`#J!+tKGg3Y0Z0 zMxLWE!7+AT+}DP$gp@gb&>`^<+tjy(zI>KQXXzk7*#3I|X7pS>Dqmrn)%|Ih7~e7fuYXVAAG zbo2c_tlB*H5A6MNj(kM_0yE4N)l+TORV0&J38ZD;R}i~-sJwu&Z$PsE0K6t0cfI6n$7ELch4%TFfv;`Z6B@I4oh{PWwaC_1=1@1AKBmv$SjnQ9Fnr zYLVr~hcG{-Lz3v$n@n8~+~yOV{`;vRn}kqSvaZk<(T2aj&l5xkcg1N1L3BXYo}hEA z23gGdbN!kArCUkQ*wopQI58fYJ^5?9#j)pCEyETbu9lsJTGo!#vN<%X%d%V&LqEe? zhF1cSi+`P6TNlkp35GGr7y6-deqz)5uY68N7_SEv5s3aM>H2IAG%=L3!p9!l*Z#sF zR?ct+PUqlQh!kiJj6F8$e|aD@uh_bd-HkZ@%1rq<1jphT>&uA5L*BW1eHl=#TcPGE+a6b2@8(HT6ZYTcXM& z3)AQnW?`?f@GT&thqulYZPMws5MEN%RdzZb`^?rhi)X*Ez{-s?&bil@w9>Pvo_`a3 z0a^;@B(}xx=L(XY?y!EFDn^-ff2g@_ep&dWCH)&Ly#C>KM#a2~#&jo-S!5Lm9@+b` z40{A*jb?rOWBd$Mzi;?Jf-v>1vWcz8{VoP)#m@S}#!s9&oQk>sUEhT6lVl;a<{Sm& zDVOg&+Jca6&Z?C!MtUr+xz1G8>{&L%;+s#s$$y{Yr`}_MiVtb>47^c5u_!`~Y z!Wa%!lSz_QRI^f=x475byS%COjE(~q1N~$N505eD$#4<`)`g7a-5bOK`(^JeR0-KK z28reHjw`uk>SB5QSRyCm*ud~yd%VIB5w}!+(`h2FBT5c`UCwdyL>m!`4tRY59A{B+ z(Tek(2ofF##0GVJPkEXAWF@ON>*}3uX!HVai)=Mcx93~*6Hu$qo2&;GdxjdG8&oaw z*oS5rzQI*mTA3(LsPoy!q^@%K^PI%DTYGNK8~;QFZOL2smYm-edIY9l{Vntm&9LtI zvOssKcEl_$69LkudDVYPnQ6TE(a6;8(S$a@bhVXCs;i46!gC!tbRQE2qeiyu?L{#T zZ=Rg8QPI5qUB5w+$xDMQ@bF{qj$}_u`mcozvy#Gd#&VOJb@$0RfwZ4OrAYAhtu&sh zo+)OWIqQh{hTMH}C6wdY1C8fnQ|h|v-tde|<$9~u_r`jp(R#HqmNKEf3gFhZvTbAq zL*=PG=IIY&S7W7@-V*j+vKVzm481?xo9;c@R4E`wo`?VAs*Zfliq1#WQdjv}jM*#S zmLtE>m3G+ee4i+_H5h6r#_}|D*sm-bB5-t+<=vXjuOBp%7w};M&CKWgQL?1#Ps5&U zxc+_~CH5B&#NM-ie-2bw_P3`??;jwZ*yErjY2f-J*@pRAt>1TlW4dOiQRY~QXZI;R z_u6kAsz|~D?@^zsjlOJ5ZsODQCf~FT=N!;(W-EvKVvSxgCd?~-u_^db6 z6~$PAj&kkWYn}ZAtrog~ylyA*#kTfi*w&ukf3hraT>H)?hsHDJ9%t^aISiwhWJ2Fb ziPvk{SMfX4QDY(W`!=g8!|7bar`V3bVny#I3E!%{DvsLr^fu@HHjm;!;p(Goi&0ZrPpddu6QVxfcaqnt3I=bJXlQ zhwlaDkCb#AQa2W$ucdGDt;1x0L3X2L41!hAQ!)`LQ7inm`lyQ8(c4OKcboRFNR*O4 zLD(!^&_fCF7RFjl>I!Qgs?^w&vQNQ9UDRFVHnnzcQ@?hHso$0`vkj0cgj`xW}HIj?4qsh&rxf~LZ8M^kb9@Ca5h1Le6+46R3KA~1%f zgE!bkNV%~f9HFl394r0v3a*z1EsT0+9eX7&&{71 z@8!lJ5dD;c=!dfD(||zrc59*i1M~y=?zaD6tDrbF6X#M{6`{gHNh~d{T`v=L;SDGe zv8tb|^9yo%*T7eSsD36p`k2*vq}urrR5fgK0An_GNp^P+Mcqb6&o4*Ams~s(33~8+ zpDq};M`eCawz%>>{ zAwwVTOGK zpVjmg*q(Z;*a;KJFdxggA^)fv|BqX8Fcm8&|6Jv|bY}uk5n(+k= zPf!a)Z@9`uni>m~UljG%0e=mvqWtScVMB0)b-J0MnRG-gC&SI#NyNtszEOhjX?Vsj zRE8WGRNyV)4^7O9Xd^kdUeWM=8>QDJRt$Int$e7Z7BKoyzovfRKhb+3T`6PWLjzZs z1gDDIWUdB=?Q!OOjLN#{iN+j)=V9j)ekSyDIINLP0eFPRf{)YPC2F#5 zD#9KatBi>qN6o2GhLIVy(GEY%cyr=*jgm=YUfT88ITpSH1dOb6t$ALC-qu$mlx@!V z-)w}z_nwSwtmQMsGW98U9>?TUFHxW|JV9s-c~^&D+s^Y~VaWcpaG3w#B{yG#@~(^s z-V>=F7NtQi8&Sv>Tm1hM*vo%-FUn7aIpWmj!PJSm^6z@nX@tIJg+SWDsxdAj1W%vn zS>!z7e^z5)4-$%h#OzuwZiD6G#+nnBh79WZ4}o$W_V(u?^|r;Qi}dJdT5pty(W0~> zXp?i1yOW2;F}1yAwTo?K@Y^{LD)Q1tj9s7#RebS5e#^_>cw@;f-6q-c97E8yjw8BF zDU8%sQ6xnfkZQ?H04vX{#lp%Dn=hHBdni8(xc?4`gV{(NJh^Av5`g6p2itIpZ~L94 zQUmAQAx1vXU#;d}sFmn^>50?zpjn|F>@K>Rz#u0hKTz|Kxv4rRDw3)2Bzr-I z#eIJS_*m#C8ZRL}ma4^`XHGeGlKY~Yvfv!?;r5<+&2MrIlKLjRrnai8N%SLil};um z1MD^>k^NHSfJFDYS+_1^Q+-7ChZTWry@vqieAPX{hsy&=nC{EkTtv5=PY2g6z6utb z-tM9jCGXi}NoXfWk^^KT{N6t_%{5D~&e?^9;j`gj_;>)rpZNoZzjGLe-rzjMEjW_$ zrTa+^p!2cs=78B+tmrxa2Rx!)k`ZRZkry~ONj|tbQZ7|jTkqk`J4n|c1FDGDDz{pU z1C^s`5S)8%b-Q0be%ii-3NZ7!1g@v_e%wdFju?GE39pt~dN93J0AD^4$Cp12e0fvE zOM>iyBft5oRL2;j1IiLeiLN7`suK#^)_3ng9+-&=?tyv8jou4f^IrilEkWoa{Q$KM zZEimO9S)0Xx@@y@52j_?1NFU8CYsK!hh7PiLHqwwy)xSb2e@1T3~*ISrRwm9=D^JqF5?+<<$eS<>yf=3k1T? zx_FHWKOt-Isq{x+9dH#6r2Qex=)vEp)ZMj_=#V&O57%e*6~0DjHP5S#=Nj8Ymc{H% znZ^)zFeCk^9nybd%1XeGK@`k`_%ZwrUb-24k}rcRAKEO=GR|8|U4JMQ=$OK=EZKi< zm&Cn=SV~rKN~1v6F!$Q&!vYU{x^32e5QLn89UELAFeP2-aar`q-6y>g>Oql~y7UY?;R*aGo5kj@RNzaD(w2CF;)}YgkdqQ8#ziwjgk#3)PpAcP0Ax4 zXIzDUJn5eQPQs9)%Aba5$(o_9tzs~+!^AF5hV=D3<9>U{tCTmcqegMmGq%L^KI?Wd zbbiWA9^ScZ7K|wttEazF3xa|`x8oToneg}KJj zB)ZV)yn}qG@+a!^953@NQpHtz*myuN&pUq|XK=&wGRZ!FkNdU7@&+7}|7gQ~s&oG1 zM6mFPgGloeHpZ^LZC5t!*qf}qqKfYjd=~<8z{hprea0taxF(8pd{rj zLs`B??Po!8#-7jLu7V$70K^FovEqcY?2r)`B^Tq=ohg*j*}f0mNz(PY3Q{}g4JR)0 z5cnI*{82^El!OntJ(Q+_FL3VanA&6X-Vhq_ zl^_>Xg}Wev61X8+xS`A}v33Ofe}nGKD(RIjt{r^~6{2t9{+qsqX4p5A7He;5bpv~g zX+H+Wun{Kgx1bR6_Ipjd7ByaryV-a^W1rNf!fJuy4F#@`9CJ@E`*HNVu;l^?N8loB z7qyLEZYvTxDie*z)gJsr6`Go)TGI@hYC6*HWDV&WiEm$vC*}{-6Wsa60Zn1jh8kJtkJ*cZ2ltQIoeaS{&11<+E{W#Daz1QQxQFmU9PjZsv; zHEk3lHL{*Zvkpa)b_%V){P)qY`HZMD0d*kP5^IrcjEf8siX%o{ati)p+IL)43;zuB zphr>{o{{QpO=Na#JoEwIV3TxCrq**EM6cD$RfdVFUd($dhL@&#{IJB5MY@N48@9F3 z;XQjYyH-+~O%ZZ8&$0@2YNgl-KODVz*Yn;FOQX-;om7Q6=e+SQZ$+v`;@3C3RMyHeX?M zhQe3&=m||#N7nUVTQ)-i6}@8Z#qX`20@;yQIPl%Y@P>Ztuu5_niyq$c^|hyObUQR= zq^aW4#dBC)*44lV+q|4!aJ9>K`1IObKj!2=6y6#RdZdTQA-8-PgG8$Rv)6Ohd^zvk zf8~f?%E+KXR^iaBu>MIWWBmTji0l#6*L>C5{e{Zja$&b1k5jj%NBkXylZY3|(e{_V zshyyJ^T73GG$OE2zI{vF;ci=kZ=wf&0!y##Sm+-6+x>SY_f^t?6aI_4-T8l4(Gvbv z(F*%{Sg(`o5Hh`Qjewm87Qdw8nBwlP7ZJw_1kaW&;Ptf;Ki*9&*0+k`yax0#9N&Xi zPi?PNZ8k}i($2Pv@fj+D8>@fUQ*ZYSVmXYA2Q#hx^0BKtdM++U(@ueMEJgJIsHaXC zu!lBsS^b>jY zM0A5D8sMi|ZUo1`<|6exfw~ZOyup6)LJ-Y8lB_k5}7tD9a6_huOT1&n`rw6#TL%7>SY^yHS$!ca$V+ zs=+RsR(0SpT|wMPw>ECtU+aCQiHulIr@IxL)*~vcy&l33N7jgcGv13%X=Shs;ODDwqw9_3?xWzdNRU3F!r`x1(G(n|uHa zu%~v^?ZQdIgVORF8J%!}sFh)Ml#3PKgt>wJ<3_skXAbe~JsC1q*2V(btS7bYsaFUs zDoupxJ5tY%-Uuc>M-kZKDThQ4-ZwqHfOebV5h8t%{Lu|M%#*tVe;DuYaMR zX8+iuML^2U@qO=0M7vY4nuDDnK(sr>0>8C8=Yu-MHm|#14iQFXT4d|v;xDw$axRav zQVLM^2n^F3-{E~{bvreGsHcNj)+Lw+FZyBxnyT`aasTo1>3aH?qEw_dqaa}XiIQ1G zIXD?F1dAQ4VYlObpaQ05>GASU|k8#aRWcSIV6TAQSfAJG2=S~%W5&g-?mrXQBG{RUJCH1nbO*|S74!DtQy?R+9?Mhh$vhdp&qpCSznjgS^TNu*MD!#Mr^HyRwavnn6n7C+Y%& z(-;0O9l{ehfVgX;Cf5IeLh$|E9RR6U_^O7bP7@IlGr)FO0C(P{JN*;&1hDwgG?ZYs zU`AvOFNCKC^oaf}7`G;y69nY2O9-IH;3n~%4d-7=hcnDLmhTyR@wWn=mTsTUhEtMM z8&!r3oG;=SdHM=-@7_yMvX`Ro3?;o2rhS!T6SI(<*Ioj6YQ|V z>|fIM_sVg;yZM-I7G(_Lj0c350Kk8Wv?V6~T6^{ue>0)*PgFKK`6M_qj3@rB0R;=; z*F%x8@;_H3{E3=tmtLov<-jVLAK2~{>LGTz3FUU(dyx_Q*1Xl{^{Cr=- z#lG3n=4;x6(rLuiY1C~QwHC_0(JpjLIM0UcSTer5MDu}l75*-)Zvzjo^1J4a6nJ!h zGQ_jVMR3UU^mC7t9)!b|(xN9YKT7@96LZzkktapqAsqxwu-< z;6EOoaeQW*eR0+r9Ur3h<4($@(NIF`eT+51ije|t2?^~@a+J~0r2kqYPN8Tht^aoK zJ1!F0v5Yo`d4Sxa#?!Ih5DyahF=%(nYh>)-Mv`NWa|Uvj@a)aZqMPMM-QasH9f}{N z5lQI@)N^cI0`Z6ADI)q-GtxI$Bj?HHddjO3d$x`0>NDgr2wWJP1=dqc=Rg)-Klm?T|7%-|1FN!u{G( zD(+*gC!)edwMrJnmbAiFV)doD#mK{kT7Bte<-KP0xfPCJ$^+!?I^S|u4A!vXD)u+K zb0S>WQ9I=Xs5y46F(-U}32~r09I<-z0BQNhI4r(qIy3yMnnMPV`PC|&Z@%lEM&r2s z@Num41~D@zbC7rLYCXF2kai3(Tl_yXAe_92on;>cAJ(^fZ^*Em38g!R#mXZD{j&ah z_d6bA1SCGC>iWbS1R>51M2Mq}72<^dj$ZI3X<>XR4E{Ks16m4xOD)#Qu}bOPC~`Ho z9ppXx+Hn>ECEo81P`%vi^nb@%xz~9hAK30l(drrO>69 zm4S;;M1-DaJ|fzgG@|3Kp)@cm3EQ~-GXKi~X+}8%M^CE0&qD-TO7u}FZr;w;Noc1R z{&5SxRS`Q{8mvVDI+_dw8jM0L8em4cjGd`#D+Zg-ZhvrZ*WCgBr0m^@;D{H5s+UYX?u)llsKk&X^-U%L@cVed(1eH|hx;M^VL5j6k>;`mbKumn*O%ME^ zA*zL4Jq(B|uwRgYr-H{|2c>oSAqN6=AEr+~kAk!2}CG zfhKFo;IEwGb@OU%guO0=KFZG(KSKBSRC!m=q3eQVOW2D1pKhSd18WU>?ZgFEu+J!A zDQK8PV)f*=k8zkSKn6sP{8RbsKA(m3gLF7`6qJG9cpwAG7m!kb#EX1AqevL{`B|Jc z<5BRxx?cbQMD!EY{@K^us4(WIh7aqabxE>R$<7->LgxHL6~!pR-&2FEY$#*N(v zQlx`Fg^fUnsier*8P@gOum0Lp|z89pQJqa^4}Nd@{hjWMs7CUILyD{!i32a=ePTL)i#&`y)@^ zn1yHX%PEW&cih3;8-n9iX(Dn*Q+%)Rmrr+uM3|7lTy@h^L;^%gisUGF=|onTh~&G9 z^iaQ_2Op}IfWTi76@rMF@DM8vH0~^`R7CURJ!6$Z0Jat)LVT#ZhyW|~9=L3Ez_Q$WNQvPg$p7CW`PU}UC_13^5)U$fmZI=PgEXy`25A^g(O@=B)#-- z#~`2DoTik~dkPj8IJ^Q%y1&;dXC!6($QkJSb(($d)P9MR*Pin2h{lAm;vHO?i*1;j zow#p7(P2N;8^{=Dfo|~V^xG?3MRgLCEMUyjM$ASc&Hj7jyK&`B^8MDH)y!+!)pU^T zoFcvQ%SD7BeVA*o)sX^mUF}v!U2JWP{9PN-+i&%*xw)&TkAF0v{GaGxcfTY3w>$#6M2x8+9qGxdx)^a36G#MvR*C)T?1Kr_`6QM12P&J;kP1-Hzlf5ZflmA4j(204r>_T_G+R$z4GW&c~sWVVRm~4eAITe$ zz2cDTZ3VYTC_GS={V$CKN*~y2;LXv&6+L!$611aqIes%Z=zfr1zc^I-T#i;sSXGCw zt#!@Hpsx(t=+WaFvqOs(AM3|E(xBiT?A^mkK^WBoDKnCd{G-=D(tFSaD`j2zqlPux%*5tjUVf5>88pTn~$+G?_rtGppcV!KJr&5GGP!S^B@p z@cqAWH~sER%>VxrHzW1`;c{TL9y0Pcb0G3ZT+7tqkyCWlF}VY3Cc(#pn!nV0s}}R-H3#w(hS`tp&)+u z8gOs-etz$BJn!+o-}l$|2L}qw%vyJ?wXXZR&QrgKz>v%Hs$5%)VQI#yaM=pW!!u{2 zIp~}y=lWRPr9WL@9AK{oE<7uA?_gdRav_t}#qwdb(`=>?4-ovccWT!sXG$$ZNVO+w~DYc`8>*r0f2274e%iYxNgV35+tVf-9HW z5330>@>`>=&KGBMU103x8+kCGL+t~&;z3m8=71E@uXyQbdHt@82>B$~G{dvi9-_>Q z;^)EQzWeTXriY(I)Ai5D($TLCNq+bn`faCOs`f|rMlZiVJ!S=KV&L~ax$TySAIgE4&_u^BM$7pT9c+VC?VZASX!@yI_M4#O_`{I~I#Ir9BL2sV<2J z02rA7Tg=YXt4pz>1>oBppp$?An|D+!V?Qr&Heu)4lX`@eBrdMiAGVR_WGmQ7h;93N zN%Z1g+C09SUYDda7Ys%s&UIZ>^=LzRp>C(swg^d#zxEXg(;WOUc{mwvAOgp|MQJx9 zVuN7b=NjsUj}oAb9>NW;lf2{w9uG{3jW&K2`eInv$Ix)j(tyiVy=f6r{FnI+)S&WV zs2bji78Go4{!o?*km$V{_w-FihVr&VViSYjC@U)vh&wlP=Zz_z_r*XyE9mla z!6)R?SLtZ->7{>@Pfsz%AtyeO4CXKhM2$9&bF8o+BSejeM`j)~bPB}pgcuZdtQf|X z{!Y2zpWZ)u!uliO2E@LNgyGBsBE9N8IE5XVD^jaDVdv=~c|^ByfV?#p>$Bax$vsYn zq&hI1?3?ris=OY(wczR_oa*-xo!&C9v#$C+>zM4Va~=HvMF_k+fV(Yy!Z@w;CG~if zmkvxE{gY&P%YZX0R6!|Wn*A#B))|iT9WCw@!VZ)AxsB6_v-_EhhuyjRgNNe*dLI?K4&PyU+{jSLAUX2SqCwO1WL ztiHPJ+q2bRj&wagJvG1mf*7?M^B`evJ*| zjUuf&Suz081~&VC+5g=57`P@<2ahy+M_c#cpUi==Y(=6h9k91O7mhA_WgQ)s&*>l2 zZJjrcE^q3z`wEN|2sF1gR$sj)pm96_Bqi3To-xu#1C^_fjj61!Yo8!*%Z{Ki)N(4i zh<*VW&JE~;0BCmHXTM-Y8>UZwqIE6zPjoFYe;!6x$(CD&;DDn9A)FReI@dtnkNMJ+ zb3(6J@Z_(W3iggDE__9UgE1ktG(>z)+#-24s!$USll%@4LLLib844?R=ogXy00+M> z{3kdVV0>?h=K;8@12Lyf(*%p~C(T1h=78Cz0;szS$Kuf*yU!hIVzCe#R}7jS_RDwU z$a<25ls-@FQWnU*odz=B^!mxe<8d~sZ&N2!A1ZIzrIq1H1OwDAXD|2YqxZL1si*{C zQztTyPLIImt_O@KrVEHc{Ck{WiZ64}(6sa94^BIDh0Cf1Cb_3#{XIWU$-w`ZA7w*M z2{&gQ8f-#0v5FP5RnZ7^qp~fk+CGb0({q(rFzcsHM|5&i1)MR`-9LX@%=mDw1N7V5 z%9OJ<>*3s7wT}S!Tzfr_c8MRa_IQHx>E?aXWi28tnhtT{J}Qob%k%Sm;;J{m8p^gw z-XJl?(EZ_90h^?Alr*m21%eGC)`?`SRaU)jj_F1ihd=pR;m9DNE zifO|m-J7CR;by^=->Z)EMbleTM;yg-wk+lmE#spd#6(HV8iixm&*=m#MI}JcW$S2h ze$2FW-s(b8J+SBi${H;S0;i`Lo=tyL==!y)Pyk$|+!we$k^jR^0deeOs@lLh21Auq zUqkVG(5wMt19RpwW}6aOxsqYnl0i9;V%Sm=N$uBuu(=38#N1+Bg@q8nnah0uTtn5r zj5l}_l-Qj)+n&cm>hWxGzX;3^pj-NjQLYUb<+dlJbj~Z2tzt2%&shjblU3Q^wHpYx z)^B;kLwQ4OT{}9TMw2X(hM9yzT`&C$9sHPXi^ljIdNLv7gXctXfgnlT)a#Dn-$3<> zkm|oV>M-$CSiW zmQ@FE*m&+oTu!*Ahd~odMLuR__WCj=;M+P(K-oRj3>t>rFZk2zarb56tbpK@yL@4D zX{d`O5AI)|QCEX#{F)x+=O9Af(n3Coa3$({z;xq#FJrKH&-rCZ)AO_n9>{sTqvvK% zl42>lg!+a!Ib9K#2&5Y>X3Ry@oOFoI;a^DZ>3QhFbSgcQZqlJP4 z0BsLFyx;(i_$B9L^zel?~7!kQ^eJ)b;Vn9_u5Sf`)S7*+7Bewh5e z@B6Xl%ydoO-t^Hdo49#o_wMiOiU!laVq4fMXp)r8(@pNR()_iy6vi7dLmyt7&B&jm z`=wd}epK;lWG4PKE5cohp^~v3hm_ZhLoR)e3t0;Wo}1*|zB5zDE-9P-V<0jG&{FVQ z&3fNo{0wi~f6j`9sGNQTv$9!8sbTCO1CiK}46`v4?Nv3w-g9ba`U_KuZCa@F$F4q# zMhjpxJ=~iD1|<#)Sv+wZ#&fmQ6S^lTq8);zMSApRShkYiMi+)-n&QF{us?B&xGlrl z3%cdh&e>E{quQwQ+AXVbc1yQo^1wXHXv>jmg6#{l)Ua=f0lw20I-PuwHr>@cZ_2XX zDJ&n}F^J~;Y}b9lTGW|dy7&W->tJhX{dqGXrk3iFq9X4Sy228c&PQPq@?a74`_@{= zm4lntyAZifo_vbN<5EqM%Cq5b|y}$LBEBmKQHR50P6{wYnc zHzp>*4BE_-8l%ioX9N#YVkf!p`FXUKI}Cf4@F4V9**zUAai?R#(=9NyBX3e|u3d{z zO>dFJ56O=v&ZS!16MQX@9Wiv5S4&N|^u4#^ z<8)(9fEk~$gx_MYl=1@k2nkzLxcY(26$Nry@i3Qf1!7y1N5QE-5I`c=^Br5}crlmn z=hmHXlPCW^`*RB_51Yc(11~`~nwB?y{RPXs)9$fxd_(<_tm`ntHpeg6CdYHm(VY4c;<4$PEkI?vLp zwuykEnjdBfA%nnE4V|ChnNaUuEF%eUxf=kNyHlE3B?ACE*#WRq)eM@+Bn=?jz1T+w zbY1RVfR|xb8a;CuDA;)P8~3K-eJpcOug zteX_T_;e7_gu1`?L2CTHbI^vShw<&oYAt)GC!RiL!#DPW``fSOyq#e44ChV%q0aOP zL_xrwW^TT3JAlU7gdOjLV)e3#i!E5RVi8laHsccq$jxdr9 zo@pn|xi78>-5(mA8&14K^w4v=;&PQMWegeKoPyLA{_1CU0J~wsc!N48qvbc;FINDMgR`Ty!)%{noGQnJcKbZahtXf^%unAocRk!D-0+2*TDh3R%@u&Kxr1{{T=#H#`tJOtZ(uEpK8Ux$l60Kk~;1Jb9?v=|fBJFU5U zKaJql5?$#QZ40BPaTjt2-Fd*aYOxe=FfQu7*p_q@`xvx_E{zQ0zFmlsMcWm z1KW26(VYFeg*Z_naJa3bFG&b>P#X~K*i)of5Gn-&biE>ZAW8+>Osz~01rbl7Cb%OQ z7zSpa3e3dgmZ4bY%3U0vqQHcD2yT=oeHL>z6qR}40UJO{QCmd#o?zarGIU4i#7?NM zx{o=A6V)6|DcfGvBO`vN(@sfVOyN;S+@ZSXkxCrXluWNnYA}YXJ*&14D7mrq( zkZD5P?wv!xnRV2Yr><{is~5?UKc)2Lz`mQuH|o8-4oL^x3Ovh|4($(Vayv^oYvhdw zQlqA90r&M=;tTd^r%=(eCNF7YKb#H%2nF;jCet>o=?&qe&w(jjC4BizXu2xRfF|6Zo_kvh(xJVcMvxiivwy6%;WC_-@LAVHpVa+BG;Lnkn5<&G<+YZcBe*GQ-g5UEv~Ad zdJC@9WbjmZO0K)MbwaK?-mwCxs;b>navk|^avlHU9V|dH8*V3je4&Z>rU7Cnf^aeH zops;UvO%2=@@48TaD^lc|1yve-y9}4vup{k2vjYBSY1JW%d!siQeg27rcoQWV;1)) z07D?Ibm1{{-Dw6hl_r@SI4ADr4eP$B=;`XRUfy$ip3%KRfO#PRTNlh1WiVedZ5Xz3 z!DR~u9X{u>Fu}S~=+te7vuQh}co6JwV3Ndl_LAd4zt1DESUmU5PRE%%Sw*-{R*}+D z{aZKtSzUuL&NN_V{p(%td8Pz^%MCNW6XTNADc8+EQgfY1sGDsFtO>Z9oX-w?6b9@h zGiz{<^?Cu}Xj~SV4=bhD1#sh0{V^I_j4L$JMe`MP;Ie4~E}ND0_GbX1r-uVJ$2|eo zPL-X1t(^nmrL$F+i=ESrd-ilYA4JILx3wm`k=g=oL`LCi#p&HBm2o69A5k+gy96up zwQ^~Cprm?3mvgxh&%nB^5eXU}j`R^Pu0YJ+MKYuL=lX39H|PssH{sAhEeUDYecfAS zQeLA4{Rg4fz+r93gXVrv2RMx)B+sHk?59IKIw+BWjkWZ*I4{L5oU;djKi%JbV%Yss zvF~0F*zi+0S-EJI04$Eo*Jd=-0k7a@1gOEBJUQJ|;uS@zzEp-)#6q=BflxB43%W!u zmiT_h(Ff5H&cLljTwT9I1Z;A1-Y-&qFE>fajH+S24Cyi|{*3-o5C+h1#NQI_11;uq z`+FM@kY|cd5-v;2Rw>L1j*co=lq%}pe`$vBmLWU(=>Kdt4dbyoFRnF=9X!7aC8hYN z<0c<$TIl$ZXc#^b?p^x9qQdFdDB-_i;NC3HJK4msEkjmy`$F<1h3c_%$Kw*h_My^i z@^=Q$mKBz3AMqK*zrB{LD_54`9z;_#EU>YfXk7U7h1`d-88=Qu0!j_vI^gPDoK}4* ziL_|XHEYhw+D`L*hB2y)G7wXW>h=vae>>=Bd-0x^tpFY>|D?Cqpev>K$(53TPh*&T zcH~NtbGr5Ue`DpOy8w;)Pp+K(6W6@~-H|%oV16`K?$%#eIb#yrD<@bvJJx&{YlQ9P zm^%SCuWKl<44bBn-MI3KKyC`~1XYKbLrN;g2hLpx1n}LZ2k{yegmaPSTVU?>PsCqN z5$`V43K^F#_dbf>PgLmUEE`6?Det!+p4Ke@MLO6)6KSF^zrSP!Who2FnhEIgh!!=~ zdt_4%?Eib@>Hm`y6Hy%j7@{)g4lDysPP>!Nc8lIxzev&GMI??IIbpm8<6Mx5k@ejB z+`F1;oJs3~of1m=bi7UFm7hD`y-nuR@O_9_aB9m*OK3n{w#&Y`7+i>-8@YV8W6%#N zpP;@jCMXyZJ*Gx-p=dNO`xngBKZ}&eiDGzL+DTEc#xy5y3P(h+U$y$dn;x+%V)1wR zGzR@{5Q~zvDJ@oZea%hUFuqj-?y?gP@``RY!T@{X)WfG`I?bVw$Z0kh_~MBj2agAS~?-Zvkc#sQc# zRL+d`7TOsA8z;Ope+3ZOH05M5(9Ln$kf(nF1I>$W#trToHjENY&?(VS^214kp&JM9 zQ&EmP*d`os7#|&rW^`zFZMhJcm@DtEdWN_({*7g{)m8D1%bOG5{Jy?@9WaKl1=_U? z0tFP%HbdtHzJV}qCg{S`{t!p+p!R`%m*43oXtgsqlHY#^l0V=vO1BZ9VZdgxMo|qr z?8HJ0S_N3>!EtIRkwrm(0CiCTm;PJ#-cS%OiDXC zBG3J>%!F%hAns|{gxGM|)K>|tg{pD9aOA?jdJlDpvNy@&v_K&LGo~Oi=oe>@i{$W9TP0 zr{jQ%qz}NmU*RHfTboME3~P6U10-}njTDWh8AAL8@|L;MWbDo-tV7SghGo2nhrb5T zoELj$XyQki!b~Mg{MM(c%Rf++1FW1C;tb@gQs`?thkOLc~vr(iCC0inS#nT~EUTd2v@t{{?48DfwS zw^^VASSxE*(f%15I8wyx*3C0*d-av5@+p@LD zUx$<8i&0VLp%c)QZ)WL5o1l!`fCeT;u`Ii&X!;7sF8Hgf{?SUE*3v=+2BCMX49G z>ioSk0W|8$mS??D)eEiV4r4100A+v$N4)xjazGyO&ckcFUo*h>)xOY-G<}HkDZ5=C zf(NMW3J#8Q3I{7;0KNfd{3cP!rct-~b%?2j>js`92Dwj@ICP*V^V~Nvimxt21InI7 zQ@zS=!@l5T*_|CD*>r2_@E}hkSFPJcH%Yu;vGR%WPC6h!VjMT94KEhz4~O zhZ8kEF9dn;BFBbx+;K>OwXWv5TA76#rnCt8rBA_UEMn#E$}4UAk}m5Z z)3Paa$K;--(ph1AzG3T)^8N)AGDv6hg&Wr7C%L%+CJF|eihMyknX|T}Od+k5(LcaZ z6EGmG-ud?69A#52KEzv5)TO5yy5g$-xG#ur#Sl(NtIouM{Jr0vdq)Rg4J1BR7wLg# zfIke_1`K|-76Cs_s3RZB4_p0%_jc2vq)07bWH|tFw;7E5`fDv-7eUdlD8v_$1$>cj zKK=?s<9up+2JoLz+OV%X!Z38%v3AIB?$WnEup;VLNvOwV9P_0CafBC_e8d0_0)S=W z-|sBwWj!t6cBN$fp5kmLxVRH6Nizb`MN)}{>vbGtvQ^(#XtVeyeACPbpIfx)C^056 zQgIdhJeEjVNMDKsh#I|^(_(XsFE+!xO&Kb*Ncj6rpxt|9FQ8Lgjkqr4U=`;u;gPwh zg08CNfDY%3w|>a(GinyDRK)UvoFwIT{r96h6F*Tk06;-A zLu~SMC1b^a>1s-c?jPWfLWA`=fM%&CY;041ZPyd`30)#y34%*~l?8u3)asr=ttkz7 z(%%qCjcKZa_K+>YLG7P1ZMBcT>Sk@0vrC=% zD}raO7^&tL!t*o1GqUuPX1oq$xdN!VFMK9X`>;XIV?oeuyPKxdJ!pV}88%Gh#N)&1 z)CIHB=uv{LtG+f%Eta8#BLQg>Szu%16{*{ZbnejT10GQYPG9G!yMF z0z@7*NQAJKh+ssemHcI#LpX2~PG0lwQ z2eb6CYMQlA)k-a*{34059ajDrqM9Q&JW;t(+^wcJ0gToD!2WK<;1yb>Cya|WNl=YA zIF5}!P#nk$(D5v9o*WPHD0Du`kPj-gU&inXxgDN{RxeY$`tuJu<<}@pDz42midBSp z?nLYqNNbhMgOO)>>(OzN8gJN_R0~j>oKfj*i@amjD(mu?v{y%|0`!wc=$7 zDw-GYl%+%a1ppIFiSdL9##!lYxl1R4uWs+U?5&P%OHU`XpcY~pE_5%=opv7iTC79H zJb)M105Of!-ft}D>cxqo{gw?)m&HS=6HFma>j?`+=!6B6--+s9B=O&Q?~>O;;^FzQ zZN#pKxlUpa`E;(EZ`%tfDG%s^g44vtQ@Dymy1dSU3&_=N5~cYg+0;krKanSZUT3K9 zd;eOVl53o?Yh$k}gJ)c{GACW|Xtf4kkgnN%g1yAkjEG8gP^xJ~bQPJY_`(l=winmy z?~op1q|m(2{Or%4pd@}OF~nAoYFIrohh=Tt@Bo@(07~;*`cU!EFy~80H?G$WvFjg> zq2y%DiX|f#aQ84$@bxHI(wM3R-kR_d9o~UKku~)tXNXZ$0UxSl0O}9&Z`)#|p{hie z(sh#AE6?@3{7eEsVx=Y8kzCL!&o50}{lsvz0|P3Ar=TYtY~+!2Ja%0qIIV-P{apty z4AsHg{HL+z^pCN2-19Kf6%@jg+Q^IDT=yKn-yEID5b{dF6DOEcs)Z+R4Ta-&6tJw~z8^0l&;Nmqk&8vu z$SMQO^$2e|%J2Ls?4q*o6zNgnOF24bI5Db1eLkAsu=ORul6tN~gDmXsAMvuL}Z zs0%b{2@%w!mgmI7n9)2+&Zk@B)jjWSTx93Vp%NSgoRN5lCa;CezgS&v`C7)DvJ1}i z8OfBQ5^~Yu)4Qu2>*Hz8n`!wD7dXAA_2Vqz3gKS2ZBboH-yWs31FBay8{GZw7E^hR z0#}`9Odw*>)}YfeTBM1$gFFbj4rcvO8Qy@1(=M#=py@|!q%URnXcjtDI0%7=|rit*ZK5+H1hRj-JC1iGSK;Iv00Xr=)(0rSpm5`q9*zE zQlwK;6r{+4XeC_p%7`X(KhklJ;{+Co?Lfx2g>4dB&5Z zM=3va-pDX~U5h4MxYq)^7Owi28~uNpw()BXvl%Y$+hqdJkVtL3 z4%URZje=yG(B?F-7OgWC*Wv28VsJ zqoj`=u+n+#qstm)IKVMEZb9y)y&vT|l$MKScAJpbrieCF=?+aeJ39zcVL46+g0#M( zL}~sy#9TGQ^uUmvB$zv{x@8>0&GnKaPit+|rv0TX9CuSK9>xhpH5Ywn-wt)jpoqJ- z(4qD*!?)V11nl%0PkZpB+GGzf$s}_|Y$jK`c=x>bkL=d2k=J9f+%Y{YMQJmOZCf0B zCE$2J>gtKjOsqY0*CD};NRRt@Z^Xga&Zeji@cKbyVpwd;n^CG<-M1g?6|Ld#aQCTg z5Dw_{KZ@&EU})sm)bnkZWZ0M0fgWl}gbz#bQ1`aJMNj6@sGeEta^F19U8Oi4Y}5GA z?|2+oPE=I9Ju40`hZg&~@=G@lY^3(*Q!DD?0$dka-C35qRCn-UQ#w*8W70933lB&O z)gApOkRCP-eaoMVy9rH8VKyT^*FEh_70H5318nL_DiC|)Wa|hbC^y>Es zmzFtv@jVhAiA~$4Uy2O}Om6ME_|-TyDOV~a#bn#+kAV6az_$|oYF)5ksj2vLw#(!8 z^5d_J($3X0WEjf{zhI%L{wKZ`;+?LT#auqVm%3)v-$&A-ijKsmIl~?h#>>XaD<>?j z)-uT3deV;W6fWcgtOWx?UtSjxx{+%Hq&bFiTzrVx$IRK`3Z}p(aUb8mR; zqr;9$ArpEk)|w`YEb+}3ocjekFMVjj;002O*$c|5LUm1Tb+*((MsK_})kqq$Xxzj) z_gFAxOMs;84V2vO;(MXV`#wv5p^m|(4YBdF_gu*AC)px675PHl>)Q_yW0FH6EH22t zndu)*Su_C)9tKh1Rn>y13c;JE4%2wM?~YlvUg#OD&=uqMWOy2x2e^k{xF^$wQx!pc zpfsbe9k=>Eyd{iLFkg~MqMR=saYuJ5VI$w}O?CNQrhCodjz)lzK@vvbddI|hQgGOZ zKkhCQT3z17E1tj(p8Azc7#JoB_zqry>=Ucq0uZ{>dFcagKqE?i^ihjE%g>4uZVkQd zPQF-2v@syJHFj&q0(M^cz}pIY{WX_nD$7C)FlF`6ZVu%|z$4Gt)u-bY`R^r#MaT)McQ8riNuo4_?k?aTu&)BaD33teZD%qwiZ*ri6cIni)9b}?QfnU44oe`HgKPR!SVZ?^rs zHTVlg;}P|(ROs{WV}50Lb1h$lQj)Bld-6e^xA8OkON}h(erxI#$aWo$*8jSxDAJLy zzkz2pv{%68&iFnwBEjz(ecwFI=!0kqqNo@|Ook^9Cr+umfMks^Q+s?vwK_&%fo&30m*p=g=K6xhzfO3TrrgY zhn$^^u&HG0afV=@+$Jxfg9mc^98py#D=aj@duJL=Q-6rLyP*ekf4kJ%7jhbID3s)F*>=6aUr#_K$rv3)X z$yW!Sgr39UOeSU@dTjCB^*obP4%MsG@LS5A5sQS?}4TF;{>J z4`+Jj&EsFNZ=+I?S>oDx2gX{JbvK9_$+ugtTEe}9G&dTXBct5Y?C*d26XqRFw!#S82G`(G74HQY>>TQ_R10u`&nj&C+QQRWd9G zv%%9eDo~Xvq#lt=)S+&ZlOo7K^^{d1Cj*ix^2U+twLAl#HrifT!fVQ0qd&7c2R#_G zdAWrfGSPhxlu_-r$fK@Vm3*d;XTbI|0Hc%mz?0i#XI&aN*BTbcF#JJQkxZ7109R2A zRPN!fK2cwA2IrwO;=#n97F>kz`QQCUhB0~W{3~Kmh@#&tc`5oMDAxM4+w#!5A1E|f zmL2Z$C(PC|yqz#GpozTHATlm}*0<3D#Nj?XzEd~7arWm2&PRvkVCn+V$-RZurSIAl z`O{IZUNNI6#w=iDoSfRO&RLQbBHv!?WW(- z8%LqrF^l@}TtC}xN+-nML=>}V_g}jDS)iE*y82fjb$=eAbJ!aF@|hrhSVm|}_&a`s z^?1~xJ#%8$Jr-p@PHzK|&*rR$rSr*Ty@{Fw>5-BH@+^oOg7YAi|9yo5WvT?NR(`c< z_O(W?!uPFetmLDaDdtgm<{%BG;+@xcY@V0IYUJCtY$P78p(okKG)>tX<8{$KIF;FDuYm(k@;U=yiK9+BVr}n2NpwFrtTm@&# zB6=#D^BKEI1PlH#P+^b41}^k+Hcy9(BE5~b*!x`B*5tR6v_&ft8}(BCUsfr3~zsFB77;toG(`}n&OfcS7erzO_?;d|4n2u{=|7(>WZ?z2SM!NOcQPZb_ zpY^3)qszdM1Vfj$9%q_AmPj-F#`m3K32!lw47Tjz`#2F?o_c{D)jnuA^@_uXr-HfJ z2d`FF?}6HrNSH{T{WCW6L6c{+=e&k*O-GQ(o0=6khujJc-I4wz4r*eE#PHud2nFKk zisGu^J!}sHe$#~Tm0Km1XpE-Oi%rfls4 z_VL}^TMGwnioVsaK$hv3u5l=d$?J>e-2+g-$NonLNaz>TB>jTjS0$_lj!<{$@DZL8 z1C$nHk3=sHd0nV0&TFh*bk~pF9lzm?S$&17s7u~8W5i$-D6ctrr~D0cMjmWtW;0&7 zYbK$N>kF31cU7_9elLYL_mj0>*!zARH@Nc#SmmOepd7PQte954$fyA67UzZ*I}h(> zU%QX!N;mz&r9Fq{qL=EilpO#f3z+&TOL4wTstz@a@En;POv$AsBga$U0Wz_%D!*%y zcZ|uH%k*+(3R+B`ol5+p=|nDYKZqtJh)zW|YsxAzPDDL5VZK@(*=}}76wy@&s?K0B z+FQ&rk0E^y7Jv(iP=VmLYo(6^!5FNKZ3t_pQUs#^br&GM`aKfec}SMAtQ*VfZ;E@)zJVf!7k(+_W92s;iWpR=6P1;_2k%3 zD-$fo?E}pIwV<->HI&&Zeb26l(7dwXnWN{AJPl%e<^(#jKc$53NYEZu0o@Z#XAa8ipA^0q#5#IoH(}6qKRaC3&WEDvzs0HXmw7p<0sG+3y zoa52iKm(ody4h=>q|z8{)m+T^1w-D(xYhKS$=2G6`TjnU%caK;38rf4{CKW_d((A6 zs^d1ROF%+viODVZm-Cs`0=$=l*;ABT;l>-IQ@qMkU~KJ8gM9 zU;81j0xl|yengrFo`IeYI_tAT@z1Np%7wxlAKtu=qd@*@^UK3H%N}(V7`P9;1dVK` zWX3K2uOH9VduG*gsF5wlJ9O@eyRay>%BoCH5_7-v9KNTp4iw%%YV^C1&=B{j&vpCl z^2ra6>xWtzt=#e?zJ=iLlGl5bEyMHb1r}iE_{;pnNT^mWP`Kq2;^_&~$vPaZ7 z-IAG0zkqzny|;xmSXkLV@#FF%z>>zUJ~uvw&#c`b(w<7x#cEVpRTwvqx*CL=p*THB zDpc&qW$~8!^H3^+j(X}QB8BI^K}1tM_8NLM(wVP+R~7cxQlYub|1-SrR>XSf@EPmA zgK|wSgLiVCWO#~Dzf;P?$$N0gE1~Oe#f#dXqkA~z_xtmvLx8Chk~ODnT?xog*)2Nz z-IRrxjcOoh%n2+O2HimFyZZcK%D$?NDhtZARpS+gvWJG7MXJ}d+1jw8x?pzJ$Lt>W z!&Y%$>LWQBj?Z7yI({^|4Klwb=)+q(%qp8d1j~80*mDO(*)b~rWP{^2)m{|-uD>x} z2X5QIwZ6c5r;eKB{fYy3!8#=LeUugL(vCm7Mux$CnhyhV89Ct(67b7)Me2@@en|gl2KV1E2-S}9DA3$lzhK?! zaXF7C!2IyutNBZS1UYPKiv=RLj%=DZ_+*5-TJ7Zu-i$3`K$;FgFd!^fgi^$+w(m}h z=N@3gVHw{m0^SAu?;5Ab!CSI0LB;@vUAFT}s?hc~DJ8^vl!j=Ve2iKEj0q~Lz?UYP z0rujBI+on&2}_>>BZ)cm*kLEcy)R3*N*zl8Zx6xl_nb_D_ZjS(HNUA@+vR^#!~TG7 z39RLYrTf&r_~%ES0Jp9`d>HZv&gcXmRRv&(P(>IfoKW~;lu59pDd24afE#qWMrl@n zBx=$`D9^{J`3S%}F=CSTGdl=DaYcbN*nxH>!yqksuNCVrLq90wQNPH}mX67X_W?W+ zDy`@jmHUrh*18xDpqrH-e)pD^g0jo8sewPSM>O-2umx2r!PbZhszyP@;e#fBgW$Lf zL)61aHyMO&-dR2AqUJXWlq|PjgA^%n@=%NYH>XfM0sf|+@G5P)e?*NqgrEXLS>=Sl zcG#bNLZ!OmB$V=D39uq>p0>ik!E`XjAw+c2P=H@s0>~-!>%|cFC}H;;*xo{>3rs2~ z0qP11o?1Rsa*E;mO`KtZD~0`HKG->k*L}d(u0{VXnPGEe>1Ju$hJKMmA7%1|Ubz>U z3u#JMWnH+OoMo;(9sib|Dr;zQEZq+Q9(0<9iLwo@I9>HXuCMcy>Pg@p1amUTY;G?O zldwto^zz?defYJ*k~C%*;qn{t)d3Oi(Ok67<5Kt|s{t)cCQ~!wn;;)OgMsHvJ(-3A z&fmRq?{}Ag*-|+Jk>C*bptG;~Cvi)Y@*<6i^gAzqrHcrD0O}GbIms5ufCzuT`LXD+ z_V?Ikq@m@lmvZoze6g;$54Dh$KVf;?P}_xbSgb>pb)*M=bw8jI8<~IOCXH}6wI><@U2P$791ufga^FXLg>?q=JnOH z|J@-lUO@a(mu4nv2V+te&~igCQ>+1N5a<#ZyZ{{UpG-2-c>#!62oY`niTb+Y#Op;r zh+p*HGzRnBqjzAMeVGm>*#%5Y)s7WVqw+T#GOq!^A$MBv1EFUXwEkPos56d+F-{2&%Lu?{lZrK1>+iC`QLWW zrsZF{hAZIrf{@_j(3R@+5fZ%t(^5qsZ_$bW^a8O^AgTMBjJbrriUIU{@syTf~qFWz~*{!}PG*IGG4 z-uZfyFZb&7y-LCK#3sy5Ixr?uc6J~R@QZmBd zxqKH3BGb4_?Vp?A+7W!O5|z`RCT>QgdZl|&Q%76e@{1UzIO1WzyCtXZkrCDvGl<>P zb)=`Jwi^>rmFK)(y1gcv%ecc3^5jt|uFp_P6YTM)g>u2P86IL}2HY?vAW*R7KnD;M z%8f0UXRq8&!14N)$9ySiTHY%!;dN+4(Iw4szJy>yxz@eroY(R%Yil?=OIsdYxUFcr zeg?TZ1=NUiUMNbJS2x2kfDP%nZsGCxjV~Xq=Rcrsh27O~zxr-BUkdxc!#X;@iJ`(- zfkg3-kTt`164sxtf@@w?o?^5iU$w|lZmPK;BmKKiKL}%kSU%%H-8ebUd;HJyZTnVn z2^kSzP&h6OY%_wN4w_mDM_O%dzesKcBJO#P#~(e7Ij&0B12>u9DSCc77m)YUd>S(G z)#>s!TrNIvc}G|jfspnnMFbXHjEb61<{ammQFv&wJ;3u(Oy`Nh<^El@tGAhAI|^=Z z79j2oaJw0ZTo0t}#hEB4bXwvUct#ntV#I2OySGi~IG^y%p3(!!sT)@M0e6De(a1gh z#xF=)i2qZazb>)H1_X-egER)O&+H!TWK0 zd+V1YnHKWl*T_I*dY<9D%mv4Vp${wLcC8~Lici{=!dt7Kw@_~lA>B>qKq$)f7mQG9 zK=EM6w|V2>NG;#;i1!yv9fV;md{jZexA{je_C~Pd%}r4k>|h5Kx2oyZ7)hxQAgh~U zm*imh0k9>sU-r#_d4xq06)@h9d?2`9<>J`(;6mIR8I8Vbj<(|)9lv0PD&93uk34T2 zuQ5vWqpU8kOZ*smihhS7_vW61L+E2c^cVVAUh!d&DW?i;fiz1>)fnC1;y;$`UolDn z0qK+Tw%Sb>`0FUG4?3GHw4ZfnEyzT2a)Kc1QxIhBHUJBdpF~9CkLn4!+Czb*Qp0B~ zgAvc%fgkVc_34lmM9~&?OYK1PXiE?-OEwaFF6zLIJ3>#|%eaYT_bL>s7a=KQ+RrBm zW>_|Q=c81bte+7@`kpvl9XlmhU2aoc46{iDh*m|N0B=<%?BGVTh5W1g_qQt>1eed- zlxciP^yi2hO)`H;d!f0)6tR5u*#*`l?Wc{K60fAFXRFnaW##Vm)B2bnc!JCNW#F&W zvqf92Fyhglx{*+``4Mjd*Fsv?0&CDdM7y}tDf%LX%mAWw^Xaqhh^viFbIw2+^p!uJ z1JFl3-T(ds9dDr;Q}U3?bI7&IR+|n9jRHFB1vkk%5?b(r1LNaNwbtTeR*b#oYdd-j zpwl}J2GyXqcX^L~dl-rfRqLRV8X2)?-6WG+{;^Y({>f0*lhSsVjyU!i!aN5>@}-z% zY6&+L2Z^-p1-d1S*#z?#A3;j0R0p_OH0P)-&M4lCT>{R4;w|g($!Ga%{)S)L$tRoL z_0#C_>Dc{BAU!we$W-~HgVAF-JgEut$uCJug%&_FLqg-*{+MAu$Q{f9Lg4F`?npZv zoUbF*?-+a=E2m5SE&F)ab0I80BSs&g@}!aEvfoVyk4~*yW-@TnG#Dz~n0grm3D>^s zJjiIu9KU<>R0@}0mSTbc{t~ujg;Wyunu-C}H6wg8|A1h++|Rq0zD@_<7?4MF43s{% zv6TT%IOC*qX&JWGZx%KW*BHcEm0)v{bdJsrxH-tJ<1MhgA6_Qxobh#gJfzj8jzf3d zDAZynMo6(0!$jgk{kaAYs4V2VmTQ<<|aQcB|@ z0#AO{Ru7*snvmV2yQy%7&M)LkW(iV(Hl6sT6fqpW_BAKHeKX zf7ReXZZ0hEK~r+$hxYU{mNAOkp=O6#XY)$WIZ$Y_!2=})2JunjbsUS;q9~zSYIKK{J+|8ynlYi z!sqkt-Ff!6svjM$@1_!RyEns?BQL+AGzhvqCXQhNosfGeM#CO6dk#iw&H)zhE=VzBwT67|7$o!G;MV zxZxSk1*zN`!*#RxQebO$_A#Ar+j!f|?PI1C&O1=uqpZOJxC$`1Gla>`B>vSmmQ;lF zR|opOl1ih?9dS>~9dl2d;J>>}dsOwkEF{!I&#&4_Fu(Lp=U1N~Hs8Vh7n?Ud^1{?~ zOUvpMxbEpJL__l{@vr$c<3r9?9KJq9{3?f=nVxG9>`z2nmp^^_^`Sj;<#)qkKbsr% zLOU|<4&50VAuTZDEuN=C`mR;1m&eTR*brGRC(yNkosVH#myt~?fsi3d-2$blYOy-A z_toK358c3K)R{UGoX$?aYmocB%i$QaJb|TwJ5-X7FA0;5TNUBa3Xz%n$ISpKfsyF<(nbEBi#3!a zJXdD1fe*Cp4?nXyuIcY+)}2p2V&FRZA)>X)dsC;eSy+S4nE|Mc*Jrj;2_{70$LH`! zD!@lBD1${0NSe6kZSAP;D26F?oH&ht%YN0dD}X?HIQ+4#7vWBOfgI3~qJ`0psEuzw z-OgJa)~AC6kuSz12N@vLmw6p1R}BmeFqUm{YQjdFaCjwsc_@)u_2FFhthdloxL(}H zAj7Qh(R9gnR;dW2wWE){b-V7VYAHIinhdX;yc%6jEE&6yEL?vYTkk)x(XAM~S!j-21l9N~FGW+>?z%DdMZ_C=@J zxBGx9&4|v39Aup#xE108G@4L0;HpyoBHd>@Gc4G2;B|K`Z-cqY z3F%x&eS>a>On79K8>*x>Lu}*)gk3o+$xCJ-*m^)cVqRSly(NsP+BZ04)7+M(s=n5^ zg@82-yYBY0;AhHFrqq;Z%O73xie2XpC9Ji;LcN~C*6+*>bi%4&rOB;6?kOdzyeIuA z2i)`hy2^!q3KN*Oa_Qq!TFL8Px!XK^IeH` zq6b46Y8Asr3rC2o<4Sd0p3^?~z(DGpHs%X~AA1gtDt;uamd;rTyn;ON*f7UB;)4$r z@PT13Fye+WrgSKTi@{a&E4YgG62yzgM_OWrS15e8Xxq1mH~oPBd;zN+GW@4TNlovOFE<%D7YmGsOto98jDUI?WI#>>18BAFh`o)--L$=g9q zmD`WUe@l(o;Gu|-{g(9Vj5nhP+BgMoYs2!S--|w$^;&hfVT~V#$>XDwipheW&wC0&Bv6!C9Iv96YEndPhJk23wGqcE;Wu6o?bY5+ykg#Uu}-i1Cs^}%+64+gw@@_->u?kgzaeh2;`7*zXag= zYZ%8{@ARfypM#PTj~wSpAi^{E2>AEN90em&66%9hFft$0kM{f?nYkwlT`)3TwpHVC zPMyzLzU@~?_GN(xI92}j!NT#4$Vam7RqjUtQ;=jA8;oXR(7O{$liO#|cU+cl5hnkj zD*XYL{(tZ1ENo+AZ0`zwGm#@HvfrhQ>e(Od8+S*nQ9vWmdu`5C$k^*xOvm{H!-k%Bc}v_IpDhJLTH&PC9lKN7nEE3sM2wTcUfj_h5|}f|7Yh*EQT$D@hLG0bXL7w85-ms~ zlp;aP-D6{M5jdx&r}V$-lmGDZwCLptc$o#@TBoBa(V$WeDvU%|bbjILCXZ0=#VXNc zCw>zjdyU=lpJicxy*ATY`UX+w#{_UPfGG(+B`slj;!Du$#-gPJugGO8NcTs9eqYd^ zSmD6|iYp+%`afaV|NC$L+k#_^Utb9x*qJ%II6b&;3;oO9#F{`*fRUFG`iF!BkCv;6 zi>Jc_9!1;x77qw`ZrDGxchYjWZ~B1e<^wk?(+8UJ{||fb0TtDvu4#-RbPGY^D5x+8#-L~v}Y0$6BNYbSG9Gpv-e~Y6a(KYICy$!+qx^d zIJvqw+d6wPiR1ArJKXfNb?3jNsDH`U#^t&#|7BZeJMeB{2@xSNS=rMo`D6Hxbr_*M zxEx#9br|?U`(qTQ2qVP9KZ}n`c$VNSF%cmN1sf#=85zX|CT1EoVLmZYAwEGtNqIeG zNf}L9K|$4PYMKT{<`(ASN;jNrO>XL$nj1rZ1dWK8n1Ymoo05{-SV~aJ`2X|QAN4Sj zGibzwNDMR<7&-|W1_|09%`irAjaX=?FX(!qFEn%vOe}1iGq`y8-~}bbFmyBw40KEk zEG$e+@UM5kzr!#|u+A}Gl*cC3vBqI>BNGgYPCdh_@TP%Ww`Y@0=$iXITs#U&Dr%bZ z>>Qk2+`=NFV&W2#ikFm>RaDi~_4KbA7#bOy*j%^0VQ25)=;7&g%iG7-@BV|}kkGJ) z$R{yRW804ThOhc?(E;Yv3vi~o&CD8KksV< zMu33^9v%h>Ob+%n0g7S&J+AK`Q1Cy49`s-Lz*YpoV|6Ex8d4<^-AW|R3S&MKh~5Mp z2O5t&5~sFC!6xKrKwhee=%BHN2+CreksBu?*m=yTd}ClHSW}`Pt4WqIvhjn(6s`tA z_>S37gxs8U=+U$VC_>Fr1S@|S#rw80V)nbSi?sqBrFH0|ch}UY(Q6n$KFVX(@;j9^ zSjTANxDF|IDVW~>ppRX?N)C!H?yH;SxiKhtc~6N2x5-Gqv9L=)c$-}LG&3kT71OPa zldqU*qI51RD%2j-6l^^7MC*XgQ5D_Li@G92Ky_s+D117*@km6YU99Xt%6}GYZnHKs zD@Wc^(dPNzsAQ)SFJPS>PuyED<|9sZFif`{U4{z~rc~X5broM3_d7H1F$2x&ST_$Wy0x zKiaGe=~?BQL0K@{`8bLbU5?ZzcuIB6a9${=!(wycK7FFXg1>4n!OloU6{ntgRrrK| z2!B<=SE|rw&e4%qmC;gg=x$Bv>HvxwG$~2IZAyTLu_#FTyux|m(|JbE@&OABpJ1kH zO|rA!7~YO&XTM0^us;N{K>-uwOJLf+4=ql#g*vMPs9zW&$!8N*q=lyUzg&o2hdnK7 z>k{ek0WYS4UQD4Pc@r$cQ?N{FS;pY;KMa%hoA11^405Ww^$K8^9)pab#8%;9IPo7a zQ0iZfNViMnZJ5i&F!MqJ0*`zKpMm&emde+gw2gBNNk)aj-6B=_>><2LdN`y(Ibc>^%SiiI{4NW z<{e}XAG)}O%`az!WNzR9sZGgu<$>*>VwX3mMB_bpR03cRf!4Ec1L{AFdB)JVtfQ0M zOkdkvHw`0|Q`aDUDM|oANP3P|U^~gwMDGyYyk+bC(NR3z7t|zgvTff2J5!LNVBQCf zFgXl5x*%BOL5l`G5)F%M32a}oF!@bpk3nUfma8-D={>i~sz>c^x9w390DM%Aq_&;f zb+PD`P|a~yap&F6#4`5BWTLNi(|)?-cz6I_;%4s8)k~OflKSd!#gnJ-7Fu%q&WB zCTBJ7)|;iBw+cvwO?bY_!TaphNmR_jbhjj8i_?g2j#LE@_|Qipi^YjX9M~2@#*-jT zvNF4s8$dkz5tRfcfp?~#R^LL*yQv-IP*ty!Gj9^}3EIw8z^C-5P8JWCCjz`8TSB_qBKNP&Oma?}5c2 z-fwBPfUR8+NzMPcF=hdjtnj9FU8&DYv}=+B&ko*4YZ5AGe@i>a-TqoI(^Q>4hN9;EbcxOzLB)W;pUi=noo1oB0 zMIDW37qNUKjHQNf;F9YrNB3NTv%ZrNpzp}x95e=sigb{;2rsz|ANDXgzL}PBT?un) zYkhjrL=4$A?Vc_8o{1-RlbAxxBY$WeY_tIftM2({V>MTaVIi~g_kb_1jnt;K$m^ML zp9ZEkIYafW& z4%Yp-K|%oLUV1}|V&(Gu$)J(^ZP3)xyLmx*bAU}f88jNN!Juh|N~~UN4qS4-!swRp z1yq!u4w}OKgYrXr^yFso!y^;UP*5-ASxdS3^%jNtH!3LXix=E(mD^?n#`HBsY|ByL z#2}FJi-FZTF_UcLD^MP%ql6Bf1rushO@sNyw>2UqSY#NT2^O7bnBMwrwX@m{1k5G5 z39^vLMa?%QqQoSqnWt<2wFQC;;M5rGs0)%I#h)jT*aBf8+EE?aA254u9F6I5bSa~| zJsuA)-T0{+dWmOmJUMpP1spTLzw@f%7}nGHhA< zF(NHKiwi?3UDC+ajexnUa=RY`rN1>MkUIK3eS$NRJr`|}l5i){?WEGTfPeb4oFmAc zfLS^L7Qr0yv;5{7J($WQx0-wTYA~(a6q;CSNHhr%FF-D|<>08q*XKKW6zh$~#(_L$ zUi5SNq%B|;5X8BH~eHGOy0LhUQEo#IesAC8$JIfyqUAl{g-0kQVSJMAYp&yXTly%PvcPPYRX;BsQ{RR(Rt?ftC^a_ z&20Gf7*Pn25P0xfucqalLi>WNCKvx9t$5LswJZr%H?wZ6$D!^Ty!{7bZ#|H`Th6t6 z9(RJp1-BAD?cWsD5We%?u`V+3coIU6{X=8in7vY59yE)3JY0h~l8~u)l3X2}L8ZXH zBLnfq*{Qx($#=f3Nv(H>iLBlTjuzBDFWyA8kHV&8F!hV^K9e*iUz*IdK zZdXmcv`xH5)yeb0lh<)ott!#vy%B{BmNO%bV?0>?-a5?2fL1U}6Qd-IPsND2Cdh_N z^|8l)fQccYddoS-+kOw6O}Hf5WZ3&lzbg-#j{~KJ4_D#z?F2wJlDt9Vbh4cLH}VYs zPA=l_*Zg}qoBwg`1P+`2lj@p($5#nDI(`Z5A`Wte5gaXkk2J8})hm4EAR{RJxmz<#F%D=G1;N_Y;zCJz#lTu-1TN-1M9n)a z&n5j`JRvw~>$lgP(qJRSN+7p^_Z2K2eK*3L_}GW0eWGFsBvMF*EYm+s-+L4OCj43j zKc-;ENAIt=EzPVWYWjMjTTClnZ=7~Ng;t^(qh>)2eQ|;yFF*hy0Fvl zjnEnyh(~ehgd^{uW;m>$%g2&iIjgz7_I=z0Z|J$u+E8b`505jeS`Xfr2ZZkRjgD#F z(1mp9?r=VPs=xNNHaD2A+^+?Yod4pQml9S?@2KnO*zV zWRe_9<-i)%jpGg3c>oWKjPaiP>SEXZ8$6I7HV11*`rq;pRlpjn|hxQqp}VJ}xQ-J#O!T~!NJ6d|@mfegUsj6UXQvw0Ujll8WwYD=lD zyyBC6R%*)G4FX540M-RYUK~vzk*hn|it=>l^QIO@*hHYOQL!0f%t~oIEE%?7JFiG+ zk5L7xaHCGR=W0z>b9Po4C$In)2IzwR&UKEc1rFD#JiJ3VK9vIbs8Etn4YxRgc|Q zI6lIwaIlk=>66@AhsT=9=?!RV0C}2v#Oz8zBY2inV3RQp`T`TQVFuFcdu`->se1jK zIq3)eXLbrtYf5g3W%v46Iuf9U?yvXK=6l~_Ix9&Y1qLn|!SvyoRU21ZCr`|X-xUdL>e_a;>nBv8jw{NQ-1{AH-Zm8+EioiFoZOsxVh;H>$+ zuY=5sPcd9n95G-j1zRmh+07Nk9S0p9fmk{Ix^TmEI&+!BCw z3IIF#845vKp02%iRG;0w2Lyj>p)qq8KSO||(69pQP_+auI$UZW@=u4dWeKzoldduY z1b5`ek)0Mwh1=opbNy)6naYrZ5p!m0L8u)SeHc zeXo_w|By}3UNY2k3JPP}dnMF&s0eNj@i+r4xKFDQ@}-<~SB-o4FneOJ5n^*c2Ar(Y zs^m^6ICbN=f=?KrzkLjk0ae8iaV(>NM>awbfT2=UST|RXWdY6kQ7c8CT7DCIqc!IB zfyXdYEf)`oc=dalLgukYiDKQ-n&}>dXEC^!U6+RpE}lt`2-8WDc^J8^Z)r7>&XN=!xfzLA!h z{`$sJcJZ9lPM70^_>wr;8E9NV^YL#jaZ+nhP-SLthsIVuj>jx3kT zuHTe5mn4@_K)x=)jNdsg5azh`BJ5`(gVCnAI<`f`dcxN z;yYICV#>U{5kc%Y=z-FUt&H0Y_m8H{BSwUiC{IC2G$6(nfEa6w>0v&RbTLaIQfNC+ z3FbNhjyipzu?3DgYhWkGn;sUdo8RMWKi|A1=n({1UPqe4zOst+iBJ`T4**r)VYwdP z_>LdF!X=c$tD}i9RK#Q*f8*S+nz!iEpsbsLEUh(r(uKJKdvqc?kOR95SSEWXk~E%> zt^Cu_m=c}<-Kr>btFSnTAD0FSlzWbT>=d5vYWyw)_*Eagk9$Unh^hwYC%Rrt?*zNU z`zg@uf;D^F_k~HwRb3lhK}1y%mglhkrUFu;$W36eiWj^;B;Twsmb$(W{(*HTE_t48*FW6&BUPYRe1syESLuSYO1GT zXkrWLXxw(f_th)M+!GN5Y&of!D-@=s2iN)JHC?&Ts)Y~4XsaJcEQ;q!jz<*xDK)Wi z=Dm)B7l`{*>6KYB!J!a*cIJ+Tj^$fv0$?i9f^orLGD(eZoqVi_x<2<9l58D+8(~>>Rt+WyhyYL$)#0BOOJzG_&r? zcKm9y9;6M^u6lNy@pJ zr>FGt=~VElnM>2|pLG(IRe=^JG8F)C)Tl+?^`O8wU%NbN51gn6yjxRrHX>%U*7yIt zOhW3I^orgss8&sM0e^$cxO&?;Jj)UGW^-x13aV5{-|DFD$XDdffgm?>O`~dG<`X2I zhLe6M82s^(XVp8R|9UtEoETIVjXCsO;G@b7N0#F}i}L`AGvA}u(P}RD3Alq!2a8XZ zUO%15cTm^?G;9W2FZ(Gazo1hRD8k&#^LwTCp=s?Aa>vO=Ek=F7X)gYQ-OU|~!mL;) z(Q{2qK&FY`aM5&hLK7@+Zb3`cZ+mxM_%~uQ9RNTFFUH#0e?3)1W_pfGj!&qj6P_@I zYSaqn+~&ZPOlLs#U533KyNvR#eFdvelB{)N*iTvnU59o@jhRA zkTC`jb z(Q`TAsGBJLWiKpnw565FSj&knc3LZ5aw+)V%uSrNXL@$zh%Gyla3QaM-AJF&O#i7a zS|*k0Gq~!q=5qZqP|$D@2vmFu!}sg$f#Yc6s9U5X+-rYn+`tjd6Y;dbYh-6+fIbF1 zuoJmaN?;RYQj``*at$fBt4g^HN#y!4&xtM*3lV-j+=^@jCe&!H>IhJq>zPd*>YA=UuWDMq&|6b6po z7r2RlB{>(YkASy5h0Qa|bIKFa>V;65EnLE?aj;Lp$im3r*D0y6R9ELjXSKPmc^Nl3 zLyb-cei09op}$xc_DY~}QILsuRYOUDFp&^UCotv^N{MJR7ZVHUM^t4AOnmvulQW>; z)GVm0JWB^oa_3&_u@A?*t_qnpfkF^Y2`^b7mtREw#~(nteI_CzT0#JvoU*wo!J0XV zZ|nA`qDM91C$!cH#n!SH8NU_7x5-hur}pjq^Nkp3?E zQzbJ0_o-?br!pTZoRB&22IZT1qcM0fU$fW*nvOGou&7@bsE$f1^hSW}=+az${15$N zZS<4tlYLrzB45IQZH^(sKO2|vf_DPVBZk2lR$7~I?r$*Nu(ZcOIkpFV3MMv{bu{P% zut#J%f538qi16t-i4E}cXQq1ryKQs_Nc$6oBg4RXvOu$~$o|tu0~MygP@RB_f;0UO zm_ADX1=BM*!zT3#um+;R1E-X>@+1qK%^=gpu%NP)$^gGkAP^{_wENYg=4ulI<@( zO@8s~6mS1!Sn2%!PH`Z^j35yF1C|e;)X_|PPJ+)P;LfCdHcdp1K75=8np){p<|@M+!d%LRmz7Pn!Ubcy$a;58A!e{*&D*r1k6(vX z0YGca&no&loSlECyo68Ekb;NEbubiQ9aE#dNEed5*e`tBp2prkhUM{7v`)m!XZ11F z;q4N5n(z+E(fU3mNvTd_{kiaNL7v+ZhkDuHcXIT@4=V~5s16@_KJb)BYS>>Z39@;p z5GCNIm7=gqtHrad{eqUo-RklYw+Sa2E0PnN37)KO!kG!w#w8(!y$MB4ls_e`f6t=7 zmC*fPI#d3?^@0DbGwEMujD zJTwjd{lCB4;NR^7`pMfJcT4C`j#yN2!J1gUH!fQK_YeRKaP^i$H;}N1|I(`zO^Hg_ z3e+D{3I82Ee{Z_KzyG^G{O|4q|NmxVs*I~0>e+y42l-ehxne2ryiec2d&XAA#eASd ztE78-SFc6o=oJs;!_3OqwhsEVs1y;nBRt^^`G}kz(yb8pW#C$*rfga{oifycOUp`ANX(eA*kh`9?>M(4^SQ- z$ojK>R9_WZBIw0>sA6BaoQ@vFghBS%)~Nr9!@EyKscbt&hK5&!5*c`6NW%1ED-#;& zT3$z7O3WR+{c+u+^2KgiH8R#tXZ&5N64M8nD|9_dH?%!8Dq0nRz{MzJZALm_prqE= z$EL$t_qCv?d;!uZzVGfOb=;R)n0oZw!4d0UcxZZYSZWfk+US_m^+tez5m`d-2-iLF z<}!Jm7b1B%O|CAI6HW8A6(K=;^oGh_Y4VBH9C^~{)t$NTH{>oZIkMl^R~l;<$EdZZ zf9!HR2pB?(Z;w3#5DtI9c0LD4Zn}ARn%c)H0GLQI@2;*Og+HSodTUuh&b39yPp^{w ziX^D%&-x_AyW~bFpc`0;dBj)@+2`H7hO^;B4K!F!0sQ-Z!Zkc)E6C?mYj{A*E zpU?ZzbPYLA-`9w>fCE2U%*$S;FxMMqkNx6)`o(RUK5D=3#sN&O!Jnx+dp^!6xx;-T zKIPU4LK!`#_xXdgm%t7%Z!ZS(+1hAXSAGd4Tb`)E6ed2`YcOy`=fgm+>T!u5VvG!`^CBN(zNpO-0 zJlnJ`F;~38@~$ciE>)kp_|uYYBjQH9$i9IXcU36)q|r`hqn3GEAX^&b@aJd+nZac| z-snZg`G8gNt|4tk2>E$k>nJA$tsK z)rV@a8raPqbxlnN$v#-x%lQ&!-Ls&FWvH&gPx>0<*f(FogmPST0E$Kx6Yn_abAhv9 z*zpk)^ApsK0>eB=btg%)15ni;r2W32i*dh-Q$G1eFYjEd??{RH$M~;fw^GGpWcGM`5^wXA&e}p=c2yHwiBJ@^_JqVd|t=t2ScW5*~U zZu}~;cr5Rn3HO6Zh0Ftg zAV?fqWNgO6&|hgK_qp47wHVX@J4Y^x)a|FJKl z+%$jd%zvF>{+@CFXSc_Hx&9Q4nC~|JZD@<)+99guAIkqQ>#G5?1`3=09s7gjLDH zJzoj+evv<*1CiD6#i6Qi%L>~~I7doBXwzL*#5hx%%0+^^S6eI*941?I@~s~k$(r4F zOgjh(vJGWRmgNWn`ekf=j;Yc@M%&>vLMC+p@FX{@O87kx^POv21<|?vMj385`ijX_ zB+5~te^doHD)_$4&mS!G6StcfOIEkKRcc9`gvg$aRZpiQHK_z98tHw5tT(;mR*`MV z(;LsS;(NLhD8)NmpB0&ne$<^4)t^m(?GfQ2)(X-os79|=U!C#pUNq{q6M3;&k4EtP zTOJ@Mr`&l%AZZsNXv4mw|C41gXz*Y4Xhd7 z(f$%DLDY#MtZX*|#j3exFbZB%Q1O_P5}e~9YD!`>$5Pcx9GsSrNP(xjwRq5cdl(s; z)9NS}HdE;(rHOd9WpM8q+X@G5+V^aXjKJ@4Z$A1Jb;u~sA{QY{zOIn7%8yj!c)#7j zSzzV5j|KA>f%y8-IVw((bTgG2-p0J=yu}U7-HWa{2y+ z>@#Gr%Gg7iJMV-eF`omnHb;2LMb?`^$i@4}q>Q{|5iG?)PfGrRZiY|AH6dY zY}z;^h}pAB>m)aV;{<)h3%U*z#EOJQi|p_d@!AKSi@kamNuECl0;UQG(&^a`(nILV zlZ@inff6pnE8oQYvY+U4w~gT~eeI%fvxVd#kM}zPTJ@&2jFLD?^pgT45!&wbl@GNw%|E4v(JEGUzM ziGMaZ02>98@it%r!c9;_&(r3wm}fS=lBT8|qC92zmXqLCQQOx-v8`9cnKhtAD5zVQ z(*~n~o!7(!2HNL7@!Vqprj@;2RK# z)?ypbXq)>7449+727W4`vqf(W%h6AW8EJ-0fPF)roq8CmtmTvH|6sHUgA6S zkHX88d`No>CjyoXeQWWrT-hMhxU@~qLn=0izOMJ>K`n1TjlzLV*fviEq#PwXQH}-* zNTd8a`0D_xs~{>;jHnW-b2Wz%LqPVAv|(g_z)p0IK+Xb8U(z5~Pf%oAntJDK>^mWW zb7=Li-N0I`khX(mwOg6)!39As*muCXhCW!Ifsku&;$pvvC#ga^wREDPgN?Q0AaPs} zE;sH>+;1`}PO8#pQ5Nug{E(aOSVr~Q5Z`}LEcB~bZ-#qUxtP51#D$@WK{u;JYM%~t zBH$dd#*T6hF)#;q62JOW-Si~U`8aMZ>29X-qF7a$BN$5dBgc`r8{@k(sAP5(X;4 z!tDJeTx>)okSJ4L_&|Kt=o6v(-WDSERz5EWclv*}s9 z9!wStoCaDULx}}oD1jzUhBj`+dEpQg=*5EGJ<)q&6vDteG|?MS#DT3TWKa!+UI?O7 zp_e@dVf%ZUN9M{vFhwo>g!}O$zNzYg{8z#E&ndfE+;__yF@taAaptLD;%$#3euWfH zjJ}A5cK`@KKupuVITS`~5_idE>UCwPEQQ=|XGH*jGUaSaCBW9asIR)xdv+m`Yon0f7xr;(IJ383`PNW zQiUCY;jt7O=PQ0pJXjUN`|KEAkH7^LCjDVNd^tSHgz38sY8RdfJ*11mtV%bz4%A{lAfdz7etoq920sJzdKkI83{ z%z*VCm~kqTAI+4Ohj3C|yi3TFRpufJ%rgwA3poeB-smk^Dl46`WT`P}UcB<)57^ri zIqH4xbdN;N4YRs1e~t4`fuTqIDspVdDD#mNR|EcF`9|nU*)uWhDO^`gFAVYS+=L!T_DLK_-n|<7+UL5t#jCyjFs={iKt+llgs?gP(VgtN0e{FL ze5AjZH2^K2-dwtlNR4{Y5lCG^t?(5 zZBez40NjgrtdR~me4V;k7n%;mr{;_kl6=G|NgkuAmRYPm|J(Xxkx0+1 z+ehHlxl>5}_#L7M2;QRh7)l*!ST_o=kQ)KgZSl;Y&^dE-CTgzs^f1}U39uqE6M zVs&|(hykao3oCi_qDEhhoBX;n&#PX4!|b+h)918y7~e^&~LN@R_O(!Oni8 zdK4&u3@tcsKel)@>{_d!jY!XE-Ae@B{jFBwIyuvHb7(5Iu($>;*~Xd;)kkL zM+{Qwix_=oDt!Pyt}7BIc}UIJ%tA*6FRP9+T?_ov@JH*X;g22G+t-Z`nC7D4oxsTA&!@M3b3LUx*hCa7 zY~fAGqkMYL4~ZxYkepcXUvy1HXoCyja^WKa;T{v<6$VlE}VH5LN!tE8(cZ_ zMi%O&-S0s!MPxwT@y)O92=kZ(9kp(!0njJGl91IOZ}KjnDwwXGavyd!XaMRV>ZC_% zYuX*p4o+kCsQ-4on`@1U;yvJ)A= zBKFtk1pJyp3s@|v9j__lVvvI#U>C_A?KRA5$gDvClmr)eO|?+Q^;%>hZnr>3`8Ao| zsC+6oOuaTN9pn+DRo&}kR{}hBbV2Oz>=tJ4osao+XXPjY=35uG3kHI=bhduFn>k_p zOvj}#CIQh-Y&V_#2`W9)6G^hS$)Dom6np^zgl(LrpdiY=Dyb6~OLfR>sR5U+yz3Ms zTMKRp@1{G@rR;0_PGs9~Dp7DRX9MAEH5+r2PB(LJiyKj(UI zmF@{A#x>w3q#^Vm2#L|q;wei#unrvLyMx_UO>wh6w?eQ6_$t!rbLf?~PiCkZ*QjR# z&;G@91zHKIV32j;kgdvzwNyTmxbvnNkRBQUGX{?X#f*VdF)(aV*PcIF2|X?FwM4Ci zEQvy}_lCnh0gw#Jg+_X`4p?u%X~n*Ee>N48LSq8nSGLglph%S}8!WV>y@VeY$kSBd zskRl&Y890@$)a~NpGV^$Lu(lY>Tri{jT0-gnwMWFi+C4)*zw zayCM-xy#NP-H1rwuj^4%ynpl7nC~K&TXYh__vXzG0MT5_NN{%T4axJ687%&vfy(W-K!r->{x@8szyJL--TgnLjbe_C z3kTD4adpS>_cqhy}E>MSa2h^#*CZM$!uC~xGdK?950}wP{|sOQ>Cl zSqWd!C%mHVS#eFZOE_){cSwdOP5D7KhKu@27WK8e5;t#*gtX;k;8F-JT)ksHFzh6e zZ~Tn7wC6r@Vg4Mh=^ezw8gBKtna~+}pV9SgT2-PET0YVuRsIPx~^`zuY6JaTF` zQ}fxEEshz?`uil<^FAIerR=6v5;W!_0=98p9F3G+6{-7<(E)+nb(?;&-7^XgeH4$E z3h|4;;$u5tNY7#!2&ox}f!Qu6ExneeW?$Ra%&Sg{I`=h8eA!&-2(i$mzs=~YVU0PR z`y#Qz6W#lAp?|G8+{}3iVQDJt3z z$XM*ttYDrT?tU7*=CG0!mese0DBu zEO%WR!{Xs)2TL3^ezqNb2h7f2aYo9@581bGeVhhi)!Davspy4JSarGC%LE$_>+h5b zZGfLsBG$&^(X10muiiax(#6}`7N$=4%0TRaw6f>JI0{CdL{e3v>z!sf2eq;Dljo)* zdCK>g%#z&9zx>z@H(;Mr&nR7_E@a)3t@e8Ta`?Oc)@8z`>Chh!5JU zNVFm5clA4pJac8SAb9&9Fe0a{dk&v~TWO-9VXm3+sPgtF;*U7gs|jy18>5XC$k9uC z5_UFdudwXjqiTu@4pD-s9}D$AF@V;S7)Vb8@7fFOY8r}Vn+3fe0ma0698gRcVjab; zOEA+Oz$IE>z7#p>vJv_9k@Lsa7BM+=`)0{MZtx(tg8RiRm_k3e4qJ&A^nr5yXd~ct zd=XAJ)Ks{?Uw-IV23#5rUmX50(*qX4`Q zrhU0_^7{S3i5r8{@%rDbwgD>XjYJ=$His0(IT>S$9$C#r<=1irWw?hKER5U09ud>G zE8>IXA>#(#MqX)vZPUW+jh@7zB%j6={FiqbnVYNw#S4bCZ)oA4%feKaNV%b0HG`Jf zMye5h5ga|`CGV?yNqsRDzEHK#0kRptWs3?n4rKd9=Y!C8f#mW)d-LY9_4!dvKLGE2 z2jIQFU|(de6}CQA+RGkki1(=+9c-25L|TAYQW(t;MH*AwC0~*}g{m1Q1Hq^=m26rK zjwYrNM7W0SJPzZXTj_zA^s>J*>61iD<9Ewn0Ve%60s?*)-sHDcX$RR{bN*)~2;+Y)EN=OWFYp2?C_xV(LD zCh>)*8VN6bC=76TS|t~0+I2Y4Y+1lr{j7|35-%_Yd(@P~f|xS+24$5dXuMM7w$_tl zfdznEkH`|mH-f)o2f&0@k#C z`W7f|0-hYtn_9GLKKbQ&xw*?YU}(MPYuw=yF7VKOU*OD+@1p zOr4!kQyN^IGlqVf2JWiZGV=1RFFwXKxuHiMUwkev z5E%^_BfLibB;{Lf?YixEW4X`)tP?IK&X^(ei~)tHfb{*|j%XP{ZdN!-p8v0emfH??uo$qHv4oFsMK_w#{D(;CX;UL!cDE zcKjrwRsSxDhexVR4;|hyyDMVa3JYkINBc%@clryI+!ny%wc=h~?-r^mlITNW5P-Tl zC&TPlkm8;KF{+cyOBnDF=+1d9$);6}5`D)8w_Yf-6${j)Ul}w)m;=QN6`6#u1{TTW-%5SpZoX@)ddH44N_z#J!&3D8fdRH_??w*s0OVdREsKoT=fDLU*V*NQ_ zCw~ptjfj9Ak+#zTOFf2Yrl)YPjwm?+x>o>mibpf1jjxi_kRW!UELFR4tY;WJ5rC}y zc;BmKpq?SKir&}c3cDvDA_SS)1(_L5Xg;%RzX39EghzmyExF8kDVcHn^}NQ*_BI(F z{$_7&(`8b&PV#skvNQ8g;0JC8R}VcPVxnwXp1*`tfisn-MDDQ!6d@RO;GKJ?!2cvL z+>HWIIK>lYw$JRbVs}6_PtBXpN3ldNB3>wam{CT`0l&(F#wz?lu4&zmu9wX1sbdQE z10CLC_OTLZO^g6Tp2FCl*mprNcBNAoyYVv^0FckEpMcMKAb|HK0C@kfJXNQoK@P2e3$;XJ&#HAF zAWqR1C&a-$eML<}a&y!m%#{<-3D6v3)J|IjW#t@q1O|YVqCLt;;N&hK|AGr+Aidk+ zZ|jBCS%dRrI?M_b)D#2nh-iH-o)<7 z#K{~12ZlZaybi`+ePboARco`h3;$~vRgOO?fQQThcu1(t_B#1wfZgY^PfQ9#B^c5x zJ1vzNe9Qj@}@eo18mnB@Bj=Q5@Jf2D{B)0~22qF^8gAn!9s!)_J^(5-1iFtD6i+BXaPb09kgx&FII3Ux zeSZSxrDoQri1f^_^#0;1XrY%E{jxCVg!;V6G^-NS=UYztyil_t=<`CL&m%WENk0Da zN&xV^0-Wj3<6csP4-!D78Vy=RhTi=I^@|Bs9!cjn_v>6r3nu}H5av^+SE|Kqb&d7A ze2X_IDpQ!yUq_RP5O>&f7W;n2qti{*4joosEJDvwBR&^JFd*e zi6Pqc10E0e95GMqzL)S53p1VyE1@7bIcn6kfi^heKbG$Xi>;uop~FzCAIOcb^~x^+ z?}rnktJ)oB?+XaXcd`CJ(ZM77w z!1kRpOh=oa9}7&+0d-iu2Y1VG-yJRV3L#-%_`sSEBJF{A^59WBs^jX`QgDxvP>Qsp zTIMqpZx;_1a#rD@5dt!z10eS1tg3gVf68emp9x|xOhtgHdv0b>u>Q>wkL!M)e%Imc zvU!cE?EJMtJ1})iF+OuGI5?2)sI^8XzLQP8=$*v-=hXcgfKS%=n4TCrvvOL>AhP>A zGeU}}suJ#Wy+uU-_a!j^60ri=G9g6Fg zie(=FV410@8yJFM)AC85uAq0o-=eQ~(qa^>l`1)1p}GdO@Sn zpTr9=ecd9;E`;}?(Rc#9F0caXIt&HCRc!A{Uk(irXUL@k{8IYr<|x7IvrfFXq2LNV zX8b7H#(f#-+}U3b9zWJ@v$mhwh7tgnW$;ZZdtEpv-o#-&mNyOk34yi5QgU&+4QN`a z!w^eo^7Ee4&KctSYj6f{-l337 z$GE=z1Td1 z@Wp;){xB31`_X59;r_*Fv)z%ksG<1BChVTN0BghZNes_5Vsbsak2VA0pe*x16yzUt zGIO zR#o3qV0_{bFGQ5gyl3(YCQG(0!C^VyRls!wgzx~;vySMz%c6K&WCq`LjnTDa>FHny zu5T=WAHW$brzY_=yj;tKa;}6j(X1RAPZzH7Fip*;(HUNjZY6H!rd-zSRHluxr|%-} z^E^@>)emQLPLai3vuN-yIA-7(IIJw&Gu8G!^GvopYl;LiCl0KbG4OL*8jKF-eJqeT zQ}f*PC`-+VHsZs5-8*spbYajdBPHG7X4^6WjUFQ__r&$zN_mkl$&z*}M>uB52}L3t z(vgalmk63FvaWxn$3pYylw~zBGn-&lr1t7^tlJzJyzP^CIoMsxWX*)?JizP*Juc5` zBD*NI9>uwrf>)V5%>FR7iW8r}!$NC@k?=WRyF>lQSBvv&rgbE`-_{Upw9PgJBa2@d zNlTwonQ^^X?SNe^?)5^v4qN+t9HMOH0g-oXNN)I(Rf1%8pG3IMsF+(VUj<>fVs1h(}ux!;-)4*63a+~hc!h_WYC=dalU&HZIU z*6Et!y&k#5UxlAvnClIYRUf&2E>HkRkp8s)+HJ7E6Dc~m0hxlMuH z=$|r^l*HLzg3fC~p~HbWQDosL%K|Rb9X-OHRhyHh|~KTQXS=h zvw$n`-3HlXpL+K?V0dVhsE(+#FT>4dY8e43%*_>05ErR)YlVu-UswjuDCm=Pc(2Ayyef;(BD;7%_9Jp(qIfi6zn@hzB-N`Xe-L$#KxzXY2i z6I>rPSSbC19t^yFr&wXFt)hs;_H|C5UTv2#zzta>7>)3A`CR)sowv%ZLcp;}34ePD z_#mpZfAc{PGMi%8NIo-G_SuGyZjWqo|BA?!&j(U>uTFlzBn9P+@WnAb*#?lYlqTIy zu|xB6xifQHtUSh@?3kuzbG`SrSb{`VQ8P zinD=jk9b-X=>QgZb)|-q*?b-u1H?qN+>~w?TF$hz{qFJt6bU(aSpSxR37x z$j0*rdY^K7blmy_cIrm19}Q+Y;uQHccq7}km8yyo72si@EQ(Hu$ZIuSdx;*SsZLoX ze)J-#_bhj_sSc2E*GetqE-4#D7aE>82RY*-Cucq{Q-^c~d8UL7ER-2LQ32O`D$@-B zO-Zr237$N}2Ls8TD-h`dU7YA&GXi%Y4hQ-~aSaGh7>N)YuxykUMfyas0ZUJLhJKU~ z*di7fG;^?HcJ&4&UWqMPMDm>?lg3N|G6}C0g-p_nLo2KW+tXqi%fRa~OLqdDP1 znbTgI*}cRmLnV!VC+WfrCh1KStBdWQSzX?lknK7^()?s+WK%z$uEBITbEB(+gS}+K ziKVX0=cV!j9nA}An-V7RWq2g^)TEEWbahm3dV&qamcse$ABXDA+rN7APlQJ{b;R@r zQ3mq+H}UAnq}v8@l^I_ho?QH3fn^4svMSs$nHgy`Cz+a03%1<2zv2WS;E)~Y zc4Nu78Gm&E=Ysj}NwCtSi3JbASWJLdbjKhNX#4sKFiwti0TBd^{!fgb>!0kjA%9#t zVAK9{IB4Two{YZtsL^-bQI?_l-2l^bXV;GMp&Z`W1p0Qody;f|Bb=5;*U(keaXciC zj1L8MRJ!KD2^~;|0LteH5!K}+M5qEY`ya3H?qrjgTIjJyOJ-eA0hw;}k=wW9KYi3c z=XL_(0cP?L(1+|m8v|^he$feEKP9HJ2B>kE8^iB+Cbi00m_H$=^F&;PMG=p2JlitE zV`RO|BXi=FTk6G_4=Fdu8)`Q*+I^Wb423z6UNTB8g;DJbZi$8_B3HNq9@le=J6zendab|SGBRPO{+UKr0f!QZ&CnIv zUZ{Gm*H)&ga)~Mh2lS_A6>p-Ed<&SXkyil?^w8(S3nxdhB8j`Ml|$pXV@CHBUb5=oJ5 z{nawQcDeEbW799(3U&V<_TB?3s%_8qE^>~NGXj!D$r(hEpkxswBN-&;BuPL@Bnl`w z2N4h?=bV(BBtwBBAUR6%TLpNo=k)FS-M-y#yw^RNF+8WJDysHcd+oi~UjI3N^8y!z z{>@&=Jl&_>cOeU6Hj^(91Vz~S;m!Vf6Xo6hf#aKqT*d{yDQi{!$n7KerTY_n)YESq zyrk>63y$|XdX@aq$@5hUE5^e7r^r23V*T&Jof#ZzobguIzBn$ zmc6Lt_P~T)~nrLgF=}n?!Nu!?nd&rC9>3lo<`0Yl-Mb<=WMq7SIhF4 zeT^_4t^CESx~_Ob7!%cfqZP|DcKC7fG?ukk-h?f5kItanoD3nbm%Yy15Y9$B8bXPA zErib^ArCPwFJ2LTI{v`cd39Mw9Z(6`?ch|xKKTuqkIkDXe=wMk?QmcPiYML)T_!t% zz3iEr>%Qe|HrK^n?ZIWE^N$U1>##(9FgjcxF5E7}-dHHp$o~Pb2~DNom}g6z!!aE4_fYFzS?PW4W!AGd_FLTBESf>OriNrSz=`ejbcZmz-wcI;J>-e`#SjwGEufvQ{O-JmHtwm;058@XM^IsBYdQR|Fj# z;9Q57JK?S`f59TVvYU#FQLBXHfpG8h%<8}Mm~=+WQ(F|x{D)i{PuqS4sa8zs zKpI_yf~$XbkK#jOv@xOuY|evzDljeK-PE`rsQvr73kg0h_bRo{&s|kRjTBGV>COlu zRmlt;-{A9j4DQZ3rQ*7_YN1U~uEm}Mm{$?JK-2Ip*wl4czcmfWWO}dl&g`@aT(t^q zhk8(~t*xb%`aKRoj3MjH=>TLmNk2eNLk9~B|Jn`w;_(!q=-^2l1`~geW3j&ds!zn~ z`7wX~Y1dDP@WI0%a-Y#u+X5^zi)8xyr>xkUa`8t~Fw+?E>{uip`?JjMpOD+Sajli< zQ1g>atUkefTI~5C&BY!3n@a$#3;p#$8)wwgZpmg70Y>F3Yw^89qRlBW(ym`L$Gb#j zNzMC+TD6UZ7#}z<+GsZ*)D%9iXKi2%u0(@DzQ&NWG_ zc`l;1JW2XWgTh)zUAd+&PuJWy1M2DvC|Va0t_g}+O+V4}F_Y?bo50|0gxeCm$_tfR z>$$?^Uoln9c*4Mn&Y|XzPaluuI}g+L-Ry%l_vwmOA;!u(&h(md@$0x5*ztzdfdTkc zFkdcUgS2+v)f11pw`E&8S3fnDDtSM)i*==i7g7q0pi(b;pkGDRVKV)h>MBXY2o3pP zc=Mjm1r}ZLUs*b~mWiKT^)Rhtkl(@>D@}OWf{e)CbCqlhLc2Tam;A-3Hwi<`1sYu- zW5AOmg?1p#qf!^FRA#|sKn7GE9Kh%dOtwV=2{6VGp0{aixClAgUbmy}J(E!-4#P-w z5hH{`yH_YzO`=G!Wxr<6yFZ1jO8Wkz_G<3-yj)f&5-vXsW{g7*%VejzqI;UONLv1p z@j6*#FAJh2+(e5NrVR`k(OUv9G6sz?Y;Gq96CsRU#h)5W@RE<$EM(Z8%I&jsPHC0# z%pFvxC!31~@?t&hnN05H`4GT`2AT$7=vHBV{Uu0AYZvXfz4l-}c-kkgND2^SQQ;<2 z`mTejB8kI5l-&w~1j#Rsy%QV5#;__|;?=Eh+ibOlUE;5N`wm@EzKfepwD=_pXt+H1 zK&5eWp3_0h%%!vWaRRJ}us)D2J#;Z zb$V3l90iKeAV2V=)~-y#sG@YP3P-%NQ*hmPjnJFqh^TxlBbbVjClx*T>bj5(kuw-3 zGuOlABABXhJ*bq?9>Kl8byhtR^F|7%ExNQpUK%9t%H)Iex!K8%^$Y5regxm&7)W{?V%Bz`6^$uoFCYEWyY_oj30L5yi*T;U0U| zg=LD9TksLp&(P13Jz0@t83h(zO%vRi$G^|mu7~y`13z(s-qU39$f8zCMXa?R*U?XA z<#L|ydmzF|Un;U54s#g}t!c?=vLiGWBHBKWV(fjJnG4K5BB$EyS)XK(Io*JyL}Jpw zz2K~3wC;++mN7;B8)3yJD#ROBJqt}^O?om3ZAfC>ElK=@9&5y$GC85k@BK~(?ho4< zz(4pkJ3^%73vq1^xZ}Kb27CiYVeT{V4b^zqZY7+$P{k%%&=X9jyr~Zg8wt@4LZ9|4%!G6> ztj8nM0W4-r-)eQ+Xo_2;WME7<+f z%n3u0rtd0BgO(I`e(q*Te-{DR;(tz{{qygLl#{Zy)>^Fige~NSZ2G|}wV_R$7=2pn z%afC%5i~x){4gz1?;{*PHvipDhcR><)6w6m`T`nqTz7)F}st;IuIrL#d}xyWka1@6HD^C$O{)dJqGIP%&{W1 zTZrF*wh{RSK)s1Bc)Gv!CBj`iZ0`D)UaK=QT}8?Lj_$n<;sMnlhO|sHw4V@k;=Yp; z+TMy2iTU9{KOWfK?@D}ib#)dP%mol^$Hry3U!|CTQzrRq+2p_9?;t~EOCd+*pp8y+ z3}$<@do&UrL~DPRoqwY66QY-*RlM1i!?Ulf`eW{Y+?32jt$uJVGkk~B|q_W72QEQc)fNXkLNJy)AC-S zPs>v#ZyZgw==j;ggtI#FvX}Ep*oD>a9uiiy|oHPnfKFY z_+0ydRb*A1ZrJ%p@OZ1AM#&%|9^tqBi3d>5%-QHwU740X?)`3aMu%<(p+dy9>;2(n z7(8bq9(XOd#6KYvkj5>=uz1w$Xx84PDHK;doH2dPvhB}CAIY+|K-c6WDJtCz9mAT} zwJ5c|_x&w5`Th{n==#*eq}+`qgB~DUdhQ%hWEpZL6msmS+wkJ#&OQldg3lPX2E#lK zhI4+4gCc*GCFDErOB5$>R1LMLCw^B^p+P5+^w(f|n~SZ>Mi$K8xX!Y@VmB2Ki$cx2Mu zxLESRD0yV1qIc+9IHQku^wrwC_!1SbjKcZr20P4$uFk%!aqoe+Wh@KFtY@k$L{bZq}^VB)%zL`vbWCT+IsZs zd!7TneRWmhG2>oJNNWTsSqhu&WQ%g-{Wp>4K&svu&Dzk(7ss!Gy*xU6dvznFK_U^e ztc^Y1XelYSn@1XNycB{2zl5fvFz!Gh#hV@Lbskqv7xX;Ak<>6emIm(9TiXY~DaFah zOC$b75vecqcq|JXf$kNp8+%=QnY>DymG<;U!?af#cNQe%i#HqAyAHu`KsVEIsEl?c zM{8R5Q?YhX3l)`9;r8r&w;ZBq6#ggfyA}=D=^-N@Q%#W<_`c1h@KEO=!0OpHzx8J- zzf<&H%{esTD8WFgG9hobtZ0SZA2_w_Xaw zd#!7?@FUEP);#o-%{J&p$5q*0zvs-z{m8bPyVp~eP{mEB7WlfyEhYjBvtLlzRC*aZ z6*)M@vY&{@(0(rXP}8Mz1beNMWnby$v~fJ6&j;%Vx&U{d)dJ6_?`~#(LQ^P%0e$!R zGZ0S@UcAi-Qu_4R(P<~UMcm8Q)WB@Dic5emy>s~uvSu-EDXkh5 zbptQ4P#(6Uc@)p5px?_6a&Ni1-(%REy4sy-|8=*>aR?^sbO^-aF<_~_t5#;-Gl`(7 zoMRxllFu*4>{yX{+I2^7HUCbug(ErsO-!rSs}QS3++=Hrr<0m@!X3GW>NiC!TX@f} zjh3MV*vq!8@vW%&bOP1+ll&H&rnCN6%ri6gPy<(z8QdYJ3K`D`@*t%i&G_k150oh- z6aG0oLB4ppk!D2XV^4!2TBYH2A-61_0{Y~i8#i&{<8c2YZuTHVKjobKsr*jL4wimhhEHS%w3i^fK6m{7m8 z@5^3si58Zj$`1&SEpyT*)c=1CMb^qgk9anjtMgltgLQ8^7?fVP&P?#= zj0K%Y8|Hs-A4r!==4Q`Zpki)$+2Kw2j-mAum(UQ;7p5l*wZMxov+#2IC6i-4^;l0Q|3L#o4wBev z`rLM%h%()8fU@j)qPg$Ak%eitQ01Wr0&=>Lrjry9dP8U;9Rf8e!lf!sa# zr-9WX76cYJ`^p-$|Gzg3>Ho_1e>*$O9s>4P-yQvshSj0fhvH=39Y^uDt)BN@ym;*@1%&%ID+9+C$*u<%3?nMB&X|3QlnNdl z>dDHXRb_k0mR43)hPIH~&k{?tcs^QdO?Dt67wmz!_O{;q8tv%;F6M4S=J@K~nlXc> z1^_CUPxSG5V9y6hj~i_eH_@!ZJ*j9R`b-AKvD`y_phT@v-e5GD@*(AGKg?;~SswFT z8%ey`NBm;nTbpcBT)Z^M=_iCByCllIEl=lQQi~R(4t07OkK#toTh*zKJ}PweuS0Uq zJK=NoNz;Fg%%NP*12ymnD+BW! zFxCtfP!UPRwbdEZeHds*3o^^i zp4+gW5aJdyjEV|_<91y3o=Jsa>ul#Rp}V-;rNtH=fz!>5#htEHCV7x}V>La?E=F0U z4Q}uJ2^&|L`Ihl#&I$8AIJYt*3H@@=b2+?Gi=AU$EPU|+xh##3+RNypAS8f<9Iw==($#a z7ufhcV*l%VULUOKmDs@^$6DfVlm$xjH3he&8g8I#rg@nWA>?gcA9XjCd5J~03SBy3 zf?df_WMKGW+EkPt+T;5caB6Kwi?e1{LFnG8 zY`nlX8*n@U*-;9aU5y4uGwJEL1ce#=XbxGp(XL}wrnEUT>S@TF7>EFt3~v2Z_(_$Q|YOnh7HNQf443MOW^JGp+txcJ^KL)-1#|W+1e7&pTCq#dPy&X1W zd$*LV`SXrrqB2@hUq?{isY4M-$govf$d5Z^>-bGe-!#GEtUu|lfsLQq!N>eU^d@c|LOc`Z3QwE6l|}W-(%#|@mZtWH5j2tDP$9W( zf>BX!@TFa_h^HjFXJjGzc+j-sVr#bHV|2Nuz;x1rG{Q2s{+^*RScs=-yZUQ`vZfry zEkk$c$sF7_^i~b{mpAjn=NC1^U=7%}-)g@}S1!yDRYPnDbUqbPF5fOBAc!#fN;FI8 z7OgZmO*p|D8Gaz`Uh~@~RnuY}K3-6-BAf}D2o|)Ibg3sEo>f!r!HX5KS8*$9?Mdq{ z_N#HV{I*t*S`uOu2+~?%RU0ISc2@Z09kaJ0@1u(fz{DgTVA~K7bQ}cA!0Nc=bpxBwsGiEKU65Je`m@s8;z;^A)AfW=2r9v|(Apy-U3j$dA z&2{q&-)H;@Ss$6mfZ_c>=mX|zA*J9uKMrWsbl2q^cyvhNcGi>?s~S*!BJZ`TUh7Tr zihO&8Ks0``qy{808w0$OP-cB`(Ajvp6Xo+&ojb0oZrU0ofgd??Aj)W|26X2Hr}$w} z*#S!nTT{`tUR<_{kXortMwg5L!FJ1^kf2iJ((tt_k7Xi^&B`DSXV;nbJRjj|RV$ezc*h$+16`23TUq#%IGkj@%(3ltC z<78d%aYS4|ielVx3t!{m#HiU=+ADf^a^sXm1%6LXYq20BOJ^z;n*fytPvK!?X`Q@? zfuIp|IRO343?wbruC{gB?j33kyZgy@5utzIa~Ivf6@{PPIX5@X#F>xcm-py2n!hL^ z-(`Pu2)8Ga(yB@JZf#~I0g%`jbI~Cj7?u+*Fh-ON2Z=3w$7qTU9qEH}q;4-w!5&7K zC7UB5!bvrX{+BJ}SWm0-1GF&vUN(`s>w_!fFwMwEaEeLba6QooO4Z|4dYG@s3DrW~ zgA3+bQe!j~rqjXwc(aLq6X+u5LV-1x=)GL>LLMsn3SpHBiJ(H1#F@ zjhrY9Fku1HcRw`4F=6bEE!D^_5kO`blL>fPqg5BYEJnb~LX(H=Y!FX3xxdqv!$M^Y z9ZUZVR+ji_!O2{)I8!{j=nnY-;t%4LeKTPv=F>qG2SNaR zPF0C)66F=}I`Et}NAxJfFRNJ;GIcHxxQfM*1bgNoWqCY~#^ft3d} z_aIB8=rfVKJkX`ud#TuztB)DB0f_|S^u;qQIP1YM*L+F2sVSnQAaUe8wR@Rlzl3HG zd*W8@;PnPF zP1WjLM3!;(ANSdv80Fff5gEo#6!)W%-~VGSCsx*kIJ0a-ii+f?aNNUZv;Gz5z$xjM z9qhn6+T*3}j4(z=;pkgMKB>D^#qU8lMe|6R0^*Y8gPQV-DD%X%?y5s^y({lf#sV3G4^R67L4l#``Gk+3C(YgnT`UvEB-f7bk3PZVb{J@Y7?d@P#$-ZJ0KbbLmVuqLNvV>P4wk6#Pz(jT4R+ zcvsGK)PK5a{x5{){})0-(cf~epI?5+k`B*!eEO4ZWtGV$;!=23 z*}Q}32$>Aou!^X!WMWBNb!k~C{WU!NRAc+NQ!Spwge(RLVTiXBw3p@aW#3*TcOu50_d3oVNFPNnmL@&Q z#M;gLrB%!YS(#}sfR6k~bwC=zmlgy}0F{om~2BKY&oh6r&G6A<67N z)S?8_enM2!zz$S}NC@C`W_!nu32nzo$a@ntqS3ng$!zh zUGVx}R_y<_KK(y^^8eTN{bz0lF3)$^@pg|{OO=uR8O-q3XE!M3#Q|=h6&~0=bh;pgifQM-9=oL& zXUm(u_t|}58^u}j8OqeWjK|LG6$QSH=k(eFT=)_({JEh8KcyO6S2V5qRRlX@Ypu^C0(?ksr*V^~@GQeUW zd*o!x`Dp+yz;JvrasTu9EU!AJH`F}3BoV*P90^Nz3o>Mkk=0K52d?HstCXYO3>lVr z==H*#uL&@LG1^zw8!ofbm4SbLB0RwC9>(=}$02*2k(407-ML3=ud5VteXimUT#aq8 zKJU)^Z*r-)A6o6(on8c+Q2K9Ly*hN}DCx7W`^dsfJgGnVV$y=M?=D#(E^F|!J-;Wl zKiYkTe?ka#TWqrw3+OZ$po?cT1kR#s0vqVe$RiTea-2P1N`l!+jG!yEtZCOHjZ2WC z7Owg7)=J$>??t<>!E_1KUiFf6Oz-v1kGh6aBEftKdqZ+bSUJbq_0uErVgum$Ty_ACT>K-2Ab3b})B+_9SZ}0E~NyhNI`K z0qfD(CM!s6cis1tD4E}}|6tH-6@SSgun+13mappNf9iT z6rA%TvMt4Nk~kQvE&3GN9Q6WDQ!FVR8hwxa9*D}hqSQz7I#fP10fvQ-C;XHY=EtEU zN|b&;Gf%{Pn)dLFDzVS5C9UVyf|YxMF4O={H~}!Dl79wf6e3Osa5=iC;U@ub@{vZ; zAwU_W;NM;pd~&0geSpK~ymadq1^1Z{9iHuRr_j!1q9qeqbff1)yb(PqXJd<5$7`&<{kVvo!~O+@FwzuReLH zxQ9LkpdB$ z?mWE8?&+B~q%2K%^M@-Y#Nro$C#`PFG|%09|0l%EHqj`{gKOV8!GZ2Rt!2hr{)8Ou znp%|*2%zjhzSdJu=xDz&u9OPg87&i4n&0wfp45m7k6=^6S>ehRfm`^8pcC=i6QtXw z5dg6RnUeudMq}V)Z1rIg%(M3T&8hzl4pMMOckGkTC>+<8$(Z7nf_7H{-f*3TC(bb2 zR;6jjRiNo5JoH&B+8;Rv{zzjlk$5>9GYyBvD}K7A2j%@;U+&Lc`P`3&2v@5E4+uY; z)o{=1cPPVcr4RNs02JV%PVLe?Ax1MFMf6a;lTI0B(yFtF?qLX=1T z7|o*>j?22dz@Z+V5Z+$xL#TVpHdBEL&bVNIedyq54)eM-{BKwfT zUacU5>eP+@oj?DM3;54GzCaBWocikdvc)P8-7`nmLz5QauU*O3WTU&7L1$XL4g2BT63nP**>?!S}lC9{auT>DG z=kB>*6bsn1aE)4zlBOKIq0<-|3s(yc9dBu)*B*x_%aAXXS(DMZOfwq3cFh64AR+{m zy+nc0J}j0lDq8sk1MOLym1KD&MpcS+gbsPD7VI3S=j6ds=19IxpR& zE^(JuIXYmK8weJMy}8V}M-s%UvD&yYUe|hVQ``uSjUF#8{*-Butl$!YeG{iRRb5On zOEdlUaVDlx79t~O@U%2fbhz4 zXuw;`si;i+ly!@_z@-(H4A@04thiXaspuQu=j$un-oP!(^Ep-8$$3(iE_^)9{W6n0;USp>}<(s8-4JfY3%NrA7BA z^Ssdt&`J_=Li$aAOw;dRBt~sc#;b&Lb>{0E6OZJw~S6&V}op z#6xLn!z?+k;WjXmy)58im&Np0`S5Ls4ZB$Di#U7~I|{v#zwqk*hGj^xguJ4iq1fsB z-R=%rs`K>@3J|8m(%}dbN0@yfC-#GJBK6vqPh8p^bC9yQRLZLK!P4x=*3%pt(G>cy zULI(C_ryjU=~d6fb356k-!X>KUK-NMg72w(le1v{Lx>UFV8*B+0aGBcDnB+>yrpQz zo}RVBU%|dC87@k5eRyrG3;*VLyZvpq6qVt)@8L)&(f;;QR~OWRu)|bSnV?eo zO!@=~-hgYVTi0LkO`cx3BnQA@mytU$RRk2yfAP)BsOp!9Vv{IhwEfjLF9P#>LqpLY z6cO~~WDq;P2xg1-V(Hl7^za8__5H1|VP{J1nB7#FWVi#fYmo!z`I)l4k`j@n#v-^4 zN{4^o-Ag0B`oBwpNP3RiOl+U>${4<1;{d5bMPGJwUy1QHM~0tdC>Oz@7cjj&DH9)XHAhlPyDJK=P|D{bh^xOLYEHw-LfYvu-``&I|U=OQ2bfS8_3r&r^3) zIpw{@b8^OcXc)Upix&Q%(N6eGgmFJ=+qupDdWIt|j$H-nadQREVo(g#*i$7TqAvIu zqm$|w3U_iQDJj#MYy%sy8S$W-XUp>AdhcFF*QMl<5{`GnUjXK!>|XNC2|vG%TaDlr z`G40D|AXtMxTPDMb!=E&PkT&vz`d1e?UB!OhYp@pRjEW(q(RYgxDd>}=!C5Kp5lR>o`jAZU-vXjgtPP>&JKUR6V{zYv`Fd+S1$iQXlEK3T4oQ9lmM97( z=D$9jv=4j38-&)VK@OV(xvR}6_CFyKXgfuc20s?EuF?1c4uE8##M0cEbHAJG?dZG6 za`axKXEgELJ^tqS1{GH$SjE^A#!h5T!+ofj*NdC@^ff>R2eR#X28SfIZR~KM{9cjh zPsp>6>dT7)U$oDtx31`$fb@}Rzf|0?u+ogLUxd(rH;9uTh_Ecq zj~Y2q-E5-#jCZ3#=b?AX3umGAg^)P|vbilu>N!;pRSlkZpjy|J8cx*}IwoUz=AG&2 z<7Vnh3r|>O=>m7ubX$}b0t1tN2VpEonH_>zY|;;+z7H3)tDbRPP+VUyVM zWJjh8>1r)dw72zq&82w2rc#+|R%r3I1EAF0a`UYENe?A?p~JoP}%P0P2^6xj}t-tr-By=afr@~y?RU$ZjyF6caI*x|Ki~j8! zRlLj8c5U9WI-kg))A2)hGEiw!MoG_f&U{CUXGKbpS$It=3cI7~G+Y(2=jSHt1jM;XZ%1pFJAhxrtv1x(&&L@!FqMWSAURhiV z?@vV&j)GOs_p6~#ULZk&hNfMB1nqlOjkphxMWaVdc&Vz-lPvE62ra*sy zMMN;F&%%_2rIpn9?-QF(kuXGR($IqeMmo@lHUr?bQP8kaCGlRNhFTug+^#kV*hX~) zLRmpa|AB%!KnIba_d{T5v59RvAW*)+`;jSK!9RT)m%?s;138{w3dNzH0O^e2gH%R!qs5SXW;gQa9^IJ9wu@K3M*XXLzZ?Hobo zx8n@`=J)E>w1tRlu@!wh0PD=U<|TU?QqbS(#0${ylK&?ybF6pqaJlPWy;4RKDRR@X zbOs8*U|EK+&Vmu866f$7mjFJ~DfK zWjpg2CH!PlsoPi36Ch?Bbuz7yP>cfFT+2g^0~u{=rSEXOd$lO(d&=f^XaJxs?j5ay zC#Q-m9mvUL1Bcoz1E0q^;>e=iI{O6Q;Zgf^+5jx?h9cv#9axd}3n$^1uJq&C1wxG6 zWBw12G9XGa#@y9BJ1i0baN3}`BPe7oqmsWGQHMspBYweJOP^%rP8?fgvb3|S#5UVc z$RyjBr!@B7_Tg%h)TP4CiTIiDnm@O+A*i~-4EJj!rb`?HH*|SU7vv6thPso7(Hl1l z^PJsZU&jyUFuGP1{yg%>MB>e`%rL8g^a?2HC;LE2 zSYd%d6jm|V`$^Cw5Mi&4=duaesklfTBvJK6$j{$|$aWQu$yWyH@)LzLnW#kGA7cpp zwo{YKK^mYF+|p$dyFbShs|-RaXMzY$dhO6Wz};TaLnFIc-SU2KJm=6q+R;!fTxE*18|roX>N1$*zMURd_b zzgb+g7saVs>9Qb^;&n${F9W{r+mCi{z7LP7)&~Td7SQ$L@s&AeX-#R@J|3Gmo*U&DvM%D*6H(aN0+oYRgHOFV zQtXy(ukT*eN43q6UH~yg)B8>X@i5`w)RpU-veH!(ZEH!7L94kz-r;CYU)QwZ4ao zP}oDF+`X9Jq94RQ!b7Y>l&EL#6ZPD&x?z?q4RPgknjQCfq7utmiMfzgQMbjPuJ@#a z$gIvq%ck%9bFWWNCV1kP%GSJ{IxW91mi}OK-y_iLvq9g}^^{5)?SKn)g?i?lhN>v}31+(4OM=ki= z7#}bZg~p3h;a&e~-lweK;<0O=#5O;D%b=D5!kh5iWXMoJN{b zpVdKi=*ECmpFUlu^yao(2S<)1mBvfbwWC(le)j~~UiSBus>vj5Ey&V3aquH*=lqE3 zahaGyl1;=#oq)j3XhK(j{!eS>`q)gniZMJh)C5kZjtJ~nP;uKuDws?GOmnngUgU}w zYZ`*DI(ho|J~(ENPc>c!mAS+_W&wbIJ^{!VqVZwe23fQO8yqDxC@wvJ>(BYx%U*W< ztuG-9hQIf+ibc80es>WjenynE&;07{RU(%@qTNpe#?sbWYuM9O2aifaakEaz!8{-3YY^kG?fVj=`>1`@qcfR<&Uo(9pj5U;AR zPviErXl^dX0(Y0lTuWi<#WwoK7-D(YdtaqABNetMYQF;#KJ)4Arw>v#->js-gDfGt z`kZ+x@|8XAeJ9sEa^R`6)wWoxq{7(>-9#M)h(bk|v#%XcEjvG4VWPGc_WU1^qyk?N z#INnnT`}C15A8|le%c*!qEk2Tb7p{G6 z13EKAg$1G7Q`74vAeCj;05>}HT^Dgu;~OzqyuA@NPEqEU!;oW^gT zqRGS_ty?`$44@=wOvTe-(^=OG`rv&0+Hf#COao!ujkqHPtXsb`*e3g7M&2f8hI83+ z{9RrMxX~INYV#E7%w#Y_&3D^L0+Zz;$(ue<%KHKXTq_fi{n*A0$0UkQ-HPu7uhEC_HHbfWmoelEkIYOIH)n zFKh23qeI^#@9`4&3NLElIB<^b zvOILMVOHGtkXD3QzIXE=c(l_ydx=nFr_b`6xXuDCR~E$mC&cfwrsb7_`R(zLcB_8q z`JUI{14WB9<~5hUf$%2689Gh34}n^tWD8}O2y?U~^};W+_hU=|eo(XMItZi_-2vl-0*sRy5Gh3r&rS%Z zoS0I2CpkcGf~;YigIKM@Hie(=7mX0@_rQ5Fx1h92B@>HP|CQ%Rew9L9#-{+V@UL_K zhMrr3DyO(n7|);|@ri(yJzv4(RGNe1`}mY5S3)gIo(>;+Ww{B8nip2))&`m}Xx%rg zQns!I?ECG1R4X1jAMDyGuf2y93VoW7vU*?%p05}_E?lc7ArnlM0y(a*1o-3}y9TZ?MBxvH2&I~(`+Yg-l>}n` zB)87fhDX8QeQGD}+RM+d4{rpI*9PhHgu<#NaK9nK_r?+^4GbeVEI8?rNHjOIE!HBY zZyznJ(cSa6kKedHubpppUVdY0C8Z&(GAomU-Tn+hDd0*bJ3oYdVkNz5|1tSDOm>-t zkV2lbD++2ZPkU!$m|8VvSWDfFamW>i5x820s?S`g{1seX-@mAFKbM2i&hI7eYw$33 zOCoPu)p3UKNYZ%Ly2)q|6p7oPIpe_(v3pO1)T7CX2M#l&v^RFQ-JjXCIZjyO5$SR~ zvEO$*$wf+sAAIT;2VZeP;i^ZO%d58dSFW_gT9kG478`(HEYA8xyI8t<0_I z(vAGvY^-o+2(xd24d=!Z57;~HR^@f2z#SMeOxObH=dKTT#A#0;lmhv2#_DsT4R7EP zaXZH`b(;krc@eT?#Mt<^^m4q!dltEWB$^RHlDQ>pM-7i@H{iEqhW6E5ShVwo#A=)C zz8t|5Hcwrjy02-w+7*m^nB09xmWqql$i~H0C_ac>$xL2&01t?pM@0J09#HAO(5%6+ zpQ|J5iD~u+S{w3xZ#9?GDGwyp$j^bnP8~6JfGvc^hx51o9WnZ?E6ov-Maq-*%uS@P z@iAPh;iUOW`I4V8u!TFfGoQ3PVy1aZ*k99tV&3NAL30I1KWYrsZYrK6lG&#zgwfi` z_AzB0s~hM#H?a}g6ajd=NK^YYIlPb*`S#FbdraBizUqK~L6RmV+a5lH&0FD=V7UKG z0L?t_f`R?d7VQ5!y^rnOs1|lHoy$Z9NC|jgXzID71j>T+a~#ve#@Nxx!NkxS{>b*R zB_bU15r^fHRs1p?sg_za@K}sCYW5eZJ*dWsM#4BnQ+}Paj`HmQI(Ox)Q4f38DtZ-LD*ffz%;55mt$$ZZHNCKe7B1}+XZ z4n7_(0SO~12@w$q2OT{HBky$qexB>x+`_li?h1=3igR4q5eXRu6%8E&6AQed3?G7sfP{pIjD&)Mj0|4&2CqYq2~Y^>Z{9+^qGE`4 z)t-pkFES0CL8`ckSao2Nk>|04KL#cVDH%Bh(=}!mRyJNfegQ!t;oEnl@5;!^$*Vn3 zf2g7PNXy9B#MI2(!qU;n*~Qh(-6P;xU{LV$5NK5NtC-lh*Kgv}GcvQXb8_?EmV78J zE3c@ms%~y+ZENr7?CKsI8Xg%P`#e4|4_jFL@)bCHSGKlycK7xV4u2fM+l2r@x@Z>o z@84|~0caN@GBOe}8oXTyh_3L46Ck6|-$W(6rGjQ?f8{E-A3Bj#WLj|(1_O`kCh=p3 z0ZbA`-g%}ic+<{X_RlrU|6gj^9}W9kyCxvmNC;r(ArU|%AiMGKiSXZbZFEvls}d?`)7Tnzh8s1zP<}dFe(P5md6sXoyXjTEw=f!eo_wpeoTlZg z#%yO`AkNCM3~Iv+i%}`tyG~M{qt_qK*q(CzE<5=yi7R7Q)7#n2C|Y^_Lpi+ElY9-9 z53Yh@T@CY8;m6G-W!9pa1Yto%08b|CjrQeHb!@6_Cv(}ID(kewD$X=n2bNSjmUo|| zVsBPUmIf6pm$zF5(%CEEuz$!InA=W08VyKhrI(CkJ64so%3`O^dqi-M4rOcnM`teG zo>hRWg8)(Ozx}7u^(W#8&8v&I$Y=#=PnuJK=&wFYNIa0Ur3Fum{nZp4cCW@w+qe*k zW`vGDX#QM__7}w)(I3AfRa6wvGwuP)$KSiz_{Yy>nm*9&wM+LUfrg3XUdI61IWe~L zWqSxq?qW?vV7dI<%{5iL*CrnD&Ht@MK)fbQ0bk$$5B!UKqv9&m429S+o>wlQm)|H1 z%lw-g;uWDVh5Wh8HX_Pn@K*r|2WA+^dzRacn#!9Nzw;>`DPAp*s3H7F?L1y=yyUh%#PwbKkT%)_2kRJ@b|{e zfBHEV)oB2f$z7_h0A!NzV5}6a7suL4K>hd;s2_WXb)D~_8RTOe zgpPj?m5G5aAb<&8$bYHWT7RB(HIir#_KvSSOKL=bqaCOWf*dT>%N(o`-`hAKG3zhF z%0E8iC&W@S_A`_2^v(G9=lj?fj4y*f*N`?sP>&W}n~a{udJ z=cT#9ae(_-=O(rNc?=oYB%o%!egeh~mb5g^m%5L{ek}xJ#GHR;1fGvLlsC=Ad#M=k zm@kLz?0@or%w4Rm@GA!$arAe4;vbDc+19J;fLjd2wzfj-pqmCS#kPNDr$YW^G8cxC z<-O<6in$|4U+17^t3|4|+iNAg(3Y2_qDW`2s{f$KppKfCi{CeV?f9VdB}Wv^EnSLS zb%+yjDZ@w-QQ8Pp5k<1&TJoC8Xy5M#{WT)mgd=> z<5TJ_+R2i**_!D0d=2jO6=m+}n8RD~ksaP@+UxE`Md#d3u8}_HaeC(0 zJ&-t{T_fOY#ob!6!<9R=y_wzB7f?_Nm4G9IB zpnFu%+rlYSz@RI1cvSr1q3t*RxrAGZxGrytV=*6i<+h6^VR=@T_MFTn`VnSL2QesP z!hnSN_mMBFryS9PPZB+T`#9>vP4N%wx?DNq%Y%XY__3@uco)Y*`&OqA7l8JFYYDF; z)yNGsybm6uIx$8sWfu?*=(<%#m+u6t%7!kDU>ts2NdVr2hWL_b*Z|G==uWt7}C{*Z7a#Vf3qs2p00o=O2ds z12ZX!o^e%Agp~m0^Vq(93nN==oy#E;$e>^X3fQ~9vg*gTZhNz;~@?71CkMr7Oo_}2+!!x7@YHivDXS#1n9(QI2bg|YkGLv2MlHI zCN|6004)q106C+htv|GMjYDQ}U$>q443W{XA_T z(jYB5YAbqT>+X@0hw&=|ZjHxp1!u>_TTcj94Ti#Q71M97*LmhBvFdebR~hmQhzk|y zujF?u5Sk3D-LZo-(_TIqMra696>}2<6c@IG;hkuYKR+==wAdUCPLs*LGf$!{i@Yz(@i zI>KLQifrZD`mD?_!G>dofgV}NIqVR0Oabf=q$DHOO9K$dL{z=JOSrT!-Aj|OVcMopL+T70j76%|P`E3Q@K4ewX$lj%B1({M z76uSgHIO>X89Z;%pFN}K2C3sz{t9B#YWLfqFu4i9lN|$PK`%r~_Z-7Rc_8eNFoRBo z&VVI=xPs1r|3=s}pk)F9uMiT&0M1w>EA~Wks~zT2{)lh7w<5xRgLpXfwj&${mV^dM z!GOvshorI;WNYMiVsks6;SoFP))uC?hcK#cT(`uEg}Rsqz3fh{97XOxAIHIuOlof3 zFAsT8l3BNzk(XuywtqZ$E-p0Lm4?g~!L7wZ^rxbKFCKs=3;nuI2k>Ot0w#$`c)}ZS zf>9u7cp)^B>A-e|Co{==O=n8{NF4YOq(gdyXPeg0g&YcE$q0KJcajOh0e)V&YyQ`> z0NRnCf(nX8Ujbro!-`*7+_SMdjkMxY@M8T^$M(0x9Ui(^x)4f<_&0y3YQxQgUYY_t znIv!Bi{Dz6z&@f4DDe&O-gfB%@lLaXGUPar8Fb1u%kjCSqi=JnSEFmf{n~QC=~Tf4 zgryjSuws;}O!x|&QVIpsr@z@gW2MblAXT^|xo(!VjYiSr5tD!BU zf&@Z5!yin?D0X@fsAJhNl`P6C3&9?}whd$U+K6bhzvy$#?R5D_c3GajV@I~F)e`)P z{Agk1`~?3H&LDBA!S`aeEk z5vs?Fv$7T*J5rnCRp7gQh=G9jsrPQ_r#r)>l)9&fbUfx3PuQ>mG4$w~BEPoqEbGhT7_Ib=Cs48ytZRYDo?(nmXk6NDc z_lnJ;rWiVpJX#;=B+Fq@fFuaEgPG;kPf?|~cr1k$a4R}VKl&(Ym+Sfu>`FsnfXnP+ z#E~Ud!S|_mV>3nd#(9E2%cRfrS=xb#{o4ZB=2H4l*n98@K)@4eW3M`+^WUhF1&t>_GlPZycqyb_-d^Ef z_+UiJK3ZW8#SCH`2#S9uf{74`lJYc^^Ng$`>&QRw?R1TB;Ar8l`dHMIX0@F59hcD3 zp=xLa2fyBXItwh}q9Tj79HkU&U+niiFqamEWfj7&&Y|FWyyYdscc*K{{EA`U6KE!AQ$b~<69W3cn z9vr+Xx&~y_&2e$OZ>m)!>>41BVoqIGrl>Z18sn|mTuFNYe4^ggmH@~-G{wR^T&(iP zMZZ0Ma%qVTWsu`>Xl}`uK&n8LxI+{!Ik-4EyZz3NdKoyd`ds#w%4Pe~HC;^z_nOE4 z@+=yJ3RMuN7VGJX@08ju@OQ@Ddbnlu+DJN99oPAxoEpeD6_>=h&{U}V_SDyE4Vol5 zF+k$*BFhVP6Y_fr;r>Xxn7Nq)A^Pi|gu;FOT|e@5y#Zq^r;-!>4oKgt zx~;)ZMkV@v?npffu2m)WK=NtFet1#!#FB_X2+Yx=O4F@9Wv52&EuNoF`OLkRSh?JC zx)5GG?)4nLec^oE?2FnZ*eDy&0|MRvY4kAw<65p&}g9|~x^ zpK}fS_LZ+qR|#VL1clgmRnobSOTvGBT#mrmHch!Suz!eXx@0S+1e{!M>pvSj9htUU zfmMK&0baBIP>QK$7@L$oX*Wh!cQ5SY(A=x>55FeiX{4=Zn-21?q4?`x;}&fb$CE=B zDdcY3D*)FX+8%qGXIQbgef%KS%mPc-gn&W7>$0Pf%!pVYd<4rs z%wtu2UyNs~oqt$${K6bi$=@@7pmF~Pd`$nyRA9AfFPfdXQyM_4CgrYT$` zBb~crkwQ(Qhp4LWzjLHj4L;W2W;!6ddE#2^TtYLHjs*aPp8)87MDMTdQ6U~?{VDL7 z$?VOAoNNLZW1xMr^mzKxeDv();UJS2HvPQF^u|gZmM3iyphh213QTs-KMemR>QkV= zgY!g~0>h%)x~Ra+C9kxF$k6X@n}UXgriLaxmL9GB8w!m z3Ba1blwi&?ERX%>VbUID{Y%3Q9~4+w@zqD=u(2~7Ht1by{h|BG%a?F=sJ{ge_y#)O?N_`<;)-OCoSN$?zyM?9l?xGgab&B)t@r6RQXuE`U~|PYLlzkQwJZ65TP> zYr2PV*qygc1Tlux)yKXp{pf^_JgxI1FZ7{v=;HBx^qs+*8UAGTj(Vyt2>GKYt7Wb* zJ#LvB9Xm)>#Vr@aQ?rB@wcx~a-Ulb%q)AXHRtpe^SWx_v1)8&q;u7flUhOx*QU>E6 zvGDCqkD&M4+niW0wkBda3-w-2h=}k2kT?zJf;soCE5H*3HdzG%Kbctt}&#{SY%IfC2cn2?rgpF#4S4B^F!F@t1 zS?cT6Mr1beUaoDC*k*5B(Qo^7QMYTATfk;QpE7mxCcZqQmyBkm6uTB!?lD<~rMIkU z85l8bYS8D;%Dq{=!_XJK z+jQNomfx?kMm>g)5rJ~7p9M1xkbfG0whG?s#9lZ!p~$=+KVak^4(mE6V!+&oHL32t zHPS1Po=u_;O%9_!yIp=lk*?&D*=3Z_O99NNnaCw#f7FTBdipoM$;SL>wW*?kQ_uq88q8;sj|$O?V;ps8fj?2mn=X$ z2|hF`(@_vUy_^Vp52UyO52R+A#3P_0DdC#&o`3?H=`sWDp|I+t$(JeAJS+1EB%RgA&evkz?Hcl4C$Iqb*1DpG0*KAvC)|PB+TscU1X{#HG#D4ob7J z&qUh6b?491&0@)|iL&d(u<);8p*z$7UM{he1!%ISIDYu zG9a>)O7^=v25Y(>zCC7abNjM3M6D@cBv$0#`?SItC@Bj09TgserUPg^aKT}~t-w_f zhQl|Ql6&772-SHjLd3L_IrnzcF_0J9yl;axEt>{Lqj;R#st>L!+L@U_Y@wETEt>`>H z0;jd)u<-7$pylxnZ00l=?jod`*YvN4xmdN>lK+hd?th0Q6%+|6=dVmsksRZ$p14>J z_J^Cf&U>D0I0eQis8gjgU6Gh`9kkIZXkqO%VLZyR44W!MoJOBhkQ?a^#t`LMiO9Hx zWxW^u*^8y!}_b!-m(k=)PC$VSuAHO-}W^%<26HHhX)-%ai2b@kU6!qCItX`cdUtB5XM~gC%%g zqc;Qt1a>Qo7w+2GoELb@xxVlSBk61^(9)tUz_pC=dXh7Op$HUFebp!VUb zO+R5Uy}xzg?qx;EpOi5<-#auB_k%bXEGKyKVp_LqdS#@i7-3t38BqyGT=a{xDug|I zvNoBF465pn*LFP6;xj{<-?=qJl57afpAaS^WQ;R1h0WQaTQ@`6S5Im@Jq|ESAjuzBAo=szfs~VGVruygit0kWQWGduHpZ~7JGImz1kN~c zmoCH_dn)D;4m{BI?8n2I)6>aBrN3vn_2RZo%@C3$@iY7D78Y4}{wYg@)GwXMcXmWA zNF$(G+YM>fzOclqA!a>Dh9ty_ud+0uW^L3Laah?9R%oRz+nv0TOu~6b{nXaaH*!8? zpUi$~5yTj=rcoun)EY(IJNbG+T_3Gk)1={dFmB3{@)S`4=AEik+P>sg#qvLaMn zxf_;ODl@vvt83rHCTuWu&TdIv4=nbDt!qgcunQ>l zi~yJv6gKNaSiRm{8GQxTq}z(#_#~k=AslY`=Idl$X?KBJ8(4b!3^% zCSTS1aMW9#8k-D@biS7Pd@OybaKHH{AwcRXe4k|2iAMm*)}A zq)Ap3iYd|z88q#lHv)?$m+xMAquq@ObPF87dBt%mF}|HfGEM#y3-|E*tK; zbN!I}DIkubcc2$wE1QnP_<_8q=IjmHPWq9+t$@WI^ef>CW zpQ&MtE{|eE8-w1C9B8vg?aa5vm zQBPSLiwv(YvkQ`WLTOe)4X*u3(IXet;gu$GB<8CX^;|Lwxw5IuMoe)x3+DAWUw5Om zx9fIqLc5b8R(sI!s_RiDSc>a~YDCl~jsp%dU=o;qoiYd5_Qglv#({a=5{p=vr|sFo zY2(T4xl%pV?a%!u@Yzth6{#d#L1@YMc9V|lPjUjMB!6aFSpU9{jo{TQ^{=$FlWEtP zHfRG?BLs)iInx!?9|6;wP%eLs+zCeo(D~88irRWyzZ*j$A$;30u>q2c%{27sWw*k0 z@B}_Lm-N1lfSYV>T5rZ%Bji6W!67zOnuU*N=Gerzxb!(!3Qf}1cx40|=M7s z3tc#6h}lgFShvKgP$CixH{nlbc5T-{@vfN+ESUyT1kD8K0^Kh)6ksG0NF9~q&z~}U z;f=rYn!bdlx!{x!H8tp0!hx$Ipb4od_H@o^c{|`8v+*-I!h7S-l%h{QE|Hf9ivQNF z@-oXBscS2}26#r?dRIQ&0hyFSvP+sA;hX2PMM_^IU81^d3P&<;d-y6)J3V64TC57S zPkcZu=d4*VgZo;To}`@kw>_bya-Ow@Jdl8kmhl2q@J`weV`=zmDEi_(Z0dpVI+m19 z<-H7*xGjIhO&G8)_b93RVAtgK4QQ5a!#as?OYro1TTWY`X7rpF7J}hvWHKC%6ZL^Q zjm*_Sf(akpF@8AU7?#*3KI3CKg+cQy0Ot8SnCH6ldG>_nx%`!up0Ln;G=(3~rhet1 zK#xkda+Hm`M4?8Yo;V|J5A7JKDGH2%|HJ?;CHhCH+$M(Zz6VYYVZVPn-wYDE zhvC%Cg0Af`epm_sd&HefJ0v)J&fgKeF-YROS(ooehFP+B`FHi!%zel>{9! z?jNa*IljVE@9E!dZQ4HslyhhxaPK6i-D)L{R0MprCU~UqR^g@W2G|1_xj^WK%ea`j z85S?shm2$d!JOX#SqsR6?+r=KGXZ>bK#Kbo2Ju)Se=&{FkjF(3d#ce2NRBmqbl|Y? zC4+xMu6-O)DLr*y9sB#U5^$jwEW>Dmm8;zruY4Ay+OGT!sJ3I{bn}Kl)xwDnQtOkW}qg(vD8zdjn5 zfw{cS(P?>>znP9N!uD9U3~06|h^D`izZyn*4`~kxOde77oaswuHf=szHD(`IaSm^H zhEw@6DDlP%Y&d=CT({$*RE<9R^$wAo_q$L8G6JnfzUG zpQD7?HBAZ2spWo)09eFlZ?QNXJG;9gX4ohMuqXmqNvr%hNiOWl+TkxgOY!DR)6ie` z!^J_NRe&T{+&X#{@#vg(TF2*&k)eWzWeam+BJHqSm&`8r)+=rRX{WIYalLt2BM1nS zARyE`fq-xc1Ox^S=yWnZk~wFV*%(;G#XsI4Zwu9Sfamd&x^#hjK^&Tz{fX{bWi`0| zr!EiV)V~Il<6@YRyPX!hnv!;RY-xI6j&Y;$Dc6UI%NB*_BuLz>{yUb4yU2Zit3m9+ zIbv0y;mP{%p-dx<(WxCkJ^Y~7#zxeE$2@wqwT3-z@k|IG@$X@NbbN=7Em0B}nq{FU zebzXr&cyzUA+i6~-8adKra%OL@%Z8u4gLi5CV<`JPv@AUs}J8Ql+TR7r(CF=ia1oM zyJRszG><6i+*|EEc2Gd20q*ifp^D3Q)uU^fxrI{mG~gez(xmeM1*J2zoT9Eb4WP>t zYprvTsr%7DaT8|hp`(*;#gKC{^ShGezx^@qF5Rr3IwJgL-B)9M>mIwG5-J*^3d} zJ2L+SbKUGQcY43X4`_sb+-wTTDE*{!;}(}=REmx3v%+piOp9gZ61L^H7Dpd*Ago04 ze!owWzQ3ODFY?hzui*s7Si;4(Bs4#>UMI}5%+HiyoG zO>Oup2T!QiBfb@V(m2-SD+$lUZ4U}6u-c>oWdZ^EgL{^qsx=^NLeup*l4`}Rd!Cp0 z!I?BDXkQ6^CNMUGZn!LzW=}5fBqW!ulML4Q(d+hHuQ=axD0drA%6Y;8NE@`kW}w5x zb8?u9s3ncSrS6saP`Z3Fc|Hba5iUgQ&S-E*C0&TqEAa2txhFKT9}1|cHypNcoa)u^ zuFhc}`PLBWlJRrVT&tsNHrcEp7P;&Mav-nIE9-7ad+#~0QD(*df>zDTmHy&GpKGsJ zdnHHXjpYKecNS@?6)mr?A~~K0&#Qem)iJOm>$Xmz&vll@4$lUo_U^svo#M&a>fYQc(1-ahhx7}>A{+FBFjx9{b8q^{URPOx^%I6RqAeg?HduN(l$@Z zkqQ5)t1Zh5h=iZIJ)<$6!WCg9Y&#Sft7=wprP5Ic_-gb?(f-uO|RQBFL1ZqJ-zQe2W&~RHsfkt)kX);>V!TIG``8j%18Jz=uF&W`vk7I zD!oQj0fo*DdZML=Wfe!n#3k8o5svy-+c=NcG^pdlQh54znhx*)mja2^DYeZ26a=u+ z|7Ynt>MdJXGC6$?XnfZr9+L%?W+_q)a7Nd;Sf=r}#Ewx0r|$)_;Zi>+oA;Ma@4p2+ z^FyQKz%*!d@dVHfp1-oFxF9!@R8q^!<1)KR=K*R-+zD^@7v4#_!ETCk7F46)8dz1v z-?<3BNI~|E;EJ0!_y*-zkgLMW_x0NE_FThdtx3E8#F_7t;)DQklu8DjuX-~>?*E}~ z=YKHDPk@-FFiY0WvsP*zHh_>=+6F)%ahyVo?E@&1?31Hf?th;ipqg5lnz0XR1&z@jU$%)>!JpS0+87<-1Mag92c}ZGMO)%z<+9d&pV4=^BrA;2 ze#hSIFxAaw?@vt5hOeYXQ6GRiS>(Ap8O$@aZAP*`WUBD^CKGRJIAT8;KSdn4cL)6g zb5iZ_7xK12a|~wi%Z+ph7#ia=j23(G)9h7o4AwEdp7Hr804xbx>7%;N9DN5dMI;$< zhK^@CzX40O>W}eWGVAiDoYNnk?>Zg%g$&krqo3XC6g0cU#gVLrr*vjOi`z+`*6wU{ z#s5g!2R!lYc9-wP6Y~ofi4Lx;n}tr?p`M8vtm~4b&y4%IJ}*MUDwqlkiU+#WcnMmB zeulN(!9e?qJikeHJt$L!V*ahOp&k`!BV^UuyrpBq1jQ z>MOv;7avSOG=QO%0N-k^#9R)AB&NwUxez$s?smkK?Q`YM<2M$kHK;eO;NSn8Irm*< zg4~6d;C&=@8unTEBEWig`S|XvSh(fYTHahy(@_d$2G4smjJD6S6X+ekx1PCH%abu~ z8HFIEqohkk_6iHA?TZ)WpIXsq&-`w8GrICxpfgoBY4)AEsE7+r0MNT&jh{X2%uWh+ zuD^j6&^HT+9!JQ}IaSBdBWi5$X!ZB!7K%wjPVcV*i)~A+iC<1GKNSGZB$fdPWE(@d z_PaJpqsQPxdpNy55?Wl~*LB?<+={#m5sy6kkSoQ);OXgugk9AfInk(*y?tWXiG9L)s|4qzjZTsabP2E5$8tT z9_{ju{gu{S%jgz|76ybJ3BUNtMNiT$!oJM%_1(QkLg-shR%eP?d(aIZ{SK&rd0ZM9 z_mv?wSe{8?y$=J5;zFZh& z(1rD;e2gUYi1xX$@Wkm`;rFEquf`&B<*aX}@HVbuvR9yHxYd~iXIxMgqlWKJND1ZA-aYGoVlRw1;Lj(6Az>?d|fG zr}b5CQBALMg>&oiY=3bc<-XlyvD%HrhCz|Wo{wzPlMhj^KHn;ai2}pvD;K}OEMC<{ zdptJ!v1Egb+9$iRsGcEP$u0r~6Ch4athPz>D`zLzt4e-a^u|Y@nZ;s!JQ3H*#_iV6 ztBw+3w3)Kt4#k{sskE$2Yv8NT&-Xfo>%YPGZz5B8Ok5~&P<>ETi zzo-dRKz`so}9Zden|!JM9qj%;nB034S8{k{6I+Y z8cwdn+ekj#X4VZ#{58Yh=CQj|M|TnN)^|nY8uD7$-rng4LfFcK6q_}&^sh?c^sxoq z=t=qL1r63NB>G?PP#qakZ!}>tjPm^l=G~7cgq9+EjaqX{t+VWKXjoAtT!}|`R#i)j zmxd+&l-wNi#H+Zh*G{x3{5fVB96ej)Qeqmxw}zv7TqG$sciiqMv3Iad-Nsm=44i8^ zAOUJ|lgpVOxX(^_tkH7;oI?cOT#`cO$djlm5dCs`M8ZzEH%hGbMT>_ZtXBEk?d6h8 zJ0fm>8GY!6bcXa#i?>9ajy)0!R3cjjey?uKRt<5G&gvIaV6=Pm_)ZtXZSfMy!_aj! z0T)U)`jP*idL6%+h%IgNRz3;a<|7p-SJbt2T4~dR2-Jr|XHOZUZ$c^2-qE7JNGiD{ z*EPEFXL1W+GwQQ^t`*9opTOZxKRWu!F#{yqj;UlY+VIXf_@(_7e3Q{9`2MEg*TcDc zQAd)KFVAXb%DL(Dx3{vO)yD&VR`g5}i_sEK@dv)9Ge52Kx$}9X{5ui+|*!#pIv;qgpV_1SLpz5+;9i^SDsW2 zekCGoj+oGOzMIDNRgc44?}$)fh=_#iIUorPpto;bX7`bH zb!WdPOj&@Q^!#N;rO*-|Hmcg%cYr_PD@4|2vaoWgD}xt5%|Z^+{i!7a3CSSIck$7Y z(Rdq)x{mY9yJD%zt>8R{Ovge1>A(to>(Qr$CuL#()t@a<$D2Lx<%ABqIKtib<`^Hj z-$oefo%LPaxTd^&7aJfuC0pVSh4`h9{?{Qxv4Xbq;_fT2LEQiR=8ZXIE@bqZEA@)}VqFg-=a5Q36r5dF*`X2Ap7{n!F}kVq&B%AL84C(@ z$Fk$a3eU23$@dC_X?=S#0y^N+XOd2M3Hvq*sfZC%K9Fwz4nyU(cm7UPvX2dcwUxQk{@fAo8|$4w^9>h z$&k8#TyrGT)#q%tIV|r+b(FqWdn+2HFV%{cO?Lz-6zhpC%(E$SZhHf&K=hyrBz?0g zWU#l#ytb`yPU@~u;9TDUF(?!!tzKS)5gebVgCj0^lg5y98&YX@C%Q3Rv@SX=nebOd z>H!wCKby$>=2<}nf?NE?b*c274hOEGz$0+g{Kf9YB6Q*CMkdtjEh}l5P8cwcpmIEqL;V!pQO*cDg_ckz#M}B?6&4LA?>Gu zimBaayX~8|z{fjz1@g1I`Hk|$YAC7sE9blIHHa`!nZuZBL7_w^4K%sh@8!1;>x!Rh zaECVp8TmC@XP1Iv8H_u~x~^>QW8|s+5t=gU+11mzAyqA)&vEgCLgO~6+XU6nrc72Y z1BbxFg|9$A%AlV1Lh(!vDhYkISME~J#Tfek`xJP5ehMs4T^+fBY^kh~#`ZQv$qd_y z2aYB3pY3CHgUw5j{X{X8Wc+dmLw_#-VDAz99+4%6)R(MTQocOa?9+MVYR_ewf>}UPm*;#AJ zA=i+o4$n0;k1|6WJSz1t&tzhRcKut#x?8(vRokP5>Go@9C#fnpNty3CJHOVwSBIB4 zRx=2^gFV_fvqIEF5vjWSt(u{O7YC{0e-Bb+=pg-U51iF_N*mnjH;+J2T24kJSRC!P;xi6l-Bu5cs9rTx`nY;k zS0!EQhY4St1dd%**dGnQxk&(4{wc07`zKa;vXb={NgF9w3OPzogU|BhDRqx?l_cMY zovk6+S=Y>ccJjkF#O)qO8tEUaa9UqJRMOc?dGsjFHefJEuDL@JS%E!I_K&d&^->)T zde2`W4RcPVtU3UFDGhXU5Yz*P`xY9Q3}^Ldjv_67&Y~u;bDr^+LN9odXPI>xdP0Vu{2 z=Xt3%U`B%eX*Ey5^GJe8!OB-g-yrdr)4uXv-`><%<5fvoz43Q()0b^maGd2jyz<2L zsuuL7=(kv>$N|RM?nfGF@DF0Dyvriow-SB0SQ^bl9!*8Re{qIH`M<;=KukW!1{kXq zox+&@@vVNULsr+H`~yML!vW)o(kOXtO&USfxzX}x0-{@c}T0hx}h?9V#hdi2L0Yc zRhz22FWIL5zHu42$Q2Z-Hp#mZ2h>bp&MBgvcJ_Sl&U8*j_8&D~*$KIjr?4_xM zPO2~$K9calwpoCKYTM7t0w)N5Te5^{))|Jy}TmORkCn50Y}sK zfA{!Dl9&-HL8@vW3s&<7Eg?$-KrC{Sf{dcjfU^SmM14M%sz{kaJKv7Q29i)|ejb)I z|9x^dMAx>5$ukpP6KbSV$7AqY{ouEP=~13fVMDVBngd{d>fnnXF*Ua6GJN?#n6JU- zy1rjWcjn>mB}e-9-@tz-tyP|D2;q1e-a!O;;w~yh-lJ_o7|5<(sVtHwg#!;azED5?fWEvmdz|7BpB59CnKeYo(@<9bOSbjK|F-^yRF z>%JHpe~!ovM6w48m~Vl8`p{rwnRqG{PfRjs**H{yA99tW-7i@7=9V}fZwMn8t=kc$QVz-3PX@lTxGmEysOs%vaYwB zm{N3O-wr1DTPIZwN;VHaQQFAjOWEhifB8My&yYkIISia zs3C2gYjKvWgrd5O9CJZsM7Iv+LScOuf}JNBMP${WLYmf_o$<$Q=Y5g zE|gudi|}A`LE5zI(oSII#(Xmpa#>=irlg!;dRG42$$|Q506j7R*_iWDU$&k)o(5_1 zd5mRLNP#_J&r?NJ$oD`l*iN_IOP^`U01@n>HFWJrI`vP+^?;|&>91%2%|=$!D#&@SjP5)=A=LQ2d1g)frn<NUMlHtI?x@9)i{%(B{Z z40Ik`i@3ug>#};}8WdEJj`(oK8pJaIZWhq?Q5JGu2cSa9i+%v{(5@we% zsR|X6fcw1r{FQA^7#Y(##iWG&d;Jz`llX2LQElDT&0k@%1P{?QMj?J%zomvz2FN@g zTGKEmL;&dR9qFvCTL^FgjU-E~YQK8x;3lvVffV*+0k}WWKxt(TWNXqq<-GhKqp$R> zhVmYy%Dc{Vh+Yp37= zHclopxS8!+|Ib`Lw5PE4@;~AVdZz&RUUXi?uW9-2F$0QgOkn8f$oDU^KNzZ?CI~70 z`*n)=T$O$fv6)2I6T;>t8UBHF4ntm!K>bVqu0NkeRZa4@pnCu)Gkdy~Mh)q@fu@>J z4W1gu`$p^Ke6ecDAC|lGGyLtCA_f8mKB^C@!#!@@m_Xf{^|@T};jx0b&(x!s9-~I} z*`&BnhVgg@D6QEKlrCM3{W&L=U((F~)Oy~^y#Fx_k-Wd~!ltCmp)SZvl>STNZ$Bov z-SDT>&S3yGG-Y*{f6{6IpZ*SoInpm5XTm=tuUIU+xc;Us%}c?LDn3?p|5~YPSl)W4 zsmRaIfNV1bNH7`Tl$$jqEth|5)r+O^ffdXo2Bxuy&q{pqn(4hSz?5O`l;MS)9oe(Q z4L0msLi1jd8F`k7N6&&@vF#%FT6G(G^9$|Na)#A#*FgJUUY3N{&np1*5-xiE(nI%X zy+QjPfM5SKd>PJ2nFO+N`34*SqaICU;U7eQB^3Am#fOoHt!HFpfOm2&>gmn16+AOP zT6o2i{TY}a!LP`Hwr2eW=7I8O=~+}8(^p1*-eNH$7D>B2I>o9m>r)z58uqk?3A@wY z)?L&Z|05^>W(^knu~dTe|C-nI*;neGnb)L|1|CWFG#X<*InrWKFP{{J0=O_ev9rF{ zew}6|qw3pEppd6*X6uQ56D84WA|pWpv)i}Vc)sV|x{$WqZl6LThf{v%ZJ{HxMg|SA z%%%8wdIIU=LIABHY!r+6tP@Y&pq+8;(9=u8&p3M=d?h2-XzTfxXe6xV!}o&LGA!>a zvMr4Uq`W>YzA=x(pzPWCrfKNUcjeR#%&6o?N$sK_%6vPIGRnZ$=-H({$KQ28?haPw z2ZX^=+)5(AMq8)9R*>%9tPBw;w`IQSLG&^Zj@!g&Ci9n*%(5haQ`Kz^bT%tfa>b@A|#OVN|b+PT!G`HQV+RNZK&JcI@1z z$PfopgbXwQ_Z;_!4TUQ|R8*U3LHc8b9+)5iR?3M7$GbM0Pz8o|~eqwr3X1UCgkjSOF2>)_DXV*>XShts^Kqnb8mc=z~3(S?Au- z%Omz=mPAj2pGSTGf&6j%-=XBh3f}iE@N{;tgT-UdxeHDCS&RiwlrT%CA+W^VCCO_{ ztb>4y6cA|sJCy!nOqUH>Y%_c4k(3D_k8dJXSuF@=AhoXOY1n)HYs&L3i|TAaDw!?E zr#RCD`4;g+Sn=E&t8u+xEe#Wm+cuS8(bNo~we@dlf!M|eT*LasRnDDynCv!-T0Mbo z9N=d$dwN<316jUAkFP64AH2xeTQ4=!YsGG<9u)|G)=K*f#U;mdzWQb9j!qXiRCI7gWL}RP(I0S$dHe9Nsd8i$rFLRg@ zDz8q}1IguAe2`o=+&sP44`e3&w>rTmLGVKOWxuHP#;698h5l!u#pEossl)k_Zz^zpOZn*6Yj?q~UNc9uB*i1QO{CI^z?KT7l2&Bo) zYN!mV&zk_=p9w0Y(Cx%)zB!*W7b*(>DJrTn$Io6z&5Al6%bhpD@@lt{_b{sm(32XI z-T_z)K>6?P>py%lzFokKP?&>)ICXY@P{IAYGFZQvb~SEWFD2}j_7q*eY&7IcLg?X_A};MeBnSFX@4efMdJU^S}!t~K@CuYX{J z{-RO@Kb10d3e)Dh1auR(dc#HjfteRQNO=f(wQ(aW3lGJ=CWEzrDGYj4sh|n}M`$|o zPsQi6y;t+C3p#w)TTT|R#OFGhK#LimWp`7-FFov}%JWFi1hRbM9v(HoJ7}+xJK4`>LXmT*9L`9ss?>042b-^KD8{ z0{DxyoL1H^fo?cGQ0E*7I9c%A_}4t9k$zgxIlfSnWh4wGviSjAVo5s}CV1+Hn!)qG z^~3Kfym{G@$x`avj%x!B&}lz*ZGYom3S85yxHIIk>h5_BIyanbB8;wD$F+Xhrv5c2 zoL5-1A+GLpz2=)`PI?;22Jwo$AI~BaAD#+NBDCV49ER=?DOuWHlb?fU$r1pt%IVZX z1@%&u^th@uY-8u|LOurNHcOY}$IL-*M4tWMbu4aVx znWl3EH_v5s9|2tLgk2g8h-RP*knOm)sHG;&Xrp=Ap|0VHSOevtF_N;rpNAUO3E^ z(b~^L zT$L`H5GM3{XM~}|(7=hi)#`F(<&&chQl4HMWIisYYGjeE6(eQs2wzs>l84z(GF|wS z?@dVs?JTDpJTi2zAhkRMb^z|oLf^W}B zxtb2K)LFY>NPJM6jEU%Wyr z1MnDa18KH~8uNd6)P`Mr)CJ!ZNUg_c=N!6Q za0#LE8eGc+e3H^Ys!wsv$GP z)$q4%`D60nsvNG*U*`ACPUhc!=#7ZbwYpof5(Nedu^PI&iczKdTHlZCn!ot<Ek$|H&vrq-L^_auxRGbGO*E?}k)3cwpxx8Psy4j5x3rVFrQ`8i#wajl zl&uy7Rp(RIv-3T>ek5A{ZSt3xH6^O}Tm$`U3iKh49l8yApQmU86)MT)(?0}zrjdw5 zMTUeu@jf-YWys+Yqir3mp!NbOU+mS@ry4(4lS;Y<E*nhdjuY2L1lBhibc;(YPmq z_flG?5ZRk!9g<|(u^)l))WXHWws+Ml6GnySsfE9ejz-SfG-!R z^eN9#*&c{CTDNqY1^sKR%%?1m#SycwT$P*!6)A@;LbpeUTq{NMvctqMZ&08!8(+ zjNc06Hlekj%M%}T1@eLt9`Qfo+PDJ00rGpvTPDpX^91?*m+2B#1Iq^%jelUbx5*R% zsbLrt8bDXu+z`hRv~M+rJsI!cjqh+&t`0tGr-~Fz%HSIF=h%0x z{VmHa%-hzgA*0Se^dH7>!LEEkj_nT8eP`rQQzFKKQ@H$BLcFU}$hG{4O``|<326;w zt9}uy`{jxlElSp( zl9~4-L15=^T$81EG*HR_&<5F zbPAh6%BM$rE+4N->?>1y5A~$|ULn2ZZ>C+#%dH-y>r>O}7lQIXvy?!m0+jqzk?ema zP?tqWfS!C&26|FuAdK-o6Ym@Vs~Q*Ux8lYNI#rW)HzN_VC*@m)z1v*)KU%VNTF+j) z!$cFjwp-km?t`dn{+fU@-wZ_Mtsw`dhmTI;VH@QLqAkp^h2oEi(A7YmU?1g*!n~d! zNx63o04_L9jWpTGomPLTj?J1n-TIlGc%MKqOdJ zaE9zslV^!qE!vkT^YVt~DaD#8Q0Zc&yf@XSnSd^(VN(yTg1ZQ_u;3Dy4PV-OkSzlQnTzh5z zM@t;IzxZ{@&TVCM#tkXuw=zpV#Wqi!;n92Z{NOy(UfZxWZU{oVVwW@v5@%$z=jeZb zP})hyuU>7EJhJ#-{d^*q_(sYa^Qw!*|3_?K*N;8^8<-`M4+!mwiU#>-EC`YLTx8;p zu((&h_~nWREKlvcV{r}MR-tkz!|Nr-CB{DOjY_esS6=#Z!Y$3CCEeO9LIAU z$MJkV?%)4Hu@cxn8@d}b0=3#_|5h7M=`l@&=IHX>#C)BU7|*MhAFe`?gG?L_)>|ZS+Zjak7r~KqbvOcjiuW*JXD=A7vi(y z6wTt=9lq?ZW-P;a&AES?w@?a~I^WZ?;NGkYshs!R1M8Wc<^FC zeaX>Xv2cemfm$f){7DS=6xkT1m3_dwxQ;h7H|5A4FE7!|b4aW^%doV$tt|Ol%O7H~ znK?Bg?7m92GaKJRelHLy%r~d4Fu`U5_jp^yYSY%d5HZ}oF$Z15aLsd@>)A}$mEt3H zN%{Wwe+lI`5Ti6DPTC7<4p1Tp`MbNK4D5T2L!Q9C7Z^bfLRobMwcrCN`h%t@kqWW^ zx4$^N&@12Z1fj#*5-OSeZ-j$7u6f#a z%1_n7@?F=X4EvR)sNtQRx0jzLl_z%do}Z5B;*Qw6a;yk+yzrx}PZpRBlM195ch_9) z9=!N|<&{ISQ@WC!0W@{>`pK5;!Y{yyGauQu1>Ls}-@E8TR&z$p)_gLo^Ql1a^1jis z!dzJmcNdG&LbH1`Q6rsO#do9heGWd^FL$`EDExcl2`c!@+GNS z+RS?DQ9!#}%P237SQ$ybcgl{bokM8$wb-!ZJsxf5cvTgvT?)ZA{>3}-FP;Ptf^WMJ z0(y#DP3vyvPD{WiASR0V`td@gXz|&1mnSN}87(bL7jGRR@>q0k9;`a6HF++~hP}Q8 zOGR4y;*@iqc6kK99iPj%WytR|yD_m)32H2ILO}TKx8P0=VNsh&cA=9{8ur;MC9@dO0Z*lh-F}CsGFy3aeEJo;V_8G=*7w0+slt@3r619g6s>XQL4Ozf zIL%k6KeA?77&AUHCU16Int9MhkPP%!mbaHP4Q?bE1Emff?b8U1UCt`Lhv8px(&yWA z9gP{GAX?ZEhj~_tcjek}3zz03UKoZmB|+RZ`dufrLwf;6zo?sTy4tVMq$JX;0rA+d zl?F%tT&G0f^QENO2cOS%k)~{Hh4o#u8$ZP`IGd4Y7Y} zcGrFSUor81|KMa}qNem9{Ys}lYQZzzOfBS2tDx*N`ZnLN;+JT+-c$UCV)p+=V&VUW zl=Pw8!QsLz zll;=X9M)ljZvQ`iOsm5FEAzmQENJjJO@GXTi*U543O=45{C~U-A&;K2I5{y}FVsQp zD-zS(E+%4k*JAW`y81jivA~DPzn*(AtCMK~wBM0z>kYYJ*yjps*DK#x zo^}(|tUpV1e|*>ICJQ4|`&HTvuJe_23XO5z?n!9lk{56(6f@{z?9_C%4EN!BN&pXl~RkfU_*yU$?9(!)xlQt#>Y z{z5%P=L{ww%Ki^gGILt@nRub?H>9&PM-NSVS6*7y#E^DDei^2@(7R%%KAI<0`rp16Q0EMkeD;(K2kSR~IGSow{y>)-&Ujm54P&i95vwDtPQ- z85X|UEo*12J&qrIk&MHX-wAklkbRNDzM`|cZOm2T73cfxi;=qG={vT1&9H2eH4o%USUj^^ zDd>W5=$T=ITuzsC`4! zhg6Jb@{*jtt{5Mm)ZWZCa76I`yhE7gWPY#HpC7yL?}t&@F`PBT;E(}k@q}Fl-mb2a zDo#9FJ0kjXEG=GBh2wB+JGszK?W({yT-pdKZglR(dQc;uq2%?%(l5UmX425SM_*2K>)C75MWlS5!$gLNP;T z26yie(#;#>)dJ>{bLmG?Lr4a&wr2^`ZhNhzR5x00HpGRhSS~e%O5J|<`|zpz{7Z1@ zVz9%yR_OoE^2ZRnoP~u&1Mc&)6k>tt!8DBrl3PL^_jdmngYiV|rw|*C(E#K6evm}5 zw`kWb{XGr@1mQ>S&8cxkC|V;{AAu5}&@Fp+o9S1QDL-n=O-_IHh>p-4_@guUXh8PM z@D9Chq;iPjgCc!Yc9B>c_|8BTxrmFq!yo9bBUbk*kf0e^!=A_!2n2`on}0q-5vYat zrdSkyJxW5;7Wyxg-hc3X|E4eecj-^y`Z|)DJ~~7gOP)cPQCe!Ed*3fB_52+&-m;3J zl2m1aiF>ENi4NLvYLn<6eYoPGMk0dZ6>yZ`ALb`;g#T&5647r=`+lHtEP_IX@N^au z4^wP7Gegre`YSgghI>SPg7e|T?}TYYz83=>j#6A4RL6I2CipMoks)j{(0*(lQeE`v zrD;$n!&cr8eN+_J-P>LKizEm{Jzwr!NEh)%kEB`0Q`}Fm6aYihNzbF04k@Vfi1lad zJ*Z=#j;1(Xa&xM#?3b>Hv*Gk*-Lu7t5h&FNX4RwU8qf9v^m;*0(QjZdgKbtbeJ2us zU)}es`#qXs^Jvc2vK8FOH6HpEj|9C~5?Hf3tGP^@J-OM0!g?y(d4#_OU_DT!2>kt= zMY=?at#EOvV7!te?5-+)n1nQ!zDS?oja_laHvu32iIkA2%z)|#5EcUy24q(f6-#q| zjJZJ!J=|5#_p6s8aL$N7eK%0+qR`+GAFY|0&%8DNH33vfBw8cwl{E@%5CDl3+c3#L zHPg%ue(jh?*(7OB)=_#?=PT10Mg5rp`fa=^9!M4Q_cyfb?@E4XtfUc0AAGU6n3U@% z>6|`Ylf1s(Il@GRi$8uqv|$2$*48kOAOGdi5nC4s#{Ux4y}$WhjaY5s?r)8-U;6J= z#PA3V^Qnu!KWS+26LQCaes0q3am18IB2PlKw%34|{ zDqg>Qbxad|Gquu4F>HMLeU6{u@9$7Me|=|FN64E{$53#(&19#Z>N2~dQ{>c z%F^&FX+Ziybi^CFptHc%_g;#C=_SPL5Qx{ud}|Ot0M;o+K~y_s=xlE{TqLN|otYj> zX~GeCS*GsB0O11_`hcboonjFvhvlFRp8~Ilc>gHG`==J^p(*b(K_9ny$aZ>?aDMOf zMOg0YDjbItE_y;^(M81aS>+6D!kPa<4R8eIA{j?uc-yuw-?aW&dNJx@tWFk;GjnL@ zqA#nKZux-l#gLD@23*mkRpw$)zE|JlGZl-84>}pLG?V04J5G@gUlwPo}3zAUoPmh76xrQXTu!w*B z$kmE}Br7JsHwe~G#-dxhokbWZ;J>%d!Dz`((~E*H-voz&f3G>@$=UdA@kQ^7 zqR}7OL&`3!3Je-T?m03Bi$#C;1v800eLL(7=~6}xr2UXD>;?-{2V^bo=8me-e4DdW za{6NgAvLgcj$K8Z2=CkWXvCyp%R&eX<}XwpEOtxC@`-XZuEf?W{hFd)#iz0Vngo4R z4L4;AlEsQ+4Hh)PPpEPp0+3L`BeztqS7&5|#nBAMirbhtywxAHWQ2S(kMw@!Td4Ql zh0aO!y1rBM7AM`2PTB0EJ}ym|=fyxp9kITn94n@lDc*&ww_wjx5%+=GUgc;w_Bn*@ z+T`a0&xXEtsCfVK)YHiv`q{$b%&KCCxz1`~ImgGhm^4@t^K~r`sxJ7MLigNG*(4Eo z&i!K4r1$iSQyyRK%0uk+qBLhX`zk-(EI;0?EJL=7zVH)@KK~fhNxYS}+(^OxMVGG| z(mSf6-6k5m2aMakP}rY=hvhgDAeccp{cirft8L`}1#W$d2o!_f4%#=PQiC4AHGRtS z=g)PO_vc?fKeqGpOgmcKjEr9YBi46^NP##e zH}P+PP}cD1e}A_B^t?OY(=4k3UKhA`EFl6Bi}>FOYLRd6mUVy`zt?N_BB|v%L~%At z9sS=59mvU8DUTvU#lVv2y>z_QT!^ig;3z#IlM5>)cmyz8{m`?g!5<4C7`A`CJ|3_3 zh_&|+@$EkePdlGNKKcLb&wr$sA*3>dB?W_urhd z3Hi-WWb0`wNOsaO=!J2wp-=&Xu6TFirgIF+1AXu>)aAm0<65le4-j?ZK8z@Q(Tp^d zOTa$QJ0r^*EW3WhMrclj!bjE>^5dME&$6dT2_LC}qt?JN4A`xIeeeI6Ayx-e`jgaO{XMX2 zVE4bZ>3R+*Ci4JRn`Y3($hosxVLdlLOze2OgYP>6ep&W>-sj|9n~&C~P#LOIXj|Kt45rxQ-@b08d{FMS&h3vnlN zLL$oEpFcoi2*U4w8dUn9WUh?+i=+F7gu<-#Vfk7bcKrwY|HH=c3tsF(ve04FeLxkS z5EX=DgjLm|%+JF=JdAwf>96WE z=K6Ek7=PEb(MR~X$s~Czn6@^$Gf^3vu28lC)7S;yWfB#ETDZxP`riWG7G^cb!};5R zivoBZJfJ|Zo(f`x6pTRg>xXa0`QQ95x#HD+TObs8~b^x0L2FOI#3nb!Z^ckGj= z7pM$pM1LXskdJu4yj_l7u!NhS(A_qS(#B7>N5F4$$h}xqQUSm|AL<`@xu}0l+Rg+L z_^_Ko492^-o%h@Q8X$F$97Go(9(%;BL!)l|_K&?^^XJ^-zs85ti~^Lr`)VdY^j;^& zht<>0>EkDz5bwtRcc)~Sw$gsRm=!t#ga_u;$VfFzPjx5UJN0KMIj0n0Fb81^6}7#b z-IE6SgC6IfKmTuE1NPd$aryTbv|ncw?<0j%`=eSc>Lb2=E$ey0hkFl%d8?mHpxxnX zjJ*)lf+zN0&PrLDXEKpnTaT%FHZ_GqYM& zNQfiuX?{E(fto)qeH@S?Oim(lWaEJTQD+#wFmn1Du%MVGlTZ(?BI@DKz8E|fBI8@U zAsscI5?GvPW5j+nSdN^OH$I$ZkK-`s8NK#n>Li&u=#Jj|;d z>c{no1lXTRV;{+c8^@IkHl@iL)6aEGzg-}+j`$w5&#LzF>tkPuAIUHXZ-ba}=Sz_2 zXVI1H@Zf`Ci8RdqYOCH@1f3k(bey(d6i7icgc`duK9d7fFJhcKa{ z)Zx{Gu`u{GlkG6I+fV}~1>A{lwj?WKi#S&_h0Dxw!XW>ywO&kk3+I$D1G1Kka zZ1^3>OU3}80ZHexYhSb07pJ~bqC7pHs58@#J(6Yj{DHHw07i}%)4~v-thz|g!Q5Ay z86VB}%~rb{RkZxsWj>-AkJXx+Ix&rAyN!pN1jtX&1(1KbzOYGT!FGbBkOL&oS(1Q% zp|gY6@*zCuCUge?emM_;XH^DZx|76+fOiKn?JjSvt}klW44k9m<3^CBU73*)zzr!& z!BYdR@zg-wc{YLjOc~A!eviw6FfTX_thDhRXk36XUJ)9DP3tc=-@~oYym53`?hW&`T zg8vT!7KH5dt5Ln@NvB16<&6f@s=m>uJn{Q&Tu40q?e9wSu5gGQ@7M>5rP~OL?Rl(o z!UY+oR-Bd9viu+dva`qW)AoJEL$N^i|J>}(BEe1kgVjPML>HCHHv2!zvqBJuYGdlr zBq+0$!QA@a4Mb!KqOeyTa;3?lvTnvjKb1VE68hgDb&|juz%IF~QKRu3##FX{V2a(e zP2=l28Yqo_bNY7BU8$v5s=^(J4YVHC*@ALS=f16HPXJY*wImd{`5IY`r*~h(X!c~vsZmlwed^mj4UKxDq^bb_d z{7kBN?^e^w7-D^~cnT&kiB3)^mD~pg=5@sS+*>wtvQSccs4UA}R90y-bFMUCq{LPG z5sVaQ;s1121FQf3X5(D3W$I~g-Wxs*yc-PFzlYZL1#Rq$~5C+S2ic|@}`~hVrQd;^^gPSg;M6R5<<;eXP=E&e0eghOn!o% zVs)N`PwU1>?}+=Af1%DTTV{@)*|+awO@~nR&2O*ID)~k`(0s`&SUfB|EyL+F5t)j4 zu$*1sVSA-ZIqY6I8J3)#+S2jZE@q{0pw)tHtdP{zbR~vrJ~7F&Te=cqtW?}}Hk~>D z{ut#uTPkX&efEgJktp9m*-LT#6`z$&CMrMG4s@BE?2$+Plwpu=j`R|j++kdz{P#8e z$Q~d9x}f?VUC@UyaW5G0(;`eMyQai^-Zo}m)>g%sS=i|lCX+X_ z0^WIdNBY8M(_YWwTtL$sjVTdG%EvJUw;m?W!O`U-eNDZdqhY)38;seT7dZm82cSM; zCP}j`M*J>H$MpT~eAOZIg*#GTKK(gGA!?U>a{;i6TrgwKAR?2MpgGqNZDO-pAg^UQ zZ}c9wGhOvdUSApMETp1|rp9zhGePm3ek5wnGRS?BRmy#`=P4|Wgbp{F}& zc^XKhR}d2E5}uBTMI$zHq`SCIr(LZ(bP*)KX zQ#d{TQ#z62K7He5YE*~L3DWPluW-0=Ra~SslQeqc#+mYN*NhPR%PhYJPGQCzKNm+E zxLvJ3=~yk#x9I{UoZq#qep&^~^a6TZG~!v=Ahl_*YoDAhRD|NKeqZC1s;R8_n$zLLl4C`4Lc-q@5U zbSL&HRru=<7rO{SPaVT!O>TCQQ}nXwg$m)`Augpm?~nSlvU1 z30#qIlN>GArWSge8b6aN`xi>3AG@ODQyMv0_9al>V48hT)GEwb#h;(}ggbWioND4T{{(T)*Vq0N3fs_|k999l`vf?mrOV zj-a=hC@ZAdh$?zKyHK;)Oixf;aIjoq+E*SEwGkxz(yD_83Ep1iH&cUdSz3KNn>2MD zq&=Fqpd%UG@f*r=$j!23cUW3D1H@!y5iBa0Z1l5T!qees<)y?H{q6_A~syX+sKV?9lW1Ck+1wfXJ{talNClJ@i191I~@1|GK3Fjm5qqhkB=-dv| z1rl~V+6dvb?!l&T6aSE=&~*9;p6rO~%=lUSrpEqNED(_EKS5aJq8T1Y+4yoHqyHjp znclrdb)b8wm>Ym&MO@nJ#{VDOyS&tgA)AAvvQ7n8i=T{LGNMv!-l|CNQF|L z^VjA-2t(E$>;^jr3}mFoPh|Q17!~jBH>Ry?Bp91Wpl14_B|&!S5`a>58Ns5f;#aG_ zlE0U+Z{{knc0kUR(EEYCgaH2vZ!4Tzy9ztehu0=vUfd-v<>FaDy0X%gQB#Ndzbqjl z!U?}lV{CcqpF;OjqgvL7(fHOm%VQB=&%F{eJ{K%>4CdQWatD`$W(z^6bv6G|ixd9F ziKxYeTm`i_2p1y)?nN%ZYyH>!pjj_-Qnmv;BrEBp9l?=!W){PQRDef)7MBv{=DV+A zunbh2@~~G8H7~fiLQ-#J?{bhX3b@4Yd#LQFdq{>r6_d71eTS{J&V*WQy^&BZMkEgj z(LT^?oA9is#r5s$N}#3rY9MSbA~dTAy^Yv#W!@Yd?Ry3V7&s18-}m*4%FtgUriUm#Oz9H;&;?IRUn5vjSh2}=wMsduD1(ooZKKVo z?8Pq9s+&l3e6yYR$u3YiwJg5dg?!0-;J)uQ^NJoEk1w~dSs}y7N2hhuk{I{3hi_Tf zdMVx_zQ74#Bec$2hQbcm__43z+JOU)v+vaeB$KDkG|Al`R^!H#toNck1Z(x2UF_ED zSC!!_BVe{IQ@ULKx>@D=Aw>vg7iR`81GDEcShev{o-|UL8&(}+@)lM2h0}#BoM686 zP%$@$Y=ZN}-U6BD+G-CNIpJPGb0J(e!wE#y1*dJE@oV*0$2dE*sj2rzFwqZnLqF2_DV;nd|`g85jblq+%U6Ur6P%a5igF1`tCt(M;Dd-}`w&a0E^IGC0k{U8)N_HzKVHNLI1U#-?FR1f5T(i{w z%Ig{9<~dvO1yjIFGBSScmZ6R&AruB2IXD#tq`f}N5$5EC9oSZPKx(uDJ6)rVhjB-w}8O%>-e5U&=8vqE!LpNPjUo(1t``-WT(Cwb{sm6%bKb*jQP)>N;u|mdXH5Z0FbnGv3bYA!U&Jl8V{jvuAKOkg z*pmB45Tpp`%XPzhPD|lAb(wfhovk^%v-&W?l0!{|u>RDqauiBiYI@=IGyx{decnv& zpUFa9SQ+Y$f-EucM5Gs|&`-A)ut78h0tb*6ozwzspB^pe2)V5n z3@uBmpW`qdSC;qdX;STH6}q!|4wyS672>uJmi4F)I|a{tUHECFGW9FE;#sX!teEcT z1A;lzGRzxld5$(Y8}g}2lDh{U_0O+gX_%BAF~Ks5HBHKx(}K3&iA|;39DDQ`RX#X` zptRcvpJ3?by_4(;B7)Z&Lmj({Zn1Olz$psTr~L9Q0pc>P8X8KJL%_-6B(fPtnx`*h zkXlh`lAC(jDP$_-8WBl5mC1SYIWBj_K{fz)ULy{+r*L{6s#2Wf_>2u? zczlHzdUB=^u15os*dDGH=v|zA{MBeyEiN+R)%Z86g5>MYT?geO$JPp1^(Q(8Pu#y4 zt}D}NKESvw*?ZrJ4A|j-vRrW4m*}vO!lfLD;36V$Sh=r6+HQxq<(%h2#H zQIWRH^<|T}>{mF3{ad~6OEvQ$i}+qhj>rd#@@{d7^B8Ar1m8&4KFjTVHHhlYrb^Aa6v4-=uq4%7JaH%s z_i?Z}qob8v;6N>5vDLT3PYOXt0fDH|wr(lhH!e+9gQIJP5eOZ%Tk>$bb7wodqIt6^ z*c!ID7j>73#j2wu)q=>gXXm|(H)hhZsvZByNYW@=QLL# zYnWeinAC~h)kAUD8Gz)}U3nS_?%VM#0rGqcClEB8LsDRpDqeW6yPahX1somJG6k4+-u}-YC-C~!LcpgrO)}%!&lJW)O20g*r3+nWZv@dA zE=QMAb2;pUU#1FGglx^*Jl>p?o<8*YaCFtKvBZDr$Gp-Bqt;D-NR3GMhHp=PH4=6I z{XS_z_-3_8?_vE-YmlgXF@Sbvyy)*-DAMIsQNa7z9mDLVJ}W?h5Q5aw{~!d(R+n%o z@w;#s(Jp7_?O+_LmhJNV9M(YN7f%TCVxt{+Y)E;)>$bJ@yMR-7JNvnS+%#{hM3ukD z;b@a85%#J-&-W8(vni&76bFUxb@>BFuLbi6OGtJId0n}J$C9XD-ht*NDFKgnf=!KU#RSlTVb*_&ny}Gj=37vyM+aSIQPhAJ?3go zv9QsyGL&*5;@r;5`$UyYA~*-l3Tk*E!^7Xg;2;+B*&~c~{w7cX zUk;nQUVTf3D{Sy_8=5l+j}?la2$m^4lryyY!L-*eM6H$KqZMH)6Xz{1MHNseR4Xq- zxQ4`INnZodsP{QU*`O_~^Dll^q&K5GVoiqDGN9Y}QOObULx_pU1|6K$I8|MuXqDJX zn6;Ez>ScrR+ZXU68e?psw9JFJq3bNc$8h4`&)`0u&Nn_^r#tXEN8$Ftoufnb3J81UPoV zd8nq%DI%H-6o?1TSN*fr<&0@|R<-a2TSP24X@@fx6X>2hKUj3Im578wUY9ht({E}{ zb^UirU*mYtTg4t95^&Q6%!iE{wA}bcrP$yb21ch(C=(-O6J_>#f0G>4N`iY%SOC~NKyP0`p z-g^3HK&+q+*?hs%4D<-dx?(Un+dN3 z;{NkBT5VDC#$eH^=3RM*QT0$}^yEoQL|l{UeT`bUSQ~>FT2Rxyz`j0rknRhtJBwaY zvtY*#!YO-a^N8;C#+$7I4&K`gAx~#JGcdZ`WkC-CTW6WkHhvXr`|fg?6~RQ^qF4Fv zA?Wq?G4-X+soUQo2x1b;8G&h52&ONAnK1YyeM<9H2%z)pG}&=d+GFy^P|x~F?NSb? zxvzw(7s@ZE{A$D1#A?P56QH{G-KuZ9fGtbORDSxg_9=3p6uSiiEQ|5XRbsM=!>Tqupe3R4~^jx@{g5$p?|6awghxsa~Ucl1W-R2ESeJzVd^f2yhO-a7HUc6T~^(6rrz^d56lz_(`G`d?+m6n$h^$q|E z!?%l60CXCt3feQw&F(Rsx=&&kZ~~xMlC8u8mv&d^lpTf#iZ(=PjI(immNIclw<;K?fu;NMM^@&3K+*16&cdL2%x_mLBoiKqH;MUV3u z^KEPSum$y#S_VqXi=X0&P6TLT2`Lv|(EdE_PMEnAT{(z#IFf&w8F%@6V^Y>g#?bE+ zgxZ;bP&-KzG;hCU>@-C^Stb`%G6MI=<6$8hwsn# zSr_J~?tXMpy@#W7T}2ZeqqJO=*_mI@#fv!h*WHVpkF~?N+|+dU=N8XS$|)?qJwP%x zz_+w`!M41VV)_9cy5sAvi|^RFoaQ>f`8T6h2xxF+cp4m_7J&NZu|s_emaF(1OVzO@ z^yGL>UMoOqqXAOuzd@v$Oto(iR0-qODiEY($)4YdF2!AIC?}6U(cj#*(xk@F3wf)i zxzh4c@Z`k6HM5X=SzLKT(F7VXQcr|3t+o(ypzbA~FT905&=z^Emkm-PJb$d?lg_K6 z?amN9f#H1h4WcZS97wtlaV1T3XzqMhJ#UOW0z{y+eCodos|uFsytTHZ>9xm35V7Mg z_;F_|^Zd_i#h5mM@MSz-O)=XpD+G|2U&se?VHJ!$z?31DC2ym zz07lj4pQI?67|mPX^4DzG8-mw<90xS5kAK%fl7(Vk~1{ozpehQn0kYh=GiEi|E?0WKr z-tfVG*v8?@xsj6Y|JQ%0ige|=i08Xs7RR>~oKZM$p(?UWH>a=n&L`_hY3y#LlC_lt zI<>g_gXsa2@2Tl!ZLS+XtqQz!(q5)n6cNM}wBXPNaTmC=n?WJjqXJ zruR4u_fm8f^8@FqeK!C*ppmhk1SMe_oyPh3(K*;r3WS`s2xpe^11PBS5+-_yr1IdX zIT^Q6txOB9#~hZ3Fo1>!SeMqfmF#~dotCGxd{Cq1{ z)d@@Z+bYfYmVF*8^FS?>_xrgu_l6y{@beaS9eq-FK60XwteJ1~a~>vWg#=lu?r;ib z6aUSH;X^#}m{AU(2VOoj$pQ4hg&=CB$zPMpPe0M>#OJ9X(3g-D(OU`%3ClYGR8Vej z?~lj0yDZ<{*-LgVR9fdXV^}cwG$WHus*j-aBk+mIc#^EhoGx=U-ZyCU@$L>x@8jFv zX!lcn;sGf}=0SCYM_~N)gJ@!Q-K|i1U1BIH7AKK|y5=J2anFR#-1+U(Zomaga@`6= zxL`nH*}Z;oe1lgqLAN$hQ%F?DzuS1MY-|wZ67Y&?7>!HFsEBeA9z7(Z%ETMO^66Hk z+JN`LnK)DvhWF#A#`27SO`yu;9;5YCpL$*Nv)kZ1tp#70XT`Onl67O1$tzPV*BpmaB){659(*RtE^LQiWEo|f-8pQBtL7s=n!?*4`* zuA?^{a_~IofCCC8_gaqaAC`>ll67Uss~;NyE>atCkt_l=tcbc;eXH&LwZM)GvW=$#$A)5_w|e&^#}6Az^VNq; z4{HH_6U8Q9oTPP``8=5lH*dvB-U(*U5Beua;?Z1D{xTi$Zi`sh`ni9Cassm<{K2R$ zsXxNytYMw+RIq#F+JEu*jdz29;3(X|;ZSoJ3pK)(H~zbJqf6WimPHO11MR+Ph7}=UDKC*s ztz7%sc`fB@^1i0(bTmrO>@$`iDO`I?9^9kaqRuA)O(zY>7``>ws}17 zxI-c@j=5_xRIT4tcSO!Mu(mpfM$A$yhaEexHulcmJ&Jn

jD80tEC{SadLT_?*alcEboc-ECrTncCJ+C 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 z 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

S;{p-W&msU4C>U^FV@;p4G(bsEKNioKsj3+wc4V zuphXX-{2>stM8bsZ{(n8jXeB44qQlVvK`MR@|=`Cgx%Et8^ecp;@-$T)&ES=F%aWB zz96lCI{Mv#Xu#_GwxNJ0g|sW`Wn@hcOxb?@4j+OJs_OHyv)O;AH((!6&0ZCn%NsY@ z?5T0Rg?f}0=P2!77sw8B)`U<0J6@2U#(U>qX%cESku}@;#yU^)c#*!s_K`%f`28M{J}b-8lkuW>0xX3+Sd^&6 zUBSNudgx-b0uD#a^!5FRb4T7=gXQPZ<){Q>{X*xrnSBFOP zXvkPha{ZEx4|zr$i>EX)|D0KHq~!hFvekxC!v=MFw{A=3$Nu?(|MWQm+NofjEcS3( z&+Nh(h-G28&6S}@h0cF#^mw)bPnYPUu=`TEY4rA0vzof$Yfm1K-EJzmud!zRkSiA5 zhfrcvIM%WUxo@5`o4h^=vNL4_- z43Dmth^}Gg4fT&YfH>5gfP_Xm+H8N|vSjDt=)e9A2nTp|%c*IL8;N%<*>o-qTd6mj z(kF@P94Fxs8);y;d})~V%KeWBXE$5ym7GN8YgbW?;uENhFMaGdmUxf@NVJiMtqg^v zzZIQzF*IW^3)ECo-3a=+ReZ-=+oyK3&L?*&+vQrT?y<^`B{R<|&m6XSr7lhk)C0~V z$v8NGG&8h(Rxqm;sc&)l@H<{-Pr%!dsfTx>U+#HO70y}^7^Kx{2e~;{G7?|8KI7W$9I~x)r;7$LVFZcu)y*=gY&JQ9 zXOEuszEnh^q(9 zVMxmq=XZCL?+988_5MA}Kv-P@gepx98n5bBI>a@_vyh^y_9tNW-+-;+Pm}?_xmu|A z1U#grPjV2UD@=r$m>p!`yI z=ldP`JeytbYzGQFvFv?Ub1r_QSbbKg$|*i)Yh|7@)TOlL74yAtg%!w3t=hjlDsQFJ zwVD(^^U_m!c$i6UlzYy~`d!ah<}DI6MsC{BoYl2=cV_3hv2ct$Mq6u{8PI3ezM~c{ z+E%+}9XV5MzF=Y^MXVR2kM3?p@H7PlZ<_Nao}LIhCQa9>Imh~ogA~RVj%}Ho{H$V? zy-*{}l9JeHDazVQdbs+kd{JqJxEVFoPEQl2ua}&fnd?5<-I3ZB%3W-=mRpLDW=>vv zNOsUt_lCqogXEb*#9j1DZHF_8XK_u{(+Zk9%;$sIP6;F%-aXG?a>hucU{Inj?LrCVJeSLe;Iz$lw8DhYB!)tC6#6sMZ1h8Bs9NUJhtctpb z6#}Qb^qjGL7YGPIfg}~pY5?=;fZT;jddv}Wnc?(f5zkjeCUhnnKcRyBhj z`gEE%Gqh0`PtK=mMYOLlFWF=HM`fX*0I?{@RBjjb8Lyw1rF*q`Da}A_9(9TI{TFr` zaq~MCV=*F{&22uxQc-WtT5x(=M)iqhue#TccjtDnv#j`;sk9JOx7I_iHt#9kQSJ2Si}PMWw8XQ%LR6D3;~$k6AKhrX zG#slq*0%txFztM&ho^^%a}9UPs)Bu&B$?b~S^V|UowED0o1XsFfHc@^%adTITcc zn1NjZh1QpuM%vWmro^lShi(%TLUJgP7SsY$e;AcYeSF94g`K-}wzzL)Fj;yw=3|d{ zN3fVxkxEyXt-R6sYF4qf+W0^!Mv5LnFRRZ2hhE#qBZv@Bus#6udMl?i>;LpFSe_uS zGk!q3`OUB6Y{>KmG3V-if|j!c5Z$8UqaPuVs3XZ;@K*6s233ESDOa2$b~tCm0y+%O zq;Zkyu~G2g^^pRX%*>i;c*WQF*jo?@s=5j0;3%upqtUItF$*y<9F9GU#mqcVzj>C) z<-8gR9vxstf~ul?>C^H1p0w+7(-K7QLekmgxj^n1D=Y!1&9AUPRWK~$_0<;)(sXax zIFXG*pDW)ut~%4P)Qq21lI6=dpVr0?v9{DmXfm@S9&8)9hsOS~$v{Q%|3yVH1}e($ z|B(2T6H6-QB}~&j;E}enp|dU5+#?VXc&o8=>TOkycdBV*R-NXxBD`EQT|BJUqbbkP zZ8!+&3c>7LO?|%FQ|$AoK#JHX#(a3FG;?ryEWPQ9ClBsu(hv}ZHpZ^l7u;gDL%NA~ z6L5jn7ipejae?$F#`%~ns@iq!z@PtV0(1U}ZIqe$ME#@s{{u46 ze{#nD&-ef3tn|-kr~lu6{a?!kD1VNT+PmBNT=cd-=Z1Xdao&YgLX<<81NlTwPRP*r z{KY^|dm&A?bB^|;LMk2?JiHA(&)M1wowWCJwzW4tp zB*n!Q6!xFw=U+cpP!vk=IQA$z6nxGA0VM1CnKk#q@bqfVxXs`r5E5h ze27c@xRj*WaZyoOB||k?c^w5&QH}GOIwodT)>hK04sQ157Yr?|&LF=8hmwkl{vbUc z0|Vcg6QU>1{J;MA*@U7d#-XCX;NcuW;Zoz^QRDnaAPR=eq z7k&Nw0|GByy>>m~#?4!pJMjsLNy&FpQnMar=j7()7d(3Mw7jCSs=B83c}r_sd&i5; zmji=C!y}`Ajg8OD&dtAlxA1=P!`k}B=P#RE+h4yS?ZQFf?KKPj{QB>CSuilhSjE&m3JtnucxJ z|FedL|BqVsyJ3H~YaB&}hXaF$M~zZMeNIJUUI2W*e_HX19=->hVbhS)tjjGp1i(Qc zk8i#Ym+xJUF>V5xktqW&E=@97+YHfV6d z;mJadW}!3~J;W0pLXBg)6zSF+Qs8cB0n!XP+riiT7$uToYt`eKmBRXpfe3p)Sh(~(UNxxBT-d~gDaktlU)}>ynaj&+H-mU^ znmfK+58r!g!lGI;jXz^p_;7;gkHLY*UxIM8wZ0su*M6XTdSr8Hj72+0xa*KT7*RlZiF~BGvnIiDwB;NuLA@z=uT;iO5e;2?lUN zKHiRWEo~|SblZQeNDr@89K7lT_`@(q`*2|ptF(Y!h$i26dvKT%89?kUw*~5hPLeT3 zS3mkT5>ob#V|sbX+J2_NZ?nU|_e6&1{J}*HN;5eYeSHh7mO#?_(+8+u6gc59h40;A ze>f0+@;GCRR%r=Mt-xCyim8ehJMu|qjxW$4C+g4>k9gs743L0^I6Qd>xDu|#)y+{@ zOuw|g?)rFvYhAorS~Q~|2Y2+Z-*u<@?2RW~M<-`Z1w=3HNm}ALAu|dd|1>hc{s_LX zI-y|IRe-x53k}oDj>6a={f2N2d0^%u*YG3A%8|qvz)D4K+2MyszW|gMT9G7id;tWj zu@wB16wnD->zuw$t9aopOhpZpD)E|$uji+jr(&7Kkz4C6b#wiV3hybt(TwNzW%@Bv zQGJA;HlJmj?K*gT_ind2_D*{C!Vc4kPP(zQx6wNebxyXt?qy%bMfQTjaVfS2E1nMv z@(8%R^sSZM-Kv`CN6kh>r8H-Mr`Y(5a}#_o7NO z9p&b9)~gt2S~oY^>jbvs7Y>@*3}wZC5~e+KTSuVWHka;5w&uf-+NQx5-2`;+3z+z1 z@!={>cz>%<->S(ZK3czTiWQgL6n8HREm*3zN_*JVsJO7?22NP2kNKWm(fvBW8sok@ z0yVb_Pj)YcxH|ttZH$G;uGVyascG%z3(^)~_kb)}1N)E%nF5#ZZ&u!ixJ~j#!TH+o zg&!&r-%KNdl8txgf1=VM&59zcKIYYTy$gP?(Pk?=1xys0tjKdA{Uc*^gDI1AeagbZ z>%?`1&uzmO7?;l^#DB76Xf4Qzo{_8K6C1B?kX`o*A#uLPT+^B9CqK`Mh;BUk<~Afn zPaUYkc%7+`6ei~K-&IELru2A zs(>`jRre)mKEeR<4@R<6hU&;d^lGGhn{?`HYqXi&mu#XyRhiwjY*LFHczAdlu#dCx z&V(O-H=`m8AVTvFDy@FTw7$_fF)$ zh7-r%%M}RAu$T?R@U6O^W6X<-+;=w(p;@9uot=g!Le z^Jh=eO)qB(XtEArH$r(nt?6C%E`j8YTP%+|m#jlyoMO?#zlhxo?jj3DZ~*pJr1Sp> zO7R%H=DkvxjpxjC&Bbb4e`pYsxTJ4&5*8&Qb}5dEowAs`^LTGjS{+o0*Giucl!{QO zsMOIxHh5&O7iL!FHIVHyLZVp+5g!Qu*iB~~2*~B3TF7N880-cf7~@bk^`oz$B-oL( zJy*983g>FLW6Y|kYxFcSDR!t@yw`Ivk=iD*mdwxA^jvJR_kriwt@rK%SUfNSd)7Mv zeswz5>izaL_7aVd*bEZitA^0xhXYq{T8glG=`G>kX7jFRt!UrIJ(E4eO(O$VIhOS; zE$I8i^13I$CcbY}kfbuVE*g z{qw+)ZmQ|WP?ziGsAFK9r>EWkk>b>lx3#;zFLkHSyiJ+ZQJc%CFyCt0m>BC6u9i{C zD39>VJ2QCW%;-k;?!=(t0=)F?6ieTVZ)Cv{=fCi`N}{$2Jp-y0(@}o0))Q7xHc)rt zo6+#CnQmNd_7n3$_b*M_CS@w?t15^j^}5(79UZPGuXH5s7|Dj+qrRX7uj5WPTQM-b zfy5&IL?<3cE7}WPx|nM6hy~xL+XD^_7bOQp&=rQ3YR!UdlHB$pP0QS`sm&T3eM!xq*tmDdFtiyZ@?^O8}ow&maNGVpEsh(sVYA}u9Mb9|u zv%Ff!lfN`Q)0Ua&dYr9~W7c`=+i_K2;8sfDs$cJP*G&?$4xEuE{$L*Yg5BjIjVj7j zdyZV+-ZNGN7}3Rm#`ztcc^%!}BW@)8fWub0#J{zcX8O$pHG6U=Zm4W#iVOq*OU_!Y z32o}+u-17-d8H;lm)&rA)K_H|A!gawN?iZrJkJe$*b8ck0&+EMZe~YZ0J@ zkb!6+#92%+B6W#cTPO`PJI6GWiYWl)UDyNVQ6%6T{jCpDpi4y8^yAT4QkSgBGT+!W zt9hs(;d=81Sn0@xG?Ni?+Kl?8xAjW1XD+D59%6yj%HopF7+s^7N*D5uY;T-~$$6ip&&=4Ec^2a^x z$vbMudO}mwSESg>gkLDqmoPD{$cs%CmkEMQy8A&Uj{yJH5cij7gI9E#Mn22B{U*91 zSTM$4oJ2xjoV~c$v%1-{AJerU?!`DKA#~06-7wt)_cAhvnvk2+f!|v7DM;j<@O;eH zPRDjIJI}p(JxUk%6Gf5)02MjrbtrUTV~>8`X+2GH06~FGS}==FqEo)<5mMf`qU;f7 z@#%G=jcXQGf+KN3;ooy)RcMG{PE;`Eo3Va$e$*v&6O(aQfx1Eqh$yO6-qD*vBZZKc#C-J)8px=1Kdi z9XdD+J;d+1Mw$ZJjLQ>Uw0uA{=!m+&_p29aah|I3f+TD1krOqCriR}tCEQk)sMVqBonXK@#~n=cNsZOuDf6D~Ea zXg)P~VOcd{4=H9HvW6?9XaYpsRMhJcIYTZHwef%rDc?3nb3pT@E^-Di^0Tn<`~Myd zESPQ5f?s}&DpOGlb&-qNK1qjA)HQi@NB3xUv-lcB#_rF$X|3=Q+L<#+?9PnLxF~DXGEUOPeWhBnwS>HZ{!1WHC>jC1xuLz z2Zq&Ok&}4^)=vIOOA^M%Oihn6q=9FR4?JrUIH!KSVq0*Fk&Db|KfLfOnq%s0d(LHq zY9)+>k5bE```GyGFi;6a>F|rbjy%m>x^!0P@p(KQPX^8tuFs^7A;9J?K0Gw#o=#M@Cl>;rm$NPS3W5?4 zYU3TTc8v5rc-XsuY2MU}?s}StfCKGOH8Bhd>X(1V=}W>_R0s;Y89VWg)V!hI4tezx zb^7U7CYk3$K(|;C>TC98!XcDlb;9e}Q7wFJ^&v}BFG6kF6v`+I4dODZge4(9rWY_m zY-k;N1VzFGMLTZkzo4)@ctmDvVvAK&Du{fSP35kx)$5Vy54%kK%LCjpK)lP-y~ z`y!Jh04vernmD?nvl)*+*pae?(WP7JbrgQALzd=HyzP&U9$_!HoHgX=mFpuUZ;X<_ zQu#qE1CbGk02u*#Ac#M#9TYrXJazOI?c?b%OZ}SU=c$>YKrdTEv$j7JDKER@HLT`( z51Dt9K7rVI=l0>r*D1C@-L+$`J#xGcBy$QhIf5QVYtrJBN<~RXB<{tj(%t6BRadC? zWua=#&U74VKc|dd!sL~l8P7#HJJ~|`q^LSqfAUGveqjOiBRM4uGxK*EUd^fr;7HR= zLAf%q8(&n0GfyrN@0>O^Fn=8a^T(?1Q!G`bUVI`^Zy)J9+i>b^1VjHjXDX2c%_S-` zKk8{FCrLO>nx$W41GH_V*r$+CN+f}Eq(b7vw)l5HM`X;?ubdyekX?Lv@NgJRbdlpIg>ZncjU2XnmvSYpujTTikY6&K&VWEV{38l zqzb)EJX1;Z>zyUDce|_Ifm_kEAs&0I$dEl!i5~t-Q7_A$##yz23dZHonP~nzEO=uY zue3RCM>&jjXiH6ybNOmX_i*nbxLqqU*NX6Of$6no39#5512l=DvYW2K9WcBscX*hv z^B;-Rf+A6soZ>8}-|Zg{zGun07XwuOq-sp3GWvsR;6e;1|07j`(v_=hersrEsOY~n zHG;17+)xjyNQPCTSwih_9g*v(x`H68FC?8x)9MlHl?bscuh2f?uc1d(PsM}#x_DB` zlmBE>84D&AxnI-TGQ7p|B;1p~KBV4>3ht-x(tde^B^-NZFow$%l?I~+HZUvu-}7dt z6m~DcBfFZxOD1>l#Mql&){W)P6Dp>cS`>x9=hob(bvhT;82Z&g(NAwWL!q{ZH*c0xG0*O^CKF7U=P zo;CMpn?8}W(_QT@qc_Bfm(N4(_EAx?jc$~U#deFn*l#f{NChayifK7lncL@d*R_@% zNn)Ymzv+4l0YRTiIzvf|^PW+r<5J-t)AOKppt*j-r>DMNCV$LMa?o|Ue|O3fyPl&I zj(qpKEel#OFF5e5PRj=Uw(kpaRx?Aj<*t$5oW!E&OtLpO?n)&S1g~iO_u$_71d=_~ zlo2gVLRg1oU$^!s zqZKQk3oRlYZz^NVJkg8j10aa?Wly;5v>FAur;yyUgTweo5$NJ4!TF741CLKpeTRpB zUB?xN1d%5`6?;sB(^Tm7N&Fl5@7ed-&XQyS>8n90KAqln8_$MY<@G~7%1-Xr_f+qB2-;Wg|x z^?y7x#)vd?`JkCEHDauJY%k-yqhG?jssd-HvS?haj-qANufYOoo%puYjWI0&!>im(g$gWvoRyKwQql=vkHvAWdd!h) z^!%;6iERQ%h~>U^u1uEvMAM3lVTt(BPZ1SD#{~z}4`)&g>fIe1(**UoB3*LOg(;Z7 z-55HO^yr-jrN&3$Gor3>+kU8q>ZTPZyt+ESs>(nr`vgz^jvdWH%PE&EO}JX>jZVnJ8rxaYK&+hx$m$uMs*Z4zrM=Z`uODa9LcHrJtv?mU0_IL~ zz?XQr3Cx|l>qGju&7SX4rsQ+9--D|Tm{Vf4Kn@J^&zvukp|$1k45jOcVIKVJxVp!*4Cb^)ef zBMswPmW{kMO7*lAdZd%EE~p+6C1UOJAoq+D1VmQ^kI#Ur$uWYP^TygPJ;UO+#tx&E zSJ5RFh*vPb#ChkTG%e1Q4UfPM0MD=*M+17P0iZafKl?i9<2!oZ=H#g17z!uq3DwPe zX}7c!x7G3=)!tZpqk0fsGJz? zfAnUzfM?FfFN?n@GQv5^NE; zlq!>xm4fS|#irDM6Yl*g-10SXI?uai4t_DNZt}Tmnais`erz(2Hnk?3Pda`3aD@7i zyNhP2CIxlG@2bMcYFNn~hNJ)L)U<-jd{!4(!e5v9hx%H$zYUQEy|*}ZdX3a^Q3o=X z+c@NUXD#*B#e)q97SfDkB0O6JyaR7CZbV^j%zAwL{B1ZUg57I3H!OX_+}!c5;d=hc zP9Z-p_buFIrr9FJDG9n(1S0ly)jp{X8DQ4?>Z@pO>Tspma zQn)K?@+&-iH;2#_@xU~VCn6kv5)-aWhwR=49Cq!JlP{@EEUxEMFpYQf4HjNwKI8lW zqc}=ti1%tGtG2fG?#w*SZL!k?zS2t55hWAN1$6D{zT!6-)4r4_3lrT$v&xOD$iHlI z)VW5vf{D>@xS?C&eAI@Kf`H5C$Gwx9jkPJITx(J{-6bwRJ(NUR97XZD)xCR-#wcaj zD3J&?GIeW?(WCh29Y4~=zeW$w+$ZWPVy+Uyo<&0whMw+y=HqjqV!k8nNUoB9ww zPO$QKrIOiGw^PrK*Db%crpt}lPI=B;@@;b|<|}>g51&j5Sw;4mA$$tqdzmw{KZRK^SiI!BxV=;X&QI+m; z2hsu@s_!bWsS`ZcY&@ZJY19q(tK=fpE;R<_s}dqLCcss_JKe3V|GG&?kZtnwISjtd zwqvVcaW9{r*89I~X6wJ+4Nx>DVSJG=8szj75AL`#3!?uOh#V%FyRIYosJi48 zpKetgI0N^X{RhglM}^bzcAvv&Jmy7r4p3xtt}LBE6}O{srr%z>`g zDVKrmDg&+>qnqpe)mL?&hC>Mt0-w&Luzu6(u%(eM1iYqsDx61(l#e}DNY`s53TNL? z9({cepw62Bb>^I@{px>EEs!G>^_c-h(~U?3>LL<>^Kh3ayw!GUw%A~WNuksI+AZl9 z1y@eY3|HtXyeDB(N|SOyy+Z_KF9ni+HC2Lqeu*{ypzoE-sbe)($NO(&Aa{w?>s?SooCSSU^E=QdtIEwi^k#8H{!kmllev3rH z38zRr-0|ZIy}jbltPBwqmy0d@$8C9I^v%Z;A=B^UfHY+^f$YZ1!J_#Lo?)%1RsNgh zqT6-)4nh@2;~%mw63!0RLexiWw&PnqeDDw~ zW4h_ip+}@;%IUqHmt*|wS@_Gbl)p$&(9GX=TSlOvg`-XJuMrnuKG zoBDF*@OfkeKy*|ycYh=K_<8Ao$zY}+E{z_IM#1s&!ZXFzN3YYyHRFaJ;9t7@7hRTT zZ?vkeSuI<{x6?fz-zL_QPC(^8F%sS(g@{1PyQGKI|7w6(NQnJyl zLWHqw#xu*_pL8`Yw?+h`A+e#bK$Z2dee zP3Y<;o5$6)Fx@+w3RYmc7p?4dj4j|KgG`O%wqhTBJ<^~iuh7GjBzc_#FCK%MS>8EU zApZX7_3(q8ZT|HB5Wgx^YpP+v6c)h=Iv!5Y#Gq)^xubB$v@zYPQ%{Eg<^R{X6cS$J z$I1wX!F3edcFvl6{ibLn7vgt^Py_@D&M`>sxuv1PHfs^t4$y5NbqFdIQ%d_fhdi|d z%kF|xBBZ?Mn(=Zx*SmzSRfw>yck<4Lo|qN(bjr2R+>AVV|NETyxAUZ;g&Q)@qdyy4 z*(LVp*-IaWYzxX(1+L57aA(`{hVJ_B+nelF(#Wo*m~x!sB<-%xc6-Zvf_v^K;>k2p z2EcEs0*T{CHhaTT<4twIvS5EGuhO{^-Grd%m zPrbObcL-~bG)fY9vQwfDUE5o&Z}uS4uvj0!VyzP|!JC6@>b;qWwJ(B&U3=Jd&KD)K zu_ikY7;z~b_b3JqnQ$pEx{bJ!>Bqj)X!^5SZfmOffkD&-fc<9BfKbP$pI#Q4-?mt)6A*0O_K$WKM36 zTn1#H4V!XdzVLkhE}dmIPRm81!-L1%a;R;jux^>hl&zvHf2#SMdpBq3_O!mw{Nkp8 zr3xeV{>RPyEQ8DGQ_C7LM?#tR%=!#sR4lCjkZT-O^2jxB!BwAsz$cPs!f;DY;R$bj zWvj#C>M%4b6AQ#pKWCS?KEJf#a&o-Uth)Q+E08b0h7}!FrNuFY6LYLM=xL2ItbX5B z7W<*?m)g4%mIwPnb?=RbvbQ^i2AJNHp^n~zY76gY9BX1{UL4eAJNF4AXI0t|mDMdR zx|VvcB^B4AZL@ISwS9iI{ZL%W{$@DUz786jPKd^)rcds;C3=lmj~+QQCpll?enh;L zq^XMwLRv)9pNuOGycZB0%kgAqAyu!R$O)=?);-*2AqU9yXv;?@18Iphk=@u#9XpN2 zSGR7FFVSL;T2+~YAE&Q#3PTUv;XlxtN~#gDzDHgs^d%N;2C-TGo_e^xK73OltEwIl zz}f9%-vGb~vEwRw`*Ls{$);M(%M4^d&z002~pe@DFBrG|Q^ z2}2GWJ-pnt=-emO(e#Kiu+sj1Kn0hbPX`6u&T5C26KkS1kL1)26gzO=G8JBv@W-DcBV#y{v6!l_n4{#4K zZRsC7BT&T{AMk>(>iETpQ#aWTlj4G67K)xB_N+zWNkkPWEsEvPw0-JXk`L#kka4f8 zI}<$U4Aed(w6<79ajp`Pjh{9w06;ODdJZZ8{H@5s?$hG=Mi0HL2;*iO)PJy1a(tY2 zr0r!@B6V5CM~ea?tv%k+^+&q_bhl^u*I3V#0C zLxIVw&+F|l@8$Ss-hV6_v4}cVZ|9h5V}nHL5CPNTPZZm?OK(}My{)=1sw_~{g#h<0 ziK2A-Oa>~q0t94{&RAs89R#bqlBL*xXu5G zy3!|>u|`qllRKH!p7T&%+jVjD@tg6&)~07NwBHM*J>155sp!vzx<=e_mg6oIus|d# z&}?CQO1nPhr8i$OtTo$zZ_;6=Bf2H0wprPKQd%s^p*X-+$&AXX_tqi(I5=s`Ika1J zX);G#@UmJ-$otNR^Tw%!a+W{P^l>ePQ4}d=wC!7(NnHD55o1QERa{iCFpMLFDbQ4=AX$5jrAP-Vh@6P&Nu#GPuhOgR>#ev7H?d-{Tsw$Wl!bv)%0CobEo zVO4}er32)^g?YiX@4}e=c44}PkAug)U@UwCJoW{N-YfD+n!Y4kGEQHim@j$s@z}&u zjV7S<%pQY9{Zx8yQ3vcgA2hAPdVf|KDYh=(>Ud43xUF04pvFd^a&I6JeD-5QgRR`kCrJixQ%8No}r!5Mn&3;GKP+~_U zn&e1TJ^#%7lc#6gMUJh-Qi|h*{q|$3AiGnt;e6Fxm-|@BwKHduX7PIms@Yk1Du>#Qs-m`l3}IkVLr2-F%<)s4^8PQZ(3*O3{GG! zgcmFx417%KQa^{;NPSv1p59N6kmf%@c7_4<0-MCX;J_t<Qy+LyexT(iK;G6auWh|XUpq?kBm7k$W`~CV z)bnq|1GXC>7$vxp4>78KT5)?m;cx z$A7@2?1u2+qe_ct7E2TVX9CAGBUP$ai&zcSf|xDBSi5$fH+V~*t1!@4=3tqvpJ-?B zd>s(ZezfIWC^*Gd8Vk=MhjCEEvbQBGxZhL0`{MXb#nnha;Gb^u4o1~gg@3pRiGEyU zeMFhCHK?3bT;sg|W4w>gZ2qD|;_QjL=LZ}x>bPpw1h_IWpip=(>hkbefTkmgtfg1v zD>In#oQjgQMExviG^U@c1x-EX9j1C|`aCD6H zT4VPtu^8mNgn@oE$6v7bF6;_)gXZs<-Bo@v5GzD5?IsApAIn}>4RjZB!=CtO98cXR zv8)=iJOw(=%XQl&)(xSn z$5Idi*WP1hIK8bV>C`nI3wf8A+l|4@Xkby*5)V<5xi#DAQ47bs;h` zR357?>8XJ4`?xj*n9m=9`TW(O!~3&54{k)gMn5+QG{Nm}$bh>-Zfy*Wm6AucHcJm( zN&sEgj_lVG?sJ33LM7#NXVxxr?M+PJUs=OudsiTetYh?Lqv@lqSKy1|kng zG1p&{SpdlFu4sk)KJU(q%uam+U`1CqBk*J*Oe2gn#UbY zy_*h#i#m*C2;MubGWUIWK>?Vzu{!|s|BTcP^g>tJT>UYlL8&wtf)$~t|K9#)U04ZO zfP-Q5R0tY+3;7N#$xO!((B?#XE?;zbIL0e?DAv_%$w#5nBS;?CjHqwR57U%~>0-+kB`Mdp|xz zymB_qx`st~JX~M-xJ+AMW0d<$?dbHnr6ePidzKIBTsf}$LyYd#l@r{{Qh1Z2y7?h5 zib9s|me|g`*}2mDMH~kL$FRPjgM&v)IIDcMswc?WQ8+tyunh9^N4fdOA} z%XUGpKehyo*0L1}tXKmaQz zlQx^bRB6)xerq2b9(sJjS~U>2T!*Rb#iMVDZRthiT+L*eUKuq|)IBty>El`QHnfMp zc&&9n=;q-l8Dgl~C1GzjPkq_UaXxg~O9#`l)po5@#K~`$ZrtoI(2P6*``gulVs$df z%mls2XfHII`lI)~4_);*Yl2lTsXg2X0LKKT=-EGdiNE5R8eHN~*+<#phRS%{u(X`S z*~5W{uJRXOpYQa$QibSTp-O-fgK8u=NpD z6PQpi1ne-$tiy6c_T)?fXWxW~O5^SJ0rf&=kOQ&&M02hPY~S9%*08hWjaE&>g6^$z zo^3{Um-Gm#v0QPP(dk}A;ZmqD+Ou)i{~!&3^Vivs7mq@gVoMxn#uS~a+1}L#q3Kp@ zOg?ae)E@}ad{G?gBMJZ$FwA;+7ab3G4yGW;_^>qO1x?776ZMOo6F*Tg1-rR*9pBrl z75Cn-SFs?8B*7lZXaF;c053|^VZH_Fevue;eS_7&nGa?ScXy|}kg5VPHL8t=mO=b6 z+rDkxO>DV!f z!YL%D*aIX#5n@NRAZu6hWp@pfB)^pRO`cvaAZ?u<^@LXRNgf5c4DB4l@^@h%Qssx& zN=5MQV$;?FO3+m=JC}ak52q@#WhX%*S%SQUMh% zGR*AknoiE<49nxkk$xl{F8IEw@3~cBhk^{CkdD_KbA|z>ZTdN}m6eC5^ur0HW`>Jf z)z0K8*KI`giQeDWs=a&;ItTI#=$f|QhOXh`O`3+}73_A0hCJcHb=s%G%Og~HMoJ-U z5T{$t-j|@Kf#}Z6O&er&KLb|)vAKMpv3LL~#RYims+ib^g_P9DlEvOIP=l9{3hoCY)z$ z(&r86o?bQD@qvTtwnA1|`f?aIBI!#93O$+N569X8&^!Z#hht>dIsmB-y=)rvyI}z{ zp`+8RTcn@K<#jg^p;{)VeWi=};azeT!stPW-Fg%AB^M-uV4<)f3nf}{WHc=R6jA#^>Ur>J(M66vf63WNUWh9i3JVS)PR9{fZ)G41PFU$;AX5mK`n6j<2A;NDRGhU!I9)WLHd%GUc5%rDu4WgC%u4 z;WdWTyChX(wGv&{3>Lg0FRW{g?r$l-|Ci?=!!$rvs>7;BARDH}dp1OGi$C@dZ_8wKexH;eONM<^2 zAe2>=$3RULbUmRqjWmx)q9-7^W%kFj@y1{UbV(#reojN>_4)!t(G2aW(pH=Pg@|tW-;3Xkef}=uJ6M zFDS@d_SK*CQ{&T*6Yr=F6OD(;efZRtTKxLq#8>i-sEfty zH%$DgG!Y41!HkN*4{m>mKnx3!eeek4f5$FJq=G@ctG|ddnyD~b_gZe@6e2Vv6fKzR z=D=jEd0T^P)D8B$PEW#q$sBinBVV>fzqbz@i2@mnh4CDc!pg|*MV>g@ZL zA8vuYdrGy?k9i?j$pzC<+o<;&bvyzLS53q}eI)?d`kcB@YjgRU_bosRQDE&7sPe~2 zdlK$iyhb-E`OR`>p7d=%iL{2?(IR5g`_jW9tX+byHk)LOgxSU$m9WI(e0_Y-_ozUYne=^Ea6=O$h{@|>Ze^rcf~^=CHCc3AtU%F zYHkyR(~0H$h&DeHO`2ZLOI!4WZ6{)_yL`E*g|9%QfJtK9nL&7Rv0vag<0H^b3B4nVvdx;_)>{2yYWC_(ga4rzVic{$D-z6y6 z3KOL85Bc-37^TUWli2E&Bwx^EW1>^xJKs^xR$fJ-VC=(e{LJ;1*43t>X&!E$q%S$e zx(eD=ezf|UozuRVv0N18_pZAv)}FFDwn)easw$kFKW4Pv_Z!5Us!LTH7G@@+jc;Sp zV)+TpGMGrKn`n>S%^^|uDo-#NYIZT2m}`Kke@84r#y~v|Pq_D30~!02ZAHMRh%Xxt&Q?5A(EhGj zYEjk@{*5b%n@pp#O;~OT`ve2qR1Ezqbb;>93fv*3y2WRg#QVxie@Q0bv1 zlU_bYTM$I?RJiIL@ecFXVWV4j%>aNPtPn4At-uQ9Fc?-oaJ@w`UMApWf zF;Y2~jb8T7ynZCwF1vOrA+^OwRO=d@w<_v#@ik3~`wU4Bg7pU;4$o?q*F=FhdCBGH z!F=Jn6EACQt`o}S%blHlabZ?+-Wyp)lkfrp1^vJKZ^#<&- zS4J!Mzr`VEO+`_k85JYh(50&}JD4THW0}8b%}lg&BYC%Wv<7=hWZzO1wyT>MxdR33 zy!}7cv_a#9on=D%cq!SV?DlLsurROD;};MAU+legRF&Jm|GQ|Vr9(kNDd|RHDVvt= z6hS~(f|N8$2nZrwA|)Xqp>&HhDk-6KcT3m4^H~e`cJJ>wcbsv?@7{6$xPLHoA+nzJ zJac|}zF$UOdHid422J&ybKgS_vk(!uxl>{=Vj|}@>q+FQg*FgK}VluKM;jqyzZ_sW(}s~=TKcUv3jgF^6Uc9`!ph{`pt)b!tO<_Ws7oD7TTx= zHhrl~aVF;joJ`pde^s~0841M!(w;+}Dz{`evuk5&Y8;d(|m!JpT=GV zhOSGjJqhNjOYK0On)}Z0z*8XVZdc)445_a%2&>_N(20Nc!ZKimt)bvrTh{=10jPV` zhY|XV*z1zGfqMS@Q;XM+CXW+W!DK1Ket>szPc1Q?fg~HCi4i^r-XPAt2)qqQb$l!& z5NB`@wAUCtYU)0`07Aweh`Za^AkCP00(iW)A!j1VM9-}rs7-Au!#C1Olj-sS)Uk1S zz?e`t=i6xQK=`xf3!RS>#UUDr5}88@7Bv-Qn`R`mE}tfUWN+)Yd(7#n>8Ehj_Dzt@ zuFEfE*{m*q-U>zeP%hRp_62cpp0Lk)+5Fo*=})-q1{M$u<-2KQUn<-$qxzZga2;^U z=!(W>ja zMe`6~Aq#QZ^07-`lIcD->-f)Z@c{JW*QZ|E-khp?S|DH3f&cg^411g=mwfQ^Oq$qR z=JB_4YIW#V8Q`IOMe$IKlP0!7P%y%d?f8)>m?i-9d!B&y&QL1yv4w)i2DN+Kdhm1K z`3(Qj01~j;>^}y%N?#wIeW8B%VUc5??6Fnfb*;IOEhAxnM!ylYr?Uj$gktLn^mJdg%^1g(oNwkreqi06fofz# z`-vCYU_p0f;mRG+K2xapLO%1wdO|x;3rRZs&|7$~@|&5w5kET!+iK`1$QM#14$EG6 z{cJD#1LMmfBn#+16dJx4_<;zxM)%UtX&>0YgAwme@G`jSnK7Fb}-bpW1@{FKM3cD;sfqgqE@X@a|V0YbQAlpVeAiOfaAh zqls;sQQlg|F0nHVXwR(&;A8TgZTUcV_FCnp zHW3C-*s|P!8{l--L&F!|Hy(l(q`VP0jHu!ET3X-y*tY7@p)@ltY^kI-e%+$!7NmYoZeaP4Mu_QFq*-#eN zWX^e8%dD~MRxLcpRkTHGVAVESv62HF{apk+4UZ!J{rJc`CclGOt$~IUsYC@q>VeT% z%t_re7ZLL2zy;BKL&ji%5Vs42CZeH{g+yUQnN(h znLdt)YtJ9^SjMwuzyGSSgc}`7{3i}C8a)x1pnuwKHnGe$L3F|P_Eh|O(l^Pg#EGT& z0Jq7I+?AlvX9^NJeGq?Uq>p}b%4!5h;mPi6Z;F3>1s#^ZwD3gou*?n0=nA-z`-bD$ z)~n+uMZX?zO&zbIHQ?fWl6^oe0Y$K-&@pehl=FS$>LGRF4@Nb{$Q#{IJIgf@&UB{& zyeEbTL|Zol$hd_&%u76=j8XXr+SQhxp!<#5u67a=pX)MOOHp({D*fo3l2WcWH;DS4_V zo)vTI#%>kbRb_7CsQ$rIs~?s4S3~_5*;6u|$0Wy67B8H`N{wOTpA?UYpfb)Wbcn7d#uL0OKc(Q^E zfWi3pO96uCAd~NOd#6-U&A6R~yt`rPZQ?MN3QXlvsnVDczr#W>_Zm)-sk;|J8SMTjqN z-y8Gse0{Rlt2eP3yBzOU@qp^lWRk|gMVa{whdrNbpF}#ryycI*Hx(C%=>h)gbiv;W zLCrPn6jc*4pS(HguImKNIj)wCBajYn0p<4OjlEF8$`7HN9q~j-wXnh2Womv~_2293Lu^25o`# zFJSE~y~djZx$;@j`vDFuSx$nbo)Nel7i}X zzS`CEIiKHjY*3mu|4X5L4LSAxNDWL%7Glx8LdM++l?j8j!jCg!XR%Gj_~6A-(=K1W zjFJp_zbV-weMf@A5=cZimkna#BLgsfIINnOh|8RA@RWT!K%6S+2x_Pm3%nhP{bAS) zTo}~5t(ksW&vDTMH}5VwxoYqW88V$`Sb|~L*8M|E@GEjb^v>5SXtPWY9z0o19Jh;I z7&!Pbq&mfs0yg}vz;1e)Rf^m8_`=_V9b5iO2owlStwIs?gn^pQPB;tX9i)Nu(Q-Fs(YObfJEZUocO4*<2xcb+IK$GlZgGiC|vQPyC z*5P1uG`(}miV>g+-olrn0FO1=&q1FiD5&VhuHJRpBz`-=WhE=iAjihEu!HPUbtx`D z>+yYc6wEOd9oZgMJJWO|Ug4zl7%#%y>^u3A$<>CQg*FUZ0Paf=-^c5}zXiWUPr2+e z+ceAjqt!uEZ+Pq=WzooJ9w1tW9`5N_1V12^ILOXazs-w_N!Jf6e=lQ8(?a80YF4|@ z_Q5+_KjiWZOM%B70CJva?V@bvaq60algJK@QL&qMLss% zgn#6WeP8!bPF>aTrl6>v)};wDwD74lEax45Bd>Mn?x>oGsi*J`NBKg;lnd*V$Ho~A zgm{EyjiZ8p!UF6JI|$gTj)uHYK$ed~vH%GLx2OMwZ_Y!|QlF^1RJbatz3CPl@ecfQ z=EgFo!F>J!@b%QqeD5)_XOMTfy@3CGy;hE59A;!8?>9VL;x6TK+)T$d)#{8$?y9Zb ziK-(PmlI9yBBD%4=a1P2U}1vE)Ix9j;*??FDY@C2>&?JxWch#!$Zr7oi9V_~POpe5 zcGIM9_!^6mOWcM!vdR#931&~nS6cbn1kg*hc;;)q5M!s}R(5~pV{2vo3xlPGBMJbF zU60C#lS7jxUGvGep5)qzr!s_f@rUeiWgr{@c%`_QC6IzM;FGVLhvPCo-gl$Akwgk+?}gI}BLW|u^f@Ao^nc`jZcGce zi5E97Lq~UX0$hj&=cgXED{bZbQo|^s`M{zximC(l3|ixoBu9T}grPVl>tvGF6V9@# zssY=#FE3*HA!;dHY#iT1q^SfHY05XW7|VH4YZsSY`=*LD1n7Z>IYGOm8?{Rses3k$ z5g{=~&wl8WMuTB1co(_2dhSG|O;2&K2n%^+&Vk2vx3=HCswSZslgx6L2d+2RFDyE! zK1hEGL9KlF%P_4rdu8aQ;zSA`O`QU$F#oHV9OfCp5nBzR$n7JI3+dsf8d#G37o0#} zrfdMvkYlm+LaJ_|1yX_D9S-T{*|4YQtFP@^Bo2uKTSCE{qp1%A+S$6WoY7e`Krhc% zwd`ij@M!KD-00`0={1cpuSg`CSva_iQ{hSbCXYV2%<=P0&L)$bn3T_cVK2>6F0k}k zA8}`D;;m@y6M#JQ`V(e%7h)dDt5U7Wsh4io$6Nrva7^WgSAg#aP%39zntrKr@5>xIOk2Bk9sM&YV|ca_dB!X)9+6RaRz3ljNki6$&rwq8i8ogJ=kBR_I{+Ac%V34D zSXOE8o2wDv*v-|#WZaYs>Z(W(6H^v905M@oyIYa(mNYI4^Q;(2w2jnq*pI`l)jM4q zko=|BfWIU;?IV6#tDd`zvHF%morSu^dHhNb#V7G&6b-(iq(n0|;1=Bg1TwCIk^IKVt zma?n%MNpm546F-Un7h*TF3LzxOA#G*?|sqy5S>K0+r!M$be4tg&34${TqcaEll}Jj2+%HdTZXgV zZ+iva6zO6|a3H$Lj4!Sut$O)Ct-53kKBsBOpg@=)ET zP~(55N@n9aYfy?pk}jKEsVy0}nqX(&Svi!8hjNKM(i}uO`W-^^mhmgc-X*HG+kBzGgKY%4 z#8X5mM(18mQFfJpo{1(z?0W#-11)|qVgkM;_VTNUV3Uz|O=AVYEPwzHc}9r>CILhR zgP?BEp4QBr2rr>R1`>Th1;P-Me-s%pl>f4uxlXM&)p!n_`~ahCK^$;a-_)OTnycAO zGOXvkSuZWT16KGKa(d*o=LYEyfE>S_{I34|0crM8nbDfV^E`avT`W^;NqZWdmp{WX zw-KfFrGZB{!TomkK4m{omrm#h{6f`Upn7ePD(dz6v1RiIb`W+Dv!1n5+$+ zxir|fk@p%(C0j#h3kr!^%bmIlZ*MVJU^*EO_;9>!%=RNw!z={{smWCc5y@NEgE?os zi&-F--qVK!GRhN)({T=P4z&|QQJu6~sz$%=YB&ZKh#ifW&O?WoUv3=xzMDCmMvdQU zKH~lm=gh%b@4F@nhv>mNI{u$%!?iPQT$CpMDXzFMFWKY9y$_`fStL&K<81vKZ9gEe zEkj0zQJC5w$_hC>#~Kg+dOTTx z=x6>pt$-Y&$@kAq}tuy5MijxrdJl__x} z7l{_6I!c6vt718~YgY%5^Cf2s__&zF;t!RVXH$}3vJCq0)T+NJm^is}@yl&tv-bj( zLoLEK`3`$emkiDrhQ79~>PXcpNNUKKY_|FdJpX!11I>F@k+=&j5$$8M7nWx2xC0+l ztKI16BoExwtcMy?&?W(hU7}w_K(WivO5XiGE3LWb)A=BL0de16)>UDG_B2BJ2BDIX z@$-G|3^^;z^F7#urEIOV_>>nK!ar1eeCV+r$5L!g{Yb- zmM$#%lP&+I=6NpL21&O$5?YrYETJ)7$x{V{f&TG_nYx;y&73=hT!&DSnUgT&p_dOd z-!ul2%(Mm_#N!pU9jkI^*N0@LT699A&;(u=b0xWFnd^PIQt+MyFJMV8$}Rd~D2$3+ zsD|v@onShbl+ymqWiqViqjG}mV=AwzDjw``Syz|3K5&g7uyPAXf9USk?WJuirySRA zd3k2I#I2=3M;4*$0mh67QqCZi55!EL zRd;i!j{EY}WkASr%7*WGI-~tqxlJiXZhvn}hqXZ*NPUTm8FQ=E^oJ?$Q&w z*;^0a3m0z}E!ZeA@Q)-}7$Q4K@z27jntgI(vv!X%P|4Yf@W*tuRL~{kW@btTzn?w> zBem*EXH^*95A@PsfOz;wjZ*x0S_WKJvnACR-ytw8{M>HIVGX2KIM0fZ zJGfhw&R=>9IH(Ni?3_aOW`5d_hFJZubxLJ(S_wg)){mrnP5HWqTeQ%y#X#p(UgQ1X zo;!6xPR2qx`OZ~3+;tTpTO6-n9AAN#c3y3Y_Hz?}1u68WMb;){VMyrK*;<>B*7n<8 ztEwTa!J&O=6x629jQi3y3WtTPf=<$^)XnT!+PyF~w9f`|vnvYp`}bQsjXvLPs?m)y zFQWWrma?y-V0OE?Bidx{e&x4xIS_xa`HSmZ;oCtdwo(;7=HshBf9Ik$Fi&(mIb7w$Ce z2AP3)A9iTAP1)vlmnTPXl*Lv2$;7oN;OESMpYs9iTn6BYQx(w{F3!AA3f@hiA-jV*EZWbv0ikNp-phlNg{t&p)CO2GQ7njcM;s{pPx(tsD85pz#C|#J-IAf1w z-;<$-E__bD<5jy`cDXj<;S8_8fGqQNmn_lP4l2}RV*%!YpjmjFwbVUxj9O&?0r^{9 zQs&R_j@co*h;w!;nj&K`p*cLWhmr>xDbA4^Zkq^?;7F#s(Z5Eyx`Lb(;^_Gq>EAAq zM+$|hxC(n|gqOs%bH^h=CmBivqx0NcwujXH9IE!AL=cs6$VrEILb(sXiK0JS?4J6_ zO)nZwRV2{&XqS_4&r)8`udU2u99w8+ZYSp#uNBs^+4aHco!zmPh1?smZlIF2#<^Ex zjttf7BczFrVlM8Goy?kU6WL(8FCSEBmC?yXbV3;Sa(feiaaVFm=p~Xiu7X@J7Qm)P zwvb`$gIo#TIy@q6f!js{(=v_JGhyzvsFy+nBNNFh)=rWB`%viO-;$V>cZiM+VpulX z7Mj?j)7VMVVtW-1RP2(OYNLM6PR*eP5GR&7O)69Cd}?TM4(#fzdZ3k>C2H!&`+NqM zNDT`^Bo*C2)iy`PQX>siCc%`cX$b4#ODN;P)EOkJkK`-5p#vK2Xa=K(6X)5KBb60t~79uGPs|l2{wf1Tv1P6W$7ajvXJFkCE@w)ejqg%lmv`j(B^+cZsXdt zIU=K-S)4C2ivwGtVJ3Z3f(;yV_Iu?-IeacweI(|b ziG$@_F-}os73BP;dl2N~|FKcXx>42R9O|YY!$xj}OLkm6Z=1$z2xKuR{I69zY72!_ zT~=$5a`csq$tGxWBtRE=^!q1svp4eNlVImXg#-gvW=e$~vEx@#qxJ4KCvOlFQMIT(;ZNU&ZPIy$SY<}(Q zNQT~Fi^Ar_CF5=iN3F!Zp~pG>c$}OVH3Z>}fj&Xeu<8VWv%?yJfM9rBT~@mdi!i3fIIxC#rS)nkG{TtB)b1jE;elB zL^1|#Ap_LT(|^^@MWH=@=^===!6v8?(z!p|0Br(P*;Ncol^fXGZ4`i)4m?Ptg@n?1(jR@tto4e`-98$1{(6R{68HfIFh$0 ze7HXLt%bF!*xwwIR!Rz`O92=3ZhB0k$DK}EIKI_E<42SG^y^5@R`Wk32wdhre@#jt zi(b=^BjX_&1t~BFwJm}m36D%3O+7S3Y3WI)1@mdYW!8#zSpawDop)czm*Am~Af=tx zuNd#`6F5KQaWJCyDPRGYWv!OOjBJtiV1S`lQ=NhS^NqFvt;S_iROB~iN=F+h&lncY1v1-Y9UDeuy_onPgHuIR|Uj^dKB)3J&;%7 zC}PudIfTde0cpSo=qsmO-&gN1VAMGaRJDIvT7t@^6w7h`?c3C~_52}mU9{a~qrrCk zG;cu6{_D9!0pjwLIdpGUsyLTkgFhk}eY8vyr^Fo)4w6L}w*z7>b-Gr8Re93x8(xRb z_^nu=QoDXrUA5}Pnog0O8zHZ1!(~FOD`ILm*qm0I<+-o#a}}q^la~}M@!Q00jc3F@ zHXcEwyS<5jrN&EFnt|pLUb6(J^AOk1GbsAejPC`mOBQ5jULP$$MKhI6r10Q}esnZ? zly|Po`NvGN1$ttTq| z!97nmFyRbw$5AP2sn4X;l)!+n)#}=zhAR1fh%KEyhOB0p>&Nqs0hC!%1*7}-<6=9| z6Fn@vQ8*ulbj3wm1mdT%RMq#x5IyN3%+PU#6%+TFA-w!s-J)bLICm|t_2r257=Wpr>=>|0jlX_mq6N;a-|0=;#j%6YolA@U7ASuWn6yn z_<;4FJ#Kt0!y`iUTxf{flWcI&(0WZF%k7u3M;_dZKefR=`X-Z{AWFt7Xx2JoUy1U7C?PY96?F17fDOjCD9abJzoC8=)U?6o!DL(!1amcw?UMI=yg5QHnYbae&~J2H4%#kU z$X1jKVNL2>?L_Bs_LrCQUq8)mypJkBkOiS6BapJAjR<_Xi~h#!SID+L9*Dr zcL<5vgyKn;-wUwn-=Z#T9h~UynW=b!cb&k1SDN7~WUa&F1153d_QE>*bfneRw!|M3 zJT?DXR=Q7_dAdOyero-97s@Y%V}op1yci1bK5QO!dD2#a0Pp@};yTIsa{DWO!ln-{ z)#nZ$Hgm)`7a{K?qOgg3vFCt65AJ&%5qKB`w;$$zN19OBq+yF#@-`G-Fdr&_3My3( zc7k$;lz>08PWwMx?`8V10y{22JyghO{T97ii+z+wU6bm~ll$cEpmG;aKa1yi-cZK*Dp4vw0w)|Dj`4hf$a3lp}L*%Yn$id={ojlpo2eT?yJu|*901a$fT z{}<{W1VRlp{PDN(*%(>>7_L@B&;8VCijcf)th38?aZUx{5kn$I1LwoswvD1+57o?p za0n1*;J^NYPB3&I1U2;`NU+0hClnk(;Bqv75bY6OkGYsiB5dYfFfTgkyptB?fkfT> zQ(jHl-5OXG*+sldp9+QUqN{9|+?Zt(#Sk3Ttf(lsD&qMRLz!%GL)1bO7~JGiUW0}Y z&2QwXL~@0N3$6i5%rBP7Z`BW|0um(_mU`tX#muSnDMxS(6;PUVB?)bA8m=5ul!zA8 zy2Fe2hh|ph6*il$TLt@wjLnIo5~CUC!l0(&bOwC5K-Px>`q1IZI99FFgm&`h^;bK) z<9#b6ti5DQgz)u8!Vs^S(ar|$n7_#~DAp*xIoje%DDp65Zr2md>iSgAV0d71B7fyV zNOzfp_kgTGEMyA@@H`o&e0_;4}Gj%CPP9=V9-k zFx+vejnuB1)3p`Zz1=id9&w4O1OYWARx{7UaS6AjTgnLdcb0z>0q^Xi%pAb#mbEKV{LTs=yMya2^lF{U>q$e@ab6)0&)r|M(+eVUct6 zhvT;u){x!7bm=`!8DOAqFe1O)$2-@SkRK5~|mlDh?R8c)9n9`&K$>WhnT&dOB# z-TY}1O^_V{besxV2#1K21SfSk}k;3Om$DhGvyQWF)}-~@kvoW-tNfNSprCsy*b#d!9rv1&~d zomv{8mUZX~rVa%;W-IlD0z_L8HrKY(Xb88Q&G(f zhp;=`_k>--(UT~sIxQaWYb(f=UgK+Gy|g%E7*iw#@|Afh0| zTM_`JWfj@cFwcoFJV0-D62Rg#+ zH9_PPdOzPbs2ZpHFhjpN^b5_pQvg}}x@o0IK+~lm^1J5*>>(Bu?)oc)yNONGyMw@1|6zHLs7zh0sfFX5k3q0c5E5|8nknc zvO@vaBml4v+-HdJ4!=f52vC5701gPielR3*PpHF)gKj{K4WHlS@r<>lvJ2of88?N% zJ%||sr+RwT_3kf4kPbb_^#H#eMHKvo2G%c(^}m7W@w5MqUJI+t5nSuYP`L#$0E3!- zSVXM@1|WV)sn2>&HkcblvHyU7gM8focfa!Nty!-;KyOnAJ#+^4AL!M80DS_Da?(Z> zJ{jiKj$FD2Nv2CmDv97BQJK9mNO3DY*1cbCBt$9jS$b{IH@Wdbp{>tUabas++-FnL_UMK|w-|MS71qVykiX*?P=h$eNOk((I z!P^ECjrC&{=_}V`8-8plIop;_vc$MK2ynZ@g-a#?L z#&=1*-AO+sL`R1jG;|@&77!)=8%Y-i>;!})pj_Tt56 zAwF3j0ATrcK=b}Epjqj2DS>g_j!cv3*VEK8sNYz1|GbNfczN*Tr$Ua=IRmpMJ@smn zRT+N)l27UZ@k#+i4GJEiqik>_jSk5OBMYL9kMPjN_#0_fxT1)2EQCI$7$W^%;TK8_ z4PTg>9npOPa9u0JNL<&75>{y?gzLJH_!}Y)crysw3HdQt3}mxHZ?joW$#C+`i62`& zx7RcC;YbF!u3O2s=yp;^48WPAxRt{pHYs1LI4cKH+Axm+!wF1PTMOpK$vJF~KI)Mx zRw`Gl?si2VKLS0S6!5e0ZcfrwgIxE6vrS3ItNACXKTS`bIin5V^0Woh$aL%UOPV?? zK>`;Ayf&hrc&|8wDgVuU{XHOL1tmz7Lj!0nWpHD_Q$wv?CL~=iD{mOw+F)>Nt>_EF@|m5=ea6mN4f7HpP1OV;CQD4MS$(oR_9Z7TI#{g1}0_x(;qUM3M#G zodB#AlTwHZnoJKyJn`doHidp9anKt?$~#oK<7C-Oio4GMwFNsZ5{|0ATW4P@I6K(c z2pc;d19l)Fy6xtoo`cWUY>C`2bQlL`7F?A%C+&}aLBCw%#$y2T?;PCszX){yZ!z4+ zTs`5*LH0KgPNLDC&L|@tR{CwQ$S|@LUnYk5ILKcd!^p+7M__37@yCbiEZ1AlqKnSw z@jG~6re}srMNu=FQ4wSD+ZPURsD@3c!f2YSdcL}|^BX%9P*!!b+deew)%;>1CWM|C zzFHENhcL{z$s6+uJ&Ph9^R!84ZKulO__GWPb6~Wk+ZXR~Ws?uzGLu{9rppTiWI_XN zzK4(n!?n@hCqFJ#Hdm@LXl>!tOzSjaL63M(PAY_mEg$<)-_RMY3`LvTv|(&)Tc^u# z$D@tlr^Sz1*G8V1hxXI7h1?Gm8BwLPT(8WRqHo!IX$c{*%K8tinzn!xz7ZPRy~q>? z_*V`oie)Eb=0|u~=Kd|Nk;Jxx`XW>vZ#iRAPVz4h^;JD3M-(AMzGcjOoe_Xl10DX^ z(uC_N;uA(X78Rj_6qUEcZ+wXEV63JmJaFe^{8*RJFo-#O* z04c@*wYLcppsBp9K2mX^jXFm#oU8-ip*%&rbId{SDKX=*><2PwKUITeB>dt=>^dys zeS5b^8a^%1IN%h!IAsxUOs@!U^@HA9@}3VriY`2Z+12b_$n1`W3D4xu0E$Qr))Sf2IycL!^FVs#|2*d_~jNxBc zwecY3(vWMa41~Ra53@nCh=G0d{rSlopbpxVc3nkoOoAhR$V=%oI#Q$I<^m+-tGg{7Tox{DfVzl41;&v@%=IcvC%o)a- zPxxx7V^_gUqDUx>BAeFzpLcFGqF@Sdf8#T;1n=IgoI573CSjgoEO7H|dS^xd+8Hx! zM#RoR-ijBgn}?#Bz4(pMRAetuBiFn{Lb}Y+eWLvs1M!|fw81EJ4M;!sTOD(T#$W8} zjWn8%on9G$C_NxOOf#7_vA`IGdXeU$(4>9@uUDaO5O18jB{wb@9BFM zY!!YuUeQ5{l7gT0Oy_QkWG{{H+^%KC>cA5vD61KmUJSlQV=FH%B7XQGkTGF zVF0PMP|s20_fxk#iUMDOx=7{&SpN^f`rl5rlJ{mYdCtF%waqb*ALhKMdd%pM2bTm7| z7|~h4VN_lHEvpKg5mZl+k$&q|OO4A?_m$QS5HdtU$7pfG0> z>Vd+?TG!`rBUcPB-m{F%w*(rxm2ZvRT__%LmYVWhhOwgk#!y0Xvw~5iB(1%{_>^n? z_(Rn4GoYb|$o}!k4x=&QRtKYx$cwvFHr)2Vcp4Aa(`o}C#>4!F$M5Q{ICl*4Qzqb0 zUG~@eNSGC;urNLs4UEs*nrZ1w8{Xdxg!*3w!VF~~fUt5nzT19LCq( z7Mo?lFH>fdQ?(yD9Vdul?G`G9VT!jz#^A*NA`FhiqUa;stH(eD#`)wOp3Y`_b)CW_ zBTqIsSvY~=3W+wq&HBsiYA!_PJJ)^rDUL9*Ez4R6evBd53iL92dKfQ?L*n;H;*{oE z?Y*43#*1%&jZ@*MFc#~=v!^3#Bvc>|&mUV{d8?9RMuIhi5%GY!Z&k*qCS;W`;={%N9o( zJs?rKVOn)(`(_VLf}1O_D_M~RGdB#2$S14~)&{y#IXfH4So!r*iPk3L<|h?s$}hIc zxX{dAlF2Z-(5oBP=)+$tT2x*p{-NRz!5;F%_Zlmn$hOi+Q&Sb!$A}zZBOQ-$t zk=f5(xAe;-9^e2}I8ocZ`$hJcS%I?dfZ>_?7sJ!*Z-%Gg%DH9!xj{`-f_TqavHpn( z=-Q{-yWg$$P*>NBa{hjCc8#199oJtiVOUQ=WI01nLTiXnKtK3w4Q2|lJ=aBR2O+j+ z@!PFHNc$9r04bo&Q!#6M-+o%Gr(iFZ)2YYeK3eOqUwzul zmf1;KN%#f8y5$36zEM3H){f%es)SBfo^LBL>YQD{ZetA8Y>p* z0(~z5>eYrd51?MvSLWaS#e4jQ@{GwS&p40``M=YnKc0aLH$QM~zJ88^tmYBETy%A( zNN~%dpP-;YU;)jMzr1Fm^tA+*9np;(0+`fqA8s0iBiZx9@fhUYIAkmQEI<_55k>X9 zBH2X+VRisw0p{52_F`@L#*+7O)rG4V+LCmpW25B9Re~81)-!A17uM6#OPH29k-r18 z2L~LZarSGJM=VV=4R6`Yn{HfwRjrz| zclCYC^pj5r#6-K({!SF`^I%wlH7gAhgRE4; z(uX1;2tO*A$tZGEa>lSgnRT1Q3yRHceaWW_Xr686yi7dvw7Gz%B$_N z73dKlrTc~dOX+?wlypBCknT@50n+_KkEMwt*cu=&P-NkXwaVW69>5ddd)=Dm&zNYt zc%1JsDA!bF5w-2zr7zl|eGp8an%hJ*36#YNlJB-~lU=Iw`HA#hS&Df`B4>I>-CA-)WX`IzKxCq~=FjVAgo>9zn9Mh2uB<5oy;x z&E~tO;Vl3CF&&Vf=6x78q{P0W6WvlBc@1I(8aIQjMVxt#)SR2#qOR**0O!BQsxV;RMsl ze+(P*;B9dR6$}&CnfHVh0CXr%1TTGBYS6}e#+x`VZVjB5K`C*oK9yI&$Xh3#!DsbgIjT&{bqHfO&&;Q0B=lNnNvNi!q0HTm)Yh!3pM$~ zbB1SUOX%KMFewa|o4RZ>5(e|12i^qWG2xRMD{Blf1S&IHMq&`x(qOvl20i{#C+1Ff z;S0q|i>ppz*MBWO3;Y}+jo%iLsaf+UMC#71vQjr4i0$EB zEKHO`+qP#%gi|deZa$xcSOj`!RK4`t1I*qB+7Lu5T(u+&a&^8PEin5%;L{VGNg6)^ zWMIt;rFOeXotM65qU5^zC4d*`g5(8q#2k1s7kSzj&gQV7``rABg$337;=mnD>G}(z zYi1GaSA8E%U-O_zQy~cg55T5BoN&J>&(3R~D$lE8*3D_l{?SI#+VkeBBgm{D z;V1ES;N(>A( zItqAWiJNiN!*5q~SBP6}q$m*G_pW|`D676m1fV0JuObnEUUzdP8gKLzw*sC@)l?@M z=k&2Mig9SGnr)zpC;L7<3Xt*mUk`}iCC~3^!@#zh9FpejRc2aC-m@#>9@^3AE314V zG z3ON!N%mhZ_5G!}Lu~4!)tjFF!Asgf7_8UGVSm^F=U?Cu)zYk6vvjCQ%j=1R5Y(@AQ zCfXZ(8S!K^EcwYIME7)~+?JU>taJCD{4&mhjmwMVEY5`HZC4aw{d%6GGV#MOuJ z`hzlu3{A7upspqBP1qQo>`YD}Wz+E7c(QmnCXxUvr&Sj0OiiJM-=5G>DBU2mspM(T z{L&DB*I|pbg73y`M(V#&-|+|;>@P|K0``$Wz@BX=MJL&cc}q4=%gWbC=1qLd@C#n= z+)J}+7#2Wr{@T6EH`M3|IS@_b%)*(AkpdAxsSXiR=suxqiqb*s3& zB35mT`8r%dZ|b9O)`(iz`IUEcbfS}_*T;zW?mZ(oK{Gni<6hKYh`TNJQGqjUUu# zrgX`tVBpl1xB3KcE{I4(XK3^kvI4X`9u-((qFW4}4ZA9h>DYAky#ohy45#hJki3r;7`0 zD!nAjI#>iyJ|#eBsE=PA)KHOnX8FEWc$#9+?tXC4s91 z2=YQlFESByw8~(JaT6dY4L&?7ZPlbpFBhc!4)8OX5Prt+14XL!uRSPH0&$rDQy3sU zF8+5Ep1~cOUl9bK%stdvFa&GiK2SJk`yImL4pxOj;!=X?wC}|`l}-dDpZ#y(pr@*+ zQB8)1E5f!WND-8}i3!$fxw6yM1WYX+!N=lsw|+Eqv89Olkqt~<@VOs4UGwrcoRJ1~ zvsCCU^E|N2I=amQKe?v@+&aj6P=uCzB%uW-(bVZr7|0Uq z!~;*>J#DIILQLx%xZ92h_MC@UK!w#|&(;JDar_=qwe4x8jhUs3HB_tjYaC0|McZn~ zNvjkZMmM5UY)hP3`+pWw1QAaJTWE9J+r(ZYzx#|?#! zwc=Fx_^h#FUwJ`=)%jZ8!t#{qR^D)aUpU@0J*i-l?+qN_<3CKEBhw(V(9@v0aH737z>yC{pCWC)Foa0zQ-H^%oE( zt&|b5|Af2G!j+}P)h`F=B`ag)53WSJ6Oz6sFy zj0=k})s}?mjBGw~--A<|T-m~~*>`OGd+!G|5GX#)ExH9z(3h}QKUx+?Ih-&F226b< z7Akqnd`EKrH-r)8<|bOMk*P-yzf-dbqnO~TeQI^{{Q+CU7H;y=N2cPfc9r?z&wCGt zpYeueh9RCd*3*T3?y!Ke1-Jm(OKTvmfXJC~qrwJ6?)s8x>8x7Z6ZeEpXKSkmm-!le z>th!_UScAdXd>B)V#To1*-~n;rTtFC`?`>W>2C}CJJ_fi&EmYey-@obX(gJW%0z1@ z)on_q{GA=AT--(K7FUCFzDnA~|Ku8>i@P=-wG7O^#s8gaG|_IGgg^ayrjkL~fZ#c{ zd>2PW-;K4WB?aGazZw>8VMvmDY3RL{U+fUYZxH`aGRz;Ud`DEep^=8;(@Z50Pa5>8i9c;u=o4nHQ-(aJPN}+Ljg>EF+s2jv&zraSoH7CTP zAZG=sL~gM~dRah(apb*V&&X2T`-aFv))qOV$NAhOZr&D}uC~v=N;?1{%fM8pB8qPfY|BjO#e$rc!vwdk zzW2SGq8KtV;NLy9k1Oe-5`*^HOLTgAl1S5d=5)r0$oI-auD41hb2X%)Lr=6mjMf1e z)JNmAhOrX4W)&fnU%|=YSS9WLd*2H5lYL?cv8)adx|RL2Kt({kClS+e9LV}a`qA$P zcu;^+_tgWC$1aQmlt*MB^gY7!?~&pEoPh4dCqRw?c$WobNZWqlOxQGW=f(-w@`k{> z1iRA3+8}}e>NGqECmv3FGJe$`NP#c@30wAs)V&d1;`*;opHP&XPU?X2kqb@uNl4pS zRml94D`3n7h)8J~OJ?F87zHjfK_CtwCmnnSdT2z%uwn7ZofdZ!|AMh4VNyu!Tg9HE ze|OhfAh?egNk6!BrLOGjQVwG<)k#eNjOUkUNtx2f_(0 z4rjk^?q8o4+er#ixSj^8-&=saKswcPeR^`Qqi`KAO$z5Nbs7!2(YLUiyD6x`4ylW7*3chWav%W$b~sgqscPWS0~ZJIA8kz^4-Qk8 zA7FsO)lwRG`a}jJqpj- z&Td5j{j{!=djR9`ktky7eZytl|BJo14vVtu8?^^XX#|uG0ZA1EloAGzmhKcqrKF@w zNmP`V_fMN&e#TRKER?!B%VQ19n`pKrgIwaV?cfASOsPfNNGW(SRnj$u;1vVh_31;F#v*H z1`%&XPd)>GlH>73uv`JqS$SZfIPtT~SZ+T??ajiFV2#)~6z#u0?}N5?2AE2+ zU9LO4jatqUY?-Od6C(&{jTfEe?>`7z$FsUor7<^WLgE3L*X}<-9MpjSq11a8j9Xd0jQ23NjvefffbCI6KKe z$}YrH!QF(=3^cZ&yyVc_3xw{t>-lp!B^8EUWNhu}GDZFN-bIn{E_|qE1OvH1>gM9J zcwpOtT=(TIiDpDc?pgC7=}CE4(G9cwdQJ5U*OIcbF zHhySsXmmA+pFgJO81J^VhP?oYXm3!mr=?TpYbOWF!0|0aWd&tWD1O{sN>FJG_k`zz z+0%G~6%ZC7$Y0rF!X8ha6pwx@%GpAZ+s4#RsabdP*ZKhu)aP?3`OwC{ zBrJn!!Et*wL#qz~)DAN`20WUSbTN;B!0RQhP!D5)4cR2vd<$F1S*<5HXDfhac|miF zNh+J=eZ&q~0*zJ~qD7goZLNVl8ctIP>h=$C98|bPbmW5&jcM}`#uyu;8|EK62t0-l z(aU2!ria?;3TUTwO(IL+C$q;;jp>K_sj!;ROVL6M9V7sxD?B}P;Reht9zr`#i9j9} zA(V&ZJuJth(v9u~nxvuF7BeJ0c|zlT1;MjnsQe6ZH&8yFo#rg13wbBx;o^KgA;qXK zz=x*XN)H@Kdmy?N+%1H(q^AMT889yQ8-mo^>wP%a17v6-D%cmuGk*6~ zTD^Cq2UC!J)xvv7hlcUysp=5*s?ZV_BAu>o9Li zQ-vXYwO(r`BYcH&{!cC@x2#MxqjZyf&n-K7lmQ(QY-195 zfDp+CQOd__cQ_2zjRG?s90V*-IOM#EtapOEY|4Qq7n}izdDtTEyi;#YG{!X_z$0hb z+#hj4n7WerKbjg)rs=%6+QWeKQ@6GQ1r`fRft4j??mqM3{>u_!FWfaQE>OH@kj1N+ zJsr@0E{H_NKm|K;WrTBS4(h_J`y!S6j4g$1QtsAo~?(X^pfO-dFKhp4}8e z{gc}{smn7TwjHWbfORzBI6>;is_fn18W~4SkPLf!S~t$eps+Em zYQc&2EYM{^OM5_VQ$#JR{;TuC|DB&pp#f2Z@`cJ%;d+J2+RdDVb2qd|y0W|p?inok zU(=3XmPD7gb=#4!BH^%$Y&?w?`wXJRs(2Vz-oy`X@wAI;e!91LY)X9DnrM@%)FxAb z@%xLQ)tZ;Bn?!(OEhBX%>~6l$x{01y?o(c^8kKbUGuc^lxF$ChN3VxyIMK+0a53|< zm!fotYM*h7?4nED;nezq7D ztkgO9rbjG#0F51wLSxrZi+#CYZQdon&KbW;bPDm$6=kUQ9g=&+Vw({MQ^980{Nifg zNx8zS>auYx8R03Vu=#cUeZ}3Lg*RK1M*-jv6t=!QqZ9|mCXObEdVS+qTm|)7g{kYv z5sXU}qHn4WlfRRDt;Ia169QxG7{J6nUFvhWV}TDax>%2si3DmMQPplGu_8)b^zup zHv40C3(|@WV0CeZ{qoV>Tp3FmOLXEi*i635`iMEd%YB^N z@R0b`l4m8Wc{op1TbkI~z$CUMoN^^)5hOoriKg1;SdOHhlS8+{7uL?Zo_s$@HzfpZ z=wfAox=vYHtt=O#w%}ZL3Sm^kZMR2kE{swNx64deas?@v9kO~Da;t_=3h4q(!xOGP zoW=&+(a+O6LW7C`w0)>=!}=IsPmuPBNU?NYh_2W%eWH6`r{h7mxKUm{r)cE0EJ$B) z^uMex5C)|36MaGMu?TF{mL3o(0vxZ`zS<#*^-FEGKNc!`wP*G~>JmRgG@Q02-abS8 zcqxzM=axo^`%7!SFHslpKc-zQM4LbAtOu&k#V5kdt15ufK17e=vCoQFI%2kz!u%VF z!CceSzSZ9q!~kpH&p!b~X_Q6+I1CK18|&hKOocTKr4*fOB}0?ZLro^vhp3@vw=PDt z>LKokSr&cL9mX{lQK1|dg) z<8ML!0SUHQK+rachs_3t?5QAKQ1mL5K=`C|mf5E)fHrU7^@$5=HPT=(FJE8ZDE&Nf zUc$D93f7TU?USI`&Ib09p$m2d-A@s^Ys3{1`{d)|m$>@OMO8zREiB|7WJh5Q%lBYo zK_ZFf>L;3Y)7>QR*HI_3OVWvEgipGXV_d(5!Ab@%H`lHEK%pk~1rZ~B^Gf1+f0#8i z8!k^9L`U62=%3gcU~BwuspS&rUR!?TyZLZc?tSvtcd;FGzVA)+r9F}6fo9tzydXTw z??Wn5_)TkLY%o#Y0kEnFcRI@DEIhwbu2qPQTC6F5J-k8vlqAA47XoSvK|pOnBv5<) z2`vC>ixiDXtCYF*(}{pb0J#S)1UTNPOKgpvPg$}vSPU1N4$(c{?Bv-5xwKfrc?&lKO=RLSO7O#83nwtyuBz7=Hf~qkRN?sX^Qkq50ft) z=WhlMhXOc&P!u|Q*ZAqSo#B_a#Su2djN@H)n*71k_xljI_1?L2#B7xJ`u3?i9L>gn zQe9mebMuEeb3d#0Wi);Y-byr?5<(~EoPti zUA2s^`8g^qwLv955aAAaQvDdDSUD(?jDe{OacZi68A-ogY* z?!qo3avvyR&~y!WuA^>$5TIxw#3q}h>%M5Ia35EmF)|2RC{ex0bfX|IIenVCmf8dQzt$|!wX>Wwu93qHgx+x{|lC> z`4ODd-5K*#bX4D(zH|5hOcFM}<0wOFI-s6VK5aq+t%of+;CvC%c3{{g6V=TzLf~^^ zDhZsnT?9I)V8=iQvWxYx){GKZ!fc9H&(Dl~zaN>P?VgcXWkA4qOf1LmH&#%itfPrLo*Mr!CJJ!WY+d&P>sj#(2+i|>MDEg|bf>uzS%Ky;rlMc896qDSkD zNxBFoHl3tWFlprPI@F8Dn|K@K?CtMb9s6q!Gb3z0BG}Hltokl{QQNEoR#)Oq*X!BGtgBgV@Dk2frdm2mK6hBZLajR_J(#iMK z*C{Qnk$rR*8uJUPzg=^2lez0_0?viP54=F-U$zIi~JJw|VDh^TCdwgZ8K zc49=ol>Ez9ULA@o(CjO!Y`8I`7l*} zJ}Yz^m{{_7er{=&)P2VQ8*k8SINb?EpM1>x&h}Zz&L3cv5HCwAn!2Ckj_!wHbz+3lBDLK*T%7(r$Ug+I*_&`)ON!DS=O5~cJL zz$|eSyah@Gqo>KB6`gz&EUdzN;(P;`L1-@MU3ur2zC!vl_S&#Xk9KB^>E>GvsO8X3 zeE}^e>$K%y+5q!4m}-F0n7ljKQUA5JUz<&WNroHizUOQ24>)b2zBwym!&RQuBJZRr zkX9#@z-0ln9rg;S?QmHpZZ2dF?Nn@gRJ2M4E$JBdFhUSyu$1_h5<36AyzW2qzW>>4 z^|ZtO5rCXIGBLNiUWeE8H2ZF+bF4AMnNF1wfpEFr_iSZ6_u`oP35Iq93Vd{LTsBVfY+-g@ zOd6=(Uc~UIePJ5nl%68;!Lph?~&}Q1Jgjr3`n;$+3-@IC}=Vpd*uh)rC^z}<+C1f~83%Z1m;W88eJvrehEP$QM%+POc9 zB3t(YQmuZ>ZVJ)=yTtvf)i1+Gd?o;>T;FVVLg~+_XELY13JU5(!n*-^&aOZJ}Viup7n>rc*JsRMy1{^)>6`szK-TY)N`8gvK+_!rRe8r98I=7 z8XoADH%t4EAICswX(?ZvmM^oowccva0K&GPeLn>o7-$IQE8ds5+xG@==s{@gDb_HE zR%fMBVgE(l>y*6(L6T5ce*2Ih?r0M-nEitzp<3?i1aKtqB#;{BO5#gCG9y=3VIyg# z=gC%coAIt}08GvqPd60PcRl|^;NTi`K`;{i2C{p=0Blx}cOk6sy!49^GmE6-32Ynm z9xyF^d;2#TmBP9axHIbn-~17$!V1wl)%BU}_@rJ4_~O{#XnL9N-X%9*uyl0Dz@^zS zEdTPTZqfIN=0zzoCgK$FHF(>@Vp8*kw%yUP3fI}n&6o~qjVmv#;?8}!zoX1Jnd$naCUq^b8~58p=8o_EhO`r7QZ0qus_2}{2pzh(1VU>{)YhsZ+E zF=ajF8?vvMXkw-`Yd}Bo5<6f{g{j@a6I2C6CbB9R#vq_)A9u#=<2!70@;++e>+`8< zPhQNQK6e$~V2EivWd9vm=hvw*!=__0PkF|uZnWE`Oz%{X@f(T{1Q~$z&4DC=o<$O* zsV%!n$MJ#_T5^G?U=7gS`NR0p&05UQv87V@1GK&wNxe%~-;9+L^u)n{;KYD<{cAt~ z{B#H)1pC_)=SmIy0|$@JC2n{fa(qOE0T#SEEH{37H0`$6aGs-r(d;cqq~w|$xa(@e z8o$EI(9-;t^F9cgD!W9F^m)Whf5xh;FiK+$TBrN?>D}csq?18dw)@wIl31%QTo4S^ z*ySG^Z6r@ups|3kff_+<(u|=0(Zc|GFTm6HDl5E7&!7d{vd(%`D^cGhv+WnOEBX&5 zpaC2#Po(lBpoXm_oi@GNaZ~MVz#{%=s9V%9(&Z5rNVXrudbo5Jq+Z7AQh6}!jj&bw zt;L30E1~17f62G3tPt0@vNuZY?(8zJ6+wvo{*1uuJvz!tOBSHUO>{J(?A2BbUgPi@ z42iEVFM8c96h30DZPD_$60yR(Z7l0m!2@q60~v1avkIWmv>7pTrG#15p&*nGAx#R5 z%7K&Nm>4IY2x5buK3POKDEq5O-vxwP{Dp2O=Z`5}47&348?t~#sZo|3j$0?CgT+!q zqIc_EOA0wfr~L#dr#e(QY0D_|TZt5AoDtb{DOWGM!)W{nDzL|(de>bXNIm69A~i2+ z!KW~OpCtVpz>n?LI1!0tnS_5mkOZNrWD8K45elhop1Ly*B|VG!kz_>U!r)ScyK~?1 zod5|w)sb5H519{T{n+TFOH$`z^kcGPs>;p%K6k-~axX$i+Y!H=EpOP;1VbgFm*Ih8 z6HurCGVtJkb27reat-KEScDZBY>VaUE7e}vD{>2J7cznW8yWZTk6(ndo^rvd(Atf= z*|r?XHjW>F*v5vN0>1%^Zz5>0k1oY$euadXR!tXvVS^`6XvfO3cb{23Ka;ZpOED$= zlXV>2dOnVHRRu}iXI6aHQKNW>X>E05QNDV#4H$k20U^i2v?+fTQcqNLj@7Fo`G_H zeJ_&!zs86hh3M5~aZWEB?f!NrCOxmO{jWBpz?yi+G2TG%&1dQLfh#ZhI*tkJy&SkP%FL^vGG4m2?qi4xgnFmw(K}<5NK?)@sGSWbMEnw*y!;$bx(7-+h2(865IKMNgb*$JH*!8~ zbXC^I7y$dZxCv~_Il;U-mK!UQW*6~|*?!{n3FFWV-TM>(jGTyy5xICiiUWb%NC0pT zL?Qg8alxj&;Ij-YL`~${I%+>eKGwX`D;0-@+_)G)bHls9w7fRqlfO7XrmulL`(I-S zfQfy&hUB{X>_?wMoO}8fnXuP?s9+}*20JRK&bi`G+@Wk%FvVO9vc6R=7)rd$KZ?}# zs417q(Wt_aWZ*xjlxNA}oFa`z`IJ(M@gHWSWdX9RHu46|&}9*B>e|hEi92{E=+GTi z4>JaM?X}Uburn2vXk#+M8?(spw?j>2qm}xnVzs%tM&DZYGdwjiGe5hu3^uV{rYyBq zlqtz4%ma^ER7k+7Jk8Cf8=~hbO-m$ZB)|M8m`Ew!6B8M1%9`=d+L!;&YhOIZ_5D8T zFLbOb3i#*-mp@LrXwApN`Z$wfCg%43LCB$*Gf7nJikuWI0mIo|5xrSuQy6e~l{Nn+ z#|o=l6VCSUEUvF(yX#|cxd*I2I{1V$2%nTrgbAtt<~_?K{{{PCo@)&SE9E>|W8Kp1 z8#7E*41DiQe*#ebP0Rimw|~fYqg+W=@l8#mTwQ;O@bD|fdw6sMtELM8s!n-QY2g&L zl!I3sttKr(vUe}O0%Dz?8MP-^^71~MyGW*}Z!#eHf>{;{VVm{~VT*@E*xFMu{u6}l z+u^22X>W20W^EKT{TUS)(?W*a<0Z+i*k8mF-Ngx3#B`_t4hYJeY$V$f$+d)7nAl;L zLFdANVqu;(X*ak`<^#SqbVpoXog^dx+yVsvr$G1VJ7uL}2lFdv9t!wCT@0k)C>;7) zh_ZTY6%`|q;%dRCAlOfL2+Yvs)$Ncp+vwsVBVYYN#IYok;Gnk zZtNkyWY3Vjr44xkJ92jNIW33+dtHUKFRtK>;Kn&%d1hTR*?@FEMC2>KWzI{k5HlF4 z?XEpG2F(av;MSH_mYdW&q`N9VQM<7`w(2QqXm=%87cri|oN1tS(a(E;Ig6HTn?FIx zhLo>%9N-SlOdOy1XcF^6D^TkqNGzkm2;zh^2O`?jKLxjQqHGATzr)UJHV5B1=C0oW zDN)%4Wha$J{-W=&g0v5rV>9~s75b9Vo3$=?gLXQ_FMJrfZ2kU<@K4LKsv$08pYcoT z7sIgMKUURKoOv(PRiTzc`CTrBU<2PQFDq-Le}}shLI_{OIqrTG;Upg9h~x;9?`d2! zSHHL|KNM@O{UbKeQ<#}c++^gv4Q$huoLYCd{4#FzZaUW00LRyfI^`p295-rM}F9`_8wLtWO9XZGA>S0QL`Oha~{V2b^-A7JzfZ0wG z_VXjg4;7x+{a!uzJ85WMBqyWCMhv#4aIMJdr$iY>4NAYN>!(^}l~QR3m9m&!PQn`D zPM@hpN!)A-_;iQ;B60n8(|Mn6g_d@XuK`P!NXU>~rf-!2#~5)MKM#s`tM(7P@fw0( zym2Ji877rUP<5Y^VJYq6JD}(ROyCoIeh>7Er}Z2#fir$Ffs2t$VEzBd1g5WqR^r!2 z2B`(kvqhXqqa z`XF_Ov;PZ^M%WMSbG=3frfO$s`(zjqs}K^H(lrL1WED<6UwOYTbQGUk@k_o9p^JZM za1I3YezekF4VFdpjozH0o8$@mKSI_x$T8xP$p~^F?#sNS3B_oJ**+00sYurHNtO7B z)9F+Nkis7zq%cp=1wb_QTn3X5AK5c+s!D^l$KOPXKcwhXkO5Jd4TdZm{?@t$jbNnF z0F@Gj_1;15QJrA*!DH0T`B)F!eOUKE-tOu{(a-kJX}>R)KC;MJ02Pxk&zqygrG8ls zQUhSPUW)O|UUJ?kl4v^Tu5I_m!dd8N{@ZbB6>g?T{k0Q&Swci3N_&7meWhSsgvFsx zkI{}bL*_RuzWO^f&@F+1?iaQg8&gDkg1yA`J^|1^m`ty|*w?lP+6T%8{xN3mCZ2Pc z*x6)nP@H%)d;cxK3Hnijsz@aO7z_ya02myiDvRuAEB+@CYT{*YL>z88KAGkVFun5@ zpuuHB_d`PS^HE<}`insvqSB6}Fhf-lSYWc_Lj(IbL zoBs>eSAgQpi$m9KFlW4r+%P+D;q;5O-p4sfZt(mH@5w;*2-&B~(WoG`acmSFma>ng zbkg9sA@?<2IKDyd&-~-;`+xc#Yz)U*?q#nie}7n~2bTpV9l{qSK>&;nxMe4Q0A(}z zwwQ+shRtanR|z&T_mT|TB267O6q5CkPG0xzVQBc zwwM3a?dX5!^W+3y=`D-h?T;kM`N`0NQ1#3p59eX%4 zkcy2Nz!?$Va4xuk_mjMJ7l8j>S=a-V)y-zhGp*$E0~j)$PW=>XpQAM+P74YHCS^%COYt1qPxa=BbIab4tVLacr1bh`dl${bZ8 zBGs&I^yJ~RX8*<+%YRm>DZoA*WIRQVihnfif3?;AcYZ$lShsL64VkTBj>fR80QEg= ze^!3>z>OeJZg2`mavJcL%lzlR|KHdDf9Nd2N?@lWtm2W3?#w>0w+HMl1dC=QK8?xB-jiiQ;WG6XX2)UZU%vuxxnH2 z8OkebQ&vS4TB4;4i~;k9nH5B|aw2a1XKrwuB_B8c*m~Pf%-t;ItQi1%-b6B&QDD!s z0)U2WxL|MlCV9S8eQ-NoWX`t19F6Z6+EdPezVZ8msAD^(SjwB0wII0-AUEN2pZ{yP zO{M~F5ClLI591I#xjufO9Ki5(oy~cuXaN|$lw{t!FiC=rkMSI|e9;;8%B*HN*|0Z> z^QDZST)baEr?YDQmr+>fAhirPh{FkSE@3Uk!Ic%Nw|{{bCIGTXubf%pvQ`Y7yV)_1FAP5%7Ma6uYw zJ-7mZBx4hwfG4MqirT#dA^{(`bP{YZ!A5|C1rvFdfH3LQvYQDQ#OTrT8W53sl)5i8 z^f!fBKjTUZ#61T84jyubYzE-A0<<%L9s8y`LWD@{OWwH9TW_EhK|{ie4MUe9Y%@;v zYk#s*eeLm|;etk~ivNLF8m&^XL-7`45Aj1hpxXlWfXor1R^P_zl?Oy+c`zIyfvzz$ zaZbSNoWM!-_L-zTfOk|r4A=3No|l&S{Tv8DFbo`e4oe`#IRTgB{m-N8=Rd92%Ytbq zy`8HS2o0qN1l&^W{fSq9!EO%iAOsp*XF38VZmZ@@eeU))?Y@A$lVWOA)spa)+*GYK zi{GA7rExueYO+E5yxq@KR<7Qikio*h8VSSDjBjn)K1sW1pH=0#kFq%2R5Zd$npntG z`;m}np`PDu<=uNWQ1K=qE;e|f7Q;ChVgI)xj9G=NjYAM=)WZdBr5p(@r|x?V$3c;J zBge&UojyQl@nBGnkx)6>CBajP<0kGB_Z9-MqQ8*_s&X zN?qIlhn#_$VE%mvISPS&Zz-NEUSor^y@F@2py;tZ9OU{z)NXI^JW-7p@a>x*Osr$3 zjH8VpCtd(k-ZE4i`8>2_7I~Z9mi2B9v!cjZncNrhJHwEmzKoJLRPwv7cym994ezo#=k-h(hx{J0(RrRL}Y%;Mt z(Qp!%Kkl#)qK)|8cuRK|j<<;A!R&+^*Nfo8puq|5!!k>olI=31WqrhF!!AoPZ2v(bZ)iDgo#_K*3( z`1>URdK0(hu7rjOv-ZuINg|f<*UC1}_VFXwC}TDcv5uz-Iin4Ce$EvaFf=+0J zVd*No$(!Gv6ReV;~l99&C9Sy1i{$ z4#eQR4LEj4h+TwQKw`snF%fwr6);pu@=WznUxbm9p&EMNW#e-U=eDJBl|Hrw*K|CG2Kzdi%QqnNa&x5+}=OoQ@w+D!pOo?04$t> zT-R@K*=_vkYORcq%T6I85X_MbM5utS>>#F=PT#51!H)n5eY5$qOsm@v1PJfwa;|p^ z-pu_rDR0XFQ3-$+XIN0+Bzyo)Vz<%*p2J&l9Du&%Ol-byD-ropC5ED%46Wm&!X9ix z^;L3upD@){JEpzB=KO){m9Hc29x`w5`+y8$LhLwuKGUePDMSEbfl|`k7Kc;_8qSYj zyUV=7(v>+AL9%iIu=R@Nr$hzF8#`ucZ_7^@K-?w{7pp=K#q79bo>s~Y!vr_0#P>yc zAD%MIfy`RE$rh?;C0`vKMv(+$g7NF=+R?WOSzSz2Gq0%D29EL)Sob;#>L?CC|>o?!x zH({uXU1!I@Di4C=fS~~( zs4+kuz{{AYNPJQOwHL|j@rw?1bovo+tg2^xhXRbUp8yv0e$Zl#{`6dRvH98-T?42u z_m4yy`mf+_SMpDS*zLv1)AB_!La?p}0lM?dOK%v~!nBOKLHQq*CY*e=+k~MAf}Q2N z*f+M@P*hen6)aqs4QlzKDF`9>eLKKmtFjfa&5oXx$4&to6rE=OQmPj)UIcrJ)F(^+=@bBI## zpLrWiZk`FMTvoW}uvx)jHXz+yLXqy+&I}~Z-H2W3eS1abV!nyl7{r<(YFuV<|2{Al zgE6HA;!PIcy+A_G;1IoS@RZ($BA#(^L1Y)_#`rV(t^0W>H12TaXR9j=fOCgOh(iV| zyAg3mKTl%%HBFG?ZouG2x$5jrJ89ub{1x$gj0VA0OOnGa_E))>`f>=URCE#;2-rRgvPAlszy6Y-A;uGnh zJrcfi=DKAYQ0k~)HYAsLc@|fG6NcceuLlVW!FA)YtduE4Z~%P@_;IHgkhhLW;$I?h zPb!1!cf%Fp1!=G!)RWh;VtO2G4K50?FT#{nEy|dl(X{_rC-D-_}T1!-TwparPrB1Ma z?6sgHRljTjO$cEQDX<$i02zG#NPOmDaRh+#H%^kd6dQSpir-J56zEh$5&kq$gg@9l zJ(or`%a=_(ZzWurHI*++h`W0|+T!MtZ7UQ{RxU|8A9@!qJLO}fKSMydTVQeV&g0@a z73}Qg1al}w(=AX@uy0!IYfwBSA?5{V-)YrWO6P+`;bQ#GrQ`$o+OeIa*<6j3DY!pq zVhgjHF3WG=-Y`K}$`Gv@c{=>o*2-arII<>UL|g+9LNfeag0bmJ+GhJ7t%2u{*I50& zJx~_d&?8=TbBE{eWZx5{%+nf*F!b9uM>py7A^F(SD9h!_Q*iIV9y!dB5>;55>PUND za!`%s?5jvd_qm&+ypO7KrYYPF&64g{hx5}Dyl^^i%i34EVr5%8bGK%6(u5&L%LfNG zO$7Pla->9+@gh<)Old|CpHy1Wsz@7Du{^KygC-yGucu zJK6%TWAj6OFab30z3=Z!+TLt+@FyauwA4~x<1?$HKN0_Z}uEHl zigCEoE0n;2(o~JDXlEWAMHq4-Y&|Bi>TKW6MhA0K5A7$9KQ$O$gXLF;pEB%h2{|t` z3Q=3cmxL6QYHmxpB~Ur0t0Lj)=_***fi==YK6NEx4l;`U-C*iipevntIB8hwKYMUg zy>z$q=im%)dC-yv=k#uIu`c2ryIm3hZpwnz#<#?RymP00XCU~=ldi9%3G&k}DK+G9 z(orFmY<=Nl0 z==tCu6L1zm)HpIek!X)>vC;tX@*86X@+CN3So*JELm@a7PHT`73{ID#<6mKFNZzWD!x2#eE z!{dGrwv-enK8>0>i9VRaM1YjX^&#@jzhK7_;7XjTT914dLEdpiVc=h|ZPJP#@sc;u zS`2(N`8k&y4z*kOStwy`YU|s(|m0BT|o+(Cr&Xn!9p@^Rp!g z1OBAwSxTLc&g5^nzqP4_>NR}GoqeznFjJJ?V>RauYo1CwN8np40QBt2X9}3}axOyX}14FMZL&KYVVgjD1#1Bmx zY7tT_zjFUE$;rxN2U|%i)HgudfF;QB+!^)~g6qD?^E!Q_Ily(_IEN$lreF#lnOcNh zQcKkTqd*lx3jF7PG}I>a^=Xu*mEXe@q_mC)KmP?=EIM}h^*{aXzZEMj`3v^_Yh5Bt z_f1;R3SQ((nj3wPv+S4p2(|0(eLg7PQ6Fae&>-CH*Y7ZJ^=j6get{xE(+$b%Un$&G z(3jFuoBxwj*6fU$vND0h56Nyih?Gi7pGHr1G_Z&IPl9r#k^AN<1WHY14IJysA$@0> z$b)H>L!J8C2_HK{EVY^Y zzg&UXQOY(rzwo(HjJ)bhURgXc6+&qlNl4{&VkiU!6DFK}H}0dz5&za|EZ^Pc?GZ$zWUu!Bkk1H8+wX! zGlSRa-z{+t@W+_;E@;eyd|DabH@+kLj{PK(@4h?ZN)rE0I6czO9sh;;LS>KRi0|j> zMSgZzb#lEJB0z)x*bF`Hz}eIezpulNQet>jv&I=@K(+yNg&6*djTdh?YlnExOl3FV z{IppU0Ybut67#Yxpz!3&d~4SJ>@`P@je31XWTW-YHnrahXCYY8MQR@pYctLkekTCQ zw_lV(S^f7@Iw&eqOxZVgf>%QT8VGeTC0-+6jk-@Yetq85-vT~= zOzMB9-;B2)@F99xV^8?NVHI@RXL;)LCjsGR{iie*_eJx9d;8Y@0w$}%hpO%pK zJsLEAe4nzw%6_328g{$|CIi!hSHp7<-;cKng*QQ{Vr{C>CnQd&S3XWSE;R*LueT*w z?69=uNEmi!>Ng}y2!UR-$r*d#X(gf^T@xg6-PY_(c^F7I1v?!etJ@2S`?56> zUNis&UE9|{^$4VYf`qk$XCCi?H|T*+dihpB4sE_&KE6Z-_NV$|$smkYgq&;a)S!AMuQ0f9T7NZ4k6j zs(5c?biRIK_RkQ<2ygzFQNDv1wm^X1U_mogL*J9>Jq#g-sLNbS6c zr1|kcJzL#7d}-Xb5T=bb>_Xn*Aqu!s!+q(tS$AZP=8n2DiapU(`dA z`W9|mfy{$#*9&?+NMi$pJ(24-sddGS!NY%YVy*JU^(+($@0y7TGLye)LK49 z5=VYUl{CboXH2A|Hi7`=&#=+H01h09#DoAfTk=WtHI}rv-js;#r0HPFc_g99c|>-sRnaYo=^mF|YRmeO9FA)jqG ztVG;tbmO$tYYOLkwLO+(hThNjEKN}eO9~c4$^QXj)qs66H}WDJCRrINio%-^tR@A( zYE}_qbDDp_$}~S7iOd|&(q&dvMxyXc7s%UPX#E3Hg(m1PzXV%zH!+XD=eqT_go4`X zkmL0VnDHKh%Gm(c8c^kABWd%vNzs3WXT`F#f3dhMG(CYaf{=Hxk|=QS7f>P3<#z$1 z(}EQv^Q)(}JRvlM?7jL%2PLscJk!^bRlvPY0o-eibFz7n4Fqp5@o5+xq!2L;I>_{v znvu_4ZR20QA>(`kXd1E|TUEg^;K4u-TDt@QO=|$qCkZ8DBYz-t!s<}Ld~BG6+s{t>h* z@W&f8T0kg6v0DJ6Wy=dfUKr$_;)dpG2tPEczC!i2a5`Tw(HgjUKQaxFs|NZqkl2OS zh2!E@>7Swnv>r^UFhw4Cf|1}X$c6uQ*i!QsY8N}*hxOO+G z&##ckr*RQnA8nyZcY4?ImIs%ckfSxMATv%g0RFTIryWr)6RcGE_W8ZA>&8&$!y87& zJ0K1P*5`XlFRBfd3NS}ujZiohYFml6lNF0opd+O0g%Iy7t=uAXBoOxPs&MKHvL>4i zk_{yH0L(Bw_z?82bt)#Tf$2^ZEWAN;qV!&E5?(negg>F`d&28MfE3MNIE@~r&;yW} z&xjY^@@8v^e$;7kOrwrSY>v_Hpbub#oCi{4$X@n`#A7-AxZ4#2hPBM)zFe~*?lJRs z%vUI5q@@f;-=2R$=9nU>hm-X^1K#A!udR#bU|vswW=X2E#Uu_c^>~LBo4hbvSYdjZ zwuK@S&>ZNAo>Tb)Oc3bfJchth2`pAZ058u7s%t&hanP>=mIvT9efCV&DF=N6bI8nl z0wqGr*IP;f<=HmR7Z|I&rT1f=k`HEn-XE9(;JXlpAyIkd1EfOhB126#ml8t(4ca&z^w`VCEfIcco6t;SOaZKAW zlV+J4K=Gb$jhA%iHgd4@ioZW|;D?M8SefR8XONP4>R`+h-&I z#9U>TQmN9HVmHc9(2{I^xmx;d3bU=GpUT^SU7c^`yQcON-` zf#q^@<#s!h0Afc0>*h7gy8*b@IPsc=s3uZtSziXMz{dN!#yPMe{(|8!524Qn??r2$ z4lX5DuB8MVGvmlQ6uY_p3;oi~hqgk+r;2!ue$iV#B>oq+<2}|04~87hQW}8bLe&bC z6`Z!~gkiyZx*Gqyi{epauF`K~BLOyEpe2NYmH=>L9eO*H(8~NAs3$#j^9AT&@|e6$ z0p>IX(Wv?r2Tpf*z??^)^(d%r|D(6yoxrA0=~?h`ulWMk4Um8E{jBmH|I(f9LGNF` ze9FT>P@jBTWgnP2k%Fe|O_}f2MhD=HArMK8ku$udTG8Yf4rZX$26q}Kzn?XD!iPrG zWIsRIcroPd#k5i|iy}`ynMIY)j+$o-Fgi-y!+2Qrp6;g5qVjVSs3Ws&1!tTBF5Q~g zVx~49-|cZ0DBS5!ab>Vd4Yb&^&l+aq>XC*4B2`yGzTU_L^L1_%k*fKWM1oL2BHjUB z?d#RCcF<)6oDCO1NKS9Es#b_Dc>kj400>DWM8I*XT0HW#78^&fp8g&TV#DWJqKdc- zbSVR;w*?R5JpIsGDX6kz$d-6gY@@64-5Fgu9pqCgynzRv+bh}>v(ZL=tY8GKJ$v_V z&ZnzHv5?FFA3!ysi5tuYB)k$?n3V^SR)Hz`m?n_H(25QuNkf`A*2a;}mK@>dD$iOa z;h{g+b&O}CUXqtSaR8m|I0CPsyhmqjTqGZT&YQD#AdK&M_#yuS9aXQs=D?isq2?WC zHHxZ*v>c17qOw7K$4Bn>-m~6{8pvnTSF8RI`eijfvZPx5q198%YHQx08PkgB4|>@W z^RemxGdihF*=I`d^Rtoao7D??N~vPQCYNJxV!9>HzMt^kX8WEb;$tA=ch7fJEzyxo z<&)C*2XFEk!1n^8;7QGW`QN}!{z<2+szcl z0u*yS*sPoTT?^E&9#({8&bSRdK**4qI}@&)#cRk9C$zBg5(Z185C?&R)e5Q3>d~YS z9ykqa|EV<0PM{XuUg4U~q9~k$zF-VBOVP5kZsN4%{hm z_4rpxDL=J-Y7ppjBlV_6_c54!%17RpKWO{74}VCym6Z=2sWCnw^1t~nV8#D^oOoD? zMs|reIr|ZsIHR=knYVj}2DfmfE%eK#=H8U@A#C3GD1SPeuMp}nmpjNjbnbRjtVqAk zUcSNTm&F*Z{i_{0?Tl@g-W)yxr(gPH8iucSuJzQupjqdCOkg#$Vz0~hlI(jt=B2Qr zZav*+L_T`GAEWTo(2YFsu8s>7To%@FcgAhKh~O7~EnO(>#8sL7%1*JQTHz@MokasB zdC|ken5B%nesUTNSu)>pN)C?q7(}{fZhe+=^S!~r`(=m{R#!p!^y6PJNyEUV?t>%c z0y7W3@*sU({Kx>Nn^KGkSBD+%tSf*2d~V@Txk@G`T}wTIr_l9~yv%+sYu+F^WEYQe ziZ|+ARfrFq^gz9tc*SW(@C#=l&5&Y9LZM_|4Yfk#)WD3+n9st!_f>M8WkJPz9NwSL zEVML(h)wNe{ez#ADmn&t@vJVD00<;ybJnxtPtLI`m}i7(Llp~!ix2#`zNt2Sgxd%0 z%2M1cy4?y3iHAXk>MsLrE^#e9%g$#wO=`Y1n~WSux?WLbR?BY1=sAD$yia@f*Y&&a z%XAryhbaZp>t2lLij4O^^k)6?B^_5;erMH-zIp`@FND!5eK4$UR-j~yemHD<9G=4E zBuw?%$k}`gSI*i*j?CZ0*RtpGmAmiDp>Lv@0YX&p>jFx5fTb#O>uLy7-vY@f?Qum4 zVO@vCb$-|6BQCJRR$*bO{7g;3o=P^IlZF)j)s2Ns%}qngS;eTnkTjsJz1iM~eM@-B zKHrQt9>Y;emakUdO`A2%iiT-T$ybt@O|LtkIK@)2V6^%NgkZz)?g8z8j_jzBA3iRQ~XwYmk%>6 zHpu>pAT4`Iy@Qu~{7&IBl}S05fG>hdhn79d1^CzOIj}@$BIwBX4Yd!Wj~($lJ+19{ z^J);9+Z3Wpwqbp zZBX@nX5}uNhtrrg0@jhtq1J}gz}PjKXib~jTIa7RpTivCZMKa#f;-oea5LhWfXx~X z@I14vuB@#W3~JblQ}TBl#I>BwP+}?lgdgO@-;p8e;0b&wYQtbG*$8VRi9eX3@FQ z*Qk7GbwNxoXYyud&5zwjpLoiu&Qma}oFP<{eI|K-z;c+NG`b7;C~eDXMWYnutcI2P z4gvrB33Df(_A{o(X*Waf9GG$yH65G8&h6!QKWqKOt?+Z*Qf4~*N8FJaCB)PP9(h4; zjAGk2l|<(bKHR)=m$q`kea43t#0vuhdm-OnF#k}oZv+mt6kE6TDlR(V{`5)Vaws8G z6nwEqE3A1_M#WDVs(HZN1T)wk3BR1znQ`!(7cy%=_$%-*)(X=a>NWwlBP|4|FfnowpKF!2U`?bQ>In9_Dl?Xyi(a$qvQDbj@ zbvWeY8Dke>SDCpeBD*+jxuNso9!5~_;yNtmJQQYec5|LOExK+5HJm(ev_GF10vD9@ zTmJq>?X#&VSpKXTn6j$|g+U%lKWI9r@aH}|*icBin=pTVt8K7phF*XQ#4TOe@wgT9 z5ZPz(_Z_G=T`t5Ltn}!doP!V-t-{PAQBj;w0R2;B1;OSg^dMFf?&&Lnfi5!mNb(Slv$r)AaUUS zl%~~hM=(2@O^1an6ljT7%+R2R2c9|m3=!%3^aj4Ig T1xI(YU-c;Baoyhrz|1}LXjNUq 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%0D-K#WbPtw2NWC&#TkF zpII503f70wCot)s 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 z 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

ASsm~XJPzDj%d88jnc^Z~PRy$^Y-Ii|x`k}iE0 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�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 z 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%0D{Hz9;TzQOXdlLkD2)Lf@}Fd2{6@j}1E* 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

>Jv_H%;zbbbyU_zR?x=h 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 PxB#4#l~qbvn)LqwYe)-* literal 0 HcmV?d00001 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000000..84ffa0cd3b --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +exclude_patterns = ['/tests'] \ No newline at end of file diff --git a/docs/images/ContractDesign.png b/docs/images/ContractDesign.png new file mode 100644 index 0000000000000000000000000000000000000000..be6a566b58b43083e01dbbeee49f6ac1d7f6a753 GIT binary patch literal 816382 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

o5{+xWR0)|v^bK2u-hdP=q` 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

y92!}blpz`8MvKBG>4#de&!@dctbN6@ zH=z!*hC$leSJluf&=!=vi;9oCa+yrMW@!Y4l~j5-ultes%hQb-l|=Rp&>ckC$RWF_ ziH%Ue<)gY>(7>98+!w|Sh0Db z>Y5+LQi-ELt9k82Bz!J-oQs3}z}8mSRKJ-I)u+=9)+08DDwt|7$hZBWn zfuffRzYdq=8lP?5{98iaX`tasIRNZHV@D3Z^m@(XcOO5IhFka|Lxx@g{_Q<9poR6> z3W$pU+0d8E@MlB8!a2I(xpYG4rMmu-n%_C3e@ln86W~UZ4eVMjE`a>D*EwB^8Ta=h z$g$Zh^M}Ky2=I*uoVguJm#<3~Xn1W6MU3QmuC$Mvi%h@0Z!o%joI*{VH_Sg@DqsG1 zsLmVTm|9KkIyXWe8HxHMe34rEwb@%P_A&6`Ioi}k;0F9GZv+dm%+^;kdL2-F=8<#s zlsdZ~0m$SfwCB)T1|!UYrI(lto; z*h}Uw)*Fg`gosq+QbJmqyL>W*(9qTt7Hf!BACYm*B9f=>Tn#(N=brr8J(PT0fxOKg z=|E2!$@s5lWSIl$A&%{YE?Y!_-skY%zWTdQq#r1zbc1pX8ezPZc3m4bW2sE}`5nNlS1xno|J_I&k#=;Z zKRQIEB03OKsN=6~3cP6!>L1WvURD3%G-WI* zKZ~7WR>wP(eac(M@!!bibD?yJ8=C7M!5Hzgr22u~^D3+Hot0EcB43z;P+(kG=SVs8 zVwNk&;5zEE<71&b4f-_S+mzetT&9C}4@J6j`J+?QjXB`STMBZT#Xw$%qkxlmZ|t^| z_d;-Ko(fkAa?^;VbO-(ragW83{}Q0<^@XU19m;mIQI7J+oCb~8#kaR3jMjVOArP)1 z+nTnly*e1(2wTcy|5^O*UROWhUXn)Dvtr>f-3Sy|Njg4dAq?|2WfY#kr6Xm9Hb1yw ze2S4r>pxw2#a?Ch!G?J+N~bp>Kn1S)rOXpoci%%PXyEF>H?DXwpAGfMB-P<>cSy@& z=x#Q40UkQaj4QFL8DDl(6-|lkhB|wPhDha*!-|p-OaOM#nB}5ET&j*5)s8cTp!bzm z;LDhv&u_x!rnbwt{x!|24@ z0}g+d3v!4jFrs&0%d{vaW9tMgwMLpKw7z}cdBb*m`Ex&seSMMor|D;gnVU_3f#jt-eFiYdVHjt)u!OTHeWUh6Xd2-WvO7Z*6tjY0O&dTT+6@b z1K|ion^l|25ycm&BZ+?y4`i}A8RGHzIKOW>M9~(H^P3+kkN3T>Gy}<*8=zrlInZ>V zQnmQ35}&W{^@r1b27_MFcQ5u719v8u{FN?mwxKxd`yJ||O5(>a*word;Nalp>J_TZ zR@(#9*w?v4a9R&)WlD2w0hHvgUj%cXpP!{eS~jgClO~ZH0EtIxFux2^rbWf8zg^gl zZw?%v`hAWK+pEj#KYkKk@o+*8{sR)Vwbs)j5AQjQ#TN~FZ>6r?8~{a^GxAxSu{fBO zn$`(b2oIi-Az4(PtEK1Z^IHB;t5;F_=5O8vI*N<#O5xRVt`xLm39Z$cAEP`L%p-cg z5c)WIB zzXrD`tmO6vaD5B3!EXB#EVF^J46k}qD2FpVVUgl6f%NO;l}0VHG>#&m1W|$(#`_CX zKKLQV;CjB`y^0HTkn5rqd5&h?nZ6`Q)r@DjjNMySB~O=-Mk8TBB*Q(utRm3)phzaK z%bgeMSU8TiuLHOK9w_A>J$}>~S7`~C;Tf0QpLM79@4p=Xsxk4R<{QQ7uIo!DPExE9 z4wGyx@dTdsivxQeubVeYzZGahdV9a4;$}_v_7d;-SK|W^x1gQg`b0b906EwSr|v6# z*khqB2A)(Yo&y)`^qUnH2506^E!Nc01DJy?XK1l>J#ji z&aR6C<+TLS7(ZX(Th0Pea`8=d;@Ark*FWFXdk)NH(`KLf2;!=20~p2Xh}Tt#B_}OA zqZ`*Ok&LzPzBv=GC^y`>jX%^(o#xNx)}H7}zU^ibqaMbB(u_8`?f9YTg3PLrbfo{Z zBl&=hY#?MGq)g5E`gGFh?02bOWLl@y3iGVLtcb%c*kC5FzF+v%Re%eh%AV|)&-?x4 zR-J?%@GydOOYKRaY{6_^R;Zc49FQ1m`F+Gr_j53eDTT`^gwhMZYh~i{`$0RLSw7#j ze^et&d}p6KngT~}(=TnILd-8y87``&C|4ftV|}%}8=>`9RgtBd!#-sc^im*y>ySnX z1+~w9bT0XTbg4{}x1x)m-{V*M=Jn_%Ul#E9hz+kr@Gl=$pDvwGT2b@Qi{{AB_7Jk+ zv43D|V>z+h7!)Pgc<^tOZymW`l7@Bv*ueLBvl}I%>7=S4PFq!ies|ta8?5ZSYNy+1 zho@SM*^R{=82S!`j_*sGEPS<1^tbx`Ef$=NjqbZ7oZ^M43a+5%cHGZ2K7UiNA7JIs z1YKdrfiyV6IP+21e3TrF+oJQA7YOTq2EcV-ro*?+3h@2EJzO*BKrDz3T2inv`(;R9 zFT47^Os#p#@I5?kn_V|-R;reHmmN}ut{#D=5$ju5+C$k}bpjUBtnPKMj_r}O^&*~3 zwSI7S5bHA4(y{s)e~;+sS)CNU!>k+$ zLT%q~k97E~qef9;u`Z{&$MS@G{UpoLAxLUMb@Tr`^sM{dy$?ZxNmzrvm4|YxJ z%#WeP0VU1nT=qcU!sZ(2p=@Xl33tgFF3e4F8=>yyb@tPfO4R&x`+$ z(7Fbi?~L$Ufx4NK(iQhT$}nf4TLhkLEXo@NR=mzicDvs;EXxTj(tihlF=O~2J-;kA z?~DpuzF6UAXyt2lBMal2=`BK)&5wB)M9Q57e@Oq6pNe9&Ks0wQcH(2oNU&x5w!$+c zP$96W7x9*P$)V$Y-Lo8vaEMZjmn~>!$eOfjTft{wR?wpV6NA0gIzaaOZUoxW+r(@W z_=?1rnqey`A}vr#D@|&$X+y@*{dXo}JAu2bujk(?p2)&%FYnoVU0IqwsSR!3#R|?J zkDR2*-mLlD?nA_Ddq)4<;OLsRuVVRzy~*VcUsn1%TK*ial;P~I%X%ln)@?-gpZK^7 z5FdvHF5>vrK)k)C!DKRsE7Znohz8|`X;stlLSGO8vTF=C-cO={+_QzrpmDDU<4 z$#G`GUaw7c|HtRv>{h9^hzP7|4L9vpJKWq)s4kC2fiyD1dyy!_u&A6lT#I#jQb1IJ z>#S)}R=Z!=5`Nn@A-As2(cTG*3jbUQCW2Woq=ICbH)G#sKT}Kbo9NkRUbU(M>^Z!53 zJMSFMeP7r2`$>k6*(u^T9#apYdofVrSgoLXutlaG7nZMis;uj;E?r6YbMpM6N~5y- zFLOMOyw;uj=zV6h+ICBC8~ z?LW9`6G!Sd0>s`g$OVyGjT{zO??B?UI9C};ido9RWfLN!?%a$1^Zc*~=Oh?r1YhQy z9X>LecBEyPdo#*X|6%d#Vo=xLdnR|XVc<@Z*e+X%jBKR(@@YyB*Z8QW`r>8-H}EGD zMIzkHyG}k&g_;!}M0Ow7S@aSSzn>q%Uzr&#H)m$AHXDnMT>9FOgc{0&e1gymu;Hjd zuoXfYx2qvVSDZopLe6G_l3%ULT)5YWcix4Q^&?Q*_J@W~BBvHyZa)p*83-&Dc`W(& z(6!lT{u~Li#*p3584Wwj--|{_5^|L>6_CscE4=2hXJca!c^INO2Df+`Qyx)F$;b(C zV(=eHZ?`JrEdp0-U4Dp(m$qprjV5SyvqMv4_Di(xY-s}8Ly1 z@|b;A(aZxvn*gXvyyMl4bjP3{m4!$}N0(RAQ~$M8X1y~Uvq91X4HQG; zG@YJ^4sJ^db!c*1Uz=%H_YO0_u}HD7T)zN!@j3voBJ;PD?tl@1Sujbsq0HS$ENcHl zrr0RtXj&YPR`(h~dM>-FFePcsXwEPS`^hu}fEtF_QO`)n! zU8{-$VYYsIZDNCP`HSx_M9xi!hH9&!*NqzzyPpL-8UXrkC6&5i&Ry2RUUt&HB_}f|>17%5hBEWPgRHqF+tBWf1@VEeEbyrmjWDKJ1=V>DKioCiHS z*HQ=F;*J+*v3xQ2sQ?|-|FDE7_3 zw-K9FIp|5;VY-M_x(?E|?&o`XMh?e=fZa|L*!RC#07^X&KK<&Vqb8;0lCK5$jfUeL z3Wo449AoKxX(j#+jcfzP<>=bBLsc$6tz_8)o8-OMbYt!iZ2NE7{wfV_&fvfwA{ocp zU>K7uxR|+Hw>y4dQD{Z%?KA}=r8hncjI8?0wk}pIItvprKqvVbDR^Vy+{9iJW8b){ z4hM>MAdB^b{@O}h)87_LZo@r9!;P24ye=J^vJWk51xp-%UVac^Y>S3eVWY z)P)atg1V)UAV>C5qo@$0tV-Pu^$Xe3cl-3!exY6SU%n@%7tp~S|0VQW*(OGs+jhDh=E{sHTe-x zMrui?EEtzIcJN(Y#p=Q143)EC0fO+i^*WT=%JfV<1>B@D06vXLQ7$LP2JwP=4Yo-@pI5`D3ZWIv*uQQ!uCNnO>N8|mCJkH*Mfv|_U&nlEDb!s~k6{h<)QK_70THWt` zlt3K-5&hFmo*2V%FNn`7{P5wB_C?H8`a zM0bI1-;1Hej2iP1)_z2v*Tm{KcXyL|Pt@_>1|*{8_93PvIB}P#?T;VB6po@&xr%k` zt-Eh2Hs=90zIvEM;#9Xpz4&HipQN9!J()>4dmNy1QLCJQmRJ@bgl>-mRpc~on?J!mSVDJoDXs?ProO3NjrA;`Cc_$VY9+o|mT_Em**exX(? zB0g2e!2>tiDj+csBoX%Ud}eKZpZ)see)jz~2&)86^HXwmt|cKp_h(1O_BOltw7>dT zu)J>r#Br0$n~Nc)TR)$%Bb;W8Iq*Ox+2*OL_2+g=y>cu@N25u!-cnwVr$o!5bt}8$ z+GQgutjkt)%nG+Cv9-hV@l&g_r<(!Jp_$!Bd=Ux)|9r2)v-N>Y34!{1v+JX=kRFC1 z=s6LYXuDU!Ic0$s4kmU2xIZ{3Ul=rF&Y@-WDXT(h;7;0}4x%dA0C(8pm9Y%Lg+b~o zsg`oEFlRc>uLuU{T}R}aOB!?ONox|RTj$;l>xBt~``#3R&;8UZ77;fE*4C!j7+8l#@aXv;MRqn)kX(ScRO>zoW^Hn?Eyu7I5(=zjxb>(ZV%dgC)#fR0fhgb!4&3rJ zEWW#7hR94;4|&Z~^1^k%&NysF7??lyeL$*OXE@OvW0(@0^q=Ch^`kWKD<(kDi63H0 zCnl251wvs8>+;i<`<$D%peUmy-qk-04a@(c;G1M_Axi7)(I5i7{B23r-q_h#rNQX! zC9&!(supSjQ}U%ST+R?SwQhpFXwRy^`=#Vu?fO#Q{t$nZ**7ir2p`=!46_1`Yv4Qj zn*Oc*5%)UpJ>69I3GG^RdfZ^-dwkkwTy0ctYFDnzT&q4!81$@;=k zT}GQ(bS~i@Ed2(me?60kHo76d)(2`5C^EY?-*w;FCEE1;QLJuPGBDmOu-1UlBJckr+UgkKs9xT;kGXhEL*7=^e~Uv|ujM%giKUt=3y<~1JjmLP&&LlOo&ylfcO zP|;;aW%>*d!3D@R@hD1l5Y*aQ42v`N&@p`LDk9G{Dzv!@8WAm4xGF0;1P$;T7sYHy zNv#dbkR-bhIP7l~MxpSUc~i0f+fZLDu3LZ)QP3m(9gJXZjl8y&twXP-DnCS%g=a=m zrqN?muO0M2nxJA5YWwD#U_Bh+Fn0f*M+G6jOX^~ckPBJHx5^6d18D_3By_K1v-&6V zlIF|v3YHGuw2O4$3=HVr0pW&oTc9(p8^&y~hpv-U#BIx*(D}QCPs=Q6^H?eseL+0M zJ(^M)iG6w-v;6f(o7Y&CJ-b0wgGu!T=4p%SD&aG(zTXVoz*v{7^BLb2T5rB{ zp=zRm2D7SK^RBvSr+%J9HzXvOl9j=?%$t?{0aws;DVBaE>EZ5@#qC>R-+{%if*`A= zJxx+?$jYx{sl-pK0&D0G-cvs6Hj^gp%kaAh;V7qsvF-Ah78W~WhZ~|+rR%No3oUOSROJGeD$l!H@D$mobdv#PWkN*G36I~^s$gpF4+5r}s*#F1(& z@Vtz)e>$*Y^iU-$b1g3#IwvNxJsxB6$)!Aehy-TobpMgRrU+cz@~>J7z0&o`U)(S*{P~ zr8{HEK7fh>qeL+u%ghC}Am7o|Z&v+7sSzD*`=d#%2Ck0!zxdtlF$sJ9aj}N1_k?~f z)hvHcl{C@e>+K}rKI-u)16FQz(%}nl%**&s{^{Y?syi5MEB$ql@cdWGs+rwYzn_4m zG9%v2t9T*LMkBlfn zjQ0ODJ8k0$n*+t=S+?hwzy>%;)(|N^qLzXnj1Ya;4bm^yt^f5(dK8C*na!x9t?xX~ zp-ivSunz4NjbxoICR`qMooO0BRnUr;C+@AWH?jp4elfZ_KGsxCJ*c}@$ z!LZ>^jcK{+3SfuX6*4Mq23m9E7!~TA`-YNT9`9Ty%q1bsBpo&*j}&T+Vf63NVPA%B zLNJIY!{P!QDDswl?=R2>t@_$KOnQ(fM)d?8CcS}2^p7i-N)E_%cU%gx*u({*V-2`B zfgR3&iS)`h@qhHXM5L+Q>T)`gcpiVezmAbhX4TB!=!+t6*h-y8m zkGDW!>cIhg3JE~4x;|dc`?02d$fZ|^IkK7h1}L=8@XmG4D?zRY&ZLGr%6pC@H~j3Zy(+75)F#aRM8CgRp5Pby}DxV zXghZ&&QpyLeWD(Lue>1rP`u4+ge=i?{3_N*`Jvm>bU?s|r3i4F+}$C%1r0QXr;64E z+~YUgS%%efNdmM~Y2H!_I$}8hX9vM#kL$BuCY2cr_YAS{Wt*a?d|1?|>Oc0|=~j*k zF3T-ehzf^xDFsMy-i|IkT#-XN>b;~9Q|c4vl}PIrH#BJw{@L8~e2bIAE?MCa&*8lT+@x6JxA-)>WcF$n^XAauR{S&oRM7x zVgb^pe*4ykK#k*={vZvuePKNWnEkHaGU~u~`IHXSF7juEDmzGceQ0>J=wTpkVn%h| z-+tLenAhUlT<`R0Owm!{`(k*BfxC7ed5nxx3%I8Y(y5gm20l?*KI5a?nA+mLOuBAL z9lZgr9}*LX)LHZGH>?cudwI*{t(2rt-KO2+$DeGEzwLY8mherL7q#P^WX(zGh4Sa4 zcYZ1e#Qd=!a;3D-3Q^2tvg+5LcDaMYXVT6`xH7y}V4(YCXm|Q<=+RW~khedoHFa3&Wqsm^OJAR@wceN6bm`KUbY**wJ?t|1&7UI$ zDa(Tn7eARyyDk_A^#FM+&@#d53HnriqL;Fkfbp$l`nOn% zF;k8LR1Q_ha>d^s-8_;~^WkSjEx+**e72@xz?az{UcaH68npuIU$t%8z}qo{ovROV z*3XV<*&WyqG03M25aG}h4=T@2e6{IP%1?=J5F5i@50hYi$Zoxk6dsW<`=DU^11Yuv z(BB+%4}w)jlLZ{Vxw1h)7YX(Z!5C$*Y9h$L7ICv*Bkaz`npSe3?4Maf51sybraMaD zV3#4ikL*CWUUc=bOR7SI!M@VeGqr9DWcW>^Cb16uO4XQ~uOExMsW=YTG16abjRyUW z)AzR*&8J@dF*c9pF~fsns_Pv}2$zL$IvrJmDT-a3x`^2}k|@qIVxCjS+tV89Tzhw; zuHPDwo?pcn(-w7(;r{osl}!xy@|iSR2*xp zy8xg5Xq85QbxV12i{$^Cbu)(p)i@WhPbWyp+x)b+wA~HFhm-y z-L&ZCfFoQc zA2q6ifVpT5+r1bhx7B>G%3=oMsPRXmIy5qJEhUG*w}`>t0Av^b3C1b}5V{uwuicJ+FfQG@&?#|>`Mcj1!vO~G**W$F>= zymKPXe?MJTeC)&)D|PhW?dPJr*q>q3-^cja4tU?-|6&~nx0B{Q%58UGmMi@8jpmV| zBtgJAeGIv;k)J6ECWfDe3p-52%-j^0zA#ZC;I6JeJ0FvXx|h!KXSpt5IRr;_5UQ*H zQV9UUzRY;V>HNKs4ePnYjeVfL{}QrXF7x<1!939cn=_?aQ`$4bBwn5~R#?rI2q0Mh z#oiPE+bho6v+c|j9@r^VX(|%}RU}nqz{SU5Lw7x=8L$h2b=Tt^CoiPEAj=nLgr6M>HAZo=B-NCkqZBD2}3sZz$thz~!R6|)njZDA(u>;$;R9H5>84(G@_ zkhwk231Xj1c!8e8HNV>4?t{q}qX;*;;QM00{SJeXwr1B<9aIS<6>r0>xas>Ev@UWk z0=I6veUsYJL@5Uhh1>mTbyhWfiGls^=aX0iT(e}BGH^!j{Dm3ZXI`uQq>=!7gTJ06cHp8yZLFj@<NL1|8aR+?*^>_ z1(O=mbRjl3akUoWwl+DHWcg&pFKn3G_TC;(eS-k@qizUDeEBO=m-(S)F?Qo;jbOcU zCImHziG&|-NJmmz7OQ!o5s63e)R(a4I~6O-9F78?OI~{5%PFG_VvFoqPnt_N5i3_K zRdo|_Q$8A2$_@9tw~s2`P4>06EX5HCr|KX=HDmSU_Vv|8PKH~7-S#NTH7w#`SAz+j zUY&jrYUIUXUt7tw8O?yx2N@FXUTq)@b29<8u#4UB{ZoPUzSe(V?a@6olYGsPH&bBD zbS#In`TT0>I~;g6>rh5~RsSo{BsjG|lvjFa*>*F&OmhIq(nC&R`sC@aIkgiuGd7}f z%#_}|lfsPP`;{%If*M|2t$+uGc`ak{L>-xM`NaFp#l7UUexfc>KFZ-jsjH`qc~kJ{ zynEDD?VDPGHCim=#^)i)Hv)E4wmktJ^J5G^IxvIGp+GaW&6e_reK+YyW+)T)FOT6^ zmes=A%LB18PS0KRI_^ZF}WyJ&}Oqb8D6%67qz9t#Wq-X-8vUHrlR5OQBZc7ZKN z3i}(Pa4@)9s>a?CC*gNTdxv{$)((j(*(iA&8${t-UoADC=dD(|_~d5YPm&)qj0r|) z3N!Uo!A<8O^Cj>ltp4{~%xl-~j=b5aV_GS8I{pVfYIGl128O|}?G2#CWKH{RXp$A~ zn3J~rG8PJ1-*l^Ncns-34v#j2w=S=+)~Z>cyH6b_2~1dDi}u&v{eMBmi$JVv=BX9g z25u4VTM!#_POpeN=G2acIam>^s=L0Dpp~Gc$RMn=gdCypU|xsdG@Gm}WY=POdGD2o z{EBgEml|dz?X)pR!+H%mlT`hAd14|yzgg-m(9DKm=}6rAdgW`;r(mjY$OH2&hoO5t zG>o*)fB&d=`uPs+0@I*U5>^_nnlGDU`fFvR62xEiG5k&7r?y{j3ct&)1=-PJd3+BJ zs42;;$YP|pg^Q&!Pt}$PwO!>2N7jC2f~Eb^d;vF;#}UrH6za8v42pojmUI+$a}f1$ zQ7}nzY|&AAJrDa)KWd|WnqA3vG+n2^`<81kjWU%&w@_y#Elp}zFU$AWCX8i7wi>@i zV2w!UM{X_OA*?xkS-l<(Qu+C(3_JnyFEp?+Ws@e`JcFA6Liu8&-OnvdS6y`A5+Jt! zLl(>khzHkE7wdH1bC?n)l(4f0@{rZ@Hkzz||KE1)Bq6)hbN` z>arew;&g2c7<`HCWE~5k1uB`ZqBn=iUjcij{g5ZVucyZJ-+PTPiB{LV-KnG-Qs5=u z-U(MQ-F*N%Mhq1HJ^WqPjuI%s$$K~ug&IPFIyP|J!8SiAB>Dxrl?4GL+Z#=qDF238 zFZiB5XOc~;BD|V3opz1AEyct_XpS|&kplFlpN3)F!r#Ijj7Xt9V;4Z@Iz}b->wSb| z(*{~6J1C7Bdo*LNo*1sGGqXRLsKRxgbfrSAD0c81WsI!JiA{y$f^Br$G!rfyXVzI% zA&FS5Zj3Z@ENHAfD!^@Pz@rkY4LlCH&t;2ihIqh9#gT~XLmx>}pB}G`;D$CkwBW}* z_>rT|{z0wW*am9V9sOm!bE}0OZcd%XhNg@s)sS@mOolA$4 zjLUVgnmGwk4FS3fxibEb2{}?8g7)H8rEgLNWWC(Ao>itwK#j_}b}Q2{_2hh@?pN{p zaIgN1p4w$@RLp%Hn@6EUryV%gHQdw#S2lx*7OKlHq*b!X%(?;tjanas9=Wd=b{hcF z&LNmZ(WrkF>pLu%uG2POU_IuQtG=`J+vy4gG#J^Im{2>8!IEgIaCy7g2EDD;StsGs z#5Mnj8Hf^M8DpYw=p`?dGg_V@+`AM0gOA^Jc{kUaBGY8{QT6jur#x~KPvckAL}Z5Ycxy|{PszQ2Hy=EUj(vM&OlEQ^;8yt`*@Y)H;X9d~UP#6Z(DvG*DVVJ-Vp%prW?HEN3#WT5~4L2xz1^D{>Oo zjlTggoz;vvwgea&h3u^}-dzlFLHg}FXd|l;VaH^upP^-4aDmM9T*_>n`*Xg!-WvhT zYPTq(6_-(kMVy%FbT5wM+xcSRM|AGPF1E4v!W7~6m7+xlPZ``52-nF&eE!dr$i*X4 z-DF6rYGr9We<*T3b1!(sWN8Nl1#JS7H737G8Or%b?XhZs7GQ9_=jg{S`w)iYM70qZ z+#}IE#ZcJk&!Sj6f8@Fjhk)?4a_aA=jBwZmEB?mD*y>Iyu?PDsMjOo;POE&+wthqu zjv+>v-LnIQvJkb24>XNT9q{royKadWOZL84Ohv5xvzF<4@DfQ7^*el;nZMvGM`h8;VwXm$ zL8)HA1x!JmPcbp$2-$14Zxbnzald;+-ZDfHs{t;BUV$gio72}bYgUc8pz3M0Xu5KV zRvy-I7RbT`rVFcm-CP{R6gY_`l_4ohq;(og1Xyn|pJPp#)P-Vb8_v|vAuiJR|G^3H z9_l%Bg_v)!O|?HShCUt=VQLvl{_y}Eo2dxcE!6ezuP>~V(M}dAD=Vb1^L)2|0*Z{f z_wXfl2~3*Cbc?=hqLt|v8~#L&p%P1%FM$eQ=E}xVF+d8uVzWBqNTrqMu?V?oDiRAI zQ@okJ7F7uO1yxMi7%EjLJwc$=6rSLs4$X1Woa(cr97`}v>51gYjvo4P%t7e%W%0ELY`*c^zYy`(YbAJJIckVoy zt)zbJ_r<){RF6tOe2DTUIbOYrUBqw2gGEkxeqZ3;rP>;MRzS&I^!6pGQbu@U1e{-uhDb7&vxjA|+Z ze?^4{4YXE%TU>s0duq@XIj}s0paM zqz>q=7nA}{aLarhcks&h_0_|*n{~kKY;5zr{f_b#ohDBSz~OX5BOyrZ4-Ci!Os}8M ziUuzplQ{i#T>1N2$ja;l7Ducbx2po{nNlA50h&7IGNQ|VE<&}rhOGhN76771)RMma zKX2!R#*55hmW^$ZfiRp3{g;KHS_fBy?C`X)-Fr~Id`5?0715~g!5xV>6T5q>tp73Q zVpPTJkOqR~`r&Vo`kDDY{L#Gd2)&AQsg(U1d~SBn!$xb`7ai+#P*IQ;ZP|E=s*-jJ zI52Ca0+n)|WnwnlhXyo7>>!bV@GPDg{Ce@Q7=J>@?LPQth1<~Cp$`YKJDZf5%n?Qd zdQ4QSN;~b|ALv4|m^|*193b>3`$`HP5EE+Gct*%-J007pw?*giXy2Tt?As_ARUgW()8w)F6dBiv6PQv^C?SQ$7d*o zH5Z)sDV`bIj$A!JK5jwbM`v1(e@s+S(eX?TE{(N9d{Eb5IzG;nf{}kB`*|zD&-TO9 zma{)}i7xF}kox6jYCmP;qso|nDu9}LNfsNhKo&0SS$!R@1MKq?U)@-#`nYgy*Hh6B zNx|m^GgB?8sWX?SUgrVUpM>(2@D7ZnP++4UIEI_j52dM}O%M13r|iJElRRYC!grPw zp-^eEnSSd09dYUrY_*_zLjP6jvf&CJgw*<6XciMz`3_-oZ6NP)MHw0OqnJ*Tl z6wVU?N{&O-fjhnX_EkmC0%!}BhH&kODjA_dz(~6x_Z%7dd@USfR^CRRIQcx;1nfoD zSV_{Fk4y-@D*rRu1*U3nX}5!eRhWKzWdvqE1HvHID=>EyK~cV>(IGuG!k~V*K*Ki6 zcwrs)c5-D;9N9VSLrDsK;AFa|YkkBvgX$fymXtGPf+=qXpnwJ4+C9Rq3AWPa8ugc# zy&MZP1QG*W`0oIJ#ndruS@Srcz=sPI9&HWx>K0YRx97D8GiZkBNVmsykR)^l7o1Su zr&4Lp9gRL<)5qhDVH8)UQ{`%Uaz9l?gvXu% zbL4HG4<@hC1YH~w8Q zya=JcXa$6d{rXaA)o*Kkqaq9=Gs9(zhbwFM1dAO#wDW6_a;E|+WJ_Hs5eIe zMY3N1P`urDX*iz`H^{FA06JOB!TvmSu_Dzr`oVHxixelUPc-w-XHky!wJ4LfF`>kH zpHU(IP%LgyK0UDqKzSsvjpVT%FFNC-vd1CyA~(9r8#bZLlWh_OLptxvP_C6*9=2T! zTLt^x?H2#j!Y_}-p__(&JvJc$!n?tcYq<&%&oE~$?Rl%5}^j}gL{?~-A zDWJgmN|8V%BYM{t$G+5j!=3359tuJ_5Wk?BKrd&j;SxS{y8_ik2`!A};X~T_<9u!S znaOPwQz4jOp~j^GIKk%UKV1JM$v=-dSKekG7=aPHQ_WhJG zCO)|w*GqbY5p@8v)S`Ux-p2jt7^e@V3_^$YgCcSVt`T8w<^x;VGqq|KR1Qm?OK4-e z>O5~ARq0wum_}DF8xD$1MS5SUlpu(Zcltg@-1lf46B`AI6-iuYnPNVbBA6*!8bVm# zkVM}MaUT^gaupMZ=&@Dr@A{^c4!qBR{$#fX~ZNck}A>JL7|QvRk&l{11)T78cTqzMDwkHu@&@L`N9z@?RFk(hdz8 z%R+Qapt`o{0g?d=cAtXf3#2h|F@h;ErcA`l23J{ZF;Q^?V! z_5-4JsoOi0f&tMLw zaGKrpAcTn2;G28FD(H)>mf4dNdjk01N;`SQw#ieOp;;Jy`uvO{a*9m64*V@QrvZ_t zz8*>I5&$K>RzkGp*H=$;?FRV46#qS4EjnybzmnXX=b2eZyW06t7oKaTa9UKq{a(ET zmriD!k*X(_Czw>zF32XxsbcM))pbw%3|??+!15peZSe|hg;%A*aWzz`Rc`ok40J9O z*2(|aIXK=fmUJ!16S7T~IoR)|41F$Q0~Vb+g!}7K_Xt;hZ4odO^v3vUvOu9*gV@*) z3@BgM2omlK;B(c0aVK|5k&4g>i59&KSja@$FaNzV)@$TYX3<>o=pXVn*s*%_Ap18! z92?FjCJR#=9+(&`=!|+ySrXlWDM$kbTNa%{(P{I+x2Ct+w?!66US55tNWKN)Q!M_z zJs3=k-#rjs9T#w%?=>u%vrf6P7YwSYW`tmmkxA|d{vp`AWU|YR?!)4uEqUW*D5j`f znVmqCKBA3QUC*ddA7f1eGqnIZ* zN_GE_V{+PZ!QP2QeFB*Q*`PN&B5QBqIGI+hB=bWtPtV4_qm=K3R(8S0$W-fAk^n}Z zim&1G;d8uOjE%B;tS!;J|C%qM_u~hE1!HJxIwqTfd2r?b`5e3-v-Zus{+ETV?YuaZNH@-q#MrXiX zoCJXqpQ#A&+%XR_4!@l9Ib?)`J>2dZp)E7GfN_k|&Oj3QR`M&2!~s;9BUb-KTa#Dt zvc{&QY6!@)zOo}wc@{8Jt|D6X*4jELqC@|s!Kn?@V3}>KAM))z6u;NgA6Kvcz9NF z``~M4f_@4d#LWH(JqbE<5d?6?ZVRIa=A8L`+C6(mQ6xot4sSPw47~A#)MVZV)tfof z7m4#bpYCk_%%eV%tVh8tEX_VaZcj&Y-5uzB=xAB~eNasn35_9(AOg%{*~m2t#@e*B z&;`KpItg*Oq!PC!0pfUuzTi)*Xai;PmT;|~SaH8YbqkartURuFfZzdbH1VE9Ca8x^ zQvNa~;$iHEL{a2n&0>~;{*1&Hi`gEBje4aL=^HZfI_v92_%bp7b$CUKfthcJOI$oN zqJ@z-oUo^JoFfZGBA#GiGGx-e-x|bUA4SvB5JMGiYO%iVslS39E%I4h*=|-?jAi5M zJDwpWFnpX()2XlVy0j)6ejLCPtr#L>(VE~|FG07PF`AtJStIQ!3J0N>tlARCa6hUz zBq>Fbe#0#!;l3hTT4DM^XBj;UTdRM}klY?h{^{wg=wBuCdY?!A-sv5f2@OLV<0!q+ zQmWFZQy?4Jn19KEM`@!Vg3AbA;^t+JNd)GYIdx$7T2NQg(SC&8IpCwTjD`D1;f(+-dWRZ8cEy2)7Mz<8^c@(=5m%BE4TNm|L0 z?}&QK&50TIU^w{@K&mjI>5 zUyFZ%N=VL3xk(HBHO`b1BZ;4~J8|R7rUCv&W|d1x*0K65Lk~ko;=&H$;IoS>?gy24 zz?nCs-@r*|$0NDr`TQ3t%RubIE~@)#TJN@Jy&T-4^ z=-WgyUQ2c7A|E@KP(TVgXMAbkWZ*}$jGnxaZTqF$8q^4(Qp2nxb1mB z0J~OaF>4^l;_u71Ob!@7=j_?dc*DZyL#SA52&fqdP|ZdWVF2px<+(6!C4G5TdG z6fY@r0NG!Hnx|rI8?KVvB4pDhGgz*vb4dVL`qnFt4W&-n+JA=);6zKKMt`o}WFk7a zVUntuPP!j(OX@I2G9}Z@>1xLpLEVw0A4!YSC%xjjpYk~Sj(vLey_0F;gP#eAi;CtS zj|V1J=A=2%HLkHeVujSGbva2tSNG)^!BM-j3q~W|sjOFYWkp}98nFBKJ_{XBg}DcN zPo6JW@gUP3i5Y2`l{vZ%cA4s1)1P0nU~kNS&i9mv#FvQwnE3oZIYs#ZiApy$^Ud{T zOQ=JKR!K$Fi_+=4#C;2_FPOW;Q&V6vWBQbue}+VW6vJ7&`PbX6PYoVB58R>Ns>*u* zWU2A3Wc$s-5&G#q&2yYpG2B$jP>TK_W6CVmJvX1HGEf%T`w(z9J0!=@j9oE^#Wndj zpmOvyY*=^K6!se@Z1f6~fS==g0LTvbcT9zFiMgcubixJo)zTNtQ%0fxeuZM-`w)t) z@5xwriVO{D$v2xTb-5x)ipY}3_2v{OG)|pUc~tAP6ee31`th+DFv*omTtW=nF=#A8 zQzom$HAvon8W^Yja__Hf*(*WZCu}S)#3kGx%hIqZ)Ju;<>)o#wf$&##W95y+M2GCk zNisc*g>+OQPJ>|&(BQ_aeegY!f1t&`h|i#OX6 z&136-8zsSY6x(5_W#};N1|W~B4dFvA&MsWeiz`XBqr~BhU@sO6c8rSpd7yyC?C^mk z?Dag+o7f3OWupSi>OTYH7X)ruuoR=DH9!HAZnNH#oDn}8B#H#U{4 z_1aJad&;2D)r}q{TSu<490a#smcd~5PS@i!wuwsx)fo1UG>gSBGi`(Hxc%#mpQLXf z0Oau8kSjOFm7cFtiE`)h!qImA`#sQv;fpT0eaYmYs2?9g>e0vV=>xxoF(SexWXCHY z#PiY9LtTRvsKZ4|!=R}LvQErr?cPPf!>7-72kxJ<92E6y7X8Ik@;+@hQOuDr7M(Zk z`apX6Y;+WfiaMYE?;DD*=kw`M-BmBbI>dTUXlpoL7`OSnss99v9Kp25wBy<6?v8v4 z9A_>cFL~VuZ^~$>bLA`tmusEt&0qMzzmFr$?j^QTHFWk=1CX zIRfwA$RPB~k|*s%kKKdLzVsD@Req3o=dU=nDPoxZ`@2B3C0qa6of>?=x%I7TL^Z}Y z?qfO8H@F_=zIXp-v`50YR-<p-G8Sg&hmOWnV;S+A|tpSli#i*^h724IbO$U@)Pr$@mSsi7+*&p+v{Us=9 z*rVl=gs6~0L)yHY6iV5@mWdaS3rP42+0Q~xHW(Bvms?z0Vw=rKL+=wQ&HtnsXMhG^9*2Q8Sg)wEjgPdR&hTRE$zhd18XPauV(c0(b45K{3KvtK z3CZ<>9yN9P*ATtR79SzP=cRTLEKknS@E8 z5YCd$0j%6+=54L{h&6JVQHPJt?$dtq`jJDEp$IqM+WPwIp--7YJR@5j)JyH;0EHI6ZS@h+aoP~QG z33Tjhf9_lvA@~PtP|uq0dCK>5Q$d@4o`;qIn`i-+xyZZkpm7|UD&aMFOp-duNBe-m z2Mndae5+41%0A}jKwg(Y2=O=|VEm=JN=hJMWgR*A_yG+X3u%DE&^#7Q)JNCiaYnt| zVL5vAMKEIRt|mvB&ihi1%+sW8$P(!nj;jXR>_;3yU)yCk6pr>&Et#^695Bwq^Ya;7 znrjTLIMV66O#5JUjyx)mw>6=c$JJW-nCQ3g@H;Q)0LX44fnQbhw06xYLBR6=DF)=Y z!7fYQgYAymjyY|B{y>jquH@ap?M-+Bj#bl|6&AGEDhx8SS8L`T!rSoX%K|mu(VB|& zx*Q@v_KvHYWMdV{nE|6vYM10qbiTvUih6%u8u1@M(vE_hfKG#+;~?VK0VPN)xWUiu zJX6lF9ZSft=ay{!{-GLTvntwAo;t&hHCr^5uGjAu^0e7=JOe`n&A72)O1RNIpDz;c zopAQK;Dm@c6sp$$o@}qIgS(z?z*XGk4C;A}2Duhzx@_%BPUN_&(${X(nSaH!!qnBtT->^z9kbndVVF7j+H#@acJSs_Ac8w0UzpQ3 z?8fEXOXsOgtrHgVpwK2iV$wg}qvO>AqNX}mVLW4r*tx!tH5d zBIOPhKo73i>cRVFz>aK_i$c@#z11Ndl6|%*G#*&dw~HGTxaqmziPY3n{Yy|^hKKTT z&8sdl+A(5 ziVL3I#Qkb%57V3kHjUs3I-1QmWUO&F6LgTgevPKUB^8{H`CaRU@V0Hh>ibgx`u-K$ydyEflt^Qwsx4i^IJI80Lj8HBi8%2 z#!NjaK-?~g)j+rD?j^MDY1?XgW+F06YOMC2?hCzg?Mk2l+$H=gPKtNeN6QMn_g4jh zNLUWmzs{A?gyJLdk4;n(caJMr|JPoK=Y|h4LtE1;k*hkk;3EfUy2zad+a& z@}z|8!3E2P#(;bA9b(_|+TggwZ5w>t&OM=@7jk*p&0gyIwdCVV_& zX@&Kj9a&cr7m88OQf^z)m+d;LrEbd)Rdy_vQW#N-zx3*Pu%doB zBUozpzOER@a)^BvcFNb-X>et1V(YQu%MTz1q4OT&DjKI;^y@P_&=* z;Tb>9W7?-!cr2@Wczff6#D9@G5>goH@DN3e48%e!sj z+RY?H3LGtMNT(O>XP^wA;JMbFXzeq-9zh3ADk3T#yX5#9@C%MdIjgELqBxJSG1!lf zYnnt5nY7^%!w~V77=CwnvtHyE70Kcyyhd~F#91gQEmhLcvM_%Vzg%0FhNGiiyJL_~ z`u)oT02>M%HwW-R=0JW}%vLAX?X$o)5l4CZ`PTMfkKkawJ+!pA>HV-L!~{r z)`12le}|`sA^)EyqgDCe=jQXr^yM=-Gn^t$4DG2`5-N`L?9{|REMVq$mm`x*b{7y_ zs_0=tzc<}*N&T1@t@!>fY<^oCttm$!-A!elV7L$9y=z+oM%!gj_{et^X2L26fSgn5 zP{n7Po%htfqs9yu@2KB(`i@~k<(B__9!>95femrkdck3Qho8<|6{6EPZv5CJK+c)3 zJ3n690;V3-Env{txRSa78|mN6dWHtfn}krhtT#l0*zeZ$ivPgOa?>FX@HrT`=Jq zU{TtKmY8dll59goy#Orz+w@2RdB@PK(+v$GYV^}y#=aFYEr|1L%+5cp0}=7*S7<8y znv6lra^@zZeE;p;lmM0Yw0#Y@mviLQalg&1*KAG5J1zH4L2u`~dEXzHskh=mteX8l_vLQxQGctV#=4gCQ%S zS+u2AFvBKW+co#E&=dKL>R`C=zko1BGt&B0cuRtAsWfdTBO|=~PZp>e#@=FGxIL`C z^l<>{@55lHG;zWP#R8Pc0#rvu(!s_a+x>6Udsoy+RMsD>PG^W;4?s(KR;GT|x*>lf z%pp+?u7+YYD*x_OSZqWwlHn@;)s8cl!JOW7;){F2?~t}AcmdubB~+Gc>k8tnh{9kh z?jv}d`nl`4a(Bat&b2jst2nmpbBE&c$w*ZO85(l%H5E%br(ZxQ#DGA^|L%Q1=G9lO za&RSa=L{r4h$m%$PakX0 z|KbWY?Zdz|xA!fL_s?v>E(7aj`30jDLd#jxfQ^yY*{r3RMEInW%R1S7E%#$!&HmNT zMQ}uZCrt_|164U8J;UQfzBcM^Ew*8mooA;D2V3`O+!99z3)3<0dVc@_2RdEAq=6Oc z6Q^rieWJiSMZ#_SseYT^QqGe)N8OZ8p4*I21m zoLI#_1$va0mipe0AHOJ{r=7B07I>7q(oif>kELSq^%H9Dkx39bbbla3Bc`z3 z>=!W(zC4%Cy+Yr& zUC5~jbps(xuDbF9J2OjlDDC#kw*m8wc$cTz=joE21h0Px|HE z#&7I+Krtd7TfY+x6fQ3T?RQ7EOzD=}FQrM98bA2Ye3lDbHtD9`k`C%VW{i#ER(e~% z#U3AjUS-@8+3ihUFMaO5;_ODS^Y#pD`Ob>^poMH@Wd*}o=&cRPhMukBm%z`(o|VH* z+|dhuA~|-BqO|+E8WGCcJ=IoYHeK+h?S!YPS`1{I#>%f&r-U8Yh9aGm#fY5v<2A4k`x9njN8g@1Y zKz_hBxjlYZE>xngcmxV=)O)2@;<>!|oN%!44bll)i!F6V!us3#;q#3 zqka6d%{&|+{hT9X+)$sP!+KH9@m>PXNYd-bPXE?XNGG9|Xe6Z>c4fUNz-h+eQosYl znHf}Fj~pGXuq%lZoXM&I%d(5QObF%)i+|5fX{b9i${jn~T4gab9cK@PWNs$+V17zm zy-tcD_JPdkc$eKbT(v`-97&o*KrAq#)Eg~1TnLDDpOSAUvoXukl0fa^0x(C~s1dlj zIk&Gd`DNro>iI&G&6Fu=J)9rDk+_oNDY^`xKzh03grzf}a~lmBY`nHOde^u2 z58lD;8Ij>e&s0YJ+=yb{m-qA8fQ{FXg7TY#clEj!#wajcxGNY$Ur4K9X+ZMzzvp;C zy85nW&;aY34*Nap!p@1MvSqK@1}xx5&&*7&;li1cT5A$3dC zva0f*bi32JJPQp=uoft{iMcoKd4$jL_^3ou0S&VskJV53{EAM=^J2`PS48RA= zgBU^DE*>>KLATZnQ+7_ZVp`wqLKOqoWJM7oqq(}*jOGy?tvtn+Fn!2YRyHWd|9S{2 zwJqtEB$+AHi#UXO0pfKWSOI91IkHei!fS0pP!J0{Z<~q+xNVHqKO9hzeDS*2%X90u zL~vN;`d(0BG?<_l^|g1UeWF}XxWf~w;$_T3kZ>oNf!9c$cb+-A3n ztSK~!f<=>()NG<@y9)U8Ad~r5LaJYiv~X!PRk>uqIUo1+X0F057pwa^FLR}mY2NrW zq2kjew;h*o#PAqj1=thn9=t%H4rYCi5U*V?UkD4G!&<^zk;XI^RTt{EE`?8-_9J$k zEG-*Bz?x%lyo2)%FoP&b<(0PJF4)0YXY(ENfeYH{Lml~&y?j^t8KL#L;I@)UwX|NXBr{Jbokf z82<2&UQOPWw*;o9Jn82zsDpSG`>_hZX4wqR5~4@srSW(f>TNaOC(&*(H}6KKgiAvV*F2`A*qzLRgV9x$26-VdVwdnLR-*0)4|x7_ImEXLj;^V*H}<8%9$vUnv&l zu-3sr(a<5!X|xZ3M>NN0)CSyIlzZcH4s$bVyLgmO81N*^^`8fLaB^Hawz| zx87jKv&JI&J)THk>c49bT@{a^`GAh!Mz3C-&*fX`w6~NB!Z+J16Hrl;Nf+S1fRupJ zO*?|yTfd+k5gXx4++`B;fN^~WvTr;1H9c6Rc!@9pR9BluI~abO6oGWL)ERJ;*qv?_ zbg?1*(85J(!4|csDU8BtIuK?73b*Ee90W1w8nxNvGlPG(Lx0IW3O-(UWU zSsmFB?i1cY#BBt~zE*z#=5{`Dhb0O=EmOuB>FpH}0zu{nj6+VS(&*7h-OBcS*xh>o zz8C_5IrZvcQ*E~(E{`}3B!6oMKFVjcD#PP2VW7eECQwX z(dJ^?zc{otRB<;7%!3;H}-bu3ol96Q~w#qn)_gdAZ(QmOzz9F|4<$ zDRHLN&mSVVVCbizdp0|O>;rUVVqAa+9g=fAk8N!r#@c?mX#KI=;?bB%48ynfSTcZ- z9!C_mTDsUGj2MY`KG(&JsB2!$zEX`Epe%7*TH*rFNi1|$fd)=?iv(u~5V@_!psV5= z_&VNqv9tQC6e))yVBnJlf!bUcTdloom41!k2fU}pFYK0hxoa0=xB5{lavrU82}QAp z2sS}5q~|Mi)-{ulw7<&0MZu9nWd$O%?}3k@B4~F0TP*n(Jf4TbfiF6>9q4u!kI7ob zX{7~vf(E1ey0jMMI;aBELuPR*03VK&-82Rtabh}P%J0T6(3p=2=2&z)bhK8W%toNv zY-l(bDB;jm@COF_u@s>7=r7e}em3G_{;}x*ki7ER(vVZPH+|+6y~chY4fOWUCL_Mj z$-l4rTGKvIk`oi~7t;2Z&vXNzO)WO84Ag`RggyaYhy!$)524btq=|8WxJ$Bxc8>zs zm3^Jy{~V((Ii)vcM-nmzn8-~#(n}*YlZ>7(F6p@vCpP?@binVWf`RxHU_!zOf3&!t z2&++NZ80LmN~iWQTjHbS%pehRwoa{aLUJCRjwh*Pqe&5z!@aiyMC5ye1uCL#`A!5I zoz?T!DDVsj3E~g!>PJl@Gl;6V#|eVWFqJSHz6RExP};&dXDBZO%#b2p%|X^orYGBy zYHmSIjolB(LX2~ut!zf0m!L(^#s`Is$gp`hw6T(_utiU0s4BNd)Hti_dr*O&NHK2@*fd@HNHXq69C)z5e)@n(9#+91@z-Iv6d1 z9!h!I?ExR41ArVmet?i+bC?zLv1p}7{C$#M0ffvMm?>WFSpmP3z?andj6MryGyJcZ z5%0gZ;dx^^Yc@IT#i?dJM4dE8q^#<4vBFB$sAPB?Q+P9nPbN&^T|rzA6)-R`l!Kvw z8~0+1lv9IDR&$i?jT~aVAgm|mu(uoXI`$!TQ;at&GBYQflP2o0LkuJu#nKKc8t`{o*7$SE9W@Fg<8^y_ z(Rwr_p2iIP*7N!<_!-8{r)H{fwRrOz*mjtkzOhxgWCOl8f>{oz;o_{7%LM&Tl0H7XmLmjyNC*=Ll z|N8U^ejk0R(1^ZAa$_z6m@gt5wSQj|2?GE1cghz$Cd~}Bs;_?PzhPit?6*hA3uQAu z=5G?<67YN8C#;lfWC(ee_iF$7H`0y+a5YgU^o#0i(EwHj&pO|Cu>bk4zwPGz`7dzG zq@y2z2vG!rpYE2Q(AaN|T6+ckYT?Y#hyH@Jo;&WpZMZ7>w_61efsR<<|H;?7|N9X|~H(?ox#OVKdmVd@nHBLFFYOlZP^*?X ze*S9~-)YAG{rW2b&#*d{s0Scs!QW)4iv2tJ{--@ZnLn=x74ys#vD(iZ#2Q1j|GfP_ zU%6iZ^u$3yZByLe5C6v^V((4(-*oN&_P(d@^NQXRLST^p71&eJ|Nk*||In$b^*Z!w zfG@`&6v2JwjQ!91k!e0Zw)H4lCD!w^62R|HmsxRDS}yW*xEg8!d@4f=H8tk{v)#PE z7ekxd=bj#pybu~5?~VjJ{sqwafAG8HpI`b5AqSB%{rmR0VN$^niPrh^xg!#hQ0!oU zktT`pMP8OcEYDi?>{u!1sm1e0at{X~%4Ss2+peJak@EkH{I*Awm4?faJva~dvtQe5 zCs7SicHIl2cN@>!Ef)9R4bxmjjlMw0P_Atbvp@1jnmGSQ)Z$QVMwB0t_{mY!-=$#E zTgT4oV9vKE5nUf1t88f--e-gG{okoYzYa?St~IrrpA2W>{=Kj~w-eB5FL*jL%$bmB zTqnq^vDtaNuDJQ#USd_yQ%jJ3eIBzRIn8UEuSB^A%>S?M%mHIR&v()N%izyHFwx67 zRu&0)n)UfoHF*65yxgtiAAC(JWhcEQXukNTQ1wuBU4ewLtDH70no>r3=zE~;o zqU+*JnK!;A7mq9{*V8EV)$}&In;HSwQQxnJHb0fBHig71!>Cmvz z?pms%^_KA0-NaUVvCP|;PO{we>E`t#cCOMKcOhf!tp#7lP2jI{9zo$h!ycvM^q#Zi z4lR{A2+W@TKfSDoTiqW&oe@HE>SO>7Ol*m%*)LTxVPMpJzkhz+)4Gb{OhqyZfHZq2 zJzPLbF)dZLzl=K79fln{7bh(2m6Mt?ou6{|u^2VP#$PxQ`>@ z<9s;mjuQt!b?lXu}6H~^Lovn!N9Yrjbga0QLlj1KGGY6dzqv+LZ-Ge`m7qb=)!CiBkR%6lP_dH|z zN#9*Z?p9pqIC5yaq$7Mi7oBykf~n0MqMz5HkDm9N9rGJ@k4TNuX*oTdOtR65Vm`66 z)5GaIw~<~uXLohgR<+>qriq={}vl4zRocc%BOgJKG&aMpOh6(3T|vh!|?ATQ;ik2Vcxb2HAj0;zR&F4d50 zf;tI9>5t($9yvvr+OwJu2!09*mx{N;C1pBKZekHyj zY@0*jQ@(u{!+onW9PyQ)aH~ddyY7pPN+HJ|GCVBTy#MhjP#kk!LZ@D^uUyNU!ku~0Tt)T@4tZ*~pTfyg;rVKYeHGBeXO95p zMSXx%F$tfu5UWA=TVNNnb#%~FRk`^^7O$4injC8S7GZje-*~Y zGwY1)jOPK4zLGIK4yKdXcO|!gv2ZNC3JstV%OagW>OU2i_wLOGwa7MEpHO(9u%v~7 zBGmhFXenewAX3lA>(3>?&hWYEWQqq^dAqfx$6;P`QD!ODZNspnPC! zujgv#;*E~LC28!90ScvbGP~v^e>IAov8&bURPg;A!&Md>?KmQ@Sz9t<-UUlae3@Jw zR^#&Pcaij>D4L6nNqkdJFU`x9Q~S;f0}I+?Jbvmjl67~m-9}t_*T8KvLBg_d-dMW3 zTJPX%306l6G5yaTT4cpt%-t!i`L%`bNkFC&cnVG}_6=8*wsV<1}zSJB7q$?(g!$9kn{ zht$TKLZW2G=R+?p<#^!R$sUro=|=5Nr@{SGfz76dteRi@R_Dn9!k;093Plc>_ckum zv*`Ccaj~D9(fFE4ANf}@)xA!IxM}8?B$&Y-G~!3G#rTxa2v^aKkKv{%!Io^_xt*S* zl8fYcir661*y%y6aLC6eofl+KT#J-OMP&uxs`4 z6-nD1oK4pFl)w*@?!&$6wVBkTlBCJAt#_(-0xN6}Ei`LOVyX0Bvvm3)SPmA)SJ*p+ z7B!PnFY76ta)=6E%1+S8URO203=p9D0C22taxzv^Q}d(ZC!s!<(?9GfjrupX z{i(cldUrebfduNd;5IKDTdI&K|msW;eC zK1|kGC1~Fs^+gw$#?o#4`GcD~9f*{e&hHjSL`0N>OKw~Yn1?G|yk>XK)fwj;@y8^U zzSx~Y|4@30^Ea%}^?D9Oy@tG|=skh4ZM$P^n=bgNSEXV3W50aGjtuptcfsP$y+1+L z5+h!E-Y1i9o`$zOok%^eFwDvwg^ymJ|EXY}BspX5k}$o`qRN=p%AOx>uDUCjO?kPo zO;kC2Bq+WFb+R&+Zk|xAp9J+UU&}P&7&yd_?Sl^_*~N-01}-SpMea*ea${42f(u`n zPXz=y;Nub$nbh$#pEgRI5gNUi1{Ur`!+5+XlzZ#vFtj6C2=_S_FVAQL_-klldPy&5 z*WKFYE+OLz@#5aC{1-;}*2z6Sy-e|69&RTF#ifE8f*u^GNc6D|OTN4YR$1L5upmnD zWLz0HuM6%_jIX~{{ikHN*xaD(%a)uJk)NEZ z8Qu9KZah4oK%;0itLa5r+g#Wtn|udFK|%jE?0KXE%ATzD$G~2p-6J&7I!0n+*HOb= zxu0uybj6V1i5r8E1GP6J3?jg(^k+e9qb(3gK3xemy}-kF)r*+ z#2Cv5OLtuotr3He=l$nm7FEIlEIy$V^u1|?iF~<^6%_0@63m`E8J<1}IDX4u+bxbz zJZ9}q8fPwAN}}|=$+9wy*Z-`(f2aL()r|kRf1qy{3a#qh#Q>h;>DiBH3DMC_3sk>% z4&9cyz9!$aO+!fLz4fbtOE_3c9NQYF^_^mjNBhVtDzfhbrkQD04kS8ED%L1-@NJ0D z=T+slu&MRl-5%}X0ekAVw8dueQErPh`&rsAw<$PX-L3S?d>)@=tlR?6vOk520+|(~ zo>Bd*dniS=E%(LRfr20pPoAL5fjSk&bZU8OiY9nDNM)?Y-aaeAX6Q)@k$N0j*R6A! z*^=*My%zff_)a+ltxA&yZLYkXqfndrhAT*2SQECsF&KYGx`mx@P>o+fi@mp{<$rJ+brE^q_$n`5_HO}|73b$+c>K+qUvvZz%g1dj zSvf?43Fh^&m-xLtr3<#;nON(Xj<>p2@XzR#BIe&sR>7Z(kgH z%Wu*`);2Y4A7E_2i${<~tol}!-s*FkIv44$ zP~1ZY2ULU>(5%ZN?P_Vh=8;w#p6ktFbft-EcQA44S~uE#$u1kOo`C1Ws5KgW7~iXA zA5$LJ4ezFj%-`#Mdmu-zH~ooofn$^o8Fi$B;}-#CeRr$$l@7VPoqP}%R{_qFDj#bX z-@VeF)UB-h(fZ2tA;XyOTKrG>QHiF1Fx~skrW>etmR=f^Uryc)XG!j!7EKcy*m*ny z?(UX7??09~|2$av1Z-BSK5z?66p{#$-F_SQfa?jWRe(AcNgw_k{AQ}FBql-t_-%2Q5^HJ6b#sEX z*~3+J_~tj?vC(7j)Hj0pr98BQtMlv=;OroOP;69HB4ffccr`jRq&@X=4-i&RUx)M& zb=hG=+$kYw9PxV$_^a{+wjO-ciuSY%>oJhrlMPw_eWH(@w&U6poAUCss#L)*WFo`* zbw$zMFE;y*;cMQjX;Oi4!bc<8wa)M21oar#SFxyJJPXHOQr8-7>MPvD{B(Hd8hox7 za(u}v*J+dxzWzT^(6r{8&wzY~<0cu#OJT(&0P5(RyLEfX2@5(;)LUmyALhA)rRAa=Xv507d9r}{KH+w?Txwro;?66eyR%%J4%WPJj# zSdfc?Lw+HfI#<&-JDZp$=q2sx>ABI9LGD@qnnf1`8H^yu5hr@A1bwe}28dSWsl1M| zyA$1|T(vRRY)_xxxenqBk8zY}1k5~4MSOwNI=Q&`0l$xfNCI;(k6z?Ktbs95UM_5PYwDPL7? zq3U99l8yVZY9FxXgb&5%mREFIT4+$LHXcp?v74zp3{dl;0s;`>;owFfGBUSU%U&W& zKqSo`2oZfgqW=qd9~Tc)5yBN;2-K%tN^f_zDPrB5O8?HWyvaW~?*OQGvh{z$ZO>Pt z8p#_JOgT-5Sh8Lax=rWs<~h

#O~_YNd5r{H;&yq8sGA94v-zayqg1aT?PK$1>AD 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%0DMz5>3ENR1QbxV0li)X!CaEmJCArd zEKO3w>BV0Q6gVC`6#K)xUjEvXbkzt7jv(X87HV=UsVv=KvyU!U-sszHJs!Be1UP8x zhFcOgV@<;9-;{nIGqL$gs`hbfss2aiA>Q+}_V+({`IMR(nxE-wJVrio{cp=+ocdy#7p6BUE z62g6;nw7MGk1)QuJIzM$J%dJ(m>({cteQJH0n*UWw^(&cpM(fD-gxBD!HcLf-Thh&i`N;MpeM1@doJ5drqOvT(p58p2a-d`P%lmx zkKDZWwCI|$47^AMA4l@NJowz_%m_DV#`fpdZT|KJM(E7i4Rd|8U#bdPA-WGeL)!0Y z4u^Bd9Fe6YZn+5ZfKqH$$(_&NQu%nWaiUrpc;)BGrNn2Sx=XEe;Rqh3oN)Yki*9t_Sw)B%@U$sI zi%ZA6K>!oVUJ8)^*v8YqR&#m2>9N87!)!aJTV^*U!J&{5)KpI0$co|;1!6}ULQ*9W za-@fyH;V^3yoVP8!>{59o2bl(U^1|Z)v%RR|B1XXylUk10AEARqCTSAsAnY;j|9Ce zArjA!8*TLi4hBWzD4s4^aZ&PwIcqNvv261iX;sr zktRcIL9>KOh2~U2kPf5~Aj`fLl59+Qnd5f4Mv)p0Wl~tS%%SOGw3UlEH^|yIPx!3Y z|0E^PCcIyY7M&i4Dybi>CZ+#`-WY zb;5I|qYg*HnlyH}>QL=F6UX25$oD#%>Z0o2Y6y&o*iS2z+}^ewE%(xWAwvvDJ6=C@ znFL>!zwG9KxbYg~JdZYhuP8tEFo|}gi;mL~btUZk*X42OAhP4qc_5dRaj1ETPG#sR zMW^S9qjoHP_f#5j)rJ&teJjHR*yC~z(B?}uC~U6N-u9)vdB5m=9-Q8MeO7>74zl(BJufV=P;rB zZ-*oR4&+z6>1z)q{Qr<3!<_ed?Q>%LBp5T@(IA2*<7=lBD2QGMW?u@|NC|xZ4Du_I zQb<~dM0IzzB;gBAwjK5^5>+zXa5?u&jO{7O;%5!k1$4{tXb?7!?*cFVpP`~|kRcFj z%{WaBsXVEFaOOedJ&~zhN>le+$nk-vONJOy;TBH>{e4$t zu@;Ff@*VW?RL&VHG*E#EK*h4;Z;~aVRfLSOu47l+ycGZ1qmY_8CAb8#OlgQf0{T+v z3GauPdq@%-2#30lbtr;CU@GMG;P=Sr&$Ch95xg7_^g-wm|Ikg*J94uWHJFgL>5v~ZqTNl>85}dCWHm)Bq0VZ3eUsb(!qs5+2ae#vdIbLXx$GS-+GDmcGLhe$pty4>x^|6UVzyU%l)gg6eM=( z+!-YIvgESWS^NhoPgL;Iw(jlJnLu!wTNk+e~qt;3Dt? zvL`okfAm-SY2u-r+nESrk3eY<>ruanIM#!R!y>;|_XL0(pC9 zM(N$oVkuiSCV*1M@o=L*VaLz!?juRl|HIZ>21L2FZ@fb*AR*l-BHi63A|c%^NY~I^ zBA}!}D4l|IcMKpP-QCjNU1!bS`+d)UzvuYHFTl(^^E_+a>%On+cY%J6-U+RtBut)K zzskhI-yl#lOk-^ zL{5<=&K&)SPd~up4AK655OEzc)Dja0g^1X&`y@usL2z@uI~9{31eBKEb{rp)?4^om zGX@z_-5e2bFRyR?eboaVHW3<`sre2|IRFWrvfbE0nE78X)Oz+M=`Cp zZ0|gq%6E4_`H`WY6x|f)Y~CHS*TZT(ao9z;$Ta(Q2{XbE5fhb9Ui>38zEHh1194aR zZ=5cHOHmA|w)gv)=u*V$VYS&*iyFI|cll11@9+8rtBp*3c|i76JVa?;s9sm+3UwHJx)D?n5o2W5upub4t>P^cxCRJ4gISCBLDk)!EoSK? zCMP%=)D&z{sEY_v4GKg4%waxwZjvkTM5wr~ww5862xj6KV&-T>HzvSH*3;G~Vhn?L z4cPaRc=Vu}6@4L|d4|a* zHPYyPHt8zC+PRG4O7%OzTw5#^j53mRbV)fXP!M26M@EH9+%OvtY(^zu(?*%8*|8boQ02w#b)||t z8-Z0s{jwQ#2Og{aUqvfGazFOn2d1|!&+H|x<6L%{wBN~_`?;L z{(Y-qe|3B&frDAsyZcq$|69uc{hUG3FZi_c`4V?5O?EDULhEXcJz#_`ZV2@zgmy@+ zgo&P9?p6rD;Wy5tlpAVr+taOg{$NOoOe86T#LftjWOl`}d??Ngk%dM2Q9w!|619hf zpGY9w{HSQbFn-8ybeVDb&oue8LmXJ-Lwyg%y>c48O2&oOug?S^hmc2-*y8TmPv@DI z2l=*+x5k+2+;&N8Yij62wIM-}2NaKBll(*hY>O()68pHbJC?OgpNoMQBZfzw(E1Nb zr>_3_udc7?g70mhgrW<~{U!Nqdt#6&U2*vchnljGhj=gLHCNl$JW(MHI^+UQ?-MwG zHP~*dq9iA-K18>IIybpq^Uj&mli-FL)qUu^XHS6$UR!v$M|C(OER*bd^z05*BivF< zA~`?Yvk>3&sCr{4+gCIn)ms|aXs0Ts0xO1>0L27xM?BzKkHvf{1Q!=s6Q${Rf47JT zd*mbS{V=F>exChm#22;3bkHDz?(Nbf(wns~&I>LKebtY0$f@~Ru2w^@7?tv0)GcB< zyaa4j{LBcq07wU3HFPHsYHM)R04fj&_sIUA4xWSx!ab_ZX~D-KWc;g#0J+{#jesWd2Z+L8Md}#@Xo4d1v#Z?o-mT8E)}oFyQuBC zI!`nBFLpPs-@6*syRn>7u?Jx7EGT_`Dt+XHvUsHf#P+&n9vq;29`6A+f9vK*&QG1= zwF;+pbh!lXpP4zbqW?^ZjNlFnBSQ7Ca=28{E&DSPd{YrehvfR69`J&JvBntn+YNSn z0XGw%V|WW0d&T`gqu0h1wEMh8x_V`Qxm~+xTr9ypj7V$Ri+d zIp>rC%$`pGTDki>S5Ead1KmGY@IoK7-F%DEV-~-GyFu{B*Oh-WJuglHX!~qp+u5p= z9w!Fh<7DG=cAevLN97LM1chV4qaqQe-GBeagKqePzWrSj5eT+EkrScZXa@rAo^nvg zqs`;>fs@r9B6JGD3f+{)4ru4QBcXYkgazMH%?GS7m9c|MOGyix}|R660wCf#c;cZTVYSJd}6u z5ur~|wDY4Eh(EplMvV}RP9T?RTXzqZ5wE+O+P+f2r%|i09I^#0;SKr#Kk0jGTrP8k zFmNpsv<={)86#Nf=QuxwE1b-()FJhkl8@u%`8~!}@*vG#7h}iNn5YYOxr@w#{ z#~wfE9Bv73%~?Uk-yqlj%qOYonHCp}?P{P)%uc>H7ei&myMQqKi!-OBsl7;SQSbe3( z@xedX!B|}!Q9X|XrP!>O`ZUeI{u~ZDK6o{FiU8ph7CFB$cm)2t3jVdX{O4UMfMt^R zo0~1QZ5)8Lm#AgQ{rBSkbuR=;f;WRC&G(8HyaiYkB88A!1vv?qd4!o*%^rAZeQ(Wa z+JC=v%wHdrs}O8)3Qxf9`F~#ztik`RKg93z_7jbFCzPl*$1-P5)`kqwNuHAjN0WYi z+8(B~^i&30G7MQk11^QMr_{Ho^=R!yVE~h@9*e2}my;TpRtT$Kw_kBvMFz`8d)|}7 z;q~kfijD=tD^iPa6fkUrNEPp|FCR?9IsSEXgO7(S3Lb#dOwn4O%`a53%?DoaCK)}K2$^2 z4_@g8krpb8aI7r1yH!{sZ%%6E#%5u-i|6%I#)IbO+a1zoxt9CebE-L!+VG5DuN6S& z^+qFM*Jc;)gl2It>aA$#ZW~t~7B*9emNkLFS31~v;OO75*w^5b0Q&R)mgvZo@RlJ3 zyKzAF;gv6o3iX%nCSvYU0kesgq<2a-W$$0_fs1@cIwv%gOlQLGdj<9PQ)E=R&U8%014B} z=aw4?*K($Dn550Sb&B)z7M$aIV#<^?>Ro-EmdP94>ZQ8;i;elBji_o|J@BL>aHIcZ zb#G0?ADth;W&Iv*+=kH4Mz5e}<=f5vhu_Rc zRL-x&W_XdS+$>q{TNugOSv9m}zjpi)NaCKCr{X^|E=>K+7!1F2*cgV#>*@nO_>blQ?FGr z?_6#;1YUp94&2`xlM5{b!|KqyT8X`|5qNc8DZ;Mn$m6 z9%u6W^*UeVgGJSI#ho9sUMi8#G1ycpkh>c7X<&)o&s|EB;u|$(9O@Tz(LYldX&IYL zeN#8xQ4~Y5q02)?qX-ro}t7{2u}|1Zm1pI5HQFk{etr(odl|q`-@Xs&Mi5^$b~pGNXv%p z4VGGW-FCUF-9OI>`}rD=q=n$q$dY!?mBbqvbsP1B_MG4RnDU5N&-gNzb9q^Lu5j_y zo?=!!axFRYQ+nIQ<>|X^6s&%7@y<1DjlO)bW8`+Z6pk9+v4QE}ctT18(U%L&zS-V6 zXM>OYtdIcBJymv(2?axYn~78I30M{vWzap&g3G83cwu3HT?)&J$M`oE9c%>fsXVw zHVU63$n__%B(Ba%V-TsvG3zj=nsr{I+fG+}jAJ(FCU5b7Upm?B@6SeXcC;$LHQy-Y zd$HJ*w3j9kL@)d0nIU5v8y7&LF1SflzspwTKxp&n)uxf{__YQgzYg=hnXst-RZ`ewF;2YHxxqU9NH%# z3%{kp!H%n&^@&1E6P9DVs}f?1#bFynKWD=W(9c@C_j32UloKEO3lg#tW}$l|s7u3l za((yN)10XI! z?|~oqm}8{NL#xXbKo}*LR7kHuTG#C{c?47|;rLBW&b|xQ(}TslJa4L}!2){Wb=iTq zAnKa^eMeU>V@4e=sX8q2aZ?5W5bu$X?KB#Db!ymZNuy%-aT~_CUtZ_Hy39<+RIr8;<$yW%YxAkGblQ2K1;g&yVQX1zya`0^$Zq>6c@K<5!Xo!nD1)8C@V61 zBtfE8CTp_L_SbiPcfbw$6R*0jtLx+0{>*wItqe-RY5fv}XmzwL7-U89%r*n zDrD3&yAX6TahGNRqR$sgQ|;r#K=_k0u)mPIf|D+(mi6thu*}Ej_={+>x0x&kut~JO z_+Wb(LE%e+oAhVcf1!Cu%CPG0GMNcK;kZK~E^zLIQ{}^_Cx!jx=U|Q#da`py>+1L6 zQ#!o~P`ptu@8{hCr&#(YeWh}b^BvrvkjBm7ag;6S*ylw0Is|+SG6BKh)$H=!b^xTU zX)G?p%51c(*7{R9W8menN!;k`l-epCR&@2$zD}R=E+uzDQ1WEbr*@$R)15*p_@NSq zcIPAmXU~@fF~O(&L6v|NX9#;r@Ou zvPNuYx8a>9C*vqyYfj&vz6h5tRW)B*e=T>#^5Q}L#5iiSBH^Mp1{+G73Z?nEV94&tswQoP6_<3gR>-+U@&P88%#khRDuERtdeSh{p8kk-Z zh)yL*GyBc{MuS3`$a}!6N7{28Xg{~SJnsB&FQWWIWWf+P=a1)z&2tpQ@hy!Pt_H6w<;GQcku%TkEVbQpNr%p5M`gjSuf& zZSYMS^E!{!?BvW|b)4kePPsr}zaPH2JZ{7s-@@qn&P3F=+{BAy)9iC8$#Q=#R_A`s z%CqeK^!3&#KCi7d%H*HA;)MeuBBj(}(0iwsIor81@ip^*Qcq6xcKt2bK?D3belW$b zDG7j9;IEI5hb}RQHmIBJpeq|Hq__Lc==f)`a@WpJ06HpL6Vsx|pniN{ora%+h)w04 zpxcJ{>2^3-v{D_ZVsEOL{|}$bqoIh+5nt6&HcwXlRmc6hLoN~y^BrxJB@FFrc`P)m z3O@L;hb*IuVO|wzw|9Z^&Z_gbCg#tZ_eQ%0!iv`J%50!AL7&wbPbaQT5qsN3DdK2t z-P_}AQ(C7dZCK=+f2Lv=UP1L5ShX~-1N;|xFBfMK_!?j!gs=@CvCEx)d((xOW-gm33G680w0-kf#@VCo z)+*oUoeRnq&&LRo<%Vv#ybFg9pO{{ntKTTO6X_=gg&>QI&dA(I0OGy!LChU=6uFDR zy>Tz5$(F{qY}#n7vO%MsOY1Jko@%PsuFf=;&n>S&J#U>EHF{Vl`}zcFaVPUQRJ%jv zM;OcRkDWn;8{0I;cU9zQuj2Ck+;`d2vEdcuLQ`Fk=A|B{i8dp*!KAQEWOOJ|6#W60 z%6MxGyUi21xay>wG#+l@dM|X5Ccl?~S`Rtbb6)6#D^EXm#YbMl)y7c9SzizFN`iHlCglpa}Hji^TA&o{;wGn%%^HPq(Ygw49q%*GWs4Lz{ z$sCURjsBPFv7f2c{JOQ%1#Ua#bE%T1jABVRU9`Im%Y)u+sw3W4JIE_&o6w zso->5o@upT#N*2=TYCgs)4!?2qzvUWY7)kNerq;hBd^L@&70_x6YB}25+aUYA6Lo& zlIkJv5GEk($Vs~`7@HZMz}}~~e)pELzqI3sU1=aU_T74QS4_IC>GB(~>j*aoa^-l^ zeu38yy+>RW;U3Rfww06S4|-^>EbA`7J>`~AxhW0J8-Myv zjhwM-@0aXx%|iY5)u^&F^P&mz+GmiMFp`hPSE)8i$hNYmLzEb3R?aW%jbkv$J+o%< zh=t8>jeht|M4Mt0;<$A;%3UEih&M-Pg@B6lU>o$fc8f>=u8`+k zU#UcRlIr>tZDNf4G0D|l;=n)tV(yD*RRl~ zVHc+ijpltMj<_}#&;UT;hVOvNBLr)#Chv@*EI?V|0wA)herPfc!iU_$cNpl3Tx-pa z#uQRAk+ww^y`clp3Y+r7pY0m^^P3{*VLUxHai}$i{`vblfw7RUIhwM+aTb)&M0fRN zTBhTRsx8gdhk4lxG^46scR>xNM30&K%Z-RX1dT6<`j3`*)I4g7s*hYZGM?m$3cYM_ z!ZF_cTpJV{zPM_K@pCpnI_8;-qdYFe27938kO)(KP7P|Ze7Vlji7=j`&-=2LD%D6V zD1oK61Lkhy)sCaNCda}+D71@M=iB;e=O@83!7I%l=lbEOaqs+gs0Ug$eMt!IG*3i=wS!Qd9SYcUllNgy`p8DiM&tmmk*)I<7|a);Cv%Ib!Jb-hfD( zu*0&gt(k$H7$MgVA}41h&r&aN>1Kt@aP@zs}y z4t1W!BCFPeQWAflwQ&DolOKl$8^0!Cd&XKv%}6_rysfV5ZSOm_Jg3|STBF@VL0AxnJztcEJ zp?>3|*zL+5BBVVt=t54-*710@0ndy{^5dn^$qRXFp7 zrMn@NwvEAvyV18xw1_TyMuAO9x&lwkR_h4ug@&71x0knP1xmk;pBKs+i8h>;6j<)) z>v^|QqHdb%9#JF-1Vr^wSzi|H;sd|U(y;lKK-79I2l@?1%$vD>MiSNyd0irQ^U`aQ zfiSW0I$eS0CQqN}xJtIQO=oob>e#7E!=S^;@WtS09uZq3^jF`qKW&CH@M90`fCh|G zdTU4y1HrP6{!u08uAS5&c~HD>#4+{k9GzB4^4G{!7)SNqXq%6p* zGVOWy~gYKiu8Y2$-rXYxJ0{K`GJs!Q98o1 zu_C=GLL0L?T~xd3ZoDs%(IHR$Cq0i)h#-170%x7ya)_YVO0=NaK-}vwD#fg`IHyj} z`zXpna(0yk(1lb6oXd*5e7jM46?)ZYGi=rs3P1;(QN2T-i|swVc}#q6U|_JhQ|sIv z%Z_dY7|8&ERM5oDo02&p81nUNxA$5vNuBFhGPEGY^?7scU? zl%MK@SLZjER^tUaKL+zQWes1QFlc*&u-!cUY;+crSF^pJwerzBF1}>TTT#?Ey(LvzPL433vQ0-fQ&qHY%xG@ z)*WN5_@Vo_Oy)3zB4KGb;zRE-)!H-PhE;((f(5(><;$-^<#+MiJXrzn)M=*Ghu3

vT-Px>p%7aad;X4z7I8epVQ;kvztaN3lIDm$x%9qnJJX^FzoL6xGwjL zOHr)vm^R6ni}NP@Y7VSf<-^C%(jrJWl}|Q?UJsPU1AC!}*)xNGoeHtEF~lGCdj>4STPg$g zMydosJcY=IFIpzu5(cpXAqG(kV)d!XtGp#be{||PqnsW9 z1oHsv4l9P`>wO?&VlVzDEsLF8rZ^^(?78l%-Ijs?q>(JA(ik$!R%Vpiq*C-B!|Rv7qaqVgd9q4`pZ9D) zOj!mlPq_#%bsP^kL#WlPx~#8HM`Wf&n(!KHoMS0VgRH?ZR3T6ZiQCuX0_yb=S+G#UVRC1;@dIvn$3Js<6)x6@vid9xg$10?lgx= z1FPc7Wyglv8f7mWU$~kKspR+_VQnt#K7P7Lrr1JNO=Z9aqf{xK*@=Mn!Q-R%+5un_&?Q7PR zKtMnz(XFXxAQH@~oOXgB0&CFQ?banO-T)H2wp5CG?j+n?2`TVRHTbiHe;<*0{oyU< zedzjnk>~+=hxX9I`j(%qk$NA(?{MLOF}$~oX=_$7n@+Zg?U97X4!0zom)iXDLpA41 z?;~qh_I`?-9NoG0aM+=-ab>ZMyb_piOD5hM^dLcYJ_>S1dnkTR(G*2!NtI-Cs2_s2 zSJ{}qfh+avf%m`yu;{CcHA7-#M3OIzR`@?oj-8`4)3di9amhCQxTUDG0JdK*nga&_ zbGq?;#)FUIXNGbj=3p%rglZuIR{8!$CcA%R2>$>-ALPNOY%(J5mtU^qiwzn4K<{U? z*xw(Ke^uwL@djENB}{=Ii`RDagJQDNy(G^1^VbP6aFjE{n*aSZ)$Tg&`sq-;7F(WH zaf+NI2{>~9z@t;rE#qD^8?UxoD1tnff4cv+Kk0i2fI0W04r-*Lm5c>6->E8Qf^Rmn zU!cq)2Ln@rfXy%|^I*f2-K+5?d70z@Y-;z^8=Vv>Uf29kyNG>rKl-+trLVom6b zDt~!^Z_F2$->Dt4c4orN)?yfMpk~@0X4d5t6u1|gule&D3E~N;b6ljR4+a8QtQ85`MVrapf`87>9ca`=xs8@~V%DzK6 zESx5ntD}L?gAmgsfU>{O<0tZY6QMLoN{C@i^uSR#rQM|=s!uqKm__dgCW~&v_v-8&TP2LR@xpLNWVKfUgL3kiRXG*sC zK2P71#AL0SsY@>T?ug zS-)C~atNp_RWnbY{)#<`B7%_7XY(bJLWxeVWgY^D8_QPGQLv+!5B2Zg)I-FFJ9mur z9IiO(FNKGZ2WrU#5ox^D(M>TZq9NuADyP;EH)joj=}mHC6WEH(qQ^BAcbk`Yz&BgQAULiFJ#ZroEqKRs0U_0msDb1PAeUZj7{103Kmt$2&LOI2dP> zw4qD)%ZZE39?5^MdO^=I8OTr6t{5Bn=Rk~kg0eM`$io+$fKN-R+kG6bH#8GHyS|B0 zgG1W6!{Cj%zymgX;&p<;6tpQ%!hjOcr_}wDGeg3oR+4DRZ{4c+=Z=E-8klXI6K8L( zhv(}k^-B)_pdgl5gHEum@e$n(VwV$Y7f(&q@ZeYsFr?;hBQP6G5VVkW$c{0aRnY7bn@kuQDL>uEJW@qv$?kI{3_!)=tG3a5fOv? zo8U9q|WHCfYdQ0M&i1sxA&981)A^$uvX6dH?ZTw_WPzF)a zFOk>&8JBx|a=n{Mwf!79Vl_k<;lU`3PFyj-gyIoD`JM$-{T_oCwsM2{?t6=B6hOBc zy%1S^x1kbag5&f{>|Q&d^?ZjI^IW}#L+~+lHaLo7iej=F3Fo;BWaUh#&Hel2CGItp zMYJ7q+HiTSA%^g)f+)Z`k#plRwuMXl7j(+E#S{hS91K11AB1vnrS`mN<@oa-7JzQq z+mBWpHT}dPtB`Q>H`?szZC>#t-Fp2cMO;XWgV?74Nv>i{(8RiB`Tq55wjc8E;psde zE={m&cdip!E()1vU0)8sDa}$|?T+2_$CM_MLb7peu6Qd>!TK$m#P)Ryl(VDDkka4# zY$x4N#Ctkmd=Pu^pr1mB+-V@G*%-lYzClOg_{vM)n4a{2QK8BG@HW`Xgt=|i?Xgh% zni=21pY|{YcgvGDpA;F0<(BE`*4WAUrzh$Oodu*s!tO9D`~wbZN%6>R66J#SPb}ol z2pHbHtd7wH47xF8oM|E;4eECF#>XESsnNMMS%_HG_1BZJ0j3og3j4UA`=;bf)ve2y zQg>an5X;kLT;27)_-OXd4J2pk4x-uSrM(Cu#1mZ5+7|3J7P=xH`W&bwQ&b!~1aiQw zC&q6v1X=9PcBZ($P}uVf>dEuj0|8Bee(>or*Ae$xshQ7V3m8i-R$a#=yYyvMkpn{Cy2)mK6ftVN_AtNgE8{N>`$~u{>0#M`w#htmg;@^*&sai9 zC$l_QrlDVx4fqQ4u#MLQ)v%^eB1Pbw>cq}BDzF6mW&w)X`+SzH- z((5-?nHSwSm}U;oeXY+O{uEo6bmopw6ZJPP*=oxzj0<5r#3bPH?c*>5P7#cn!TvYv zCj3LwNCGOTv-Esralkz^T{(yiZ4U7+pBcm3@$ig5_!W;Xsiap{6xZjnooLKL9==-eW=gd z^PEh46R=Sd>l*)%sCsUYhT$^>_IX|*gIzNJjyWf3O9d+lYRX^Ve2~FLbiJQaKQweH zH7ZXIU9+n@_`(r>Re)w=`n)G?wmOn^*_>_*kZU}S8eRpwYEAP5M99RHVx>_re^ACU;a!}8GSpZp&jQM^0NY8>X)?0Qtk^daec5zl|dY2 z;}t+qggZI_GP7|YjUeAxdTLim-F zJD9dk<&4AadUO``^XA598hin#x3N_I`k`Fw-$!yZl9w360utZEPeVT3s3PM2Hi+AW06#-0tQvL6K z`l@4nP@9az{ZvAzUDOBw&DJ`{^_Zp^qR=POfN2rnb+(aib~?slY{UO60mXR4d`H(C zAeu2;at6?F>S>XZHf#3p-xA|2rien!S|#v$el(j>_hS~cdmw8Ir6emO^lu^^aEK4g z6!6W4FTreG3Z(rac6l++T+Jf$%R@-t7qaza`p(Kj3%TJ(wmR4SB7MVC>P$Cs<6Y1Z z8T;1Z*te=96t#;LGFxA!w}Bs`zw|4=-P5hoZth3qyXH#n=qiY%O{x6zj%F2yU19#G zZ4xKULctk!kgw%s`Nf39?f_RFf`2Q6>fi{?*!e%yxQu{GxGZD) zN$QPaAV4#Z6PG7HHfOM;0Zd=B3sguNp|+v-%f6K@(>m4DpXvkOr=KLUq-;VNB0oPX zjJ-}4H5KQFqnSnY+^*)zWx79NyYdQdZnjWzF^ntIEcest)*cLvSF(~@MRo%`$@-kQXte+`K;2Ev zTTIPa#JSv@V{*&iedUKRjtFTkc|#~ves^QgqwT-T6~_`PZ`LLtrlkq_R_`vU71BFk zJtaJAZOk{T(DpLSI)TX84rF;T;MFq#|BIF=_cj}tzQ=@48O_#%d>x>;>O*%DXiBca zv{%r{ug;!*YwofnQv3d8t%Bfvc3xNxI^8qCOKvl$ilKg!8 zJus1%*I&HgiC#*<>_vb&vkLKh^FX>bS zreB#l%K2BPSteHk8n5-R#|1gpZKStbrk#)oRq|TLDx~5HQOEyK-Y(?T$GPk*rpycc zNUqmoz1Lq<0SEQZf)dBy0xBiS7qZ4dOBP2MuHf`I%de38_h8);2mlMIP8U|?*Y=R2 z4DI>boSfJDHKw!<%O;`duFtqjI^opj*4Koep0r|mB=j0DUOdDbb%c4AdrVzSmYU`d zT?vp|VFpAcMr#UHMwT#%%g0E?mKf8Pgph19Zrj{6 zK^o9(B(X0KKxBNtbhyCMO0KsB2w z67ICx!^Agd?lzmYl%*R@5uDDoCnG~Gsqc&teGMpXBStrC{Ch0-m>^e1ZEv)crqXh# zRg7)7(56L##5n^s3(MjG;b0!eVh6gG<_kttJr2JUsPNu*i6FH6c=`%wGU!73zzJ3X z)OvSdd5khG(wU1LKfGxG1P%3p;T%){9$^V{3Wvu-WR=AIIX_>2!B#6eMC;vtHjK2w zT%x^)km3#)7eu*86!HU!aANk0W1lzXxFDTu#=wshsc$p5mj3P`%ZI{4hyxtL12{A? zQCVd>9XqiB9W|-A0e2h|9)#1!L<9Ygwnf|z4hw|gwikD}?sHFs+++Iuzhr0UJjLIJ z`FI4jJiRg$kHI)>EV+lc&L(ZkAnVq$TeY%sj@S6(f$Zv>zXcDXSj)qLLcUvKp;q&% zd?YM=kRr`uX6P`DE8o;!c*K;;`}%M?j=P*dd_@hdfxR2wtwaaO!9=2H&#>e23h&`)%mmGIypprQhWnvQJAc)L zjD8C}j&X(;8|*RlckA&+Ao2R8KXPb_}GQOBFY+}*Im4%^-FMvQSop@!J1 zvh5{^V-&3z&YDYVC1*5Bw9N&2C|k^fwMz}C^f+52S(&rs+;D45(2T5>O!_0RQdWvrp^W;XAriCgIFvz%~MJ{jiLoZ2^rMPS0 zy_QSlWno#jT8Rw&*}bHR@d4fVGuOI2#Q0kn8Eeq-T0f8Z8$E0Q5l5}>ieu4Ij74BS z&IraxerGj85=YUcnEC<4%`;iNs%#O9FlI@@UJ|s$Qkd~eoTEXQx98?xOc=Qw=Os6x z67_n4I~j?ORTpp?M!=@nT()ds@7BkSy4VN=V1vkR6Wn#_q$3-rQ9IAWH)r~cS&Vsi zs5&6&`IC*_e3e!+=h`SNvfAzdZV>C32Loc@^`oLy z1vO$eJ3XTw*3#+Qn{~h2T>H7YDpRla2jhtIp)}kbcr?`cBMI@VU~Se8ClYfjA*&Z~ zJFFRw>m+!A?e^7vy5grU-yNi)K53t)rg2%c#UsLkFwIbWk95}cjG22a*cEKSVZW>B z7j=Q&+~BV+TVOG60m=n$lO(g-XCJADQ;wzm-wKVMS&D=6-B9vG_ee7LoAFk4?~~^_ z0gDW7oO7HR$$6$#q!hUq?wPiyJnuv#=1QwxtaAvD@%!I7;RhBeyp`gS{hYyKlSUuln@u`t>;*Hkb;fa5l; zR&VHykGJM>0j8&D`gl(f&@nfiAVM1`wVpip^*EM0&HS@)yB3#k`$0LK!A#zF0PjJ)T$X2|d5XG_}<3hai;XbDVx7oTr3 zQi}O0K>J-+wYPU}CW?*l(zI?=P;PmEvKmX)7pWk*Co1+^-F!aex7N4hB%t%p{gR;% zy>p#tR1KO#Bk71FpE{H$e2ZREbwZamnt!y&KO2kSUaVi*YIX!77^fln?i4mMk(7m3 z(OefJt0>I})Z&Lbn7MHbY9W5hPRM5)BRSYCToLhmaYTbPTo2qI)_*@YwHzbvr`9wj zZQL^`aU*GdHPqRfuDQN$yV*N6{$M=LnBF%j5h7TW31GXw5JD}SiCd=k=IT_+&HHw~ zB)vViso65YJYfVz7df~a=RyHInZ7>~lU99E-~?bpHWrb3?^wW-P=ahOuH`Q8)i#fw zEQ2%`)%pT*9qe9Gh3oqZX^PO}HyO6lC!1BPFH)Rt9w~`X0@sT*_woljF-<~O=9kq< z`&!p>E_ca+3IjxnJC6@hsb{}pZW+whCZShSzIe#F%18GEme3jJffzCtQk=Eo*&~n@ zD7CiBh4!E*7uPevDnEeinZ6WmK$4tmqH%0*m4jRPPWM9sAxLklC(&RuM-kQ3OR(>y zVLKS*&z;ikmLokx!q65fS21TCw|Yj~qt>DAGjp}-YhyL>i|XfQl3JCo*D8yWidedd zEjkqoFHeeR#M6UeM#?gqop)6zxof{q-F7!h&2TA_xMFgY#8%Q$IZ}POPzPJ4q{v~q z3dN#7btT85+oYrHh1>0YU7Nk|!Ejg1u>fV1r_tUzkJE#Jwtw%UzS2M<$u>!cFZ^tP z^u=q7RQ2=huWym7hc63Ek@nPxj^peu#MtA*IUd%s8750sO8n0uoV8t)k+`qaYT=SV>>0e-Byu{U)>DCKbVj8 zO5B_ryv~mpVsBcUJ7}G0mtew0J}!Ib{yKs|d*lm2oEp|IIllhjOSPUswQZ_#W*9q< z^zW^pEz#DQFK09msR5!|DZF5HI`-NyKb%HNzjM4;X%xNXK zg+|}zg(|5i68QA93x91ETwNGMx4CSu7|Q8o@Jffpibob+6Z6Wv_!u9t^?Gvk1UOek z%w*PImEs)|<0~ec-r<6x^3V+L0ox$;5%<+c^s0^G@l$MJq$m~&B{Ywl7Z0@aV;_pj z1AC2&d1u1UzQA=I+sois6l1WBwrGZU@AHrvmQ__}m6;r`u{}Z@XgZX=W`sVuhwLj7f}ncT4hmus3QQzdk>iNSE@8A6adc4#zjPb1Ohm zIA@WnjAhht@?ynG6NWsyU-22valgxs%U5W!V6x@M)cY%tq)4xM{%3hvslJ$Fs%$IP zuifcNwR(qABy&%NX>_{rY=Km*kvCf1kFIWUe=B?_%;SUAtBCzjp7V zNV$g+MP%VIJ;x15A6%kgfbzNr?cuXJamS*L^t0{je80OsQ9z>pmIviQ^?J;x1zSIN z;JEOPL@0?o8F0mRRZRF(nfqtpc(m@YbF*)+ zjtS0J-n*I`Jyez8Ob* zEmH}vbfDbH(U4t8#~sKIM^JGfo>d4mUbFG>IFFOq&WK@lCt;lI#vA7)`g7Ng$JmE9 zp1u?lv?H827WX2k@w8(<^jA?Pdh$VShIRP zby`_Kd0kS!y1&-uHUs)HM&QJgD<*#E6X`u8@gBHDvQC2%k3`6muTL4}O9&56$VJ6u zcK35FLydO3O=tP*JTRC1!=;Hl-+gq52({fFJcjiKj@s_&)H_W+=GO@fVK~xCYl!sL z`B78hjbe9Yq_=9g6Kl${IPPDRnzMzu0N$%ChRwCT!8_c?E*p>Q_ zHE-D?MU%4Tl}I^J1=A}_r5BU0F!`J>@eZ^<3LmIK`WwCXaHOtf9@vo!D4Oi4QC3}J zU8XFY<c2iHTW`eSvs08) zNqf3#Gpt7|MUpo1G4|`|>C#oWg+bAk0fTDqg^TCCpzfubYb>Ezn=`N5mhH(qv1{Rr z>#RJ!?m`;<7-IDIibg*IccsaEDEW`p9k$xvgSZ?mT3^5YkV3nIsV6?_1MAjssCM$P z3aj5Z>2+>Eqq?C|mC`CX->F$v38X5*EMM|X`k#3N#0R)upPLb}ChIiq<_q+G~d!FYn zKg!5lbIrO|oab?Tk5-w|e_OiWR@@jbQ$#OM?PlYjm^k)>*c36D+a%4CzJnNS2IHp~JGDY}@B3aJsbiJ=0qldQCUNLwnL9V|V2P`DISShM(+jooS5g#!xt)#C z=m&{GT7EUKZK@Wk^$eCG<{G_8cr8^rNACZ()N6qk<^(8Dt_JT&%Tt{fS1Qwyt zZ<|@g&*yR=J2m&s``hb8jlY>&47d#@98J0sKEthD&$i(qJwyG8x-Y`8L5adrdfwaf zSm~R2N?IV7SVQBx=4EKp#jnRDh?U;t;qZ-fe3Z51tGB}z3uT*|4G+XBKomE zGBe8{;cYtFfqhytUnTdK8egt*b{3G4Pi2a@tVa#fAcfJ2#voM-LZK)TSgcWKYf(#` zL7{^edd{`TvAUW5FjX;BpX<`xq3$YPsyK@)BQ0N`%I;&*$f{-<2-^z~AKD zJgvhQ?{vbmr!$Dv5Kn{PSzTAY_bUlFeEp87Qr4oRVrIQ=lTskua9)4nw31rFGag%E z;}W-Hb@{z+RIvpehI#NUia|t?9+bSY+R0)GrByJ*oM_D8qc7NnTuRCH&UqE_^V@c; zl*+wZNwMeNKeor;z-Kk{#BuXhpEm=&n> zkGW8ggI+>9fVs~Kj<+(;O=WrqO%AP$k zI=0flLa)V9mo*5@)+?0wT152O&ZoLHndqIn-<%jLR z>H)w(3;D~2$j`&kIG4Ex40W0AT8G+Iw#2i)r@Mywg9+(ovjnpmX$37wE|13aEmNZz zHl8C$sn0Ehwl%rUlt3!E&B{hJ8V2rdolD@+%Sd{89hbGiz%sMG?MUm@5+D zhaDwE4bO&Iw=o_JX|Dg3yT#_kP~tfeeO0;yb#ij3yZDa(W)a-aP{1i|4u*1GLYrC& zri)s%NgOTg$sPi$+^tA{>h}w;HXnfu;a3o=vGNUvdbbOVzHE(l)J_2Q9dpo3S#KOZ z@9E+;>s0`jooJ_Gw#e~1gU3ZfF*MG`j#T)jwj3hPOb*v zH8sui2~qEe^qvo-Y|Cb2dxfEWsba;{4NwlqC|%zYd#7Ac?=Qeb&D#O+oGEtf?JYWT zt&WCZNQqEPv)ylO&U1ikv-Dl`&5j(BK>lHV#4Uy!{}ONBb;Xw=@}}7i%1UcZ?O(CIaExTX0vB(E8+!V9!=^>2bp| z--{L~#54d|A?5N$mtDjQ&ysO8sCB)km9VcS5JbmF|1^JokttMt14fPm^kIQ?a&JF;4}5e<757M;qID$)j5{ z5ME3q3)Ndyj>fu@VZrtAi3y;(clLxDnX%{6!Y$x&J?Jnh45AFq{oiu)K? z$JOkcd+39;@qyAnM^&l0N*nf zZ?(A;5HG{&trFUx?0CC|L(2H4a>mc9*INcC31W&Gw&e&jgvQG0`0Cl9Yc8aV0EtDLDFR9 z`JV6R)~ff1*AlKe^~XZ{X|(y|j?y)La;-^weS6(wp|tza>ykr^kG$IkkxfK$)!=fcjHCX`wrry z3>v$1Girp^Oh)3bxhNYnnI6+&TX+b}Pl@?UoY|ajc`eQ7ndC=|GcTx}?5g!)mXhS**=<(5(Bu zQ8o{3W49~TethXO_Bb&wrGVH;oF;l)(cDTU=EHA2ILv8v(pt%gb^CbBwqEswVsV`j zJy|ct=jQz2Q(UU^^l!7u^@iG^oB1I5zo9DsfP&_IZ#r1O&8@4w6uKEdd#dVRQRjZ< zTD>abaS~a?h3666O!pjsWm${@ZfP-ukco+o6e#*TYE=`X5lvS+WW3Zadn3cDTgx+J zJOHI>xf~(~A!KQ$uM=6Bj{x`*=fN||Eswa*evgs0VN~uuA0ev*$bq+kxN9)@qCu@2 zvb<2M@+-6Amz)BwEibB+6dm~teDM+lY=xg^vU+ zbO7OvO>eTrP*$b~9*t40t+;Mnr{^7i1AaRXp=T<~EDKPzh1aaWR7w(ezUeF6VbY5~6igsvm1rnx|JPURm^i?80`PD=}=HbPlBzseO5n zDfVaoXn?HJL6AW*Us|5wG;g8C62Xi=n7lobE42O?WvfRy5Fgi&uqchw3{fGE zAz#t9t-rg+!#v20m_3(5NYRhwjUkhPP=*YR z@*o{&MM3?L;T1eJllp2*GXm3|xJ@V3T6Edh92o5G-C=es}f~IM=YV2BPRIs*x z(ryY+Mei&W;!)6=?$RDt)+v7633K!EHMX|DYp#z9AusQrbJ3}`e;VC3UI~$cuC#JZ zl1APjH?^7!VOvK1!>U5wg{Tth%PBh^m%J4+H*?tGv9+)$q*GeIzH19z+Z8o`qP}paL}gVGd)2PWLtk7fgY=hNVQhf6l2>Lec$ru>ku#{K+acV5tHi=hyw3$x42*> zuwQJyrcUicy7OT=RLFAuxz~@#frT$f5=2e;-!mG1DkcjwVoyOvhT>YPh^Lfq$(<9H zUOM9dOh2wanM<*}&hw%_+mG6-E$Yo6b-jkibC0zvbI7Rr|G4!o%=Ud^{2)ZLNO!jA zC(k~#=H_MD!hxf*=D1r9#dV&=WA|7TfNce}VNSuaD#_>mi(DfjPym@5U*tiK}^_jo}5*bEfa-nQ{8j zhcsX$-+2!0lR+*g^PkOLRYY>bQ@Ys(H4`X6ZOc$%jftw8z(PYTs<5^NIxVp2g zENY}T?Wq$2*$P35R(pk{*RHHLhWuQi(v|L6iK|-J#z9{0g?%6iY?eYL_9m(Jteh?J zK~`CKKPhB~$y*bEWe$sc`(E9QXrs?lzf5F`@xI7f^7&rt6hBVAFXA{Mp`CVxfvz~q z919P>>P_{%#iVhTayMCD<75Rw@m6y!|dZOh>dTHr9K9OH9Xn8_wAJ zSn!E|@@!3&cSf0;AJn*&t&xtQ<8?v15VBD3=&|^Lyse%QmLp-%ce?y5>iA~YVFqRa z>_s0B`?aqgiqJ&|lB;^OV~}bnIoGede~bL)Wbscf{d@`m9~WTDC#NE5`S_71XZzEUG9S-A(QKCOl4)2!K_zdFzW z=QYvjT$Ka(*|X~C50BHv?nwksLJX5f>%05t8IzcxO7|dsK0E05b!!|MGfk@ zNW-Ir`uUnJ_CKIO*;Ij_G!2>~Whj7;Od$9Q`;N(3NG4xZbWeZ!f{ol6!(1Rzmv;dN zZ$$^`!W>M1tT?9_l{$QLQvS$)w*85b<=NBCmJlCd|EEI8cWR1FPhl@_B70Ra$Z;W* zE_A#e-`-v;EWgFTQNRs4;Ss>n_#-+O0da&vvy7`f@#}U87JUo@CKo1gIC*)Fmq3wB z`&kMEweS$9n!2cz@;4?u_Pb)LWBtRh0Ug?mu5U%SllVmU(NNCNpbN-1O4zP9fIWuR zZH_`q5oRc27c2;Mtf3e(0Ky1mKN&YM9gh=q%ChX3sY7T!>v(Yn zi*<)ZFf7#&hFuIFL!Hq!pL^PBG^N~Tk}Gh;h-*rmsdU)6Zt?D8?e~58q$J{MCiwh? z0`_5UI1N1StVVm8tLa+KUL)|c0CigrG+PVR4~cPF`6*E>+Mr3(QzAL6x3MRYzY1F3 z?&Qct5_(RUo;(%S!No^CUy6QA-!2YW-xg(Z5pCz9w4Eb7Wh8fnL7wnL{l|ocMpL?~m4qKk9>@fUzW`CsvzG<2|MHA#latk+<=ztaw{nT@X4(v9ap4KJ}~Mq?EFW zb1%p;Y;t}|Q`QF@wRcHx01@i_Ka?aD>2I+aT(JL`X_CZRSpNhRf;C59H~*s(2Ab%g z6K2wvEV8kc1TAdAzgv`3gr?SHzh{LiNmI2pj8zhU=aFZhjA?HSyw&C+64tjMLH62h zB-{2#3}>v^XInwHstF)-c6efFFI!4eDdI#{7SemM`Z2QG7FvTQ#Gkq#eNjDjtaZqi zW*~EU7IXSL2v=Iq47y7=pNZh*$@0%PHALJm?1AV(gYFYEd#;wqCy2<@(aSH@nfr$B^J0s{4EvVshyoibfR>W1SAEPNcd zkptz^(vcj!(o>LX9(Z0t*Y9MT-*ca59sv|L!sB2WU)M+kI)PYvqE@H`gf<*<%-o$2 zgJH|b6PIcIAUujM^gIG$Ezmyz-G!bl9YwL-unNC**i*Rqz+xDEmjcykyh({SrY7z| zI~}Y*pmPWK$wK|Y14_cY4 zC!3!^@#k;h_VeGd3abqKz=|9M)&m%A`&8emGPCb+jv}cu+-8y|`p&wLAJh^uhQt~0 zRd$%G={?3z%7mV~7#Z9?PsTXJLdT0EM&4g{0IqdaGl6h4W?rG6>s|`WN}E3{FkY?m zXneVXyKdTJgKRmBd5@r-CF$vKNS>3^TmZu%fRA~jkNy%qWPlVQhYQh41nIZROu7cm z8?%X4Q!7L>^{Z@Y7|(xG;?ENw+u+4R?G=`Q=k z1==BnLQ%|>aeX&yDY{CWOD_n?G?FH<0(ZZ{YHYarjn}9~a)c)~dv%jjawtlG{z?XK zic-J&T_5{);mK9ITPTu^Q^$t)B!mmgyYH6e&Kn}?MamTKcH}6ePhyXo5Xp~r-fjG? z?k25g3sS^yHHw#b`{o&u0fRo1?Iae+)XriD9ch{X4_~WEiEnoax2nrzhE3^P081_? ztNIlqmF`!OBCXbvfWx@G*owvQZU>0?Nd8EMy}(|Zru#Hc%z>j#Zb{HTm@NB;;osuc z<_)4rj$q>E@fOcQ?s+~uaCP=8$Z1pp4svfvsh`jPwL*!L?5h4HD2#F{pX)5^b?>Rd zM-$pkKG_KDB^%mrq18E}twZ~71uI<>h|BU*wA4GDSE5lU-o21-ANmB-bLNL+=+*fo z({g>q?!R3^Zos<8F}l6HG~&_fT zZ9yzQGs??pk_TaOZYDz>Y&DBpy+9y(div?l{9Mucd8pqHkfrQ9?<24Jiz`|S)ZL-e zBF?LkXk*Id-0UDZL>o&7=8LNN&R&u2mgjjW32}uSPvb-8kT`(4@DjV`aatxD^Z1Nc z6Aumj^J;rq5y$V#s7>1xNdCe!ZvRN09Tey4gRUxc&k}XpeX$Yk6<&!t)+9E)H?XB8 z$H3Cqk;`HempnO`X9G60WKeHoY&Ra-2#Y-mxd>9W7__3xd|Pum)N*wbSD_sat-f+u zYaaaaHpg3?M#sP+2VYDg>e#Lbq3?#$Z|YwV#lZ+#AOQ{>MqbUAp|Mo;a6XJ>p_dbX z1DgP0r^e;2`UKcn=xv?yj!K~>=jYb1_jk6c`Zlv$aiw$DRyM-sWEL{o@vcY-mwD?Q zteGU`lM?Q?y_`4W^}hUlZ>GulEf77dnTt1!Xwd!=Inf}2X_-*F81yQI2$sLA4-Qh!a=h3BU$u8gaT z=T#TiG=X?M9FI#si(aRFO72i-$9er$Gps3PU1zo_eDp#m;%YIrZrA8n)3wiUlUpy9 z3m%eg@Vrc$EY4mS&LK6l&4LVZy@!bXIi*YWkYWwtvUf1KVv?88^U;;O9IoaDzxxe-g za`7L`x)gSnaF>C^k>tdO)nYsqZF+TXEM zq2fay7ayb(0seCjj!f=9?Z3AL;IYS?$ol*iusX##RR9#&U_3{O@!#JDeeun=@j8*O z!h+9f`PEdd9&v|OVZfumzhu`KLv%L^L}Jlp1Lg>kju}~Zs{Ftg$%6q^5M4T5^Z8{g z`&P!mjEDu0XGC!sOVPy+&1}37`sXd0RBxu65p~Dw8|!guMI`UP-W#|$Z&EU(ctJsv z2m>t<4Rj~VNY_A4ZspN@?R|iJw$aRu{a0l|TtV$7UbovZd$H;IYAC-l6IsE>@<#IS zOf#nnncp~0hJU8@x;DxFO0?;wT4}Ahel#SHmVZ_>{VDOEUxf?4Eth-Y)cdM8Uz@5R zBlo{9%g^8|xT@wHu1waO+lI>Li1OEt26iml$E-*HLtuu2|8$GsFF>HsZF^HwtWy(2 zCEc*1&2S)J8{7{b0?f9e36YSqc?g}DXkZkJwD-fDq<{RX^Ts#tUFz)kh5x1mllWG~ z@!uCwECuH7ri84RkPx(|N`8PyGSTS`>M>Iu_PRHK@5+MV{~O@@aU46%``e6z;LZq) zPJWFf{nu~3d0KB++Pl_cC=E7%w>Hjy5&v)6Cz}7ws0mVweDZh5&*y@BF?i?SuK_d3 zUyrRG3y{0~|IhIMyoUbW&6Gf7hoV>U0xf9;V;RMN#^gV*x%j&qQ?;#$`}>u!-`s*s zVaI<162a{yx>+!ec6UogxB5&&L#~eOZ-Z-z_qtXeZ2n<=lvfc z6gm#L+4v+q^no{LB_^EiWcV23_mo{zMIqK0DY!zbu9pq}bNM%*vHzkK`yBM}^VM9P z?}*(z7bR+J_hkR`e#YJ0PfnY0agE1w=vHF&-V%UslD^_vto(y>f!S+VgMr4kedkt@R8ABc44EB~JZi z)@@ZK&*vo%286e~?9UrgtCv2sxKZKHB^#!7IQYl~SB@_Kabc*J;N^uXdx737y(ve5 zIuCIF;|265;M=p=wHiWcG0Z`%<{CVn`u1E$hqGTLi`IK@DU6WI3@HaTma`!89uaiB zZ6y#d9V4(yUwyBvJbd!gTZK{lr*W55MY6W*h1|4sCsj zF-zgr9I{3F!)u$EIr_!e#O+ZTl$LAsC+DY6p^!fvv9HrWkzg>{DVW*0`W@b=StfM_ zT=5IYj(kQ6mL6AU>oo!1N&sDaT4UewD#dS*BwvQ2i$7iBAV@g{Q)D%f=w8z3%KYZN zs454J?2gMbRN{*K590%`PPL2%Ky;ovkUsA=`oXFDvsNYTw9m)m(gj8}l<&K(SU5m+ zc_^eWu{^Y%m9=tQq&$(Dr5se&>|1L&XRTcS{Xn`E@9?mfG}s!Wz$Nm#x-0Naq1sGeICNr$e@hy^J;9l`&z2jOu;Ax8hVmPY9 zi>t>sknZa%*N`>^E&I^qMNj4`z2U-%`f^~%dugYBpbyGwp&OQP4zrnFQAAUP$$d7E zdBME@y`y{xm1ZZGe!wxuKTw}JSH ztKiegX=5VOaeu8orQ!x-IDJa0{&WO~z4K3vN&ZVS%bL|ssT=33>zWBOkFZo}%0iWX zAA8N7Ivl+<`NQEx9jC<|pQjzeTA1^jFx>WbbJ?#(ja+qk+WxQ%`0CM6FwWH+Z+dX2 zE)a^4Oxy?4_T%RtgWB(P|2GRj_rJCrkvAhda@SGwe~))C`cZ-42em{ivINO+&p)zq z>MM<)5t;QmQR*fEnBQ(z;CJj3lb2^lzSkMfpyW)AO8|$oZBJE2d}5T90*lGMVl;%& ztnXthV*3L0VAH~$qu6e;1J@_YnHqey1e3P`7@EaGDc*x~UR&xV*aVV``3RG;>%^74 z*{fU2;n1spk*`*qRU~#nG`xhfyMNt5)OrQOVt)D-J?d4vxLsAp0)uo8sO-nAyiOAM z7;=}z$o&-pv;O7-c~N;iW;{_U`7@uCj>mtb?ijssgq6uLG;j5>SFLZ$xRx0(R?USs z1lnG85~T!yx&Z6$$+Bd^Tow{-^TW66)K(Qxe}F{PC__ZdVNffB06K8eV}^NHnU97FbFN59u3~7S^e%L4<%vkPfDB9Bj3T6W-nh$yk^ww=;YOnJ315kTRyBym>NN?7-@Cq$#J;49{2#VOYW{UY z-$)sx@Fp9qVk5Gs0bjYa4?RZ2{_b?W32uYWQHYOW4x;(uG)lB#&Ra$-5qgxsYo!FV zs<2mYfd!HnvvHA0t{?cdSqxhORB{yVS+*!>bjNYQ3Up>`cEMrP{MT0*=NNt3YLHBs z2b;fAd#s&jeRXwi$EutaI`jz0hojCBU`Qlo?QOu|uG?RMTT(d)uendvmMJ1SS;*xk z3Ol!QkL@v?h{yBHm$6xZPoz{+W^%dyL|?Meyc|Gj6u-XsXg)XFK*CB?mx$4h2}){& z6}Cg|W#%_`{kAy*q==X&+#e_V4lwIYbYg=af~#&RC#UM22M^|+?W&S6tgXaSO8f)a zrnXDDywP*0*GUB6Y(cUN&-Pt8QYYp7r;LH`)MiS9Ynk|-lkOJP3jJ7&}kBCV8k33yj1+fnE6S! zUEuMLgL8fhwa<@K{&ZMG)tcjHuc57@f~)Mzy#nKgowq3vVRELLp;)nUgFr)sQBa}M zvEzExV25A0uKGElTU3VY)7PVO+$4m+AMqg&!Q8SD17zS9WK_u z51ZIoc`GYxu*2oHJ1?Uui0V|Pt{*@5UG{Twx!EFtmh9n4J4UVVfEu)A;u2w$^l=eG~}Teg-b?2JJ0u`*4AbU|-POD%pPpWVGw%F4lE`O@XcmBR`n; zc6BjAgWz!^%Fq6u2>vw_`pp+1_uw3H-{K{JB`0Kaswq{=2WI{>#E~yHxn4;F@Im@;?q<_C&j(7Cs$c-#F3>Dj+2b$Jmj}j}J%lR6j(~=*8=+U8 z_1b&W$ExeOnwPHMwEKR)wXIbXx)m|vZ0r>t|YLQOv?WNA-#7__8 zUS+$j?>FED(g?UkN<~m+>PYD>5%+hD+Kr0?kYN_!z9{8>Vq^iivjHsQ$DDX4E2+MD zo+Rh(5l*5@_ki$|GwQ<`ri$~pk%Ao0BmF72OF~r2H=tBvDkm((!Ouf#cZQ>eY!tQC5d+^vp3lC^E1;LgM>Y~ zeATWj)h%#Da2*2qUDZ=e0@1xd(hh`&7G3WU=+aWf_iZPWRO~L;F-+0kogSQjay}mx zow6992(j$6j|yKB$?G4HpgPLZx_fQQW0F6hSI7|2mMnYlZQs+{qHJvQ1#o$qr5(oD z(5d}0`yp%M`P!_1WawVs_I!32IPwmTD$=Y?>L=0=!1iV0DuA`gH$aKBC{J8G`Ih)r z3xVX?#7zE;Fh|SwppL`k!DgX6k zOcBlU-prwN01(6|%?63E7zaKi$Y$Tr`&l%rnO~8~hBfMxTr`o10iL{U3KF&&5%V{( ztGN7nV(u^032f66nGi!F5v@3JXc~CObJO^B%5OtYsf&<&H|lKfi(NSywqZ+p|Kaqt z!?XB2-)X}atj;Izq69p-UPd)A%P;5+K);FBcqF{d{Rqu+lmAqX4x7YUYw0y{UODvf zKwM)o{)kGwZMJxTtMc`SLxEWcG!*-I8Cd@E${;_UH$AWSz5LW`lhSwTamUVEf})cz z4LAmbFj7*d>z~IhUtP5=1{{HpMuaNevs0vOoeVKbH+d z|8MT4Rv5g7!Dhw~BdmhrX3y&8<-BA6muO)X;n$8r)yCQEN;A!h zci%6VdpQ3juk~?b69G*@=)~_RPT6}e^=tj!-Ul-J40^GzuM_egF!rg_=Ch_uH@+&T zG|7^qO07ljAFG_kA&sOzS!LW5>(?+&FATlsQ5Epf&{-;>o z`*ij+AU{Q67@dWgaZcVs zb~v4?!_}c~m_K#d(GwgV@@(-R`ufCF3pbMypcN!(u~B5Q=p{~x%=@Sx%c$;73s)d8 zw~|LAX6>6waBUYK2)%176Qm78;8CqA=W%UEYCwZRg6Tql}}1w*$QQ)LCITf<*p zTeWhay3?<#XJxP%#^QiJg*(m1$JRY{or*IPwVl0NGFtF%4!EB; zTqj@l-V~RYaNLdp_ha>+I{xiI{;xw8*xbOAc{9qzzFkxn7=9&3-n6 zexK29GU<>#osn~JYO{7w4CE9aPR$C~2pLDR-@`%<6hbtO90LQ3od39+r?z9vx<9_FNj!GiF zb75qTySHJ_P+GpRbJ}De%Sqc&<`;*;jiCp~ivhBG)P!Qv;%H?KXBM`~TO(xzFS)T1 z-;USdg?bzC^Ba=`{!h>AqLgt0BAzVX;@}9%56MjOPd&Znz`~dbo zXN_}(r-lOI7W2@yTB?PK*Tp^iR0vK+`sAM@ces!%*g=#Bj${QG=+%e8js%1ZuSIV-!B@(M|Z3+1GZ- zSnBw=(Z!O3#`wp#7w6ZCSvaq^iqH&pexx?B+&UnEl|88NK8*U;y;%&qApGJCU1#2T&9 zw&FWEu$(*@f9fTDDLvo&tnJHoGHJYVpSAzOtWz_)Jeh#-N;Fe^dbzwH-%u!%A`nZ^;@$L6)HwsCD!qEvV(iUHUf+=r2;XBh}s}INaPNx`{{I6 zUsNIks^2b~#;9Z`r;~1NFs494@z;ZNZ{Le&fSy|hJF%xWSe?AWUu~@$n!y%c^{!4-UD|E8Zz`$IOpI(Hb$6M%A|Q;_(yJg&!3dN-`qTX*XyXiRyN}k z3Z}XG`AB9fVoXZu$)$9D2sy`=mR^mo>7%&-zscVzF7uVuK5wXww`8ZUKPhn2X3T`e zUQcJ_0&t64>5DqU?UZG}S8Y^Tnc8yCC zx*k?oIC6D6R7QK2?tm3g;}?1VIfP70ZT<-*+~6 zD2)BDjp2V4h~CzrfrDy^Dsee&;$l9Q)j}mAV#b_nkhLq(6qnZLZ#1miu})sc2H3;}6RL&>0Ng zp|x6hB0#IM2!zqj3%?}K5>r*V-0IuCLsnkjLd-ecwZ{tb6b?O>;8XyZTj4r0wD3jE zD-Pd1I~Sc5+>Vt!ye}L^X?OiRnRvy_!iX6i--L8u>$b`IjOzXtnitc7aof`cbQpnVSo8e4VG@ZeS*?!zcVJ`u6JM-4+?}zWxs!_>V~e>Ymt?VvIU~`Ie@LMyf*sr zCm^TxZre@iSjISv%rDGs}d$8bJ)$qG- z`rF8nPt16Gr0i0~)an)xSdmN~pLhQ6pEtB}y&!4@il6cB?Fal8l&m6Qi70e5mveM!tQX9JUMHop* zJVDX&Xw)G<>v)UK-XCw_x9jRn!E?}dDfe>SGp0AyPG2+w8}C_5G>>BCeVlJR@PNhz zgdTqhSKyMU<}8GK!=r#|{M~lS<%g@wV+K{K+G&D6!xr<;Yh5k%^8_9J9YsdYdt|H0 zTlVe{pb{r01pBH)Smga_`LHBVUyvryGs?y3tkZ8!&j|B)4E$QTzSi{+)LNa5WL)5l znVM=0Q6F=pq=_}L$vwWVw@#d$PFfxqDd#D6@sV@-X}IqE>W)~`Yac{bk0fJls48d4 z>4kEBwi892at4L8=FS^LFtiUaxMgeLQ#AHvT*WS;7_t&f`M^2JNE64a0d1iQuJ{T{ zy2_%xV(7jE67#d)$vwc6xaE9NNyOq$scuRA{>d&p%(Av3HS2@p_%_BZdUc;2BRnuu4YV?(3C7-dSTjxj#dRnKV~Qz$;b2n_{Zn(S>avXe-)xKw$)* zH^Mk3qu>6d+fnCy;qoysf^chD)WNO!7Dj+}*otWHIHCNsz&8wdMX#zlsygnGye7hk z<9iwc4dZGt{^H#Z1A59tm>F%A|CR&Yb|M!l26GLkg5njZ)3>q~&YxrVanjr{;=Nv< zGsoIA?A-H}LY1#_!F#^!-2cM(s*QaR!{v5G0F|u{t?&FJ8}wKQFLJ9@V|wNty22u786!+qy=b>Y0|&5reTV86Sx^Sf%UGwMLJV8@hQr2o6(_U{er?qiHb z%M!$5d)V;KN-B0*i26qs<%eiFSSJ_|`NfB?S63DLIM5wz9fK4{i%u^(hWTtJ`)yMk zXUQ8pkG=%qQ|0OY$N;Ki=aV1A+MlH6d}I^Hp~Uu)TxF&`FC~HrGT*RM6Wh(yN?uZw zO?4@MPlTEDMsqVIi#i3pjAoUTz$C0>genXny8;dxaKz<7kc|RCLi@Lq+tnaN+IhAA z-lA=VULC@QvcIY6<}8c!I{ULB4a|^>7EFHf-r)~qJ}GRd73Kh@PO7VqmeojYg>D1L zSC9tpVLFIy+Sm_^sdpaZJk^|ztRSQCfD!9xIM8j=XpZNPpz7o9RmoOH}j7?twocYeK|Eko_{bP8#=`3E{ri9Dmt(4 z=iz#~fQ1nN`;GU~&y(_!@;FAYKO&(V=F}B)vBWS(*goENnQhjWvc81hASNV{*;Km0 zL!Em}Cm=3X^3bhD0xKN&jCa;2g1z0|WAp`CjTLV^kc)MD59{lk6ZCaTyOuX$rVFpC zZVL5ts6!KDsB_&goglN@@rm0MFbi?_GWVLHbfSwaheN$H#7JDY899q{ffO5Q&(!}r$pT3#KhtD5>7{IrC2 z4TK`7IjQE%0AP#{bLk-Iocy^pW#L;Yo3prrW$e))nrZrkx1xrkV5DQ=VO_1fO@#%f zRp}knj1QvVIqI}@Ip+w6LgRFO8{=g->0n}7%DN;QIAx5irEu@^ zX1mK_G@uo1RA14_mN=cqv2X4QJWU>r%dU+083`s84RE^B61RZ35XDte3K=H27(+tP z0x%)LzAOf0PYL1l`{2wp#2zF_Y)?_ZYYCHlA3Gd_LEoQSp-d#!Px3>>tXpl0>slvX zh4-GS$vm%5kT5~)h{0nWl8sWBH zRwlKDJIsLS<1U>Tlip7`Yt39X0@U=-pF)WV({WJelo=j)^agM1V4zAih6+J-yEv(`mL8p9`gZSCXsC(}~C% zom28*gMHDeb20H1ASe-Zsg|6Rq(mV|&w3HLAK2$gGZ&+9_o|c$C;Z&c1Y*qiy3=3d zt>3lf4gg(JOW`+FKJkXlFm9~8(g%9A(#-ayBzrogE5h+PrQjH_7?t?l;YMY3XJLVH9%3FWxCIxt01#ZeDmSM9m z-j|a(MGucfG>5t2w(i@D$Z6Nd6tC<|QG6kUJ&;DZfc0dgApUZWqCZycIN!?uwes)c zRnA5*6~BdU*_~#_9i>SAHpAYg6X0G9gwTK%bf(wqv(?wZOXZ$p79KOhmSWVQh3)qa zWH?URK2jVFjwj84pup|<$uK8^UW&YFR4FZh0$4uTKo2y1F-i@w-b3@_0%yN`QCPtH z`88X=6~?5GJsgCg?7i%5!lU=*zoeA+9=BWH+WzgffT`#^sCV?~tu7h|UyMuf^D(zj z>2I12Lkmk-2Wx1f38Z^ zVpC}|lSe%RStT*;#}LmX0Q|?@EP8lPgHMk>ALR|FpAcz_+?d7|f3`7Nq-viac&Qdd z;d!{aU@zh%WDV0mBg$#c^sgsi9-VE&sx~Rt9S(6USW^d_%wK+XX~2dqMZ5aRL~w! z^?IvYrGeS)E7TrSgNF*Hq)2Z5y(Vs-+BTq{aEmuFd#4hu7?OoX`#4feZ0XG{9>x19 zaxoijAXM|rzYANOOnE@N?QWxVe>TyLU*>k(2jy36B{Antb%?EkGKKT`Bw^=q&dyd& zE(m|Mrl_F?N#v>y=JdgV0cIG)iV{Z8nzm4=U8!(!vKJQoXl$iBSr#mt>izXx&?5iJ z@9NaZKqxeW10c=OBnD446P57rTWLHNS^{~3JBU%o?HY|o|uFbnmWE*t98=ZIb8v3eEaA@6oJ| zcV#in^Sk4@7bA5clb9;jhzq@r-6v^|^(aVxF>tdYR-pAG9Q=gPc$Gxfp0-KW`hG zsPYx_KAv&4>_$X`0H6BrZ}|qff}n>opP4pZPu=FQNqfCV-ElBYJwtAfQSbqYD+GiR zu)dInX}hrAVpsBaHt3wAhl4?a^3^jfr+Td?XD4z#2(2(r@|6O;SIzEjYCDD{gh zICoV_8hZOiZXd5v(n@qM(x*tAx?SwELUI@5p=JifpdeRFf+O4kgjm8h#M833sZo;& z45z2P1c>E0PRRuxb|~9c;Gp8YKRpZnVBo4_N1X%@{qy=f-mvyU z1(c&2rfeyQ3?5Ivxi;XJK{r?i-fuySmxLVT7EY6}L-Z4wVB&&8Ve`_~Z@Vw}lhYr* zy0%T3)m~Yc>LRq8E1_BwvHkpxBqkZM@CKf#=7^!5psVL#gFjjet7~2(->#5^Us$SJ zBP%%QW-=z5Y|5tWX5D~tvd%5bm~604Zb4bVa+`cA+VZk8-iYxypswc>IArWSEsj|c zt-5BSze^f^by(trcWG9AXf17;c<*p-mrQD(o2=_{f0!!LxnZx48S%2C@AQVY(wo78 zqcWVW!4A|5&y+16WT|~9RyZ+F;V=P_;nwlY!GBw6%hu4MA-7pASP6sssAY=pJ#cb%N0z+KL zpZ<(4&tB|S>h0XNzP@p8f^t`<3&moUFQ!g6nJc@^%J_Qf*ztA+;`PPH@RD;@H1AQ0 z-`5K>R6dF(kOtpNr3U1H!wdr!GbuqQyu-D;;knTxT)kE1R(oeabq=kg83pkfdXo)r zZ%R}9A@RZtCWVvj_w*ZJ2A7LeWW!nIeHc#dOWVeOz9NO zAg#WrqM*#8_>!NmR;?>6NK#0kQw*?V0F*R0>DNNs2eL|eo&KvbPx{iy<|UA#)s!0DlU$uEBB!T;r)aSNEAutw5*$d348^m#RK#VzpRD~7CQ z;{1?iB1YM$64)O|7}R{A$l(PHOIrL15(_#=*{nr8oGe z=JOys9_k=(ptZ>m!oxA?j#I3WK%<5GUI`N@Y9pF4;@;qi$E%JzD8Y}K1@ENkIAYF2 zp!e(qB3jZFJDy_xJmeW$C9x+I?(L0W=GFnYC<-o`O0F;5D%uIh+BI@$a#PLhr5xmC z-akv&bV!M}krhY*=h`tg;pWV7zQt~<^{ynDObN=0k@{Y zmR1GH57*>$-6$;Ny%r9?Z~L2S<5lu>@DerM!y&?Nf(Eh-8u<}TZhOxJ2hra2e1`KM zEqFl;C}CUE$@kV@Ofy}ZK|)<952aC&#uU$C=oWaWj_N<8qg2~%$gu*jH~VH^Q-O1s z(W#o(UtMa^2@wf4K$I*#w_pIS&}?s?0YV_f6BDEaBHG!Gr>kVG{TSB%emUW%FuqDKCLD#)^~ zh1enJ**iPSP5OGHW{z()VkAxz?X`wDvwoQ3MZM`twr3Fg1wj<&O+4(i^Q8PJ-#3*&-G0EFH-3-hqnID0p`h zMT*ue5D@P|7Yi-uQ=c>%bi&S-79x^W0nX+6umr7Jc^3KEidkoINTsE`D;nh&B z&`AU3*e-7prK7s)WJYDpgPQHWpzZ{XV3C-D?`-C4LzayqAQyK%(wHq*r@!vP_J8X8N3Wt=VA&L#;&fsrMiiBD9MF6~CeYUbXJ}W)zyR`{V-=OQt3M-K&w-6AUu2AFmEck7` zAXr#jIxZB_+8gY&hEZzGeHkugDKKk*92w@3e^#}N`xyo3C?7;pid(>I3k4nl6nY*` z>EHKyCP)H=_c$jM1I;v~pgArzTV$Fem9P|M!Hej0CnxR=2+4Xb#s8f7KzI-YLae2p87F@tktG(hWRbW zDUEH8#If$ts(9SzEdU~&M#TEo9Z$xBwguxn1ymzhfTl!YoUdRa?&K!P4T#y9`Vps< z<{bbAS61+RU(V|eNtc~1yBeYe5Vi_^S zpQ_IXqYXC3V(5H5kw&jknuPFSNUuzo*rpn)h-Xqsbi0hgcQLM+3GFgDIve}6`RU6s zmL3{7*z~zyWA9c!Yf_*Lc;dp8Sa$zY$vC*OtTz)U^Yxc|@1*yd9F-xpQ07fGs}Qvz zo3!El232&eJJy6*(iuZRO1ZK?1GYLYnhy??%l;UuI--MH6G{96fH14xDqIgYzbHu4 zvxDr1^S2N(=cJ$98>eVQSM+B>Dk zP;F{}YYGu4V!$z7okTR*HIC)QVLb5;99O%9{#*E!M3FUw?^JTB7Fra=b@(yQ)-|wV zvt&v1f5*?;%Cor4sdf*RQ`i7A*vwA_6dED(W4K?nO5t^Jr}dw%5OU7UiNHO2&%Zy> zokY5-rryc5CkryKw1@XbRzPfqV545WSfmrp9McAdI=To`WT#ac5>23wKl)xfz@Y#} zkL7PWFD$ZX!%jRAf4BxJh*@=8*CHRI%P#7@OFDISD7u6i7r~Dl0L8qJ@jgZXt2vP& zR+}VIutbAiO+x_i?KN|M`9Uwt3vG)EM2|3PuIfzIdrE%9i~to#FCo41b|QL7%APSi zqJgBPe*7X#l`X(`YN;`U26Q^SPE0Z=(?d_ZlbNN>tL^i6f0>|uxj#LE6W&Y03Uq0_ z13&^yLQs9J0kqAox9%{yJ_xL`P=ek0deV0jQ8*E{PI3O>z7@aGWSiZ1;;n0^$zTD0 zOMmwj;8E4P8B=n)mh|{!J@9DxP^WVYQ~|)bL)OWfTzpz0VYTEJ;zQJUdi&R9KJQ2f zkXarU%$~%)(-bVHhwt>$B`5$K}=i3r*`U zg#@a;M#p38wftXz?277nxp;^JLCzjmn{zUMl|9D&(5QLDGfSol+{WGcjccWh6<$h6 zN~*jF6XBybXC9-P`e8kj6ZP-$Ejo-I)*1mY>Yy4{*)CMms<=z}t@L_=d*Z-r(E8t{ z2uJA1nI!NLk7h~olWe4y4ysj|+O$&Ixy?~9jkT~2#X-yXMEmK(Pv+87RjqMTwF|`p z1k6%c1DwOo>2sVJ3+|dltsJTrlJfZZa&kKo&P2$rI5R#@9nBMQ3-yRKhGkXWjj|cl z;}<|xd5c!8K9Q8&bL1e+*eCT9`Yd>2VTP@ooKllL;Rj^F@Rj85fq8q(L4PN9ZMLcM zdiCCL+YSTq{kJaxzaDLhYm zQu@4R#Oy|EEBw=~T9ZC`r^X?|7%;25j@=~_+0VW&v^jlT+tfmGzV|*K@pAvoyf0X} zB?fTf6<Nhwi%uKwP|wm$vgvEe?mBq2`gzn=e(sF5RaE0#rw zZyX7ebaqHM&7yVcn2<~FUy17htNoW=sD}ec4v8_A+gf8CYAToxVD^wn!Iho0BPME+ z1(V|mh!#KkhJ93?D6-hju}rt!$4j>TD zi_f8k%|)P~YB4Z*HjnVYG$#I_sj9~#%k)7Tz4vCvom~O#=-JVV7+J54e>nn;5xKL2 zBWh_t_ls2jl?0ObP8q1bHi;2p?No96?)E+~WL+UuK#N0davFVv&(Esj5o#a64en)x zOsPYY?V;)A+Hv69u+rhlTTr9Ps)s?3z4N$1<-!vae%(FFfMkR;$y^W@_HtPdv{ydX z9dUv>^?WC?ma63$yRkCK^tMOd-?k<3#Tj3xg*9*kW|X&z@ELm7IF+s;N5f>2!Dt zQ5sB-fBydBTBY7Q2A2lRyNB?jZzj@CAm%r=wl2xNJ7M>6@VmWmA*(GpuV3{@^b7Uc z0@4ktf?}XGAhkQ4uxQakr)Moqb-0`#0mZigjGRlWRSa2gkan<-oDmyhl>sm{r}-G( ze8UROF7OwPMpMl;C`i?=aRjk{;T+wJdlNIryAjmgd503EUZLBOpTuUU@WnYlsDuR} z^P0ff@A6&vh%VT&O@To#3NRq3yz%*}`UpG^fKpZ&ej32mu>~}V45ojV=}xQxM012v z#F?PafM{-#sx5?7s8u;tgTt>r+^hfx(Bb*&_l|J9d_p*0K{OVW0OmWdb4978vS*#G zRM{G!DzHk_vkn8yGN8$Kt- zb9A+qd>_Qnp~?yd)J@A8%W0qgHB;{Z5rbY&dv~o(xvktwiA@bmJS)$guFy)_jA>HjcSd#~9w~af|#&OxA z;z6t4O{+6wcD069s)2WjY6v^tZq^xVWwb`ADS)C->c^a$5Bml+ix*WW1>JW$V!u&K z^L=RGnXkUt$5hVQ?H)f(?x5qsJu@Ba8H~{HoM{Vgz1V>71hF$?UY)1z%cIhPgTJqz zuhs!oG;si{%66cz3r3z|w$k-KNEIsV2bmsyutrg=Map>0KWBLyGFYu7+Udc1^}J8x zwQ}Y)0HV({$9NkIJa($lR~qzS%;}I^BmMtUAymoG0qR^9Kyx1c!KcXQ`-A+eUmesI z1loa$>7u8XlgZavD3kR^)(j&=<7!E*e6V!v;K&E8C#JTxb|-7cL4qqkgIEQ&XMKf; zWP)~5Wr2h?&Wh_U@d`N*Mzh9}QJ|IeH^mklQw`B1REgA@&BlaQ2}jJJPbvd-lq3vx z)^)5>egZNXptas@2m_SEBE4yO7)vT8CdrC3BL%VCv;Gi^+ zLl8D~IgJAg$1)Pxp71YL8zZ_(Y8ZTMZyt@u*ahLBAKIcy_JC&Wv z0H-F83QGl%4B)I?6F&f(H3E(H5bVLqd9&4i9Rm>74yzD|dO+G`eh&Zfr7ZQjy(s&3 zqFSMz1CoWEUuEz+S*(X*5L+H1={Uj~!$p{JNCjsE3T~v}w1QJ3#tnMmhK+QH0G|%l zIoksMOmuLp0>0m!C@azOIJe8q=w2lPSyXfZt*zc6JteI}eQCa@pDL%)*mO6a;(^;l z22B;}Y9?*py2b(@ebf28QYK;IMvNyNGd^b&AhhM2W1>&s&xFCZ&mTq>)nO8Lwfc8G z3k!ZN9(FD+E|&=k6dI+UMRFTko_=UE?U$xr$tgD!qn5HME zwY_@udc)M_x!f=9CXrchd7#&u8zYYjO?cn|&Ul;Y^E8jEKqBb&4t(P{>Gma+h>eMfSHcR1Qeu(vG0> z*^$EJisdh?FOD4$|7EqHypfkZ;iifxID#E6ekNSMGKaz6-pzVtoAd9}fJW#Vn2WVR zHIPMYV+eVhg8^OHw)O&o*kp=l^qEYF2oUSDAK$*YG!Z?jonjmxDVmIxzXqSSAzQwz z)HGO~E!b;*19--S!5=98MfN4 zyCZ{`G7}*^sjw85hd92L$R_ttzEH`BPc(JpI-lcDA7^9qdOh0$l_*VlE_hHvekeuMi^{P>5zQ`8wt1Itc zZ`@@bQ4Ss?YjXHPj6wRYwuqx}ZuZ{saSz--euP_7nqW98U|HuJSMSO+z;?)OQ#rm5 zU*sx;+&+t|aV9>Dxw&piGi(_nb@uNS#2@H!D8D!jyVCdlp+f(B*?!+nV0Lou;m}4$ zsJSH5Yn1{iaZlT@Wz=WMd-|!V;N6^M;5Q4^D!;?=xkRNh0QN5vkHVDoYBsFcYgGhf zS1@_vFZsRKD!jv(M{E8TFyMWeIG;z*Dp2Fie{=Ht)P+26c7@k)_ET>*)9skqxd!K=7NcMPvjN5J~#ppSE3)Mz=|J~mpS;X>R zLDxF$C^wM7nJWLLE|QM>3-Y?F8>h1_ZUrE71#pQ|2v-9gUIyC-!0;DOz7$!;j6+d zl=rx4>O#rw-q)p~w9uNS-A9>~oR6yJHVzNUK1vFim^eSBQ^Y!)Yw~UMjb1=aUaev-_RQ67(`7_xi;u<2J1uLT_@F^4 z!7*<~zDc-dl6z;<-7&>pt_REuZsza|19|4?ZU`nwyF2gfivGd(XsXPyDRDn>NXckG zV?@V=5NFuBsc*LwT#QBBTTbxZ`Mus9xJ)Uy=wM&2v9*_N9vaSqScvQK9mWN`D_P&K z!i8c?~8&>vc?`G)plQzK4LFFm+=jN!`qiJDlhhH`qu1LDG1H3iH*zG&N(pOA%A{8 z{L`l3^4(_vtu-@lr%9YElv44X%MS9%3{P0Tm&WU?Lr>>$6s;sdUB3OwNxE{Lc27nw)7)Q&cM5964TA-K z94HDk0g3cVTdXR^2Ak*jF7PgEBu-pxyN>vkQO~O;Y)fK33zB~<-A28T~`^^Yf0# zh7{z>y>14&tGuumSdW3#x!uw@&{cpOZNP^@a(Wz5BiKPuzq=Lw6SS*)N-^#_^;UWj z)(%dbEon(8u`uus$zbMr{VPcpT%SQI3Uo^O4fJhy=H(z!vX1bi_~>k({ycv{nJ$#H zOjd%dvq;}}uu_Dnsu*-3yDQO06h11$Fv{(^2aHayn34nA zy>}_`8QmF^m%$#JI42x-VVe%gx&*d8hN#fi4T4hUuD;dW!EAUmjTn`8mf))vucaIb zRoU+X9dW0jbKR(qQC-lLY`FvzAToZ+Wzk-8 zD79MQGdgk2S+v#`r(FYwBx{NF|0h@f-&1SytD=opv zmK6z~gwvjQ>6>*iasQ3eoRpMx0sum06?-n~t~dZxE8?);}ry(Yidxm>Hs?4nfN8QckM_ll2TL?w72 z*7Ai3o+>6oC0($<)Wz;})DGLLU2Uw}TiZIvOI<8Ub8sOeTMNW_7p^Q|bmInSYm2*N zQcOTBnQ)*ui%(pCJ$Y;Nv43*qdnL z=+WPte7L_QmsP*;!kDs%gh91)BrcJd7z4JsIYoyD|2)4u``Z&%BpLgrnW8?$%$7EA z<_*Un;Gpzo4$1Q;5MltbRx@e=5F$n0W?_rtwgP-G+C>hqB|~z*yxH5AL@}w{vms(6^MRnnQ(|)T?2ZC-Bo&k3LO+BQl>d<2#E^lb2qKLgc zxob>M3#z04c`!#(pfO>f)&`WA7r&jigDq3oDm~VMHx*LS+!jB7pXZCt1PPF*)LlwI z>r~6NvMeS`7>bS*5N;642cVX9P<-Bbw`YLaeKAr7aQgen>Y`jE0J}|^Mt1=ClS{!5 z6#Dv3C0RA446x|>k91|it6~uwTY*=ICY0Q+tTWZA^;k85RCR(w#M*CQhM-%V5z!;yZ;fQ4@G-^>Nf;hKJKEQuE=lVl$k zGhwcWI=I~5mLTJC5B)-o-C!(FkO>lF{Y&OoynCDSh&3LZRWy>}F@ zCwP!@A7!fxw28$bGsrJ~YGb5%8M!1>7v>zfE%oR58`I@;#+DQrg(H?_Qz2Ij;^`2= zzj7^3xCBrqtCi38zZDaFvj_dx>%dw~X|vMTKQ5G^^;Fg4J6M(6&Y^>QN*bY4XT|wi z0r(~l;_tOVQDBcgnPJfKVQhSCc7p8fPbW|qZ6**&auof|2&)_4;Q;XdSZC_f+8N9H zH4?Q+X>mC}B}+xc?%7wMtzZ(74wtl@@TIbyyb;U#wv~!N0$K}3xPZv zb$Uj-pD~rFf9Ry-H1jT{wGgfR*cYseq*uQh_UZWKLAjd4U*hcbEHLRmmP~emkVKZdt8IqC+3HGZoX%INU{)O19aRnC2G}Rb}?JUW^}@1;|e;dwK_VKwO;i}C*|+)#JYqH$%oaLjywmY8}>yOiJ3%}#*zfzy0jKB zpn&SnKIPuDWr7^Bx3_rDm0AwA|p`tzwr;hbUw<=Q-sISdAxToqS71Xzv1Xiov$kW$tMOHbh(ApWDU(6!% zJl2XuFu=iY^KfApMeW0-6#hcVf20s|xMZl>RJQZJ3x+V2V5;qYxswNdr7Yhqk~t?4 zP9aIoW5t@PUqJF8jx4$jB=W}KT$U3BUtb7ABI=5}2Qo*Jgcpjbc_7KL1z+T0rBre3 z32X;TKFUw|yzr`T^P41nKy9DHq-M`WAHt*98~y+!F?QblKFGqqO8?c(nr>?V_+4^- zU$KC>G_vd?&r4OM3Z{B+*n8{+$aZSPjRV<9pm~@Go7Cz7m5Nu_py@&)iYl3Z>aREG zt~IDHtnC(S8f+HK=I7Sg(}Nsj)zzS9jg7K6S8KCh=E1r_&}eG2Lsi%(z*tyE&-iVG%diuZ};(C*MIS5zPmxvop`CYaRd^G{x zltgzR_Dj$i17OX*mWahlgxA4J!f$eBHum^JE$!-J1Q<-S9iBeTTn>j{!Y&6CX@YJF ze0qHmv`XjBZ^-_{W_Z?fwX~qF8yJV4 za6#u?2;jg{A#*fCRLSjnW+-PCU<-%~N=#K`*W)4 zw_$AaPVC<(Mt>m(s-kT9jh{jcCoySJ#2y-@vR{(bM=Ow{iqjqj0I;p|uD;S$p_ z;}37Wwk|>_i7qvmupI~0OE7`#K72@dZt8qyk~R`zz5f?09TLX}Ap{6;AMyiqMK9jy=v?RMGNH z0gslcjlX^F*OB244Oibf-1wKr_|6P%J{L3#9j-|qj(i|{eh+NV3#O`PJT3H?GWnrq zm%|5!m&-3LT6@0yi2PeHVvM0|iA?(#PbpoeeJWcnFdw?|&WZ)3b&xWq*@PsaY!h0v zh1^1gIEE%;R8E}2!j(U{ovAsd_T)9cew^RACN30clJ186&J|qaZu2% z$Y8Sy7-zlfpHw?6v|_})ytwe;A1!dHP|nEyBH9Vk{)6J-)(~kXMm%#qB@coOD`h1& z{GMl_GFF|Y><=Kh1gF-ld?pLr#N;)ZL$n0rXYZ-v9*!Lxcf4%_>fTug8Jn$NZY5Bf zPC0jer|UJ9ob0t$8|l5eNny`v1y2R|D>-C{OSZj?DxRmsfsr8YoyO$zzk!-`Uv z#|CYagXTN~wL@AIv$(||pZOvYoO?NPhWZ7hT<-o7>g_u?U*6~Sh$3H={0#J2{(_U) zaBisBy09-DMU-96S7kI_GtIx04 zu^J4zVq8suj0C&E1FJf!S?Tz**Xz(CtUA*R!Tej|5n)&z2|k3H8>N?iKDXxN5+x^$ zFMYbD_g;$SN|+Nc+1k) zPCL3U9wisCzN6Lp`#N$M+MiYWN*oy$!4Rwxp|z>+ZPVZo;qP4k`)x(;_l8oI7nxfgzSa? z9Cp|EX-d~kws(>ctE~?hbqq6MCD2O6(Pt$P_*^Z6Df!&vaHs^$;swP5u_j8*6_N80 zs1Wo*ILph+-)YO}Xi#L@00s#Y!kH}qop1DobNR>3&VAfvtC9pJ^Z}!nm3yA#C`Ro^ zEcMSoNYe3)lE;606q(&{8<{T;mgs8FH-=K)eFfMo+ZjF&@<7%jp+ZgH&gu)`Nv;vKYcu=v0zM)N7jX9e*lODF71n?Tl5{ui0Lb}o zUAfh(jdlbd-YTG)c2+@>Cu93qSA$mu%hr+xmfdeIFhuYJL}4wwJcex#8~wJ{~OO)cBzr! z8Vxf&7ATvU8CG~_2-Y{*H2(Nz*68(LRYWk(`QW-^E5?z<2Y|u8?Ss_KsM z4M5}j+`a#EMYUMvPyncGT$?dAZRZ==&ev)$5SS+&u6%g!c6_$;WO0T1WRpZwc&w|7 zgM=eyowc36GIu3x?vv1Ph3(HZ;4j0T8~}i_LBrzTYgAafEaGr`%_bnmC+C41oi8_$ zUryKsYEGYO*|h3LgAdA+@LO2p%vo523v0bNm?Gn&YNSmhdVdqIy(JLa}Qs>M$YbB6Bdh^fzzC*RZ^ug4X*PO(9X9_1f7Fl zy{A~qii4*-uAa+15rCa<@g}97s%Qlov}T;tzsEr%j8VP%NsXth-nhhii4Z;YLVYZE z;#)>Mv^c^y5zqVZj~FEiM7zV=D|CoPa6bRAx}9VW=w4OXls=j1bYkr=(0T9kf;Gx8 z{Uf;?iVlXTPOBWE8MRj`v_nAei}~fFvv;IE#VWtqA&`$%R-dgl&N<=-@yP%Esg$BC z)#>t#iM8TBiq@g=^utRe9p<-z9&wu_NIRftswGm0S2)vrpDU38^FlXH-#)xS)m)yZ zmB!B$hWK!R$fG%ddtD2|B!XHp91G>PnfW!3{1DQtllL1rT9Di&_jCz99x5WA9_hUg z-`(wNQfc@6A1qbthR7}L{|1Uenx8c^NTJb9fd6_D0=E<*Eh#r%BG?} zk7t5+QDqH3@d2u9DzG70MNmI;!j*SL<5+HT67cN(hb8!h*YDyl#Dd2;SoMie*V zULXhedEP#`1um-Y5JG?SK5bLPr67tnD{!u$@&j@{*&3|EDoaM-|QKF9T0 zz%mswq=E)w8na%)g3aCDByyXt%(2P8GWKrZwWvp!pH zu%Ech)QXn~P_hbReNZSK5(_f`u-xM;s-{1}f1CNJIiSzof_?zhULlA2<{AHy zZ4#AJdfM+L$nGbAh=&c^%I+0GrW!Q37dCbdQXVWcHq_WdWajH1kTkqL(`m)3QHO!q z+5EVmE1a9WUi`3c0C%gNVhqGG0Jh}@UEK|odx(b;R7oN?@I#|7JHWl%=#HrFcMkx4 z|FhbmOo_n$etz;3eLrhYxDecRf$?huZyjk$+~LJSuP7~r(vSgmOM5;*-`^-z=L}uZ zG&HkjrFu;F;&sjT<{(}Bn#N!E4ufVLUT10kTr9wCR{IQqe{-hnB3<#lYSA{&@+}J@ zsZR%5!M_@c7UK#0$~TllU)=>#PmbZhrwJ~C%!1gjkwtDQ(K8VBus5}as-F2=A?We_ zNFxIp^>Vd*!K#P|pM+{*YJm(#Ae1*;cz8B|hIa`|0Z{=ZDf}2wj{&EJXwIQ8fMJcy z=JMkd;&Rr71Yul5#!98KR>l^V-hGcuY%j^LJ^&V$x2!KZrJk(CQ>bmAR%JMa$Clu8kQeNvbv9 znGa1}(Mt8p^7OFF$okZ{ir^pkvX=WzG}YyyMY}93wf-Q2{e%H?i>je}%h1Pdxh zUQ&)lG5q%!llR$jhPx!RQytoMQ(b3&{8a0m>B7WNY$`7-s1o^3e5oZJ$hZOvBPOU7U9!?AKJ?uy zUI_Dbf@KV&>_AOFW7;GNU6GU*I5k$tn-1=hR0IQOd&v#r(KO8FF8evz3TaiCuVw3m z9?_|*4KxzMaWSk8XFQA&L{Y1w8U}IZ~jqTm{ z3nV1c5L)gXe?FuUT5J@qjqyX5or&LL9Xwa-*wBll@ig@Cx&^_gm3G*CY~m(3oE&KK zUvQN%^Cgyp&-l(KvVIN&eD(gkf5SYhK@O=fXiZ-xe(w1^$>ZXrH6Uq7j!6gOL^9Jh zlz@3JmN8~3p%`uk35U8o;g;L;m(sZC4EaRTC~DRLuNOWKLXc6>g2x ziD))#e|65>_!48nY(rASX_VV?ambI{%v#qQJz3ig{8}2wIlxBp0F14Os*kiK5UkNa zp76BG2h;$u`d@xW|NI6Ud4kCoaM5`7Z883%#PWh3^GuALpDlDfdQVU0r`WM5u?$}o^Mv(UFX^2xIt@{zwq?aejS({M{qO|zjAcs{BMk_U5tIDPMPpC@Vq zRYwEmfs*S+VesyG?{GpN_QRMa41AQ zyeBf;hocqiij_x96V%F@zuc?V>T0KqG>^8DANuf<1d$gbQ8U+as+6?Ogcl!@x-o_& zp~7qW0~w^j`=i{DPF{;#Lk#l{cNBa0H}&-8at~Wb`?CpogG>^1 zoEgMDGH@aGzZLQ*5TMX?5D(dV883CvEH{Uo zoA2Q|ogmS&O>#=#8!gJLI-yD;m$>)Q!FH zuz)>(ELF9*Fn*Xez7vcBL5{qVH!=lzzLt#ze1vEfejLu`@7BQXS2Ih>7>LQypL}Lb z>QP3)o1ASuig#p@{V`->=F=P-u3`JuL{-i==Q_b*ZyY@u;z+oOO*1{>se+KVjovU= zEzI)ekCQfkPp2zn^uc4a#;8?qSknCO5dxvlWzRit3y3y5+lrc;cSn#ftU*P9pP2|e z46v@THn~5 ze*JU>3Hk$B>Y-TG2Eh(stZh_h zy=|D$BqNCX;#7ju4pqBsItiVpq}DsXp;vC{o3)38qv#`4WmJvaH=tAY197kA7Mu-Z z-Z2X>tc9w3g_7S?_J7b>uF2DIdp+!S%Vx&TW%|SN%X>*X2kp3@5=eIZnF!oeeuv}R6 zpft&9fpaNW=&{f(NSm2;-XXq|L(~&Qw!%+73YHt(Ulg)8b$ymey7TQ(TT9DI>$bIo zTu-U-T4*J23VaQ+`Z@N;y>PPSZpi^>`Bi3G&>cFAfTjoq*-N$woP5bCRyIu<9&nLN z@)ucchn`^VS7bez+Ae)t&M7F9nZt}I^t})xUsN+MIcNfO;jO>LCWP1qeKSO(WZI7? zh>rJMlo%=+{@PM?J#+OgT!Lpf=JKT_a?wY^d`% zj|$RGdOsRVC!l+uvl(S0++B{neRc|l-QEg{fZ_ro=~0hTT)=o_ zqqhzyx6!C_m9l5ki4o4Jd>$%HLbztnS20ds>6uD^H#O!}(L{F(TV&x;o+Q#FsAh^v zC=P55#(GDi-%);95{)85?i`)5d!?V5fTuNht#)a>!`JcW4=Vj>GQrHqmc$CNO{ z92Epz0;m4F&lFCmNuiGsI8E(kDLxzB_m0UO6@uBSVIvLN4)0UixINF7r!AwuSqxmLSFEblTL zZ>F6==IoJ~2v@*5;$g9|ejolv0wvdUICcAQItCLs>_m?Mn*#Xqbb)W3I55kn(!aa& zDJ&nK*VNWJ*xj6LBR)QU{}6zVS>icN^i9fx!K0IMSG4|Uwo3DUYDa4GAHvCY8nJQ*Ya*ZGf6g6b2|yCA*o=aX{+ zK=%iJHgn!XxI|!{S+m|k{CCV7<$*u9j19RsUoc>GwHoI;oYp%^{mC2!9m?3{BThS0 zd9TBW8BFDUTA~RUfw%2c0q!R-#wg8!fShit`Qy7aMC9cU7?mp2AfucfSs7Zl*LV`g z50f13w|n2eRtNuCmAfirvyL3_&CG$#ZANY14-_O|NQ9DRbcsir%qC+0n-v8k1+LZU z(`(6>Pnn=6yt+@^iM{r}|NH;)??wsG%qpD$ZyR`C5gSK2}-r*y%Ffl`2ct-n^nK- zC^Uz5;_?3GB5!9e@a;2B!WjVE>$DAzf8yg$LIK&b!e{4J02GXMelRJW3D2A@Q?UH! zlD_3WUGHxj%$Rr}-Tv7*MM>j7#P2kqClom7W5QFc1_XOgFXw+7_X_{N;Oz)R!*W2P8azBaK*A}km>_c- z3H`ZTpau(>kJgvdj>jdHauLMkPIz z@Ur%b^nv-cUfI;#$=iQV;eXF$swc(4Py$m*-f@8&vb|xjVVV51S>pft3g42ShN1=s z`{xkg;(+H8sr2lC{*Mo&NqU+qth;jN zk@R?j1dub-b-gJq;LRG(3u`6*^QFA>c%ypO0Lg@@+RfEft-cOuz4~Wj|EFjVEgzWX zufcp77uW|mkTlMKmU(` zL+i(Q>M8yVz|Se)zS{inj4Ms~)85^R=qGm$G!K4Ad#(JB6UYBul4x>IQG;C5y1_s9 z-n9gH`C|V|y8nJ3>ZeHH;ni(k81a3P(OZ@O`1*h!1^nrY)!wquPcE`_!bbq72Eb8q zYtm1E;GLCgC>|5Hcw}sJmqf_3xL4P-PWOkqs?BzKW$W;e8lrqa>ZEaDEcWlWypqRg zy=auhtw_&(Z1=1${*cWWaHUQ?u#>b0Y+_%5d*!DYCFKFEQX2ZF#}&B)p`w=mxVNGZ zWgzbW2Q(U*xuu#7<;I$GczqgQ(XanMJP#tV{fAC4D=${(rX2w}0zV+K@_INL&W~q{ z%_}&$-%vnHO+bDyk+yX!hbt$iZs3Vv)B=+M^!KJNI`oepY4`io$vG#al#tBsLG*S%o&Y^!i=DzZIYVmH!(@ z_cBxUuv8a`<10O?xUXn2jK$nQF&C1>RM&F7#kJsi1+Qiy|JQbtEvom={lcUDpq6_T z^>|>21;B1XfBm;~30Q={W|-t;Mq?AH3$3%foiJ*cbXu%uS8Y2`DjdSI9Y>msRduPz z#75jz^xv{894c%Wqjvu4hE(ipi}R5FMe?-5zmqPew~JvV$w*dsPzd=DcyaSG>Z^tb@6p4g z19F^&-u}Y4$JYL7pOTmVr9(Ki7QE;Mq{Eg9o~psv{NcMnkITC#+vjbbu0bY~va<0( zj0J1g{nz{^+Rv*UZX z{hg&vYl@Xb(eR%{ZdOKHtfwTDM_?_1Vtwa#$$Y+f6qlxlh4V`-jJLi{FF)m0)|U84 zmh9A}c*o&rpH}j3Pzx~Iz4)_pApRw+{ql@SnWTO0EH%eZQFA>@u*e|gO^L_>NV|1Y zKySKMl#d<*sS?4`o8`lA1Bq%ar=1H+PP;iSU_Jcn3{m0m*$dp;Tb<6a%&()Fd z{QUeDAnPJv*5VC)_7bHhf;B&p<35MYZt%%ohN$ z>%efdJx<5(aKR|#b1^6t%xm{oZmKk0@B1YB>@ogR=!8$2het zchpMZ*jpVz$}KH=IJ(3VFW_* zQq(*MM;kz~Q~hMUbbNC9pdsOdQMZ)uz+B>J5#i$vN$DgpdzPn_v)Q~p*fOId z0gvVvCb?;ir5%|C=kBWj49eaZY`LwbbB-+r5m^A>mX~S^@Cjwq-!)_($(Jp}GA1Lq zcJJ?bH+vWmH|g?Afqch_N{p5LRHF{qQ(F^(KK#ZfgX?CP&ia7x9ydhv0_W(7vdPI%$Ih{yH9uj!3GvjnkwQGqSbEq*!6J;ex_GnNXb z|2meRj>vsLQ^M5MU^P2dU1kl$0r^Ni?QW-mG&8A94%+~TxS1n8<*j0V?)R6U0drQU{xgB{&&4J>{!OFWy+;-h)N>Rb1u*tLEMmkaArMf_=f zb$y@0S@IsG_-gZoly;+r=r2mf3R;KSCFk80KC!LQ(hj98K=fHwub{E~H2APt76k@i z@Q;+1fng_l>mAs!dmV4c^f9Gr7bRlOvnM;lg&bkZy&&?MPeN}$8?l_zvkU-(?mWbV zyQ};*^L{T3Obu=GwU2mDPcAfL@(N%7buY=ELb|#l=n4=O@W1DG-uo=z;?^;bl9{{Y zeXpFzaAjpPTOH7BH)qfrE_q9GGS-o{W5oa%@2I?$BqksL>2>I>eBihHi1Hl1O8`)?sXQNPH;|(9$RgHfEH`x z@aAj!7l7?w=dsu!+X@)B0Lgj@puyqjP#W3wdMg6}VaQ#dtQR>H$UL~;FL|8N;Ns%` z;Bv_C(AhMlZ#DWI{|L z;Hd@Zj#exnAMlZo10?)P_bUoTE;N&>Yk;Kh>7g3|5>zN`@v`T0s#J!5mw3qgl^5c5 z{P|06k2|Cdmw6A-78SA!UsitXcpuZZdGCE%dD$oD^-M&J%GO6_!jh8hlUBJH8Z+Ru zF{=Mkj&X|3rnr=V-O;S%2Dyh4aEY3}tdJ%|Va}cOQObYgFai&^G$V@Z)F>O7J}Z`~ zn(=DZ+wFwY`rKoE0hndOudj3>KPd;6olSG^V(LCvs<%IOAz}3Cc(r*}N4SlxPPuV) z7_>(w@{@}jn%W+E2jvMF1}`Xx`D2O8|JCUD@<8n);nm}i)^@6Ke`gT+Nu64!W0_lP zdGjZ-Hx#p>P0#>{QMXw{|VjPtk*CFi<7!k~$`?apJnm;(N@W(xq2xTw zLaWB1)Pk;}xKzSxOBIh2K!aW01Xdn$AIY#ytHZ{i{MWfwbNts|e@yfZ-3>}d;s8== z>2{N^DL3%@DTQF*C>0U)1&YIpiRIdF?bm)OH7mXC?;jqBq83q!-UsUQMSvCF*(S`F zfFDl`3=o?$10%@ZN(|+H{eh>|z!ueM?(n8NUOxLH?RrA92ai6wbB*iy4&nMxViXP) zuV@mv&qoT=$|m5!ymqcL3|A!EX31ly>2%}IlY08L-uj{Z@O*c=2t#CU8BGIlsyQsX zkxijK6@BKcB0f>1oq~czl3Bk_y-E0gXgbTNC>!r<&kO?6AT1>z(%lV$qI7p7A)Q0R zAPCYZ-5}i{4Ba(KcQ?}A4e#ym|GeK>vsi25+-IM?ukCSr&PXBV9F%e9UaHg_!Q1Np z3Xlg3rIvF6WITWIN6KY}6|&09-9y3}Uv**Rmx7HJ%{78Whe0jq1J9nrYvj-x{SUL~ z^e}_HQn-Q&dx|OJ|6FVn*=hL_?TMuP(r~D#Rq6dzp0`cOZcy>=@+HuQv7~`+I2N_a zEg9Ubo_~djVxYE%qi5IV=$=RMwD+Md+OAqCiUL#{`in?)MXmU)Mxne?#fCZP4eOzD zkfE3({Ewvw2*$+Pl$5Z?J-5?{?DhA(HrM0j z$pJdocmcRMp{|1}uF41h!35rNdKIR5Fr*7F(_JDvju%_Y|D$N`HJCet`Ta(#+51ou zNCLd6LksrkxM^G+9++#@3&ly(NeAQ z!vYM+@y8$#txI*KB3Tlvb$pHFb~GW_o-%vWI+nPTZdRtb0zAI#pift9TJ7Db3r8zS zd_yEgDJgE(e&hDLF|(o5U_W8QiG(7dhdnTPHrJ?ar(Z zC>bt2O%W>Wx!ck6^MLCqgUeZ@{$KH-z~~Dccjs?e z!GzDLNr)G)l_=AsK8tGC{bVJ+&Op(;%NuNmK1%TcS5(AqUuR%G@vOT_lRn87<>S94 z{m0^)c%uK?{f+;PUpFVGs_nzwUF+E?zV52a)EEC;vyS-CCku`m=RDbz_u_+FxX>lN z_MwDtZZ^|Q&yNZ|H}j|yj4-bBDcjkhY=UO4j1!gCRgZwCvs_?!s!f&Z{Bt~wZeZ%C zf&y2+37On`kjdzhJ9M$t$dK40RfZ9x4FI$`ZjJj*5<_VQ!=FK3OCWOWZ|zAQ=i7L! zrt}tQ%Z!dskG@QQDn%jX!-1$cmj;qQLpLW|t1 z?!ghgo`h?Qn%{5%A{!Rm_O^*w$x8O(^*L43qIEW^4ftN6_(zObn}12VW~Nsqks@5J z7$|Ods+P5#0gp_(K6;`Lmsj=HxB9c%yGgjXB0CWIMvL?yf@nbJ1i{mEPCv)n+mHLG;A z#8B4eSU@rvII!C5R<%;f`?G%U6qd{h5#<{L%T@ROf?-V$Oj2#Sw2DgB*?;ZPEDq>tjC>iY5J5F;19C4@0pm3$8COPbR?*zI#U zXCdQFfRfvpFSz>>CVx?x&ux6LnLT*(cqhGaH(1?(g1sQt8d!_%(DTYh2q2WCe7RT> z^X_gxM-ytXrU5Ek!bhSw@Mw}Z`6#wDFat`46JD+2`nB-cFBB$r%P4fCClHRWntBsAWZS(ytpWh4MOZV_mNH>KM{h12# zIWuTwt9XUd4{Pde1-O4`EM?u0T{!tO1F$?XEm3hJ*|hxMH6icycY0f{z*YU`QMlMxnt$j=&+=?sP^60r{{Mui&j+= zH(`Vs<-}?p!pOqH)_9Dj(rWY_Tf>>-sdX9txmaE0@$WgX`V-r{4&eJT=T@T(s;~FN zFSq-@bveL(iWLl}WvBAn7uI|p%gwI&JU$2W)m@CpbR28yEf4xlwX2uzy!ktO7e}ie z(5^|U3w{6IEpLz3SPZ^|i~HWX$|elVwY=7yDC}z)uK|fYcORH`Skg|fElAg(>B7#+ z0c8f$?}cHm;81V{0X4~X{EN{-C#zkked+W#c60ULUpVOvtO0gN z^_KU5j5^qj1~Y3Su{s>7qP5d*%lJXBLhl~cf3!(xk^ z(yS*Rldv(pe3EjD<4PgBYflUe?!|lW4is`cO=`(rskZYQALyZ+u{r4FCiM6@?l7=N z`l=8n{W3OZhVj~VGsLmDf0WIrNZa`0_^idvqxuUWcx<;r_w^UEok*m;os$c0*Q>v5 z@k%&TYcS@fe#&IwiM|^mW3_}ZRz~}|{qy}HjmBR#$!~4ce7j!JLx%E6`y9!BI`R3K(wz9QdV27|8hpgH1yZ?T|f0@7Fs6H4O1 zH|c}lo7A3`Y5=!cMGiN*iungGjs1%sI8!p?%g+{A__f}*H*Z$dKBEBsV69ej&9*Og zGX@09>+Dg$Ol2Y-j8Zk9OUqAgy1bFC#hQG-QXc<0a5TOgsv=5`W`Cp-{>%3BRt;MZ z-Y<-pbKCd8AgMpi%F91Y+^(2xDR!brtlqOhD-nXkWhj4NJs@-^>AhGgLSOglUoI=` zS!32TH%8!Tds|$5+K|xoUciQ851Pk5h3>u6ovDREECF{Ofe48fCn zW`PROSnNrszGNJ?r~q*>wGX(5oh0n$Uc%V~*UjHgR-0-4h}G&GZd^2XVazn7AAIj$ zKnoO%8o`S*ZBb7~QdK`Jb9<{rw)ERla_XY3D>6_W9T42uF8Xoxp`NXto$O>0T5PL@ zTHmp0<8!L3qI!M*C;0j~0vXo1m8GsRF_l+V%q!bCeUeRXweTxIo5$!%&vtd(I^(A* z+AS14zdxX#$M6$gBQ~}JlxPM8$YVN(OWyQ?(P%18=7HhxEPi$a1>@Sge2>x2ac=vN zy>YJ>LkT3|sD`aSWStP>0jK1*b7f z7u|302xYg-NszF@p5W z9O9!L>Zc60^agUr0bN4P|K|8RHs>SfvQwGMnNZjDD zHxaUU+JJ}D=vH>#3a`uYDWqU#;i-`QmdfnT`;JOYj%$k7@BI1STcC$a*t5;b>$!Fb zBX#C~io2vj01R3>$xWz@JVzqVtKDSYPqaHMC(!kMROM4&Tqx16ROSR9JoS8qdeZwQ><*vMFt2VRSNpALgHC;R0CkTFG28&2F2e;3~x_=&+5an6w=wr)tm?mV z2d|4=fbnR_48@+TYcg!{s<9lVL?+RBae`t@y`3}%dbu<1b9Bia9DaGYD2IrqDsb5v zE&;H761*!bK#Qwtt*xPd>1g>^u_R%4Hs4Rjq@$4(bfcEcTIIR;B4Uc1uL-}e9yVis z-29W87R`54G$NT7G*k&O|?0u*V+1$0ye>l>m6|Bi6F*wxVOsiZo@VxlVBYsAO z1P4tl6{^sZ#bB*FBilTW!8J#MAQ`6%x>#8EUKxH09vy&~ZMj2>7Jqqi_k1(ilg=OJ zwqFpKtMzSi_L!nV?Z(!o0+B;v49+YDC-``Rqmrmrv~@#Q7smGeLht%X1OPyQQWn;B zbea!)mkOEkU+by87gB!TjQnoC0`5dx#x=Gs`+w}jSdn0kjQyTW5eHy|BHm!tbn%LF zcGr9Sd9ksA@nMk!1X(?_VdrSgX54JV5J5GeIyM$Uq2^SAeB;45UydtML%Sj%*K{(P zEY%rjDSCNCa&_CDRvTlW!>P&f-uv++Yh7%9(5~YlD3O38 z-$^`v%MUNBN6yTJ~FeF}J6@s*NYP30-v}#!{HZ4_^(FcGBC-wqPGsKHmI=)%a zXD7|miHKi#s=W`-aW6%N|LCq{w0l5AqMgZ3$sw;aFwzibB|xNmj(S5e@(yo9Fbp^~ zjHp99`N@_6jpt|fK5jIzctn8ZyNV3a$p>4JkOx2g<;i;p<}DyS-{1GRI9z|jtBGur z+D5v1!z1ZkdwK>M)&`y&c7r`XwH!8KoCce()Y>GnP1HM?jeDXk`ySI^pN|bs&$*op zbTyX^dd@j{XF{gt)OwEq!r9(cifriSztw3nvBvT(4qTcqiZ{(KBK>Xkw$l7!hHlq8 zaQ6F3&3+L7tedY*kpZoCc%WA$>QEAZQ4FO)C>EM)ffhh>O$Im zU%H0nHOoEnjjp{f$?M?SJWJV9AF+A8!Jr)+2l z2Jdf*uac-rW`@7s&K2CXo^ES(h%8`cmomLh&H?~81grt!(3EsV#Mn}(=!9QQ5M$xy z6Q7=7QmaKl?`Qb6CHS#CkwH!pqI^SZ>Krev{#EkNGt$!;eM;;;n7>WrqWzU6g}^l1 zfxdo6)_a65s1KNo`HlEj^PuXvo)u_Qp#j*d8@m=Op9207Rog{0u&PX}zL>>mMv&Ny z-uvQGbExpLeNGN@nIdT^^C&w<)3FiidvL}SICNKVp50rmG#l}*hT8uO9Cw-+rt6H{ zvDW%qrzw16rs`b|LB0K^05E(mNA1)bw|Iun7mkJ(${BqPqHW(?h07G$9_hptD-+6j z&Y^&mt^WRK;vuxUNQBO8o?Wba^8nBf6g^Ar$;mgXbw~jIk<(%S-iY2>U_FUZy~F^i zyj@SGCL54hRRw~%(nCYz*SOQtBkrEQasPSX8MK8;phzqMk!Eq$={9t|UbYHQJswDA zb%|W4^kO(4pjE9CBlU6U@7-{FlyS~8IPq0vMt>(hL;!a|IKeqNO z9Aqc*7`occTBTYZ7zG53f*g$Ck{>_2<@(ASg-PElm}+ntHfxU+2{g$XsUa|GUP^nu z^cX78MDw)lGQ!%~9Wqbo@(9hAuh@zE1)Cnu^+=|6-j~+Yy}2Ska5{qwYY3{hfUXnF zR~A&ZGux8f@hw^ZGK8lQBY&y+cZA+KjO`1DbQlHza3S5fdXE#+{~e(*Dxq^xdlSXd zOw6HEzs&6Xq2+MmR%9DF%a0P~*H1iXIm&BEc&y?TYYvQ88Lc_Yn8@~`TZ(!^_47?N zJ145i>uTYqjEv^Z3Yw9p=7&B{Th{E(7);UwS94CePDhTm z3Ei>&XUL9QEAbir{e>~2)V$0oKU907P2;a9r1DClmh%40SB%O9$5Fgsul~MJd5RFp;C))9&_%XFd9w(Mrgne^qZ_@^hpRAs0MBKcZE?55J&(!?pmCLjQ z%0{VFrDb>Y>-W@XX41;O8Dc8xlSiwhZ>Au=zLO7h>E?Ephm9u4tu~*}fgh^f$r!u; zQ^fM*E#tZ4?n6_FDUzjai6pTghO%(}uM_mk zSM=o0_d{RcFpvsP{edU3`3!~Q>n^F649{oqb&)h(-+-NC<<(mW)wlBr3F1L;$6qXaA^;kOT!`TF;2oyx7MfNRDDTm|~7jB83Qz zeZ%~gB~EkMl#W)Qri{Hm`Gg@*Vuuz zGSL({k^5P5p#g7U8@Kh&8)08US7+{n((%JN?};-y=4vsGc01;7^r;s3ZKliVKu55y zm)ryeAzy)HVj+MYM~6N8jgduUzWA39{JuwktW&WX6cZT$eIp+OYvfwlXIP2D{NQx* z^WE-CU9a=$?oj;rK`*#uH}) z$~re$b+tPxED}M-B32`>c=+?lKHcEw zheb$Px;hPFm)wvJ_8@3NzyrHUbvYsq=@);GcaR}SO5V}b@&$}PI{ajGmJ|`QP zm@MQmRG1pP!h?QXd-HZHvn(O}+7Su6${|zquUM$`>d$WFsEU7?cfcAo2hs-_(rd|; zE_@u7S?ZY+wkoyH0qBBaZ{6|se2zshG7bNp12W&PqMn_f&t2G?xM+pX zVN+S?NW{A77~d!a2$zMLLxmi?&9B68zIh3_VAa<|u@lF(a_Lh7_BP1#aPL``g`s^o zP$8QqOU5*6m!`l~|El6pM`KX3H`Wnc!R4A)hs%3JKsOl@N&we z{uX`2s2brxAf_uHe&@YQGx-mEv#-(PtlzF1PVnm_7O*fJD22D0hwQF$Z~w7*SCMzk(HQM*lOMFib}0bf%T>yivR^Oer%;wp&WWta zydf_gXl)7qEA(eQUoblJ&DU79I`oXTf~qtg+h&iu??Qt@Qz?qvHE@A zC!I%9v0%LnXV(g6Cne^rNqpE?MX8hMwo^kp;$W}g1-JABSNNl_dD-aQ_DkXUly|+| zqgK*^`}-4Qqx&@*B;+|Vr7a)iuor8|#~nbbi!TA~>NeJzUF)q@CdBA;2eNCZwN9pY>v>4n$*9EoaypL5gNfyFv&G zc@7E&8JvR|s-5GR&e!IDjW{+T{SMqnTP^hE*Z9;| z`ErekjX~0m{*zK7jveD&X|O>0YVKEJ@b+IbaFQ=ygm)-V$W*8#BA?f%cH)hQLn`5; z3YtyWE28b5A+u$;F$J84+%OE>7v;I0&RhAd`*BwCA$}-Hq{)cC&nb*c<0sR>E!83k ztA|LH_!2psE7C&2+0)6~79LFmB8OP8XxJN6O!5z9v!o>DO)1q(#)x_MLxxu>{*iD@ z-=Fq5v!l3`KRH*j=D%i74y6kv3&lY6ZMqdhL9_6U!ASEJ!?GU52;mvlsd`r-3FWl@ zff3-b({kdKvoC4A130gmGjKgx6^hFk5 z8eKM0Lh1CaVp9}%CTQ!-c@g{6=j+X%g4IRQfIDZ7t`Kj}!;!ArUYqsB7qk}M{3u1lGI29 z(OV>G2b`#D!oi%!W6v|190d^=1lJiz#LfUOHkkQZ9CKq2X)BC?Rd)2c0gd7$9mI~B zb$B;>qUT*D*&k?mpbYg#Ts`-hc3icDWB3REC5~B%6T6uA{X#61)?f+vJmM~%fGEj> zky*o+0!RnAl-ET_dXL4}E=(RsL88e4HpVOy1z$GRIMMe zHvY*O>5#>0Mmlqard{HGj$EHmSLJJY2h@CyOuYOvK?k&lTO)JtX0r-(=KnTY%C`ng z`;yMqt=qo_J=+A17Y-V~B!MeBkySASj^8V#g;7vfs9mU#*|qCpQNp+0l*R`R)4I$C zJdV64tAzGAY%un)ZzxEr`91;+O)KX~X~jVJ@1|M@yWq#QO4`$B8gZhPP_F~^W)W}e zrjg=SN*p#ywSKsz8Na@-{=zR9n{A3hJr%ADafC6)@pCCx{j@bHCZsiuXP^x$9Ncah>mL9$Nx6d%s4yY>(A`Rd=b`IwGoBx5#v) z={Y@TCGvhe>}H9C4$vDPr1k1Bnhw+xFlzd+HZ2YVAVmCy;se2mU2X^q!Z!x4E6lWH z9`UFSvvr_YO1Xn#!*vecsXWq0$SJMyNV>ETn`5C>JOv2x+8_3Zg zf`7sP^t+^2ciR!KMhYtKDEUmiAOD2lZ)ZXuF%Sf zwau<+b?<#KHDUnM4A+T$SD=FBGUFyaS#EiMZj2Z`JX0LoncuX}0HG&7>3&;j+_kl} z7@(DgZndR+{) z7EPYoe=Q|9o*x#FRiO=XdRc0x#zhEcHovRWGE0xVa~D}s9{(7!y|WjsSuoJ93u`s# zE2x&WblBoc)JvtF#94rv{Z*pSyO0t{-z(yboE0N?5*`qdrFTeLEa*ol?8l7QeBoP+K))K_FM9@+^b!IM#dr< z#D7tkFJJy;V7?TL{A8`x@4YUfu(>eZPG8Xch4EVdZ8};z1L$p}aajV;43kdsN*ciU zlLykSx2+@0Vpr~;&){){5xJA-v*?wl%^~0aJW?i~5JrFtc>|9@J{snU?_egNy(n%g zn`e9~Q@DmHFBNm1OMHag`rzLR0slEfc05ZPWZ~Gr{Ur$YbLA2pgbJce)4Gs&t$#fN z^o3&%r3uEqpgY%XB*bM{pgy7FCYDkj5+c0Ie^}ZGXkr7(vEDfTLYeA(hu2P)Mmz{P z3`{;H!BoDExJTN1`=)gx*mQ_`~H8dIlSX_^b0je2C z6t%F#Z!c}tNSxr5#9v62)$3GQ+`TEHA$k!80zV-2wZIlox-0_S_*z1@Nh6w6poF?* z0BcM_sw8M`0kJ&S(qBjf4X);5hV=gvl}oiV6tyl-*RBEJ@KQY1)@teOui1s+UJ-x| zj*N@LL3);~(>@BtZpy^rB#pM%akAZ=DB`i$*G}niA=FPt;#zqh;Y|iJ7YvR<@;1gq z@_Dy1%Movs`#Y9CS_96Rz)@gT$+$_ievcwEy-YH))X(1Y>X@bD!6n|vumc0E>-s5+ zXr-|Qw(bTbizhw{1f>p2^)_E;z(kVja78^7IU1qs0){UF$OIs4zdeYMe(<7z^qM8I zqR|PN3Xec9pNDVJwfjC)zu4jCIuCEaK0zHef<0WEpdu~9Z1ChfC_9^1W377FO^l;t zKm)w3_r@%8KwlNjV;wtC9rKx)PLKJR8)&pR4Ai5eu}rsDuU}lA`g!d*TriT*vi7g& zZni3p58FC7jA_b~hm>0Gfmf{APZFQm>v153Md@>~Sm&PLZOcf)qfqN2ihNVP5>~Jm zGe`YQg6V6;!TxOeT=spBo5LG3FP{fYJIc8TCLA3Tq^V9iH=V>66DBz!UHzFl-0^Jo z88%2$Y}Q)JlJFhbsf$|7`t>Mg{PZ{pB_`xZ$d`MlXiDR?0k! z@FZnj>{{L*`{^pESNcR8ixyf~pWKizJ{s3%wbN%5ACYK;TgXK;;S4G+r`F;!$xN#v zCI2upecyES(dYomPEi*Mjv9a-g#$QZRdXo&6l&I*!UF1cG;m@AfT^|qwxYFG1fq>z zVN96E_Y_~n+MMoAB3){7&F~<&2Mj<1$&g)2Bw$PHFk^_%F`c}r-zQHIsaQXnCJA4c zJ&}{W>0@;NRDgcfB@IZr*>_twss&~2>5o!{REA43??mfeBOH}(cmP9`d|85Lt3dg1 zI5CrZb@=ILsNST^^G5@nQN^bmTTEeL^vt2r`e{UB^hYDHxkvEiC|sAVrK9}M)S>0? z98?=$$Or!;axCJl{`qEoD=>{rmMUwm{al^f^^^Plh1Cv+-_j`#YO(N%tEPaW?G z8lw0O=Y_bgrRG=-5pd21a8sHqTH8fHVk&OM@3zN@^;UjqgsM+u*YJ|xo}3YXX<|r| zWv_2hmK(D)-5T*i)@MKuEU*Ap)b!CeRN02QD_5h;(Mx%>)1uobfSxlO%H!Urt-h7` zNwYk=!lUR;mKHiMFg=H4qp}$+9;Pdp+WChFF-T+H{JUmtx-&sdi9~{p_fv>7612C9 z&-Z6xO=0!LFujAA&zlIaKuCsZ-Rv-?`NLNN~-sZfxk{i*u<}cBD zk`tn}j_Qktp4{3Kb%wLeA6y;zollY=Px6C-E@;s4@m;dkf{{vC{dWerF%orJhZjwt zVp44kUt%be@r4Uhn$FgdI~{1hV#z;$;Nwq~9`aB$Scw>D8e7j-(*HxGNsigU=$=yP zEpp0=A==;-*{#J=tDdGgi8~wGP~MKc6MvVe*UT=|wLoqqGvcyovs}@r%Bu(Nb9xk&LhsH(Dn7 z=du0n`~StopZ~-~FMNr}oDmy30F=oKLDI%Rm8{O&Sxvx5dLh?QVOpo+``2;?k1ZeM zIK@puK>ekmsh1$QzL%>TImsR@pp?xT)NQomSR%k` zRvy%AzWN5e!8Sf>i2L17*$S<3mIvy(9*QPnndQr-QQ_tQiK|;jmx+z$mfW2o)AES%!0>F6!tK;gK`XB1?dDq-q&oobLa2FU$#e>P4?gQ@y8AA*Pz7c+)H zxg^J`zr50uG|HwIw~P~n==ej>UrDwX0yPsn|B4x~p22}Khb%y5obG;dx*^BZeauEq zXx4pv55}~wo4ux-t@h^c3B^Y=?I*Zs&xvB%SPdT#c(wbIfatP5TmIy2nkQma4ceWq zII?pdz+#9p^FPI<3BGxisO zU+U>Wx0a?>I4+6d;o*Ir9ZnB}D~@{6JnwMNS8lqALOnUi~c z>wLTqCO4=uefMCJYPSr7&o^WWyYKw$lT8=moiwL+^yYL}5^;8O(0Vn35 zL>Aon83V1SAK^k)*D~$8fv+Cxfnbsj;#?x*Ryp$mcfR)xTlgL{(i5_S#WTj@Yo2U_`mJyLTbuIx!s&kq~y?1^-<#u0#(ZreVG<vt6nhb@ae&zG&!r(bch6!t3rHFMe0-&#taxtwIbn z|3>*!)1*`8p?vv|Z^e=NN~<#(Q2VpA3Fw8W*V#n+UV3=l;x^!0b~Qb*Di$6+>!CBd zxop?XMOvvZ)%zSqB%WN<&kfoU#lNP@YOsvxncMF&xZ0m9Qg`p9Om*q~cfJA}%YmiwEE>4$r1h9M)x8UAY9e;Gd^%G|=J_*d z=OCvy$F=48>dz;xWFPM2g{8YqGJd9!(#(b=houZ1Zo#k71o0^Y!WV<)H*i=oubOiG z^Y7bR$h}k)54wuVf1l1D(_yMl>%%8_>1m$Lq&CwBdPY>BOibYx%^h(o@;Z zHqr&>gq6EL{qdxsv(~Ozopv%a6i+b-akKNzDdg>rn=XMgbU39f=NdiXUh6}MO{Meb z1LeOo-W{niJ54b;n<@cRk5UO}Vau!BFJ)fO+hT<}Ufn)^2!N{+!qtJixUzAX3JyGv zKpFiRJF?H6q@c&-<-84kj4`YAndM${TzUsT>5;f!{;t{Oh#k~)G9<^??#$E?nfDQ; zwsZXrmabEZd~cdaDoLua#^CQ)IVT&k%quV0GMF3d)n2EE@66-a>Yq&Gof>nDk$;?- zgxcop$I+A@*wShO%~SFxLH*?{TRo}K6P`QgX*7MWQ{WF=3UjV1 z^Sxm}3lYc!7Rm*3uT64Nwttzh*^F^%nDhN9Er&~IP57_&{Ey*rP1M&&&+PdgKn9e_W3*+^;D0%tq{qm6PAC_ym}f=dZ$1T=aEUGm;iDg==$&G=KGmweqWc9^JU-<4}vfD-Wi_xJzTOu z^~w9$e%(I89)MaO4@`dPWr(jOrm&`kIYPMv1hjujT6({#o#gcOdrCLu)}E{~lPOsY z<`K9uv=n{M@z)}X{hpS2ff)QVnSvLrEoH>)K~ibEZoAhtK}-Q-WhpL2eDR0;mJiCIR&9lT!&^dTjTa9n zQDq&XATZL(xee&N&KXrk&`Pd)4^n$}cD<^1jao{i~bk*b#uTl#U{`qd7svErb*>-0yY*fTsvkZ0Jwo~C7S@vK(gd2+NbsidFoMx z9;>C^-vIQXOl#TPcyRuNEGoo1|LVn1vK1M#%oLIf%J}0flJxi_dEM6+<`+;2!>&9N!r$k5{kUcqJP%dO3^4 z-($9a9$Lud1J6U+Y~e=zTEeKWlGE7DnG;;yXK?Sx`hT@hWMW@f6j>Z7 zXBA7lHOBLKDunH*dVtcF{Y&Zrw=34d)tczwVuYN{-Bq>NQJ6hp zkMGV<`%i~e;>yeY{2N!;d?DWQk)~sg!`A6%@!MIz_F2@GzeNyi)QMFr@szABghDrH zkWw6_jjvwtkbfpoB20f3#-&P7Do=>YQj5{*XR0-mh-0rj(Ea|ZtWE@Kw%>@bANh9t zJ%>wQTRLRZDw?OPx#CuT10a-lhf-cVtISyZN=R)H>78jjEz?~y|-r| zA%ExPcB=`hHS98kIGSi4y_ENN z4qqH31p;(e=PEPHg7YLe)FlGoV*Ij?6XiU4I`&feQ}^yv3$l2QQU>>Ol7Xpz#h~A9 z`|W?+IzB6nB%^&%W;(;>{0z7yue_P}UFGyu;oIxlGtV2-X6q zt?2gthU80HpJN`TKuW^PW&``MJVI>@t+n9TE7H>){x^?lvFLe`IdtICQl7EvpPxg< zii&iq;&e0iaEw&qRhr;-XR^7+CRR#Ms=<$X$^FgQfx;NMp$f67F9lID$-g*7>F?`{ z#8N~InxNRonMWzn?pluj5;ZQEv&IbX#G5f3uuF~RYVstdr;dJ>XYS{1e4qhUu;)E{ zCHe_r+7_hY`IPD(SDV)8po95JyM5*sMB+br7N78m631~^ld@s_*Hd4hbM^dLM1mnZ zqQ3@>jC~|iI0AbXy)=HeFi%y2F$);#K|IJ`fS$F8VJ_>5LTW8|o^$B~)4LD<`f4>w z3=Q-ghUx&mwJGrxSo{;iZw~5wq(nS&V5!JBAjL+R z(5tXF0HZ^kdk8j^GDPq|ChpMYwC<=d&5`_PHi>5nd#TksC{X9Gv8!Cr<_XjqS7+xJ z;{ki)WmDj+A=43NS|tp7!bh+Tko!~eB;m4~$qLZ;9$eGo|D@pPBu!BYaU{;SG#YSB z!>m{6{7&SXMlGN9l>y3v>FS7fKhI#}f`cJMIan{3R4n%9 z9%(9pRWHHo>X7xefdyfWHr@XN6YmbS^qnW@@WdFlXV>7oQK~4ZI_`@}Ei5dow^^0= z?J`i$L9jI=h1W*)MX<`M6&n8*!bb^o`Sf*l#|_g7)xA>FkoIsqb-%{$T5#ZKzsAF z!i+ij;S$$zTA&5U?&NK#pVu?wDcSfh2-N_1M-GKwkS;JKzH)EO4q|K%sws7zpE)*5 zb(<%#L4?iw+FfTz`yU3%E0I6_sMVjZpfs3k(6>cumfbM?YADvMP#1j?4cad*iWVrU zR*BM056aouil(xfj<@9Tf_xY%Z+Fyu)AG5g)zhX%0F zgNHh?cvN{RhGqD#uj3b)U+5F!IeE%n$9*l1QQHsl!BX^5a3{HMk*uGh=N}FiDGHye zOxt`sZ=9_$&m~UUOQFFxFIotr5pH@R(PimgF=ig@oVncerVplPJiFu{>NauIh#htY6(!TM^0s*Q^3SFMC!?YPWs-@N!c1gi^zcj8WbMUYu}7eetLfP=Q4H?pTAi-y->T4 z@SKeo#1TB1x!nANG^%uzezDT(r5n+;)6YZD&Uc!r&6{pA%(=FKVN1I*V35817K|_x zF*s=pyT5Pv3y*zrcao!T9|fA(K7V%Z5jW#8_5tmj3gUC>%FD(CR8UJ%a`v_Y__kxN zZr|2mRO0BcL}HFhz6@_wm!FN5W~6O#RbOJRIG1BRENG4g&~uO+M>CHXzNK?jmpa2D zMu}_L^DdB@TlYfo#7TjSm|og?Ps`q4&zon$;0mIlgVWsa>1MHdNhAYPlphhL*}Z88k0=k=ep@RM(|}ehiKqg#2hY-*Fj##-&H-kMh9t9 zS>UR)DU}yQ5Jx7sF}>#Rao#TGKIccu;u_#s%kyS0+!UxFp8Z5wk~iy1=s5u3(<7W_ z6~^y2=4~)>fk``GEFd*EW`vI1Yqa-Tp`OTKm@RAba*;W^*40K)5vl z%B1%CqskmBYKY&35z)!p9O7%w7bsB`?{)F4GLR`R0Tb}E#M5K28o2Z;*+w5BGv>}_ zqzxvrrfK3jZ3vFqGhtA%fBPI7KK+{_m3LDXkH|Jh3k|flGt$s!L&Fy} z#H8HjKjD}wx99H`S7~Jm0fSymY&zG&%cOit-?f3AaVQQ&Z}}e>PATYp6Y36BV($?N z<=btxlJE-`(qf9XVQ zw$iPd#ZX!@z@aWs`k9XT*4-k}uzlnkV89;_M7@`~*9vhGNKr}^iU*=|_5zA+t5lWH z^?Zeiw`Gg%cuAp@dspQ#1X0rS})P=P4#+G7x1JeStx6ma|(l6U2x2sCo{&OHHdz z@9G=dq5k{SV7}_Uw+h7RTRV-hRj~&WLL8Pc3K?q#Z`3x!2I1#wHcz=_IdfL?Vr4;S zWKm4my0U-H;;a9lSXql9X|t0~oUty)&hSTEI%R{q3<71&nAuE7J6qNMz^v+ zfiG+Wt28OFM~YG3pl0SF9+tx_hCG9Z1y@I-&EOi(XM7g5`}NzVa&|TP87$KAhk{Dw zPmts)L%76knVGQFUA+wnmqd+f<6| z$4OOf7}8wK=!ajwvQ2yD*5dhz*>2-(I`y(bz+poB#4e2)?6V};qBPNkIkol*RNXI} zNQmpUdP&P@L32d4Sot(M$&E=C^%G-0;W=yRtA0Jq{EC}06o1V}`7*7=(K)i1>wOf` zna{jwpr@Y*g)cO4826bC%9v6`W>?mVRSq#CB+TOr#qk-rJo#&BGF3vQh z7>$(7j{4|UVg2^jDHy{X4lW>)t3ZEFAe=>Fx#d;Soxr{zR8D%14)C&*c#~7Nw0W z1Lz3Gd#cvU;1tE`2bS()OpDq9lO+FTjNRl8Q4UWV^>-6PI5ZPOhRln63kj#(RiE9q zi7s^9(LVcOoL!_)>i8kp>=Db$KKOEU-RI)ud&ghqg2Qot_i|y^jmnN! z+L@y*_K2ODq_q(s+dCq&>UUY$Zq?R6&3Z5Ib!YqIXduEBxL8gL3G=}JG-4=5Xml0a zv1I#;pI26vPj;q&s})9s3T9IMC4GLh+=|q22v|77!~ay%(&4L8Gy@~Qq=r{xH?cN% zS!Y!imCwe~99C!4By)#a@H7J^m&lB7+U@ufPi#dw|N+-Qs3|Iw& zP~KwH2A4}5)!eoM{WiXc^||G(#W0yqBK^eD+%OT#H=x&ceAKD-uGNEf%ay1f%-8N< zXVfh&MnA`L1GI8epXlG$uqv+zA_5+JU09V>c_+~3U7ZSn3eotxzrr56s%|J8AG$xC zJDPTe#&2H!KokHkBcT=bh&QzJBwW{Nds{UBSQ1=2{8K=3TPm`)15R zWMipHev2Z8%(wW9QRCRFNLGZol2JJ#q#wi7@&F5{n$B4mep-Yx^7|K2ccoHShZ+SZ z^(F^Z8-u8jA|){Ut?|21Y6Sd}p6f^_GQ(2Rq*!7>$FY}aeUs(dfwf@onA3KkbsX4F zklV)G#yM<>?#2oYUa0JHxw2m>1e~1yd9siyo68)7Hy`8K%?3b>JQZj^w6lG|gP!4U z{P@=r-`~2d01l<=95G^^NLYXC9y`H^Ih-+X#ltXg5BnXDd*o2R0(P&H*G_A6*zFC* zgdiul2b$Qv;+QT>;^;+G{CB_LeX0MFMCy4G(X2Y^=E)LP+Fz^y$#^gBZIFV@mVq7} zesi=xQ)QJR+R2KetMk@^>(Bx`cr6$*3J1Jo14QUla=-zOalgj323|6vEKCZ-yt@pc zbkN2|F?5=x0ja(PGbnY8)*WdIdC|nAB4|azeL?)At22?JPmh2C&M_=hEGp!V=B41r z25FT)%oeB_m;RMWIS-FFH1J7&f1-U+KwlgunFp~Fy!$lwo8290C{skf9Hy~9f`j}} z#%($Fp0^=3?d8f8skZ2ZL}R*=W4d>6uLT0e!!^DCw{>4qeFutDAT4f&?dT=#a`xZ zs}UlzWD_7VRK?lhHu-qBXY+q1nPKXUEf>yM$xI$ zMgWa{uO`Ogf`o7^Gc57VE|Re!h5{AUSbO8){E_nD$>t@c9((j_juK3d73_U7^eYw7 z?(HqUy;F24BFA!dFLt{Jh~)Xtg&bieF)KpHPW|!PG*A+(lY%P&DrbVOvtiM2g0fM# z6u!8Cfgfgk9|WY81?aG}cRUQ=9-Xw4nGvyMUEW5j3w@CzJ8VzK=bxN@*xT1YwO{Nf zVdxA+tpgoW>vq+bybM5xusX|7tO%f?;7_8DieU$_$E}qm^#O_gh`473?s@dX z&g6JiW`RNdafmUU6sZ9(PwFsLwLU_KEK!vij?#`bUg{ zrC=77k9u)V=_;B$`uShUql_h^UPf>;4Lj~7Ecej4pG#|JuhU_mB}KV(eBxbm~SxYd$?y_h0xEaE&D^nI2ulRP3SC5v=QTV`iYM|-|MSZ-Ed$oV^MTi|43#MzxVjxo)^TtAPJC#4yOYPgnE6hK0u`Q zZ_yrH(@S>KKca8v_z1^L0nhLqVd%!lQgg6PtM^6mAGL%fayX_GgqMp)`wicu~wkm%Dn=pu5j41?X za?0QlO~Q!Zp+>?bW0@-OcJxcMt`b-bmqv2RHIkGg|IbY4KIb5;IyG;O3m1nAJUHQqW|}oY0kX-gFehfw|79>ILugnn42tSZ zCaK_gd0;u-QZO^U)zuULOj4lP;>h11WPm0tFcOGS_O3Y?BIR)Wx&#qI{X+7B$hj}4OOJ-F@;b$8I>8ZWPNh(Plj#4IE;;D{ZOAST{A=uQ*n-zevOBMTY5WER> zx%=BzPYfj6WdSLyXa&Z+-)`T&pUHXT$XBX=@z#PP4TE_77NZBKFvh&ds3Uw9cKMZw zBN?{~5aw!$aPny2q&7Pxz9}R6%VZyE(%S!Ca~#ds^iN3*?5)6f8i2@Qkr=FrIy0}W}gD*%-K=xrjA)fU{YmzE@khJ6*zVx>?8nS)h0|ED=wn4xIsz}ZC zi-Bba3D}A10qu4b9R`??;^>-~WidNBz>=d#2CvS5(DDs?v_7?6>?+{K%I zE8JsR!8QT4Dx)mI*OkazYGleXY53Cgo-@>H?7(lt{g=Gd8L0b9LOInkp&QaiibTpF z@ef(li$Xr&0{3<%kT|$<8`*yv^DwqvX@9e><<&fk{=9Cd&;%CcbD2n~c60lpWU67KFB^xM@a z#GjuMwlddNXTvXj0XIk-F0y8*`O5~Uztw30e=qx6YidlKiiNz0-~Ne(R()-@z*2q_ zDyX+OVSTsK>MMK2OKHftDo#p=9o;^H0nzCh&J~#LX~39HuZ!vMUpT5SiAIgKIx-L< zHsk_1edI(^fze?=gaq43aDT#9*vKAkb`IqJ@(Ukd@b%qNECtnj_xJndL6nW0>DRZ0cGJVj*Xe(!xk3zkPb&%D_~&~2 zbWyEeLc^9RH8Sn>N0WGwh8-O459G0DHf2a7^3R48;Be(gjHyovjqBlU?wAE+eq(u6 zVm%5`b5d$Ca=eW;d#bngo1@w{7Kk@8;D9U_f0VUWW3NrP=oyzEAuE8JDNsc#2NPIo`_Zzh z6c*~>eQW2ezJrqb)>g&l|A3W8^;?;oV;ut#1i8aIgdw7v@0-7~03IA;`804^C~DPm z(vkrfStVo`b8y=y%uQ^NxnDB)Fj?9qD?b6r!+PgR#B+YrZDmZH1h3&iU#~N?Ra~qN z6mW6-{q1kQ)LEq2#BXBy4c?tglN6_9LpzUi{tvgcNtaZU#r5V{YF{FyMgAOMhDq1Z zXVpLM7pBC+3?QSoW57L7i0`6_kl^g5W+-V>YU;EdD#`m(O?)wy1EoxjPS%EhhLAwb6}~ zxXaST9o$f-3@L;`RQ!Px25y0KSTR&~euWTmxu|uq;bw$v0?`1^g1oOxNha$-ze4=s zEDsZ-DKQV*!AsF>*Fxz={aqznnHYMh=>aEs<4Kh!R&3%2maLFnykg((m%=Yw4lo84 zU_Mj6OuL~jS#4jJnmy1({TZ4?_YmHbaZX&pJ@`XX3cH-`5k$+uONf>uP$aMel6bpg zXmi?IK%o}07J9t~WU`fHVtDW>S{PK**~-Bf zln!ntr_2)xvcyRU6{Cih>EU1T%%l6sbOzlDUd|vNKUBt*2QbE%T#C-7)LP?$juSAt za{N*F4q;{ydIBESSzdghu0VE(Vmhw@`iKKzLp!=tz=w=1_kr5tm|UxE9tF~oZr*K6 zrY#E^$ih=4)@Z_J2XKrNZJC%)WUK_<+rKIiD?0+0oe z9A%WS->oGpN~9@{C%1TcbSSA-BG%pJ8Y~SRSr0W^PE#)#`>Naiu;6Pv#^$BDhi`lD zo6!9e-);^z>==m&uG#O-peN%Jb-)RguHtfm>(g7_e8?4&4dw5=foFOg9paZTcwkay z@t%iCowD-X7-P+PA|CuiDd+5r9p{)*nd0-j{rMPv06?_j=;uGZus}R-S6^)&8lwtC zo#_py`mVu_LZ-g;3-xNo8~@2HY{2%@>o^`)pQ9Ze1_9eJu|vxC#P+p824nCI!!Hf73WhQln2Qy19WqI0O_~mvU6uS@bKCnetpAtB^)OAf;W!lqOH>uw$dRK2Dq^0x5kAe)!Tj0>c zTN5CRu$@ctQA#VYmN}m~OI$OP_fvvWawof?{wtpk41EtQqu9SJ{256QL_f%|imR3k@s%0FCj}2j+PA=XOl>O`XZ9M?MFjztA^6Y zkt_@fL%2JLlOp^(fCf#(;sPRtQ!u7Z!x&8$VU0%ijAt{Egqaq5RCFuyj(6zcD|%_b z(N#=o^5}v+FaP2R++mt-PZU>!{=#p6j)N`S@6UvZE(Mq!qkt=KZc9htu9W2Y95!}6 zFBkd9x<HtCP*;_6&0P}}M|bPL0pNx%j$Snc&ood#wN^Y;~hG_N*DQxoK-DD9gFXVqu*vsfXB1Q1RNnsEaaWL_$S5~Qj9xV@4#-3Fc+qXP3Z;==-O zWlaDR#nQq8vE_eP8d7%2=?)K>e4V8ao_kA@(Bqdbzg1|39)V#-yLks1nR68E^@K|_^)Y1bCFZs3 zig%~0Cq55#AH$uj$!+hLCdQg;>&V)c+tzV}y?B}N)kq9nM@N336Mo0Ns_&B8X-9TN zMZuz?#2XI(5z!WM!#o ziZxZ{Q00?TFyHFyTaIS?&J+B@EJtYf#oA++=ZkHx!^OrA$PEp$KoUEGBZ&zwMa_5Q z4HJrp?zJJmHkNZMUXQ<2SN)B%y0o??LtTRypop{gpBxCM8v|BJL4Bhvi_0htzj6=8 zkwJnVJRd98GX?Jh5@Njy6w_tVz2s*C zHf07L$ow?ncRW#F*l#p!;ey6t_e*7Z0-rHTS1U1DiMIzk6sO2Xi3Jnc>}ixeTBN^> za?zoWhZ&TKQuhjN>lhAo4&q+#|N6TC5RDJ&Z3<-_<$>FgKR@o@J2eYJrb?fVce4i@u zGrcy&U_z}0(*b|}5j&z-TzX%UfzGl&r1%176Uokw)Z^k8r@D@1_B?ku2kqC=Z<381 zMdxk;R+y^q8eCnXWI+}eDt71gO}je}%@Oc67rTXS{~dS8puOM%Sg710K#)@^um2o& z!6*lY2E2a+r2u!Hsitzf;^)J}v$;XWRSEZ^mOcb`1t*TyQ_&9nnw&{XwyWjykUHXg%lC+sM(|z+~sarPaG) zMx+n(0H!MiGl?E^?e~iR=^7U1z4_}wyT0E2s-`wM1}uYuXvJ<(OcHk+}sAXTCxrlV<{^P8*EmaIkWr0c07HFzvZgRZUMBepi= z4X&_I7y1fr&Kl!C4M>PHp^@&Y|1inF#K7}lIpjWDv=CT4J?X&~rdzyyV=|VSK89D3 z1(cj0@YWjq!#1Qtgx7eUAeLklbN;gxj+xP3aBB@xykp*022Z?=%vQ%=T_kiz8UES* zS+3f- zE_NSE*F${D(RnodT0PRdMAJ8^#!n4!qPhXcD`}xE1hL3p4bf`}gFK2dmee*J{JN3wdMO?NYp_WZvnylKt1eMsVe;EDo zBR59g+oHu^7&PdQ70`kuD=t%Cs36}JgD7Nus?HeGeyIaZ_T|BX)bN}UfG(=T?Pl5K z^#bujMSfveF92CoKf|*?fLab%u1Bqd2cdF}z}gixKR5e-kMMsPF{>rOFAQ?oD{P_% zN?VZ>_&~reS_$lOwy;(3p5Jh+ghN++5M#+m+FqHC)U7mDQ4WDq)Bjr0`}jUR!Mqk; zYTj)r0w+H_5w1XocX{A_bF}fUr~IoU9SkGO+B7U}34abP9olyCi^Bbb37?Z?^kOdi zat8@DrUI1Ura^G(embpwS+2ATLCJ9De0)CVAag{v6b9X)(20F5U-)mFs`PvkSv;ZXrCf5&VQ`iiD zE40glcs%pPR%EVmyyvGeq%IGjF_)(`r~YmknAwRG*1wnP^aRF3X+p8Fr))}e%Bjpo zeujHr?voa7se~{Biw4B$0%vm69W|;})zHq;R^3hEpECJB4B_XF1upw}SACFB4+U^@ z94#~eoEB&F2C|6ey)E@n(JF}Mll63my`KlAh{PUDmLTV?gErY*XgUwI{p{g?CimRa z5GJr&?@=E5mA>^&lVe6`lVDOt+d!e7>)8o8bBx#9Lrp`TG^|+(Dh@65ESD2jM9k^| zww>(vG9O6^UgWEQ*mTjlwa{Ssbk;5LD+h$JeddeqAW#a0SU6V>=2<4Fu{H- zYjR~eRn)@s<|#$*H~RhI5|K;ek;Tl#18w=T+GnJLmDJn9Hu;*a0hUAU_TILhyRylO zX^V?FK$L~VH}$*(|1h^-K94TqGYMbe3Jau&17i&dV63q!Ko3lwj^6m92r%cTtu(nY zMv)36gkq6?*cgaMH`2^1w$WIftG00693o{1_jVq8!^x~saF$S>P zUIst^GdMGbuNs=rN-#U33X04A?Oy-g8aRc|j0NQl^?$a|N+H-mgf773q~q{73*IJI z5<}{DQZQLFXLosC~O}$69niO|^d0>5k?NwZyg3K3n|BuFuKbuFDowD^2}L0A2l0 zhO+r9-sZZyHJl}XW6Z;uku6D~#%1>9_ns)cc%U2%06JWMGU##r)NaV`RcK^|4e$1% zge&pxOQ2i>MAqX|SGXsF^#!Bt0Xv2)$drVqBC z*j;?Z$!_N$gax)QwS1JBvABb3!S!%oB+-rzYy~W!>SXmWK?Ii2$#Bd?O%9#S?DKGA zO9A4;Rz;e}lTf*bzgo>LF0W*9p|gFo4o#vQ^#aHXU=HNwY^%s9SMnSX|K47o&;WxCeP3`dwT_?v zT@-*NZSHxca@)xQc76DLVW{|_ouL=ET{M2T=QWNU@CGrOq+iP6%?1+kfX>r8;8S+Y z8@Yr?|FyR7tmRJH39CMY#peI+qvO`+%Kyqfkb3JLt>nRJUR$r|-yQxhWC>m&0J`^; zbJa$meGkl17sUo?^Kl{C*}*^AdgF|Luij8PkX1|B;5M}r8VthH^){8Ro~MiFqlzlb zT(TyfL$FED4KCn%V*D`fRTPtlY(I86iM@S|$tsPfSl;6)d##O8xQl>evGKhbg{5e7 zTk9Pr7jsHytSj_zav9d5db!_yVL@N?)`w&6U@bh(|3HGs@xU}&>!8`>F97~jJ2 zyIzE6+dkJJ+8c1Of*Iv|s~dftwVV_JoB3;J(7!gtNnHzm>H!~WPz_B;1L0+mGoV*%d@QWH* z_8Qr`mR4yn*pQ=4)lQV|-wH3=csSnS=xXx8oJZo+8WdTWoLTOnC+gZ{f3Hy{?5h)r z05Ya-zZG>?OL`vp>b6n&o&WwG4uIq(N_e7YEkaPONm|#$BL&gc z25OzE-xZJdyp|~SlX&Q>fI<;TX8M0`xe&4RNW8a^nc1;r6gGMM)e^a ze`8T@AncBSCGCKk?Pt@nWX_~Sy>qYbIM7n zOrz3&p&(IuLnYw#n^%*}L#_b?OqiAu>R$iP>z6G7{Eg6rgip|H0+e(#Lvt=tkj<48Tlztj!YlZ+^hLsDlSP zvAU)Q{B+N_n9BSDPgWuU`yAK%ifPMpX zwFdAxs>#?Y|7W_-6uD~!tr5+eH{ZNjg^j=;N>Aa9gVoHFOHfPP$tOUUT$xVFke`lK z@qj%>k3a7{R$+XIuG?Y8Dev!%c488K)56OjRQ`|p?O$q{XQ!+6il#y*hnBrUmdsd5 zCe}k~44F^OD^M@eGHtf-oBlnhtPuI7opx|EM+ zfbR~pJWE8!L)8X>o-V??f*wV&(bnrS#>-}n58sdC`cqja(v~!tjhrZcLA2#|KIQzk z{s18oXpu`txgPG%i86d9{QbZ60RX?uJy!^(^#;<#t?)MDsy0PU|Gqi@;XDHHci!_F z%GORdJ}+)NgX8tF(Lrn)pNsWgw%c1^Otn4RqJ?H{z#k>1x&mZIg?8E80V=yso7c~z z6_{ruT&&AkzYk})kzzGX{*Xy+N!R4GiMJOq?a|JGnJ~mhiX@t%X%}P3^E_qdzWhBO z+Dr~cLyLQPS|Hl5Xgk!z*Q1qtN|pe}q-N!Xy>TW6uzKJms2eK-Ht`^t$<-K8eqdTT zcd1km-Kh1&NS4aw=j80HO(==XH63<-_h9LY26?Uc-G3OXN47DHh9KEE2@@BfoV$D{ z_{8CW2jjLaLr8PyVUOjvfAD&4ctBwmHGjlaX1z42H4K?A5tf-VnO_kO;w0i#E?6@O zQ|p?QdjX`c=;i#2zC$!+e!DN*HP?w>ZeJH&LrTxDc8M?A z10TF&13p&@OUa7lP`<0;_216cL{~td(MfRrhgt(ARS&rgSEZJ zE+|5lDz#IN)UW-1-Qczi*5%3mRHdEQ^*YLkpe@&MV`aQh16YPn#4D>Q;tI}H1HX@E zh1@n1Nk0S6+KoIf?$fti?{C#^O`G05u(g#Uv`|jcg(YD6O}DNPJr7+QI`bp9-rQmt zYHUZexomVWj>q`&bJJalm76-{sQMx;uk}STfy_k*GVYJ?f)+2c3|4lDSca6~8G8Mw zGLI#BTw@Q#PxHdvZ~FO(6W!Ha&+>A_(0_AUSRc(sA9cjFP|e*5wBBE70B zv7OF;2g6|1RUi7}-Elo{#}m4TtDCrNG*k}azZQN>;wkfhPL%uk7tL#b(u+}j>H6Fp zj7?|kS_7?Nsi6wjh&L#1(|3{Si-@;Gz<==(2{}#$rKqm%Xr30uCpJZ@41K?JTIur`;25H6}Jn%Mz&U z>(h19-=3KUs~sV^H5T5ix2OFJt@Qf0i|fnYmKEO(0Xa0C!pS^=fJDCN@5zTVsqOj4 zi=RhZ!h!D5)Oo95lH34-(vq^X`HrZXVjr{Lde34%*`Il_8^ZC01SrhU_gziRuO_TK z(d|!JK%B>X2qrnVybg9LnvE$x09lHp zc*RtDV_@`+Qs_sW!@s~*U8%=U3kpgs$pN+h{HmKnQ65=A7y7IczKC-L}=;GJ#*r0|QzW^>}`3uT6md7VCw@l*@! zqIs0eK9W+fsD8&oo0GJfb=@|+L=++G*vRGI4uupwR!ViUmdGC)%;c6^H@Ik6U)gS@ z#`>4J^yh28%v_e*H0lJ_CR7!6D?gi2h<^?$9()!TeE6pt8y_xUcuFToTHfRfsa?lgJXD=1}>5?o{jdY(m11f2q9*WiR?Kt^T=`@VETuof-}R z-YF2{4G_8PdUt8pIjz^}Z+A8cTMK0X{Jv>+NfzsVS&iSF`$4hu=8(+D zNUznansjT4fALG8tSAH*6wm@eBcZ|pkG8zOy){VJmC3U|J%9I!P|VQ8i&DdbsICP| z38?emf!8OlV}S3b@hp>YtIuN+psJN%6*@X@dn(*!UF+xid}~+;sn@iEuG@E(62Ei=pq1Yw=lgWS&NSKOjEQV`q zH8Zto^4J7%U9X{ppptV#2A@>WFrL?Dd|;RV>F!A6w8b;>FjGYS$?rxUifx}`gUtQ4 z1g)f2RX#7||GEtTKsHUUGO}9OCyl zf0LHc%~gJ!s-)LmKMrllg=XY>`IM1P{2xf;Kj*&nxlX&~b_sJXnXVlHW{p-rN+YMm zp)MfXPPdPNT7M&;w_N{<`;*&FJJm1y6`b;Zo8KKB5dHR(PUUrg9$wbE?Oe4@AB%1U zxXPT%A2Q=!OejKM;s4;ReSfvmd4cR#>9Eq~&;JPEAXBYA9^Q8|HvCJ02*^KDQ&Tes zl#?knLC4Dg6MqL^9Fv{hVniO$zQw1m`0)YGf(!;_6nQdn@5XkWZ_lmf8*PYd9iS{@ zBPY286gVd5F*)(mZima&VcPZfcC`_kL&@Te*Ah5{vVmjIK&iOP9#Xl@okqna;6YJy z6yyIlXW%?VVMlfvU7wibMeQ70Ha?{Rn?zdCc-k7lAhRA$ntJ*NdYof43O#NWPz@lz zs-?d_>%%@jqW0SXbU}cR1+s)u*k;z()fY1vOPrZ?k(Ls}LFCyPBWKUWvllJ z3eX;iRT!>{1O3~^yy3Ydk!=U5k~oqsN2y+-sT7(WZt{gS|CIM2$M{*9+7Rc+bH6qXNc!jZv9ss>%P( z*Pj6@lZ8PCBpGkC99PsR&}$%gKI_r#*~Se7Vg_9D$@*ug39J zp4`?2jnGTwpI6B+Yap6j-R@(^%&Pyj$@jK65xIUTjut2k&v#bDNEg)X*Y8>Z zPqUij#7Yz7<(OH=M;5g@CWSQK?`X}<3mPBucuPb@Bge5anF!1mTf8_P=8NJs;^`}9 zREgqA1_1QJj?QMx(3cMo^|V){UjLTz*j`lC6MR{n~Z=O~e^OUgax&%Uuu zv~#snhzCUl9fcnW~uQClP(%SmtqRT^dHBCisR zuiWM|a=$ov&M2`D&>4@f*;w?P7LE#{6ecB=9%!M)$+#pEm5tq+ zAUH>clGkqKt-VkXZVeDu)WuGGV|BkTS_;wjLod3Z76b0}M-<@ISE0voCL9aMsJe}M zyRM(?HVh12N+V>|(Rg!2fd{D2t$*q#ci_WOfhphCQCrpt`3SnEPICVL7C!qxOOOTF?jC`tj3Y0v`o%i} zJwr1$M$rmpB}hd|x;or>+CP4IJ}s7pZm4ZQ>8EY*R+SW9`k9;iT(bajS(LFq_14`A zaY4KC%ghjYu(F&#y`qQG!6a5hzp_$XBW>+L{1U^sTa3ayx5hVj3Lr7Hme7jMWT*V? z4wjN0D~-;@rK{DIEF5b;C(~NNsCb^wLr0bkgI|@=!%gd6jh(ztlapn{D@t;ZExtMZ z8%V*=5C%2C$frgS6h~CgD9?Im0G-$`1!c*qwQ$EDJS4tC&u|;$k2en+(+hRAH7y>C zly$vu?f_VnvYtC$sqfA1qq_E$yUlhHjjw!=>wTh_4TRs^l|cf(Cbn#u$D^e$zRA@vKSh8l>F;QY{HmJ4}Cu z`CGd!76m+J_3@054v4QPsFma=g!&vF?mPe=8RVEdJOn3w|L1Qde3nn=hNQX0+$=r2 zN^z$;y;(NH=6A9p1Agq;jBKa7cTdOmI zcU#g{c1K(S=!Kg>%hY;8Jtkdxa5zo*L-KPr?r$vYZQ6S$7l4RLB+???6~v$UmYD5S zhe!7o+(UW8G}@}w62x@gf;<6PG=T(~lH5(!8yp zXl(h})cs#OuZ#idG`;>jg{#?$_B`h=QjwsH{-xjt_0Y1M2CJ%w8ldJ^0dC`Rl#zX@ z#OMN6jLuyIh|4WIW|8t>hv~)Z7y9Q~%e864)kV|A3&v^l0&6_W9y*M8EPwKR9>sv{ zazZOWSi8n|b~GgH>b@rE{jlEV&hmf;glPMd()P;vHMIhz{4@L*rtw^-YU^m|B?285 zKx3I78;{-vrm$i~q5z+x(Da>u@**IbiKYrS{)noCozb4V5VJA{6vW%bTa5D_Co0Ms zGU;;vr%sg(#3_3=D*(g@GX#THY=f20);^=0?%&hi8-1B2>xJm$ebX0dvD$qAF$RTU zWFw*zePw(AB%QL~U-w`;PQN1vNmS>{%_wH_osz+Yx+{g$~pby;g57IQOMa ztPC+2x9{EzGfZ2+9;l~2SD70AxfB0c)VmF~+bmKmnCO;?`b4jz%}b zP_9n4+N;6nKuSRd7o||1@>MwC-q7W1t|4>Q)W*K0RjAQ0Vm^av`oIIXrc1`d^=0kY z?OB+|W=X;V?yOUNf6F91XYJ52W_Uv=K4ZZ*?p8lv9>6=&Z!oX9aD!U=5)^;M>~AOW+8FUy8%2XaG?jO!ZJ+%l^w4UK zQ;_r+BQ=)=FMcu8Xio-3NYTqp&%nRIq-H}CYH|KCn8a9y?dWD3DsTbkcz)vMpZqmY zy`G|n-rJWawDU}L9LTSJkqRR1J_tz2~`Pf{3RynFaq7B@KLqNXFa-`kwm(AQGml<(q zC+O|Ig{HUEo>9jB^K;=ejvU>bK4olMBCJ~+T~c|FkOyHyxWeOb>#A%#(`{1qFjS~W zwA%l&3bEN0QoeV`gCp9c6d$x_a}X|onpGN^9@jKcX@4rBT`XcE;>DM^@M$jgKOD6+WMu%`5fP>NE%$85 z_#qM=0C~DOQ?joplwEJGj$~i~l2IWXb72BCe7)aV`YJTvG&g2!-EZ4>L z0&J(4b-5_rynL^ZU+FdZex{(lv`Ke19c9_YPLyp$C~AAnYmXuB06N5}HXnY?!;|YH z6S+MOsJvtXl7Kh!Z0mgY!bUtr=l~;Gp4?GEs3STTdzPM;KNBD90JJ}tB4nvpuUcm+ zb#*`Li{=0cU3p(|Y4BX-Q@NQ#&=J+5k+`+)2Fu$gX4y;%)%Rv<0CiTXKjwiryB6b} z;)44D-P>j*k2(&nmLX#0=OU8Zdg^Ohjzlhf94+$H#*Mb3T4+sICBi9&fB36kp(F;Z zdO3`OWeumE>B4&au>I12xD{W!Q&NQT`igxPpu!gvPhi~-M$&Zkxii~*zTRhmbj%$* z1B6GI7YJ&-h-+VXppzui2O{A6%#exh_AeY!Dzal7d@NRC2yQn+7qJUzNOYRBv@Rq)9inPyyEf z*ILM;aAnw%Ftlo63$@A3HH=OZAfv$en+M@bCInXCZ3lF-`FdpHqB53Sq=BQFC#9(v zzE%q6Y#<%6`Vqg}?#po6(2$pl0YqMN$XI*dtP(95eZ`HX1&fl}LA|YyiFHBQ9ZMW{ zd@EE)ysZ>cFqC5CZbzo9`A>)Hbox!YRdjYly@*=wi+j)Y3rL-$Vo=?rz2J{)Wc=Ked}Q-nW8E9gfS zRN#B96NUBZ*8^QLmvX{F-$N&k%bSxc*v>`3vxNu-%kM(DU^+zr&9gqZ2M2HQj1G(1 z%fQ%e+}l6uQ0fSWW8HJbk^w>@#mc`nea2>^=gY31<8;mr0$KLa?$7yPonfhpZsb>J>?Gw+id8YgPVKtalDM0RPUn*MucYoHe8ZpiGOaiTH%r)g=yO%eT#3iH8@odFyP0I?bs`Zry_{od>Dt{mt4E4DO3>icD<;f!-iN*2wd8mT4 zhbJzl?+~`YzlOgjEm=**7b|IAK6X86s4@A|XN}vIv+-p0ZUd$Kw=KBEg_FpxYf@&# z*Hm&;5tSz$UaVor4X$0|bM*jV;DA>2kgf2HtJM*yLvw-oQn2ZBjr2oDXGvV zZFrZI?rsq2?k*7p36buQkX*W95do!@?vn0UIu?+U?k?%>uJ`zR-e>0f=KTYhVP?;{ z&voBdr9)aA!O&vgMrVHC8;G3N1N?+f&V~8_*Cy&;n&7kl<6wWn0(4+CrxEyKW;hWh zC40Pl_w%b>owW>b$~aefXqwKkQ0j7<0b=jn59j4Uu9rU~{k*fySws2|*fJ#jSo4WP zHTm-?P`?oe1=_$nI8uZPN_ATUN~^R(XE2$bTR)-MFE;#eSZU+9)8ed4<FKB z?(DVBV2s_x+jAsl3im0mvyE)PI{X5cQ~PL<-(#2(Jhi(ICM7dDEC&>Uz#;o0c)|2* zQR|NtKvPAcTGi&iB-#WyrI+x&cxxRah^0C-@F*!61lfWU9@;+LD%kpf#yJ}8hfc#x zFOxC-+kLh-Ly!xpuH)O@XHwc)cnu_Q0b5%#}s3OpQdfUR&RrQ^~=aKe!!fWWhe5FBV^G1?d!ka&y z<6}>Y*l3-0xxu^k%U!wDIYuGVFGzvz8F1#CeTQ$4z}XV9L&VteA&=2AAHm0dR{SG8$5TLQhqk!qI!X4puFw+KDnVpgM4O8^VIdO)I`kt zS9#>-LUYn(v)9^P?>Ck$8#;EU4NyQ1py(s}P<`1vkgcPqUADSJn{376k*cFHKIHN; zh+=nnE=VJP#%?XdmXiXslOu@C{JC8H)8-D_xm;JHl$BNGC63~c_Al@2nlFHaL?`q6 zB<#u6Xt@NnGVy*l6ndd(Yx&6Sj9=d{EkyA@vi9VXo-UHsO76V90u2S#J@%{8f)q+H^_AD?U-PFOJvGWbm`Q&Qu{93ANLjB_%PBny5r;?_E!0PW zM~7Bwxl9Lq7U_D2SJr6&mixXp#Fuo2?{c7k|ZwqY|M>T4> zX_n)mmg4;W3xNYg{pikUy=agjaUX?0D;#rc0Ir0Y=QEr`h}>ee(m8;sQjUhDhkQl) zxU)y*KWsrVg|Mn066mrb`}|NQ;?KtTN4>9JZqgs1CA9$PO4oF&u^Eq$Z4_9hUvD$> z?U+>7=N|=DU)d!2pXTC!9dAI=c;P&+m+SMuV~-@4MB6fp=IL5cRF(QiSJ$6nNW zQ}*bn(@=}L1l1P&KxER}R)6rT0Owyl?ji)IvNONP#H|Sik-i!VuIhU_TupS%vtL)~w+`aR}XQEzg?g!ZL3$k0@(^yi!hxBXyOLD_Go3MT0hOjpnxjbgoqg5fE=8lI z%4(*bc10>Z9IGi9btXiN)v9uQ_TL+dF*@7mFVg7$i7@RmxGnCtN62Af-Do#g{Z}-n zG8e|Mrd>(wXZiy163VwfQ^I7BI_3z>t#{A_u!Z~XVlwFGJtK(eU)hv9pD#7(bzo}~ z2p^SlImK8MbV8smyR!%@L2+Iv5i&3)8O&4#*;`;z2}VFFQV_3AyxQu4nmVVyug@Ls z(oGjdVYcBH0N8dq7O>1(nwXf_GPpyMhC$du2`VH7xi?nwlt}!3>WmCQ+omvxX20J9 zO0u0mD+A!d>v@`^bNW}%jho5jp<9Q9O^f}UGZpYS&cDsUmu>tfAlbwkObn%Itvg*| zd+{)I(h6D_1x;(wvA-vv7(h~uO9mPV*u2f!ajk?XWqWC z1X7xqU6nVDGzV;9^aU1<^-p+W$KCkk-3ukde?<+{}Cl7 zYuy6%&Y>AhPxE$3h_RQEuq7hj{&}BUI}}ENB7}GCDuY7l7k)eB;*|R60HQdgLWFoZ zi)fFL{L$aBJZ^w08c)@*iupNaMd=&Ow~iq08La4G8|X2`yO}0#MR)p<)7ss?|5LuKkSoCl6&CEgl%<}nF3ZpfUg@u8(BcsXyhfQc5qK$P!u;1JPg zbWYM7BV_~^t{vSMLyze8?D)-kVPe0?KlePc>;;#1sx^JkRFhW217oo2R3*;h6PQoV zHdpoF+m?=zD&c=@Zw6e-bPe(jzA5lx?N}y=j$nwA*AGeKa^Vnoh*AolsbTG{M2H%fM!c~Y04yzof z3*UP(YWrX{9`qEs@Tx=4Tzlg!E7`6~$~iw*4zQ;&kEBT`0hk6)liz;) zH^{`z)%6z&rlO!(k`@{~5W1jMrpE|n;{c{)?<@zp^t3z*ISyY-*ytCSa7Z&doVDzn z1D@}INz_?(a(B6pl+`~ng4695$PbS`ocqj8PcIu6$Y%pMm5OQ;Njfa>+-M}+BV^^| zqlTt_11#F3y$3xhc!3rxYq%vOOr+((`|GACf`^BP%3+}2A#%1B zZP)9hW_<4LU(I(5$8!6-x`NC|Ij0b9d8onhPlER3UZaVjHuI{r^Lgp6aJ6!7mHj@nIX}nbkI(eik6&Kad2Gu2xlTx z@}sk^SkJmQeNcrMsklH?9DIIrAQ1yq9o|jK&=c60T# z?Ge_$p4F=)R>}7iTy-c$Mf+>ifp*~&BE(~*OYYcuNxWntd@a16m>g)e&WKVAPTTLu zPo4vkA(6i|Vypzf7hepXS5$xGxx@RzIp~>x%_AM<6u#5xGOT?-S&k%WPJB8*fiX)& z_NcIW{)wq;9hAYnQfIqj#G(Rv4#lB(vqV(VbKT|)dzdzKO|Q+vpAeKoPjyTVUD`0tsDl=cG<6g{5)!`jky?_d4evAaj%i5 zjp`@A9NC&^LBk<7yOkP_>9ldKH% zXUOe;vj8wY(xhA{uXg$5Z|Xc|qPe4RZ! zv{gus;yC8W2u?-2)M`k7PoWqf5$zC4ACf%ZXYRczi9yH*(o=lOd)8yZK|82&;N1Kr`-8cORuSUS573)6ljaa6q;=;WlS4W8;qKYp zrIN%zzG9KetK;_PR~uz(R&PfPbw2~j?INki*Azl_++^YDWDmZM8*gnE8>-X|q$}lb z8a+ePKgTEaj{NBkCwVvGL~L>x_;?S9Uf$&hA2mxgyUVWlVg5$^g&K30ABFe|^w#=< zyzAna@1-5*m!KeIP!!`a%w9lynY@ztyeARUx?I0mi=XqgaJnYWDB8+X~G85`cSK@M}Ip0b+U_Q_pw zj(SOz^rT5LF;>oI(M+XD0(}rXtc6!n!Y2pEAQc&1*xld$c88%AHj+BR0!g^M&oNLT zb@CBwb=cJ6I{L4dXa=|h08}b3(W8X9a^^Dq8quRGum#A0M$xmlpo}E>bRvs_06o4w zxJpyEmI@eaYjWHBYncArR0z+?jSgw1)i)vg#vYyU} zXoKOQFFovC)eyi@ykw85`T6poJJ%LfXskR_VGO?M-!!^BmM2x6dZ<_okBUureI)Kx z<%K zO0qd|PzUs?J=9kVE#H5);XO!G*AY{Y+G_6tB?QFbW~xuUx((7YvY6Sxe+A5pX>w^% zU|blaaUJQD*P+rn2j&<()YtW5&aUK#;^a(;qfHm9_fZu=0}=2`1!Cl=|G^&J_h4VE zoZkv$pHy-uGl}YUH+AlXc>?k2zuc@CK0UH>%?T4`i3642N*T8`vO+bk6elj9Ha3CE zb}A(;27T0`RMu~cKL7-!uCe;Tm%SUwD2oXv)_=RMUpppEQRCgIxC=7%;(5W>O6jfx zgT^A0+eEAhbz#Mb$gCt#Ws59BF4Ao5@pbo06Ll*Vrj+y*j{G$9k+F7^I6-U1<;1r} zmk<3@!3Svl0zYg-MY ziJ|L+&89JMW|_m6AwvQo%&-}_WCoisU01qLUL{KDV+@s0_!(cBb&SCh=*KC$b;lc* zO>;A|LWfrG$!d9wyYC%agHfgriwJfha&=VxJ+^d!0v#HC~xUDri5p#K)BaTl&DrLzk zep@u!`+9tJMDfKF8YCg|bk9I)`^+TX0VuV0FVH(DUTh1lr-2A}no8Qzs4OffAE>noL-+*KE%sHa471&3Bcr^Y6cQXul2j94|p^e_Lf_i!o>c6^m|VxYYky zyY~gQU6A*%SZ>iTSRrv~TIJu({sasQxAHzn_KGnT-f&k@^A) z@$O^zZ&x}ICwj}KbI-g6UXo}DJEAgHRmE2}&Z%ZI_$j`iOpAKWJ5rNM=58-t_2H?Y zuRI2IPJ~2x$_>Prd0!Ok?a*lSv2QH*r#HKYdWH0Ca4Vs=H{bJ_@~30HpNjl6pEWJM z{sfb+YA>R#kMAo9$ z0pI(C`)v=N#mvw&Hc9fSr z-SimA>O41!&(!(bpx`L@l|NeZK}fw>@MsdM+7%6;Xqdo@!~uu}g_&)uf` z9GW!XkXkU3maTvAHG*e60{j_?)*>QsPxJ_Q=+?eG)Sysz^Iomb+Sjm)$*HCaMp9By z0U+UdZ9bp|@jw=(@gutM4+QMxDnB1Z`F`@sI(q;HISL8Y6YgJbHdYXbxuyJr(U8<^ zm7VLW1;>ekOy8WLKXH$$Qjc-dXOt+?^W9%~ezHXJy5NB(4CiDP<~?`w5_eRo1H1!8 zz_k2Zyo~>9v3gQ6!W-1z%;||Kbor4%xDCFPp$%#?MbR+n>+8o()S7T?(JA#Xv%cG> z#DZR(k4P0nJ|MhPr0bZEBm8;GRSf)=L$@Bw_?228=or8Y+sM%BC4?2(*g-~e+1h0c5b>*3{eNg zBo&xPx4AWaYfwd+2=Oc;pKDM`yBi^bSgjcsJ_1l(;p6#Af+9hOj9F!hSMFMg{Kq2u zS>T6cV2OizKuqjU*9`1uIF?m$fHI8&!y@S)>IYfL7iL9`;l_)NU#^DJq;=4j7mJy` zAN&-l(ATwjyv1j|R5wRo^J(#&Ejifoiaa>G+>Oh)G1|;p6p&Z4WEt5=4bH(MOG(W~CoSLm)>q$_N$Jz~EbYSh=DOWW zp{+l(^JVmh_1XWd&I+sZDI8~>vry>^>S_enff4GtvYvrZfbF$FZ7=K-{^X$eI&mD} z0x*rb^{Vyt-QH?Nkx>PjqRVf=1gb*S(wpR{inl5CFLi8bqs3#;3(?nM+jg}7qE^~9D5{r&fOS30bb6ae0;}zHi?!`Vkr^lJt zJMaDC;L0!^PtpgzLKD${kBoB9{4!bz?cWWlQcLB0Q$j`3!CZ`&O_8wCgvJu!mv^uvnRHTJc{8G^Hdvysh3d03_CDW^ilR z^fHY(C@3g+;`Bp^)un+2cv@Defy5S3jpqn_)Juaw@-sFzR#5+7#C+QtdKV^E{SK`B zB{P%e(rgF}O#W#oOy^GaDZqLp$>(w$JE?exWUnjLw28W+z{sZ=l2S`Gv>(R&urOGo4_3lwU zHAbO^>EJv)iXFr|Gs^!Dpa-|GfpO=6Gg}thR?zIM4rBOBof1Vlk6#EVz_U9o9YyJ7 z0vv2!#Na{gZQy#sAMYHD6{}1=Sj1P+J5I4bd^K%qxjkbWA{sE&wqMFLG&R z^8|*KE(12$C_bQ-L4FA%3;NM#x92onk*CV7LM`0JgQ82##>4x9TL$`FDEc_3Qa|x^ zn*vO`$RJnc0$+@TK1U8=_vWm~)$)DwFaE$Fn`Q;B3ZIH8gbNnEB1;hu(8~tPJ7aVuf+80@d#{;^%&=fk18*n{n)6Jl5eGb z0Uxq{{v*g(NxV4>AkrxIrzk@Y)l_&%Z-OdaCP(HJqV4}Ho0(}}X;x5!sBvICrGo=gM z!)RAx@7%>lgh{w^weV;NSQb^4COy-atTS3MQCFA8U`f#Gsm?cIbTh*fKf$mfk)U-= zy-R^VLn)!xj(2DZ_Jg0lJsdF>=}aY}xkM0**jHT#u}rQc%53IhMrD$mLpBrqkSZh3 ztfogSXU~~V&yb_=AX^Ui-MoLa`wRyQYTQP#8v}~U0Qt}UeSw{Jj zlCa%n`3}$WOd7SIUuP@&@$~k{FEfc>%PgXbm+Y`@Eqf4WY6f^*-FpZCjd2NTf)`EE zH-oQJPm+TZ!Eul)W;RKo#Xp+bKgTVit`=IufWx5vq;93o=QD@-bVy{M*put^A2N4@ zW!kib_;69-<{wr|LPd%LZF}OxRNkT7SI35ux&CO;=kX)_*JlD=Ell8NL9c_~+kQ(K z>w{k=|G+l1SYy)v9pK!X^sCF%14&c^fr9wLbjjf!3=xTOfWew>t~>ik_ajmc>|AvB zYSYP?uE7`KFXBP)N|_QrMUO*vg5OB&(gpS>D}{zjdRFX=UWfed(j$abW$94GhN;6e zn``|%>_!0%+CdMT;Ivt50iBYv%|$N5LW2<+z_l*P9<%!Gp8GH7l2m;Li$D~$~fA;x#uI7A|FII zarfYXstM@7{GP3wt`af&$*dcK!dp1|-7PQAqcdvEpv~c^kp_|yhe*G1s?r}8xgFf!= zQfMV+HFMg?}#t;1>X!gI`&?EyBbskEort4c( zxS)W^VOo6)bBHO05`vmtg-CuBw@#CPmjV^?jmb_^9S24vGb?dlcF?kL6XQdC#k!45B?;3wqf=s?t5$WOR&!WrH|r zJG@JR3?_55+@4p&FBzZV68+vw7I*lahSBdqC-Jt%XcL|OcVW5PPOn7K8q9arR-@XIp?K<2!kP8q zU_eLMqx`uc7P_1oARMa5jah_5JN@V)Nw+h(rZ2qTmi?(nKaGaUS>KIbz9%?+fDE+q zjzcP=BB3ivPDa}>RJ~!Z{3$CBbWahPW`h89sr{a9gL9$slk+6oxL4a@!(Ak|IaJ-t zGhTDKO+B|BPZvqldcVi0iesP*0SD6mt5VzNhRj0xUjA^ugs;?|#&YK11Zm&LrkjI* zI6SQ2g~UX2q`#M&UYStXmm5SE?swta~R zconW5rhdKHio#2koAgp)iAfP5-(I#za(xUvWZCkMQP-^22jw51wbsIFm_P@73k_k3 zGCw7DKU*ei&#Q$VPZ!Him`C+2HaTk$fPG4c^efj7K16K`(|o|s%)5CHd)4&RG_g8Y zzh$5c3~nMKU~p@-uvIJn+xl~$SKEHATygQvA{ME{m4Y{;=;(Kj-(zw#QmZry6=T!r z!@D0FT3v{P(;oEWuBmUt=14d#P8+LDwpe2DOv=XZk`_q%0+xgjSUt)ozb(#X>vA0( z=)eD7wWd*>_jKImz5UB${v5&9(LPm$2b0(bCuJxAXKb5hyr!aIMMy|F?~fcw8+SP@ z%-_o2ZlGC}nZu+^J+ZpA+Eu)J@k*IUr(}|@{{M13Cau7`3NzvhABJ{)(xZo&*w<_g zp*duLVz3WZxUy*Ss378Lf0V{(eD*Ahw)^hx0TYV!c@kwG8#x9*Z7Zs1$*QQ@0i&`aGWvs&; z0V5QpK+HOqa!J&b7tY`ZS*1s?{5pY82ZyMZuZn3JsAP5p`QuajAz zZhc(ytuS79q9LMEhMYfcZvWy6Uom@ePvw5qIyel&nTtGUaIcyS-+=4Ig?2GQ4WTf{ zmeUX!A_xo_)Z{rvU#wM@B9n32(JU9D7JRnZog^^KCs~J5x>RY3_&9uR{n+Hz1j%(; znx-^QOJ8f;-S|%MDfYWk6u_;qG}6gU)Cf3COxH@(49J$OmlEW#M1MC9xb0@YLD!yz z!==|W%Iul893rd+Q@;Tu?-*goKF?7CZ%m{YNu^K@58NlD>BAc?V9R~}Ju=+lb^h87 zGKPY5bZ}6r-D=%Cq+eg?S!HIKxv~wO2ITLF{+5S$o=zqws~sqZp@^5VD2G7k5$!nR z|8Kvg?>+j3T&nr{9nQaz&LK@9jE!;83&C>m(tmZC`x>YnLs>M(s190T z1Zu}-MMN+PTJz2G(NJeOFx60u#mhTA>aK44fRp3o)c}#%_p7XMCM0g3XsTOW5Yk%y zLKqc0EUKcf+5Zz8)&03bliv{tTNz>XQ{&7WR-#PPMnXMK zu%pwwZ(Y2+W{4<_58cV<^7)>3NHk*vFM%?GaTm5=xiPkqwU41P2R(i5?KwvNbA@k% z6TbqjW67+q4&T~$wj6DK{QA?rK?1n(3h8nh`6vr_9;J!?q>A>a)VJ1URhx`W4@D$3 zYoj*^XKOhn4vI9_WcmV%La*?30cY|=nE(QftC?jirsh1o6*eXnPPLuUnUkugTV+bo_8+}jnUBE>d zr-5{8UaQT7la_0ZXCa(;>`7h4Ay=lt+fC zdj8chR0RVy>t}S};!p!+Z#ul-6A^Il(W~QBg!;aJTe8Rt>1$LH-**KwL;Uv$h-t&8 zWM3ssTG*=YXRdeuMr{((P?f*jb>Qi35j|0QO54xhDwv_fdK-Y#?(6h@$t4oe<H2)&PWNG#)0kI7Pd%Q^!wA)VgFTCyP3${P z&W@Ap_zIizW}U@OS>;d0y6C?-yB~ZbQY_6gGwp6Xr0uQuE8SezR?292F5G_nJzk+V zm|30*r(9GzU*WK;El6GpAoa`qE9;T+{bggxlUd5I@dk4Ou_X^G(+U7R)R3k&5Qk@S_${< zZozu8%x>kpg6S=6xey0rezSN>D7vu~Pw+KL{*O*+uG6FLu5ee!Jl4uj?fdB6`Mr^% zzwo(N>*RVZg(e&Z-hP%BudWlDKj1wjlAR_!zggqUC25>Gd@WCLF&LqA)JG0cgXS?ieh?fW&j zYZT|8i|Z!g_6}ij{M>(^N!kInm^qWOPBz&j=gmLKJLj@u)1ArA49)5x)dX8uMwZl3 z9xs4DB(E%DmV4vqcJv-LM>H+m<9hjpm*Cw&LLgWxu!W_RVd&r{WTN4(c1Go{%hb52BSfZ$4^ z$%Bc6gao11HQco1@F1TY7nk;Ifyd;w3rFgkA3W}U&g-;eBClbcH0vWRuZM>R>&Lrf zvA4R^U!hhorNvx(z?i;%tQE^14-UxoS6vPX2^s$|?VM=&`Et5UAA=i&b&p~ zQMHhTr4DigglR;+&9trM2o}Y(D&HTfdbE zTMk-H`0S{uz+O?@1!ILX)?)pb@6ob^Pu$C(LzSZyZDT)q4!v4jH&U@_1l)rzZhDi6 zX9+hF!9r;lC{M6c+02Z{fmZlEn#WSMc$)&liF zvm?_*oYLJeVF;@sw&g}34OH4D(?{=1uSvFoU%CKZ(Ix$Tl10(AzryF4YyjGdFqQbT z|Ng{#yJPOo$KSoa+SaZ}J?|py8$S&V%~-|HgD<78`GbbHXF15$XS8ZIn4vxZ&GBg| zfr|$dE6EFAjI+y2SnT)Z{tOzohk-$wwFA!+d!cU4E7Pcs#gGwf-@d<$VM^j!JTz{f zgmxTnMdVG6jNp|_Mr~>c!;4bq7$m`DQN6yRH%lJ7J&_cOg7F;sTF~6X1=vU6RtL~| z(9<#0O&1h6;e51z+?EJ&0B!dG?oJR+d)AjWGwkJy5ve_zj5@m|#f96vh!>nb$@k%2 zWPu~>Wwv%Ks;Z}rAAW2zF^-!@Ef1O#aT(Am#xcv--|)dxE5L?aMlH-~P@V#oz>zZT zIXu$!!}vsF;{NNSB?6aYWKNuu7kKb(w#?5-7#Na|2HoLkH!U=MnRNXkFTxc!0@MTT zegU$xnz128i;okCrJ9`S#Q!ixne)=ctmIZES5<@{h=twQI4RL0bl=WW!E;rhO59z8 z`+0C6fbxw#rD52IY;_{cMb(csBqkcrG-%Ws`d;TKX__)jMV4ji$Gk68XO#EOD9f6U z_AmVb=|fI;&^NV^FC(YCr`jw5W9kU56HUdIwbVCDpn+eA2mUv-2}@44FR}#cx3*6) z9TA@&2s_O0sP|)V2^cfjKwVyx7XjLTzFmPFuo{o#vS)^4gKF5gWQ^q+`YeCL2B**f zA}>CBF{&l%cCNJ!y(5w!%hHB^^}t_GpqRxivnnx6``umRR6~YzX4j{Yn1X3jVSrIN zf_N9rD`Oc%eW2;d=R-X4b~@i^uMJu9@EI2EGil#lslOQR5Bq#NhKEp!Vi4IkLTlrH zjo*nUg40g=Bl*X?2>H4Q`)c)$0>X7~fBOBZ*3bLZj&qKHs?2T%@zt;-95dOV-`f;M zk`NAkj*pV5)eZdBUh08_|2CK~{Qm!;EomnRD~U_7t`}76>r~81FUTHj%B!&D2R_~| ze?(5Y{hD1}G9XD<9;)ai7ShaG9h8R;nTTl0_;i;2%d15sF0oAYE<<{<>cKn=O}OGy ztnJ|y;hKjuw9SV8c!SO8ha&6=dSEbEVU!5a72tzkWSar%J~rc$a*ZmCx4}JPiA5&C zC1>oUGuYMQiu$Ee>@ zK+RMii%TR6*7x6(g!}%1^e?vzcNg}tJy3ZFOeB7*pS_!s=W%rfz?$9AN%|n>g zqZDDcP&$28d*`MjM8b#`cLR0_8j9Z`vWrZh{;Tr5*+&?gh&QQ!Xo-iDbY!+wo!U+J z^KZWnKMz*jNObS^H@9JNj7o4lYf|Sk8gE=*%?MqEwr7>R;u-=M^CvPXq4fJajQIWA zAP@n}9ybbxIju$3_PXJhS(4Y{wavE2i#ODR0~{?^MHzebA_nfa>pl{$L^t?6wdlPS7vX-9 zQlWz!q9K+leY7>7t=t~qPqH-sK%i-Mtpm?bCQ2&EDbL*4=fu6{VyN(0&+I4kH_e1v zb-Q`C5C)iomL!@&@Xb3hInxJT;Sl-7XRmmtV`W|H>jzjIdUXRNl%fVrvkbBc;&ZwJ z9n;g+!E44;gW`H_CuuFX9zfi0Y-onds@l_o8s{sAv}43mqG`9$D{Nwij`T66UkNEB zY&1^h?WI~)W<ei&fkNEu=5u8^VdKt>T>JSQDCFLLp5Ny8a8VB!UW|dL6Q~L{U-vyc{d&4yL?hR! z=b>ls?|cu$MCEa{-*jfZ$eM9%zgI#2ip48{3jJkS$%*~~O^t}Q&P`QTS&YRYG zQs%_$$E~6|*Zsk#GVO!$$Idj?00l+@;SfMV97n6EKNNA=;xoan5Z3u&JW z1SqIyi~~4m1%$V~YcP1{1EuwGcnTx;5fS7;2mJ2s$R}utpBjiMf?&d^@B||b?k_&L8;s@1E7yj+k{}%}>*XASyh0`|Mgpy^Js22U?L1PT$iQg%UB6&3 z_sn3rrhUYb>Bj|{RU^${?ecj@fiE|t{YGU&q`>FWD{;*({Mw>oED`1`h3O& z&O}JH-xCof)3^hd{qODVVV2iCZ@8}`EpRCxr!gXQ4JgiuOq?vluXo0RhBL&NpmJ%^ zv#mb$4ca?h83E6ly=hLZHDn1P=R1<_9@G2(9fl(AugKaVS;+q#hL|H9TS&pEHmx^F z$5u2bi!hbldFP~pQ<3ZlA4V<#7ye;nH7P)4g>H&F`xEp&*ynp9F6dyUOgs9-P8T2Y zH@)Ab7JrvV0r3jC5@&WH<>V8@7h{C)g>S-NzNr-MYy7VQZhh72fu%Xp7Eg`RAsVy- z=)X`Z{gzGaZSGh`{wdmiA&e*m!q(@%am9%~Ht=+%Rytp#B8=NheRc~mRx%avt zf6Ll9c{TsD5{TmfS8-d%;|wJ_%qLyq#=^5oso&}c-w!%>_*xUe{Q1bXG<@)FzE&ng zlaWCN2o{G9MuA>~+W7j**u1!Tldh;5BGeI6)ETQ48rJRC29mFZ$U^wqGJaMpA$%>l zdt%*cIQzD-Lt%wPSi%vzC`nuQharL7R|-|zD09~lL&0F(g##HFOUI*ALx$cxPFGfD`ngRv{h4aB{R zSEhZgh(wO!-_W%k%O!?PXw(j;+9lVVe)MITx>Q?boqVu+DYy8bzL#u|xfn?-8k#oy zcJuz>6QtZ3y1zJA|80@f1UU}t#bw7*2_W-f>sYGMXg61lC1NcTMcIo1t2tG;)VouvwEb4$n`YSq|)Np1{dmu}JDZHc%KKGKM2+x6*9 z(>J8|1TX*k7JiTHX_UXOjS$AAR!7~nXRloR9R~*=WGA~J0X{=09J04na5_Mu>VY#E z{7|YR2TZ*DB0`N{*#@LGc*terLk3mLb(*$=ZyyG-&Iz5k(Bq0?k1pAW%rNiIT7J3x z)I9sS@V7gtdZ}I0)M7>VQ8~kcLubDp^0I4q2CMizcBuff^%gu&&*juNsb4F$4B0l< zGpePB3wtLx&&2+Bo*a_N?Yo>ct1m|Bjh^x)Ho4kGxYb5v$*=w+-K%pElCh>)U%8E< zzjEz4l?{S{>{po!8;;4sb14!31l<>jK(IJ7XwH6KK!BUf>KkEMRudcpOE9wk)0`E8 zBqg8=_HqxbS0wH#qk&8$BDXK#Hr~j4&oMIU!iejVV3eR##;o5}i#^zf3mBu=_HQWK ztl-t@QEZIR3CH$FE%-dd|LZzu8X340h)_T7o|Q4NJDP8tSWQ%iyU=i7c!n)mnSR7N zAuf-yMlDCHSA;r)Ui0MVKi;u{UxdVRKy~d+1_S=ge@1)^B6yi5atR#zf^!cl432@E zt*+MIWM@Gdj{FWhf#SOZt=y8_K=4wdf_%o?!VGIhll5P`t83cm1LA~f^49Z z^U�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%0AG_d{n#X0xk0Pwi-%LKLF*6$%4Vnd& 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 z zeJY{L;|3ZqeTPvbuGF8#9i>(kEGs(_6cs!h5pIE6QoQOJI9-_W6^?+%E#CMN03F>&aSdAZQ~c~@HImKsue)jG@9nLYXhZ2ht}-L&2- z@mVhiy7U`E#nR8a^6o5k?^G{@?-#T#~w`H z;x^u;(qDIP%v0^HZfh@igh?M$WwcLWF0wX2U%bmv7Z0m*jwy+CnUSQ1yx5L0WXsiR{xu31XLrX$#-9q?x+E#oor*$SYrxx zd2>z&Miq*((78lh-357p1h!4k#2R|u#s3RQ}KJL33o ze96v@A`#i?P(_|LC{?eYyzeLUX(LtQR&nfU&8RQ<7Rk~OHIq9}7!Dnci4fdkEtzXrU|>jF;r&{lUA?;Vxk}3EWm#{L zGtrw`qv!019dkjD;O0a4_!jkX(ooVmJL1U~x25-&YB+Ub!HJE1&TwKO#%9K$YL3TnU=v zcmwkXAK5{m=Pk!OUAuQ9SHc6)Wd2`r!!EN0phW?&bp8O&*^*G5Ezu!MNW}%UYP}l3 z_D+ie)A4yhv*+380fThY0 z-zWF=#l2Jl<8Ct>Rl27Au1!N5LG=}VM)Pq6S4@wgNP}fm`c(b*A{)ukH6AAG)Fv3z z+|B14Eo;cXZ7I^^k!vEglsu4_g(W2hdy$t zF)5B=d{vo{H^4RWrvvy>a29x-6BW+v*Ey#`bEfj$*e^4+t~;b;#b$f#A-(%i z;GJXcM;wqqG|Ot<_;M$JQRXgc83n!eUOIOXDbm{MCk)*97@KIe&3`Xc03}v;sviG2 z!lw&Hq0=l6f(lmU44AdPSc(x4Aq24{+G^YMgL!19SN-=Q;eieqyl-Cv2%_b_ z=$4g(#=Ry$DbX*En-2-Rl2fxA*%*(<>#KYb!l9JOemB>oH`C^FCyJxex`%F5 zEeG>6JZtC;C+zWXOF1Vo*XRnj4at4eW5Tvag_Qtsb4R13|Khy&Oc}ke1v@ri2ol}F zBRL$oq-HdS|GbReU0=9yn(goN3+w!^)6vJCGK}^$I;l;%9v4!kCY& z@FhN*;4%ux=?F=BHB^G< zZvR+3YITl&4))486R^$jn^ z&TuFvF$oYt%n6FKU~w>L3Q)$|(cW4UT-Hl)$StCpd@vfj=K^8ZsA97@Y~a{N567+y zqRhZY<|iFBzC;Cupzhs|!hWZ}Jw@t0o5kxP$P#Dq*Ky0N#>Q#@6Iyj3UO~`o{wC{( z$aOZVC#XcrhLy!jt|PCN{nUr13y13c%nz%$&I0@a5Rzd#bFyNJQ~mRWDnMSsjYp$j zq%udMX%*QndnzOr(qG^M1`FVrnM)0WqPkD(x4=dnhmJuFs#c2=VamuVN~@ z#k2tY%VrK*#~Uv@cx*zp3HnNE*S^*+`D5uk^Dr;-5O1J&d+L}^b-oIn`>PzXfxCNH z_fnUC9(gkN^9EPS;Tm!AuZ5K79!7rt8tp}$gX^+@wCRA7qb32@;z`ivc=7bCS(7jP z->~Chg@9t{=UAL=%bzug#T{Vl;k7AXXvzl4Ek%LuLYyUtD@Z!yE$OuH`z+2)10q;i z)-i~Ip;?ssSm5qy{`3=Ckw)JUIP-A$L!-VN21S^Ckk-L!Bv(yeCM8 zI-phsxV%~&hk4}fsfwlcUF3{ks)IN{(khgfT@J*se`FH!ptIl6f8~MdYSvm?TBtmM zz*H`Hm?`lelGNy~2A&n&AF&Vk9m$3B1a(pw;Qf3?WKykkp97tyoKOYJq= zHK=Qnm9zA$Gb~h(fb0m*#o-DX4t*+bUu&1+y&^IaP~3PJ1xg2m=3;Gj^Uz%dX_ZX+ zhU$k$wd4M^S;Rj-2n}%ius?gcCl38`gG1@&O+qEKhi}vyUutni1f1clpggjf-mtd5 zbN1ED&l)y|8dyny%L|_mLy%vCg}zQNv_NOZiC6X_D7=kSVg>pm{jJM)QZD3c_Xix) zjRB5;hshkZSS``M1l&C=*jsbC8(*hqsx4|+th5F?>A3i{P=!i{94ASi^L!=AZdfcn z9+s-tjX&0#(X4n{W_puvu_;aRNSrz80BrjcC%8q|q9YoG_H7kaDGAXrUWy|69gJSp+{tQwxo8lKna zj6{#7=k2U^&v%~*Xe-QS3@wL9c(tot}H4^-w1cE0aA$QQsZCF zew|rd%*`g!G}GNL-p*`@UV-J=rJ6pDH~VIxL7^%>V_g&K|3P4u;#v0??=Bg~ZqF%Kd~-a& zo~6{6L8RS#jCDufq%{}AhPEAGfL2+d_!|Oyi#u6=fyaZ6~zSRK> z6kIFINh_CU=z57&?KRdM=x2iL6|>*9kMP3)3@T20T5oCtuE+F7Zqv*qQG~ifH0SKe z&7<#^sx=9ba#IdW#gsw9PUpB-o|%(&0>oYTDMCMZ>Dd(JUb5aR*Bq`EqfUGj3ob%l ziPwzZcm=_yz%FO;^yl5@9JuWwv`r58v>Vo(KjeD!UA0fCFke61EWF_wcBj29t}1omUJbH)Y$R10$Lyl^?8LYJ zK6M3u&VwZr1)Mj^5^7(U3s?4rGa@)^66`L6K!v8FpR+SYKDPHgLSHV|P!qqt(xKmP z&C+HJrx8;vd%|pbi0FtF6f?MRXpoWwZCYfz<8kHgXB-9NB6#|t~~r3Iz`QPTCfMq>XtMS*YFr! z0Vvb-GxFw7w?iJ73x_CS0mQ!rJai~|w9paP*BR$J@xDJ*w>R;evuqnAx> z1;`kx3{vL2%QhaY_ahdsHWAZozi!pwG z_apCLJAwaDWws0B05O$t%uInMgWptYScL`GB`;(PQ3_>IrvYV%!aHQkOzNHh3h^X9 z>z;|;%yk~NT8GIeHwnoTNZGU|dIz(lc=Y}KbL4if%!H1W;xz=prksGvG~AQ|(-?rM zA!S=kPI^ZMBxegavg#HkFe)c>mHBN?@cNX%?0U1LTAH@o-r-d`P798fVa?*bA~JvV z#z9z{#Y6fsA`Tp&viPw%F+l`n2>Wy?@MBMdQdG8HZ?tg>Am z{^6I$1t7FgoymPXj#*+pb}dwFQFubfmB6{Bn8C{pzm-Nientxw0s@%j zhr__#)MGFU(Zfq(2YS|IKV5j?r`<0f}J2(G>8*A-RRf_$^i}VDt(5QUA01W~yFWyY0s*hQWDS1fp zxCFz!`b3v^l`ZQAcuUs+pVcUUWD2Ag=6WXqK(LU9RV(Se6!D+S?O%PCCe8lcvo?AKZ;)wm&o#$ zzj6@?H?)0MT0w{V#Aj)-jmy;(&9d%Q`Ejyeg1#`Ko|BQ77&xe|4=(`cR8SZ55O61U z1OCO?DFhtZ1pS|$1SZ_akojB5WAJu^3eS-o&|d%B>rfGGX2WLxx^~3-hhb&oMf%BU zLe4$4^MM?9sRW)jeu#NU4+J_1lI#SZ?)O&$86Tj-N6(foFED%4<*&3#Q|G1fAjcQS zd`>gML7ZZSF+n(nwR)&2oDI+OlU=Q{5_7)$mrzl^fyY%`M?tQ8V{C=y^JtIHZXOv- z$mXjyyh?{jzAC3!ns*_8sS$#)jsOi%h1qL-xf%nisUtT(lH1^lBst*7{hrktJeUd| z*(b9*>NQ^oEU(KF7{O!S=>c42dF;O0)+d|Q!nx$kcuaP5X^~^|oq=(c9#{NxF(5m)5Qrf(ytG5l@j1_l7i!g2-l3J8;S>X|OlUl) zoabP(?N4U|(&+hm=eLGsFULF)#m4%9=evqkA0huxK4QO-)&StJy97)Kd_n-@{1N=* z_vRCVontDDzT^wA_ zR*ZetTOfNTi3JCEs17sn1W!V?>-41HzZN>T@q^4E7vpm!e#bii5qBSWNi1gstw3J7 zG7t&Q6mWKBhKG%j70E5Eh&3;5k&{Fqxt%7;+my=eMsg}9x&gK0%E(HuCk~e$-J$2Z zom#7K66li-2u$MLQ$GM@jJE=#u4!>kY3Mz0h-W-SlSN=76En1 z?y!m+y%>6}oWKSRnxM3QkWuaKSSIR>vi0&GAN@JpaxB0fXOF(FDE*7QAjSbcmc160 z_8v=L5WiYd(0t$8PskEwur-m6CE6oC)-ig{e2b10QT^vu--dlt6J6f`2aq%_$?wBM zcuW#-v%tS$%>dI90XgSuFBD+Z`aj86VDh!eyo&!*)%O(_TQ*xfoVX3VDk5Bq6d})( zQvb7q!cZfV7ytZ${_}U5ll@O!{9$H=jryNYQEKG^9^+K;=9Mtk0CZ2IPUVj`e;q~# z)ZQE);xg#2!LZ%_jU!VTHhTmSs80Xw`Vc6irY%MJe;-hU*|{rUh%9)&c%h5fZ9HiiSA zIzQ?!m<58w{cZM=_a^qcu#fzu{MicDQ5N|xXgDKrH?HTs6520Z4~3l40~(J| z)6=5}-2asa0o-Xf@j_Jpa;K4Ccb@Q9FByPg6DMAuYiej(MVdq4`Ar^xkh?aT6Z2OR zKn6AATUY(B>49Yk&c2;5wh(_cP7jMvLw0 ztl?TYi8&j5D&MUNzrGyI){D=S^m)>W=&z+pgv;rIK8eF62LHot065}y=Ds~yJ1+4< zoEt!EdpL&S9K1EN&5}UXynxy}*kxe31?-T+=raMeUSV0BIV?d?8^wwNzLozENsYcU zVD9jp4y%;<^9P)h2G+Z9)MC&D=7-(j4A&o12^ddj?06oZ$mb(MLkuv#%U}*Edrb~m zyaqH9-_~FltZeNpOEuQrClX`4c9)Q@BXg?$xt4V=3me}Gfo3ut)0LJ`NR#9K7ciq+ zT*Q$$)+^W;+B!K4))g@2Suut@F3T{woHYg%aWF=Jo?Y-wZ}klH#jvLUTGWOqOfl`m z=zZS%d2IZU^)JIoJ! zPA`=|radroh^=t$b0O4H1-hM#(*zy2fx!y@-xd!UxdrN65@t8G8GOx8zs6dtyg|Mx^8h*M| zthcfs@9CpwQq>ly!cq=v&%v|2PW(fUA^A=CxO@8x*Q-_Cx`36BGtK^LNQuNp=(|bP zbp(nGd@|0Psb6T*s?8jRU+o0~wlno1p+G&XGN}@4u|o9-pzkjp82hoL(*@n8`~7Qx zYf{9oAbqC#1Ct9I)Sm+9-@bJ$-cLK1u>^p-R#={B zH0vs%gsE7xBz&TK%l2Mxw4p5O9b%hzA~QNHy!@M@qMTUvCNFT&J9{z_IyMrowr7+j zrXLd8)6Uf#yNHNIvFBE2jPYNGowPT0d#BOy$ih296Xi>| z)&9BQ7>S#(?bX~8MTQZrQ3W}40swwexsh8EdIaNkWEu6e%#Nl&-@)MV;0GAAN9%s ztix&;WV;* zzQse8X0FMxCY)L*lTkHoGQ96%T4;G8Bkid2eYZBa(vr`Q=0P+@DP1%hG~7_`oNXfJ zp|NN;TU{5aTrb|ioRTm(*`UJ0XC{hatG#dp++(G3ych@iyh1w#CDt<}}^`$pTC{nS5CGl;M$Z(`315~VqH^(>Lo*q@Tc}-PYs0lk|!F`3IN-3|(_hufEpEYl4P+^sUaz6EhK@RhO!yU;->n z+8LIFXWkn_f_46{8B$pKTZ4jwk;K6D3;UnERAw?;&)sDgDiVOW)*qL zAeK~{oy*pB?_aB)aammriLc!2+;O$<&5Dlf7r>q7WGZ^N%jTS@p983Ownd5K^E`@~ zYq>M4lYLU(O6z{sbMvVf6wYTq=~(MK-s%C6p!6imyop|CB~)f0+qX--dd_bFrzPj7 z7t^lxTLkx$&GYiQpo;9(J52JMwQiHjxS*uy3+~}{$F{8|dUKJa19sT>h5N@G-EdCM zUM#75P}9=KJzAWj_sxl_&gH0J+gwtfdwcpNW6gn&iZVh=mr1|l>^cnuE2=};F43}> z;Q&Vxq{=*^6GbWR_qg45kDVPUG%(3AGsX(F zryWfw04!Vei1VQxZfhEano`6^5k}R4?^;@e+DZCj=QjYLfE zab|G}4NyNL@sD^R!X(>Psa4YvYSR+3)yxenmEX0IT-tcur?XotiPx(xN~_3CM)Z3I z$G|83llgGR@Y0S;NnR%fTe)Z z@YYoy38N}K+4K>wYj(>GDdRVQ)=Y$gn|h90UwtQ8j=er#_d2h7?gy>UHrncGH^2F> z;vK&5br{XMn0okf<*8A4!VF-v0d*^wVu|{M;ipp`ZySO%Fp9OCPUtv~12dzXxhG2%3HXe}(qf)9?w6no-^<5h20z^P8DIgcK6S4WeNE3A-4mjhLZ002` z%f*MmKPrB;#eScP0knf&94Cu1F@_Rb7>tuIc*n5mxNInt?<^IMz9fKIHCY}F&t~%5 zcx0mq7#nvbuwIx-$c9`~)`_}vYtU~A{r#q_{u^w1#yDp=22{k z($9Aj`QYE?c3@*EUk`s3tZDK)p8CJ)V*u)Juvu4Rr@V`A|Fr0=JgY?4>C@{%MhX8u)YebM6z5gz);*~PRLNJg^EMM zl>la1!(B58ZmJrA*}M(KVVh1l7mMO&yqO3v;v;ROosD-Z4pu-T@yj|NecutH$yLh{hSBclN)vDn|5jD4=A`e|Eeh%L1XTB`o-_=U zgh}x#ik?czK7pY0=&07yasY2%Ue2?|F%*{#8c7{V8R+`iiQszr9DL~XZbo?o5eWG6 zSlpx>84V-#Cwt)-rfEWCDnp1XYJ2~VO|dy#*+Nuk*{uP zo^J0zmOt(+Ee7@P!OXH?F_Sxb?jLT8*UL+804nqrM*A&ktVrcPsYLkFH}#T}FKKaW zDuo(E6;vBY{pg(}AY6g>t8>%bOGCs|?uC!VsMZf6!XvJf&lZlVZcdYAnW~IKa#&lH z_lxQeW04ha)3eNB)Lo~?0kB@{#9*(!b6r4Iz{=x)-oS|1#kUV?m&&ug4j7DJ;>gRY z&rambhc?Il-8oI3BYrO1-&}rJWd)&@4~}$K=a$RNURt04FG(tRZnkD8spU; zhLxqCQC0tI_xF$^0v>dK(f6+tEo>FrNbX<%sL)RoZs2$PlT74fO(&j}V0dRU{35T@ zhh4~>#2}9OQ?`ktDpkNRbFj`hAe*)Sy2ctnb|~RO3fA1%E`uxs)*|*{lvbQ`;^cs4 zNk?#eDmQR*f{1Q?7MkZROVd-wJ1tdJFg z?;of9(_r-8-}8Bhno=SW`n2ah*_lT06U39d_whf)N@>PAL@*BPh!6m2h&nHQ3_7@r z6YO?_bOQX|KI0%B6jXiqQnEBeDWtuEpPZc|)^nI9491#k=BHQ$7PT^<$e|s4#Q)z} z0O>pF7ik3XwadAKER+?9!-o$eL(HoaM4J?pcGk>YO&td@kLUA2-*uye#aafz(0tb$ zj{8JMTjTU0nR7KGVO2*8qCt{sklMVl%Qv4$i$;4~5>r0Bto;q7%IA7p$A8|21#?e` z+kJj~2Cf%a7y7~2UXQ2?IQ^K%g&eMErZ-*1M5S0}+{~)g;GIx>6euz4c*gV-yps=8 z{t?K}6v{kU&w;h-bU!mCUn~Us?5)SW2&@X0hB{qF&cj!X@IY{mz;$*M^G;k2J6%H( z5Nps~M2{{uXy~`BUpa49jXE%DR^>tVAEvhO0JfA^{TAcTBlbR!t%_?TuQ^pC%ksN3 z!nN`|if;J$^ezWgs&-rga<^}e+3>b?@>AVFYNvdNQSS|mcz*a)m88F>*_mtQvd^V8 zWE}8g<$m`x2I7({1Q3C^@NITQ#!tVL$EfFh9r4+2zTm@Obg2{@pUT* z5~@0ChmB+DL~svXt$|WaS)V`UBE^JAR8>^8L4sCC?M8I4(e(8;t z*v~d2<<`AS)7G6cElQ;rO@6Il!IaZ$RenHqIUIqNIzKaU;QX_#y@SmkPrr568rWjq z{9$yb&iL<@S%Y1f(_bPz?*c1xYohy^tdtu054cFpVW)-IjnH2HuQ#qPa^eg$Ic znq4KK&X6qj&WS$FZBRzjXMt0faP8+nYFb6<1#V?}YTy}Q6PoDbjuem|f~xJZJKs*! zdsM26?}}`Xw*GkVh{MxCRi-J=E*Egd9kIyC-VSAT>_jIBuy1_G5v~ydMCU*`Ii=-L zaVz5v3sMqmTQz5gDO=cQq%aPXvYQ!MPam}H9hb-SJ4E!=t-xuMQxkN-O@QW&a#EmH z+U%XqCfmkX5iL|5un+^(_MXsse4M?@w*O6!X7Qk1iZK(QCja9ed zP68lp+o&jm781L*#;5QlOv;5H&vtDt54a(Ot~ zkgDV}Fjaag{u^>Ma6>ZU>%|fgV~#9c(9m;qlaP$B=JmD+)`HuMgkLStWI7shI&u-D z_uGRB2-tO{eG|!VH{srnl~z($`W2AbHoI*G;-(kbiJm`~DzD5c*>0!sdz-y=XAoqj{O!8GL&R(ea6~vLcXe6-K|G0w0 zOTMpG|I+_TQ#q>T^(5Kv>rGQS(rx#yko6~37;^jC~R8%DWUqlUnN)l!E z2p?;oeJI}DyO>@|+|V0oxIM&DQ>tV6;oLjSdYGWd=~UmWIU9Zmbt79@UJEoYsTOTH zU+f^_tm>4f)=752oUk5l8xzlF5W_;?Vud!=*#i zZ+w3>MRyJ7A73=8t&JIGwamHx+9t1P~B$>C6lN89us zZpBfi`lSxczqXwNHmtTH*9;whG}O9*Bss0-jrUE~w1Ypfkl^#9AloGzs(&%9>h^Q! z3^t$VdN{4o5?=fwU`ov_hYMw}Bq(H2dfR}XwvqXFMBfZ#&v$Q++d@3UY+e-o;LNrM zY~OOoaQ^5_#t`;JNZA-#ZIq!M$`yG#Vt2R`)IQzW+>q1<7FqQ@k}sLvn-zX^>E|Au zpW^FG1|)efvAYZ-UaFR$#BAtwohD}y#Kkq*4T!ifglwSrix81;zJ^NAsk8)dK!@&M zvoTGi8(hV>W24U}T({qKCa)78FBB!OWu}63QYgLEXyH&}n02ZlvAK6H$5E$$D^i*b zJhfZs!am6_CNhrbj^|F-wXl1a8Ke15EOg?<9NZ(lLRHJUWk)~52@=4p`+8(}A{YA7 z+BEgh4>4ATQhNS+so{e$eu7a;jcR!0m+pYx;)IcFYVT`w_nsh>jZkRkId$1JT7IUO zDbcI4`Mkn};ReaGe!W`VY1(vGs=7tIM?VMa%!f(zE^bcJRqj7m6WbBrh5*+d zG^{n#RMaShHWVTo_DcquqUACD=acb!t;yg5hbBEe%N%;1`Qdq~$)JJl*@6M&L9=av z_o=<$AXm#APb+jkS~zYPsfyh9p`nCyw;^~(lFa9a*N9MGsayO(6zVje zRq|uB6nxolCb6mpw$b~ZHAoC3xxF(0gK#mKYS%1E^I=bSh;V1pTHjv3aX|Hnp9OQp z^_9qdiJ;v`$V~hN^`G<05+88t!u{P+m;h5zl3Y2_Kj$YfQE3!_$Axkg5Y9)lgu#zh z4HOolrj0cb9aBYzx;S})bPFb=0RdOfKt)b5*V7*fn{HK3^=$PGQa2_&-$HHKj`Q60 ziK}tQU2Lj_snvT; z>c#68j+5*M6O9)}Zq1JJB@)fnb;`Z{8##pLO~y^pO`7v84)@3^jxa3KZuM_U`U8!l z!~!q1a?OrTf7u$(<_UtXnMo~~Ug)BX))u{Ja`-%qwW=_s5HTaF_}QZ^OmP*b$-DE& zy7FL7@TY1I8Xm*&Dg+hf9=?eud28So&n@mmg*)?JT1`sB zGk*GwcPgO9Q3wh8$8LuG=9d5tF_`f7VRKj*jwrtx;a_uUM-`Y$ey}XD{!1HDFjJlL zKrFd^3ZqEXML91LZdI39vu(;LWZ}3RLAw#7d1Jg#RN{hdGM>{~+Gvp}b!;oO%OHI8 zIr?(lD}VsW;kdz49~}X>s1Tf=FU?E)cR8h^w$hUI)>@Keh9_2lyU7;v(%8}d)TtK;Wi;_Ju~QKrbgr@38m z8)`LQ071rv&8Y5B%7hS5)c6sAbS^zLw0+a#%`YOz^_K+u9?P#0p}&fWP)_O%XO6yV z$r_KTc%}x%1bX|~yCa_#jh40`tfp4wOD>L+LDg<;q=7%rQUraB{^-Nl3F@Mdyl0gBVa3f7LE$HR2v!I^NG9?t(Awu zB0q!}QvAh2)b|2oU+ zDLahr-)d>hW>nEGOn)&My>sQ?;ZfQbMGR(=_u5%Pn)#VE50|>n=c}M1q8ljsKd&r( zDD-piKaL;U*w{V0FoRX+X03~|KS4yei)`2O>$LN-+wA?^-Mp_{lFOGkfNlXP()6=O=1< zWz!)fwEKsfK%=T?G)h#gb7*s=$Ifm-$!xviGdW?y%F2CrO6JwN9h66;a2bgSI_1Q8 z=qYCLy}^*ruiN?kXI!4m>c=O`wwY^{2kC7bjRy6O?{f}|B~wz5qVp$>PtR8d6dC-t zZHl`;+xz5{u{$*$MpSVIe)Sy7e}@DT_P1qLP>f z+%A?n2T%4j!+lmMSe$Xp>&NzO{A!KgU(iv@tp1%+b9`*17$)@ba{ImwH>%dAXTtPO z`5|!)`h440Q4i1Y5YuiO68Qsb{2*T>kJSb#ZcXM5XkLCM3+>Lau_cBsejR(8sJzh+ zweu%3(u{Je5B?S3qqOv)#WCpJeOyYm z0_J-8T-Ty>942^nlYzm9)IuwR76?(7IYFKhAx~12#=2R`j|?VUWpUBT_iX%I@^D)B z=Aqj4O3U)~N*KqoZMpE{!HeX=!W8m3DR{X9&(t16;OVW(wY34-zZ4qmV=1SOswN)} zJlsw97(%xe7m7XF>HH=BLR4OKIyDI`YJI-yB-GsN*y~p6i#R!36z@ZBwfFlKSN3hg z*3+J805!ZI=$n+Tx-Xjy|iLiJshDlq{@IPW%yN#HYA_ znwUQ|@Mv6cp+fETi6F*k4RgYv_?RYnytx>967}#I%UrRYP7>GzMi!JhD2GKp-1|mTux2(F;>O|UJ97OR@ zMRpa{-NF1h&!=lgXanPRb54Du#<FM^e?2SgW{33HFh6CXQZm!p2w*78{;QL&Mc(%@Kr_PwuQ66m`|{Y+!D)SoS`H!l(6t5Xu-p!mhdw&yum1Hu;?dr>~Sx3 z0YfEDuI=YOS(gn1A#P)Mvi0dlx7F{MRI+IH9nx~y zg5i}5N8-;paq6r$c!n3p^gz|P_Nad$mB=HF;mg@CXA8zRZtk`jQ?>}((rC3qAMt;8>!=Lpn;$|YxV9o0Vgted%CA!+fKL_Mke>OH_8@o#%N;fHWTKj>GZ_C*2V+lRq zY{p#wucBF5|HlV+)_FEh(o>RA<5T5fxvuccnH>#QmhwU|J+Vg=zjoPS!)+rM)-RtG zc%7T##EL(HoohikYj2o}iwZ`Xb#If_+m&GmVnY~OUktvVA8CL}{Cafvwg;yQ{7c;9 z7}%hHqWI6`vn?qGUs|xwXn2@)RqRdb+o~VfDjO6SC2*pzt2vP;c($=P5>%62wOgUjQsK!SPl5)z`9&i{aLe_-&`OYqNa6fx4Wt~%oQ&C`O5V18QWxh2q zLbtPZbRu`BG2&yWXpPos66>cp-?AH2KDZg6NLiZ>RUM|v_x#kjGcODgINP4O;LZ&8pB^)(#6J^|9<^c2EbI* z*+~Cq1;7M~^|?H9sup)^s3MIS-w&4FHA#1xW%qVj?JS*kY<$pIgXw5}==^fn3$l}r zE^lvNLNAZFXw5Q=tCVji^~dIZ=Hj@-zajeEZo2-}HBQ>c^3%OVbURvG{o<@Dy^hJ! zYEIf;Wd%H&O1rEYPk)wh;D)P9Ab$j`LG~?1`aX}mT*EXm4Bm<~I6s>c)W5~=Lh1TE zYHjx$H-^2Fu;?g;ynf%$=((oL%nxeyQdxb*w$n#r5ZR&4`|E-01%Te({7S$m%jLDt zB`X)4dqY7u>brTIBCW=bae9-%(EM<*piO1ipiOX-!V1#iLaJ%%9LfEG~0GB_e9YGLO1P~ za$J>J;KbmW*>q&q%MY4Ga&A69A6@;@V$MPLxUjbfqpdw974aziE$CMiU<+ay3Pw+1%ezLjV zeQLWNWOzSYR2awluVKcE&mzwO(Li40u)rj z)*H~c@@y9@OCOzQ?@r4i$M<)IR9Ouggzyt z$h2Az{2y0A){XKzn64V&I&}*n(GUag=GEa%l@n$nACdQD={~60hWFex>d?qEDM=R+Y*<(lYH|P z2i>=;W$LV~IjYb1K4sN&_4*VMzdXNtdOc;bQKQ~R7gK+FNr11Eec$8IbN|Ni%ISFY z19n)rDubZXfV15)sl3Tt!5;PG9)(T9E>Q}qUeOgEOp$v-)8gBgRd1#7Xd%R9QF4cnL5kg*dhFKNUu1?OHJCI_H zUh0!Lq@sIDn4NBV?ugafcP3@Wsp%iQKdc$2?*%=t{xun}BHzNK-x>29b%Vn!_zA~c zYGATlJHae(8}&#}m!s8cq5|x=YfwN3k?I<>K4oQW(_6XhxMsqZGF4{4c$g|)D#iHW zLkR~n^qy0x#`Dj5hx@t}HS#u`zxYz(SLF8HNW@QoEtwgL*17#|MHwx|W|viW)@qv6*LU92)|24|-( z#LOPDRt^fXavx3lc~nIofs$4Qmb^$cVJsp)447QmhXHOd(^-J8m5CI?V?9~a^Byp! zif0q2OLD|%HBrp=el&}O`tH6msc~63F85jTPUXd*u`F=yqT$v_#o@YAKV_h z{BSc(ye?_!rfm<8BUJISfz3u|1x+*bd;}*P_D-!Dr<$Vr@!12lWecV}(|)-*poo3y(<(7M!AK^YI+*EwDOe>m>`+j3B{B`{8gn#Luxo!G* zYx{Uh$u;e=oh^o3<|x!9pVfy?rX-&nzn@}U{i?9(DXYXq!K&qRQSvOM1NOZ!Zjq`Y zb1Ktk&VrLAcXkEmVM$=Sr-Ai4S`DGJNZ9PqM$TxTQcApU28p85n7=r*;kXlHBa z2&6F^okIp)tmLe;os=EU*T{^BxJ5m1w7b085=1gosPm{EedGKBRyeO->uPg@fB-qJ zlqROIY+{_J(p)%FVD=r#=w4WU_1d*Hlf`6QTwL{H10>`8o=H!RW`mXWa7B@`6;~<>ct(A?rZ%K^=~<^LE;-fdnP)eG-ii1Q-{#PL zMrsOn{YVM65hI6Ue;F&61rhf<^mMUb>J>89;iBiz+QWw|!hZ zUrJlDwH6Bz-r!6sfH5YA%*`L#C%%e~f--uKsIK*FzN4#dqX|)Vida@M6+O}uz<9Xq zuN|2jtMioVHS2JtF@fd0-#M=2&p1pEUBSjK;}9tQ2VMaNHA)P3?BH)`|P`Iev65XC>0%r@2)gG zTRWYrB5or}P}DnVWb0MrnIsoQhiHmg;oGK8wSHAH=`4u2BA4qvF@=k?DErQj?~RDo z#oZsJjVf&p`<`D(n^;$WWA(7)+*u^$qXO~}uXF(Z^iEQ4xLkw0E`gz^ z)5q?MW4y7Pn^ODiqi1$2lg#rhLOmFlhOuM<{d+U2S17f(o@NJ|yWj7RQ?)z{5{OHr zXS)116>)^^nAj-pHd?l#1f7=paAuq;JA5VQY^f}d_W?znQ-1y~CGan|b?tSsl(h*(OD=G!f zhEegJ|3%62=X$$0!vbp6u&Ac0bw>NlR@8cmc$k~-r6ML|jkwCh8+H&wZ#<@~-rJAu93Oc1D)J?8S~QbA8>BIb!L*jDNuE#%02 zL}a??#DDzg9WTbD-7>Ly?SZ~=!rqH$->KCXlBZ=p-|T-h)$g5R=C6v8`B>tkZ#$uv zr(-GPYLjJBq~M>k%5Q>Qn+^>d3uq=sYNEOwihGXZ&Q1=?yTy3@{e*A*I_X~;YEX>r zYcyT9^f;>ZoitjDr~exkEF@fLL5XB`oqhEtA{rz7vXUa|$sc-0I94`}OQ9={lb+j0 zKRK%@Set!d181vI$@};~L&}@aoyU8-l|sGR(F|jE*K2cp}73b7h zP335eKHOb`@e@IX-BvSHUs?3TKZQdOs_5c|14>T4stDUf?O9f}oVf3v)6nU}A8Wb9(>MGhuhd$2`@}uswYq+!1`XQJRmQai@7%O0bZKC z4q7IBJ4A1sG1CE-*UlYW9VAOMZ`U2oD`LFIVS2Ma+4KTq8~fkOUcrot5E#Q1I9@r^ zgIAk;Rq{aNucG9Q7yXQN$w7+SRR6MVAvE-{jWL?c=lvu&ya?v8zeY+PyPqTmCdAU` zlPTGE3Jz|R$@|#Me!!=SUZA9;%rD6VCwumdIW6y9fviRhjpKVwwS`iu*xP>*(|k8p zRV5H(TEG_^&F=K72e;zQn>Ub0k}qE5JCB1~uiA8Ubd;NQkz4g=T)leb$_o15k@$%s zaJZ%C*H4cmFBseSM7Fr^$bu&Z9kT*%j1i<%3MK7_Dy=ywH}=R03NZ=!mFv$yJi^-( z5)j0C$7>!eLsM5%_4t;(@1^=PywgZwo$^Mg%{tfl;e+ILBNDV`VQ_+y0~w5ps>%Rsu^ba**cW{etx;2Rk03ZU-vk?3dAhP1@nadHEzR<6g=j^m>)N5Ivb_eH5MSo zp-N94Ql6Y%WSa{xRIb-ay*k1Cw`*6if&YI|4NpA9bw9sb-&b)uQ(v%(x1iK0qAa@` zoLu`!m!1#LT@+KVm%pXKu0Ld@C+l%-|Ja&3B~YexjXm$078&$Wv0k?AR`F-NpjCot zOzk0GmRNT)IxIjNN`Wsl@eX9V$2u(XB!6*V_Y6UQw_7V&hk2ZWC=&6O^6&r0-`VkR z(k$i@pld7qF3#_{;_4|X9Oq)5M3GtCh|i@h4n zr~k*=8#KXZGG5C587H}(f;-A_TxPm>>E6qLCstPZQ}fHqxg(;8DB2)IH4*f^Np4N{ zs#+{G)C_&*#B02yX`=Q9sV`Gl-^7ZDS}TZ|WS)C96St0-w63IH|4@=Qp+{@t&b8{N zT`>Q&RRQ~X48CtJ|J_wD3h^szMI|%gmGCo50Pyq=LvZ2ZV`c!Px+(fXa|lb2q2zdK zSO2(dkM#@1*3ghQz~7!!T(Nzp&CXgt^}>bOZpvy=&x_5)*EhQ&X&xCOImBl4R6ReB zn_4XC$@1Kwqez>;4Cu<;6SuoTi2GT!)r(b-^HYz3Y_=N3r`0u$c{1w}yb|$RlONPM zJ-*s(4G7nG7<^<@gVg2z*pNBYLjJtXS$E#iBM$Dg_@WS>fJK5a0d^9(FW7#_1a)FP zD)k9nhrN4P_OtK8&h|kD$wL`Z>NtrFvSrw>QJ(=z6m^);x)vCuyXCngpb@F0`o6*8YbI@UpQy|lVJM0-5L>N@_Kb|^%XkWc2D@CA1+`pA?%5mO9M1o$HJ|xCuu+fQeEGE2eOUSQZd(c6>RI`$0Otf{ z40_i_5W#H`B;Xm4-%s`@MvWw;R?!4C^hHYTN}3@k_P8&f#|CDUHdDj z&#Yo22zk`G@@cUiVp~`C7L-qD)c;>WJpdcj)A82*D?w1dN^w=~&&+O*3lgio@tp^_ zz;A@FIAY$ErZi7f9D!C;*Yrw;stTWd5@Bm!pJft4e^Aq>P5iSyna5g1B2xmA_xl&8 z4KKR-?Pf)k(@s?SuwHklHv0%IDqBdjKl_8iYTs+~>VrWJk<>s$3P1aDseB<&9Efy% z=HAQCOat3fJg@OQq4b{C%=T>N+3SC%uwNv~Jil^kc-U8$JHBe8+M!rTmf)z~_<}(O z9!4tjKE{Q(A6d#5W})~3l*Di*;`_oV^A2uKY(YScPE zL|fG675fd`9X`bPc!#OwKBrjj_1>`)Uf9z_eroGcBG%*GMmjW8we9H)KS}c@ZDH1}SifAJPsYirP>!%* zL=@feq6w#bRPDA%?EY&-E*c>l612sA{@Q^eO;(TPh7UQtRrT9ZU_bS52AFxnM^*uS?{yS>j@sqA@S^gT=si}jm}IqdUzmP zRsNN&IR2Zh$e3-yPRx^FoVC=t%ki}bEZ!%_Vg=2?827>4a9%Z;M9q{jUQ<(p^dLEc zK8{#T8#1X@hz!qZAj!+|Ar7;3UjA_|#@s=?Y1>>*DK72(aS~|b=`staJG@NB9(_0l z3I6fo<%#J_HAc7<#hv4E1I*#5WI!t_RY5zyzELHt^oy&H4Ld9BEwfz~{W39v34vfl zhUrwriEX6Ss~4m^ztZI?rjyBF0#_JE&hY9HNz2_HFhw+MR7728k3xuA?z)nPOxG8` zdDc{+xBOVqy8hFkV`yut_ISGD?ND>e>b&=RRwBq!t~5rXbg)b~Yrm@&Qa^B@R=7LV z6#b=udLa4~9|{2RmN zbwLXx$^O-=%7rimSA&K!u6;Y*u^}HWv6$Emk!RyNdZI256P~X`YmK_uX(JheI@zsp ze5$9+9pRbAXx+o1+*(~tUVUE>_#hp=1YfjSRE_658CTL>V-$*O8h;pX`Eet4Isy(_ zP)g^cN{0BhM#QffJ2X)?F;5KbFvoDNnpaTHkzVMs#qWf4WK}$WC0C+(MMmecU2zlJtn*phJSh>GQqyPGYGd9) zPX%_EQ~!aQ>^nr=vb$0xLe_iIn@+J?W65((g6I7Xq#ULab*-Wpgnt7JD?w^d?lDv0 z@F5~tx+cV6Q@UwDJGNw|I*26NZTqN;{7|b`D~+72a4DbKM6NJqd9IQ|SlMrOBI*Fc ziMJ5N;Uy*pw7p>8xo7D0Xry9x#X4bf?(AS?Jj%3PwJ^rrb>3o1J41l==*FYz*AG63 z&5(|6bbhhrTL~)S+q++?DQ+hw!!F=`IMhn2c-U6hHF6~=5 zjg_%gEbpASV5sYOKVJEkx`@W|!mPQ*vz3Y$i-lS9;lAOYtD)fuVR6)f2uOs7aJ@KU-dJ@K~-L&-TYDOj}X+)VK=nfC|3gP8v zPd);z4FOs;7dk7&SZ0KhWUT zYD#PHD!i(J+XXSSiQp_bs6VDmG&PO%OFMT>>Rvv0qs!LM?!9K2t2Q2Rlt5N8qRr6? zfh!HzNJ{JXNEBwB2|*g>Eo!+!${;0-a!~KsL;3;dk$&?WAIZ8`vv_D2Z`XGSQNpiP zyNY}UGZ2t8mwOKxVmq3Hk1Q3UzwT~5vgOm4<}D^`flw2%{l;I9iT(=PqyJmj24-fC zpf!dwsJ4|nu_%^iv$~%9mV60rHs*dpC)z5J$9dnr?Hr;u$aWudpMrQWueZH`^*-M- zyRyOwWFAMTdtY+=QO}8f`AfNI%RG8x^d2*$z*GVK^^PxXPVaf}kSn}mUt9I$phI`> zxUOkuc5;5C4**fj=tc`fMo0h1TuTkLHq$|+F_7!yf6hjN!Dq8DtXxd_Dx=16$&d?9ez2383 z6qg3u9qC4q=_v*qi?~}HII)YoGm<~P#_zDBV~yb=I8HAnGD5!cOnbJSKg$)oiZnR# z8<{6)_9z^4Qw-{9+pcJVM7|G@ACnH~WugoaQlCEYA^h}C%t401yME_Ow+VaPjjYN| z%a?0OZH~Lw-UgnkhbQt@Ik^nRUnChBlmCdkCPTMV%rPJQx;W;&ZsrO)&DFBj3abxVc!}3n@_ZmH!B7ko8*{^&OXZ~olD6hvRsV|KLE(M21XLUS-B%;Ra>!XSB zqsll-T$^Z*Es<;VIrATdMU$fEqh|{j^j6pTTw^S`$OQ4Lob5I9Ema{*lF2ouBB3xY z|D9<&7e*Q7;ZCQr%KpxJ3xs~DJUG**W<;u>G{$gori73`hbFWXDTU%_MY(O-Jn`05 zkKocUFBX)Tr`Q^CwXu~%o$e0z2?=|v#3Ijdy zJy2bSCL_Rc>X?^QF_PRaS@s6(@C61abe?0-ezA;cprYhSA>Y80-@4uz^ZS5WLjH2S zAhT1+aSO^B^pf^pG8>VPfPo;?RiJB#d?v zm_XOqMQbOu@Z<%$rIo&RU-NeXXVX}v^SZoZPsu&8ZyfaODpP11z9v3Y#8W?7TT~$z zm57>u8-r<3cO-^-+V7yXpY5Q-KqYo7w|z;S<9+vQ#T}boi6TvKd3=~nl7tqTj-M;n zu{vb7cSFs8U6hl(FX_WxpX9hwKb81~db|qKDXFWd5%Bh~YZ~ z%qq^S<}r7DZF4q6YfDvdPwT{CD&f|YY-we_2We`n4WQ5vsv~HadT-gBN8@p%$Z;SD~cSj)q@-Nku`%>Mn!*K?!nF&B$PXF-n#H+g81idmu#E7fQYdm_Pu4Q<)#0T(>xmrPE? zIas>{xE0Ght2M1ho|#$`qeWmn@k?T6v24^t&@TI?f**(*y(Ox!Cw$XZX2Gi3C564k4yCb<>my3#8A}>vx6gib ze9h#DdK20X-KX>lO-rrU7}wC1D{*bk+g#Y1hllHwZE>{bnywrlu)*^KR9Tx(&M}9) z^*mdK-c{M!wZ=-kqUUJWdhyDbxn!>sPPwmS5|`05lxdC$2dN+FBdtfuuG`7?@zJOk zSgT-+vJyhF??Ug|6&`;y^iV4bd^&|m5vOZfxMgJ4j%_!HuB_tYv>HhIK3H^ z5ysTkdDI#3Yj6%6gr>oLnW-pKl$m?=STG2YcGFr`e=V-R-B4*UbsM_!bL_cGFo?K! zOcNMtesla#|LiZi7>I?wD!EbR@iF^Kr?1^Qwj_44)X!wtw=sAlG>k`2Ygeo{nL}@E zQ(RKOvLJ6_`Tuv|bQh zRSO$uK?XlLYiD1w=;all5RO_AvBr>}UI%}*l;6BJmKN#ZYrsY(cWog441`&{o-k6P z8D?%_Y2RIdhi&KIEkFG5Zu#R6_Mx5q#=YeM0i>qBsbi+Ph;6@E;%={sHwyqcSN{Py zSnetPJ%F?K_x{ZlCy@YJVF?dtN&>XkUxd7e{mD8A#DE}~JJ;5VHQznmOFhI;giN&Y zLuUf!=vV@N=8%J=pW&?dyKv97!AVYbs{jXM^PBi76*@o)MBKJael(Qsn_ znxZi}>l^1vY-0A__K4cUoC+a2B(nIHyweNQ?5Z650o!GjE}4p0nTF|7uV1)wfe;7v z!kC{kgvXE5X*iyv*e&B8t$t0o0_o_;Tjh{#0P)o_?@=oxvQV<3LW^gNBWzB6mhZTy zzvl8oUUzA^L1np;g8&PZ3f!@E?;%}?qJfX{bfs1aV-F=Lkbhwl>;XZqMlHjnm?*oP zb|ooP>bx{*$xbMtzzIb)QDS>ru8S=1D)W6DjCnR1MI~-G`H=Eh7pWWV`IucPbJH%1 zP^tI3X^Cr4LzG zbfcX})M_B2XIMenFtPS+?50p=C4L>^hUj!bSc7k{nv$m@21XA~03+sg(xw{h3)|w# ztXk;u&;{lISi7_ZqC?x5YAClQodNUlOD}!AMyzlCP$QV$82(ZBmoZL$i)9AH{q)$^ zayx90H)N~e;dGiN%`ar;pAod@4Q~!^7Q-Py+b@sVp4J z?#H?M&L>_`^=c@aa5=?XlMnNtcn~ap@V$4gyUhj5#rd?(4Mm(wcREW)2pU0Zr*IlK z(`g^4D%ZyHRPnk})%*82WjHFfh7?zW?KGq-AnvgwUqWG3fQsY!n=zP>$I^6^=ep}_ z!{-J8FE0?3ATM10-OKt9cKrDqL@!YX4gK9zkg}F)UTXfCsvf6;o*`A^wfKvmvEqG6 z@bt;pS>)!J6MYK`aM70E@Tld#Ht2cy<-i59DiH-5!AxREiRn14u1aqxYqpsliTXYP zRZIit^A_v8Lp@X6GJrYuySwNf&~j= z3{PlHSohbcs|y956(abuJ!ZeH=~#EA$(W3J(}i90sW#xddgMNca;v4P9i{|_`g{ZQ zzSI>*qK?q)t*T)r7`Deku=e{?dyMy2c{XrNS89BSw?h2?=G7R%W!q|NTS0Iv7kG^4 z{bOPIkzkvhmrV68f!Ni1h1XI=@g+NqwU^no|1!{PvpcRH5ZaAgRe8Eg!fe>kiyIGN zrJd{bH)gicvH`ImV9Bl~Ho|i4%jl8$Ybq;sR`%iHSkk0V+T(vW=uUrZC%caCpOQtV zz8%$#zS{h=j|0Yo-XRle3d+YuFMNxKPDFT#5TcUTn<$gL>mezSqq$<~#Ir*q@Dd=+ z3)^EhEW-Im!sP%}qpJ<+`ChKbG_S~YCS_j3s->U*RM@%Q#MiJgs}CBmc;W4K91 ztzMR^>-zFeh-lp{sD7kDV?l%EkI%*YePJdP3O2FAAqH!&Acm_TpfTgyKCK-35vAN{ z;2y}tCHT^vt-zZ|{<2s7o~z7ky{WWLk5WkmouS-29k{7MbyHBkPO&c%6*>+udpb>M z=bA#?QCZ&sIvZnQJhq+!Q-3I4@B1*9w(;y#(RSOY`~GH zX~nK|zO;6Bg$eQh*$d!KQD>Fp@v9zjDTIE~_~9m0+Kr!Zl z|1W`4iN84aQ%$rYzsI!!qUM-^c~-0^s0t$3Iah4oUG#BtB+!G8(~ffPW=Vx4LOGGY zJZ7~2j~Qk6}|LQ>bkMF zB#JM;977Fof%LK!Z-x}7x1Lw0nL$A#>wQKne-O>KCKqD3DlIlO(t=_?i8#c3uWJD1 zUiRBl>CIkk;@1Srb7k=e(;_v_s)MCNqQ*aEErJkhOq)>Ia2sd6a*2o-w(&4SQSt2(@|>gM2`YtRufyWhD9epPoeCC(x#+Pd4pythn<2Sw-ld7E zf`UkG0ME?|zvt4WTP>(haH2NgiG#e)C8{ig~K&(Nf$)Q-5R@eHP zW#9Pd@tVK4j+(04ve+=vSw1aXYj8WBVOW!oBhbgap&oV)r*#{!8&^y~m8Uo|o>;EU z!wXf-3{5RP?{tl~@nlFTP!0&nJ%|;H6iQ2}Pf3fDpI450H$H+v4z`+`s)fhFjISdY!QzE!L)MOtmn8yV=_ zl~CH!0h3ejx>xAhNrm40tfz8p<@GyzHi(rH#o@ip=skI>-6djg!zh1>FE?qwvNl5m z9r+^}$GV*lq7ZtzAG4Q&-X^L&dsb8az3Nmx##C(AQtYP>*vAhte*#PatfY;L4JLD2^c)(&{;S3NtuD9@5jMc$6;lP z3a2Oi=2)4HJxe8Ge)KBF=+pt_v*$0%1=p##&9{7|hgtg_A5%o9w%n=;DocP4iSY=z zH}#_EVh?0!u9R^!_vRKI0 zQZ({-T)k8Eb>G91H5O|}wehTYS1&l5VdAdwWAz{6_Gm|OZ$F+&To+5Ym&CHo)$6Z0)6&eY;o z3e0d=>DGu-mRt1Q8yJk-U&T=l6_b-vww5+Fu_T@jTclNt?C5GmT z_oEm{WF=PMcHEg=$=a42i_cChkze@L^R+cGxh3ME;kyWF)nN=H#JI94Gq8B z7o_%FoU*SaN1M&x;{I799fvd|_B3~XbsNB!`+UtqF;pd*1m%q6Ars^7dycZw57Ttp zgu$@8#F`rie@KLN0YjD^lML^E#r-`Q?$b|?S&T~WwLq$;08SpbT&Z4BSB{Ds zQa7?n$bmxbMW#o9TBJ0>OJXZlFxIq72p*tId9yiO^C8 z@NB%H!>-Q_2zVK4tA}QjP$CYx}*9k^mNSI;QdzfC!|_NtHlefkR~fo=r6qUwOazK2)ut3o_`*E zk`Zq9=C3LE-^=&!?=wb#Lh%^&ulb1vsA#tJ+t8mSxh+7xTyqT6JVUd@%?(!z5HWH6W<( zu(Q@WrCG@V{sfioTDjd3XUUVhH#JO`Y&9C;0QO(PrxuKpzRHLUzAm!3t;s|*K4tny z@Tqo-4w20l<3c}-iiqQ+e7|S+4E^UB9mE~*LLV^Bx)g%>}RCB{r zhW71oL=DCCFHmZ&Z1)UP*VqxcJ!c?a6%5UG&;_%ioNTWy|FuefI)efL@74Q5$>*ef z2@a4yYq?wYcHrWq=jnvy0eG}TJka{{vIRDh%A=~tfw;yNH=0%Lg*XEkN-g%ZS_F-J z&iwZS<>_#F?Z?!?>C6IG2Mwy>Dmvr``D%-*Z}{Jf%8Z_XJ##5*ANXf*F^mg`TJ-|b z0_T?_8~Rb@NY186K$N6SR~{hM^R%Y8$J`S~Bg=JwMLJ!y8it3XZ80a6-c%$!bKjLoEZ@7JZ(LpBo$`QE{0nS&)Snz`R&+7>^RaSm zC+`fBjr8tIVIypO!u&eCF7%@#*U@hJW~HJ~1tW-6-tkU^2IHUusXY88gA_6pFrc#| zawkdN*I{S7iIZ6a^M&Ea_V(~Ig8nX(uQq}PHlX07c1q1KA>*_gbWdyi^ zNF}FO*%j|17KKsw1uG;%zt8bo8QJ7((v|2Xcjcj>hAE(0zq^#c2RxoV}?gZjQ& zf@!xevQLmG1e`&PR^Zc*&(0znKfePU z3gO=z%72zo0(KcK)zr-CKP_}=)%ceD=Q7g6W;-qIt3NJcsjDKQ?{Mw)8xz4mC~TGe zHjkXSBbIGR4&*4-C_@EbjB&794h8YTGlW1j0xJ~xEK2k#>&lPJWGkzAc(r1};J#iK zX-E^Iiy||a@p8-s_YE&%>cuN4l7}763E4^}tTf8+fN(}-em-i@vbRI-gt^D^kkj9$ z9u&LAuP($aAjDnnzYlwOn7JIq!phk!puzY|F4*>&qFH@Y&hDF)D=1fnSXJ(%tqx~p z0^yyB(-S?e z^Yp-3WL?Ik*DD|5!hqUJcE=iTy^b`pgZ;yf_wF)6wc`R96sYTTVq&fTM-^Q0*H#;% zA%&WO2ptaP-;3ryBWizd7cw?-O@c*>s%>O-)IW7I@_q=xV_Gcj21JikGTI7c@)EDiFCCYcYi`Zf` zs2=~_y{dpZ2_M3A^9)`))Y~2RDe7jS7rvBR^M@EKlFuR-MbboSs$*-Yx`1dhkb7G zyS=wOP?u4Pn9*lvS*+RQ{qt6z`1~Fbn*hx}pd9|kZ?XNtC9LZnU8?Ed0}YIRW25{( zFDqhOjj$?*huCEBJr+>gLPg zw&njIt0xU$R3XWZrJET=L1bk6mF5qZ0KB>%5D=0R`eSK#7jjEIoIm^t=(xczE6JL@ zKnxTCl6Huaf&PT9?e%EF?c8yyxJ+5b%d8xu;XuW$Y%M_vI*0d(tdv@q`V+mE!L);w ztzt;YKkp@i85=>556}g@PT%~mdgvG2E77EX^KUiOYb@BHsrkb7S{Lx0_9_n;|4f2$ zSiX}n_Tncj-}&sGh=|@+P;l_TdMX6;3SjIZ$N$p3Szuo;wBuB(7;;WW)Bf&hpEw%4)L0M%pLp{+8PbtLeBCxye(FaNy> z4h;~~!vnYq@utXIAQXC}^0^Ht%= zy+@o0QHooc1#yEzlO9*Es42g$7nyeNJTi&)*)Bi&CGnoM>I34H8I9>wmvqB(85PfS zD97_}eB<#rFM*02TfA~%-xxStW?Qz^b;TcB*vrh`I(VMXg7@-1uOsTD8UY=N~%{#T*shyP;{N=i9V)e zn3huN&EopXao$48*H-TW)`MyBz)}2dcAYm(wabdJz0yIsBq446G3TbOH!8)Oq551~ zBy3;lxnC4!jHdYJdk%Av415uOKeUyBp6Wx#biqgwdvXSEnPK)sjhB+T-ixwpZ*oht zLMyqyK&wzek_MsiCoH}=x$A0pg`*Mq;y=?H(vmu1F@r208V5P$?sMB&{W_88TCzSQ z3ERq|7q80+x7-^rt`Ga&^LTOqyw1FrxwjrDZg#vl2(J8xIR6U*C}B5b`J^?1*u*!6 zL*Y2)|CxEhu8W5IhU`>f3BGG#y~8p^1|3;) zI7rqK&8$Ak%VPJ>2Zr~YlE-<|R85rDj@x9@o8IeGa7kTUv{F-Uz1CKA36|TMGV3{+ znI`PIOw0yB+=;2qZk%$ZXV2A?Pk$cE0VTljD5a4|Ez?j`hbf+I;||mC#Hf|Y332UgdXLEs7wtBCgMsbLVr|DJAxKT zZ>eWfy?Xt*_9swLDb(5rKmQVIA^ycn|MZs3BgMwoiNs;HxnFPW=QY{%vRu@qRsI@7 z5+Z(|R&m7TY6(Aj?hZ=)6gPi#_bQu8?#oZ6i^Ic_k3OiqtcIx19zZ4coJ*KdaB9`c6?D-?3MaaQ5Ze`)3$k7a2w3AfHe4|2Mey2 zcTbLYTl~aoe!R7Yw8B3NK9OMen6s%l z6(x(-E_fqYVSn>#G)&PbxyM?ECyF~#x=5?oRC)MV$_WBB>bifmbW7G4-N8u0y4s?c z&u1D84zxzY7n@{n=5U6M6yO{=h^|B-MNUP<6ih!jCX_;KQ9Uxs={`wms-aEvG z^wflBQX3(G_OI?<`v)L^cmK5;Y-5M+u9$ng>2n`BC2&y1^9M@sgJK)OsP(sF;Ew=M z!|nvww6@ryEmZ46qd$sJzgXb7Rm%~h**8meu+40zSc2fV!;0(7D5}Fp!M4#opqpnY zZEi(pmczJeW8fp%(e?PrbX@TE-KjVCHzLeR_Yi5Ho+(A?jTD=j?GP47yuaa@5LQ;{ zB)EMkyX|i7(CDYN+c6@P21?!MR^}g~I;^SL+f#HzL%25e(`zIX_ZHtNo0RbRn)tq8 z+m)_udj{p+Ao)7Nm5&xGR|prE>c~BGlC|e>KfW5tT`c)z48rk{ywtNU65;m5VeVVB zmsQ#vH~?siFD$!2=tuwNd%e%|U~3=8V-R@RBoSUC=PLI5nu_=5*o?6;u>7#=A}JE% z!`AJatWspEw*(b?4jg^4yk$!M?5@SmvJTl9#}O$Wy^N277zs=@bgYo6QB~uYlG)DO z7OSpg>L+={6J)TGy(K)qqDl3+4SW=niXeq9I;GzAj#$3cIvswI&0&n2VPf+z(baaI zzt|Y=C1ucEXDveJeuT4odYpiAM3tO{5oCY;StIBpwd`#0SKr>RfCPwA$4gA4s5|mC z3jTi>HBwfNnEDhSpNAba(k;<6aQEFQ?$x>09c73v+2&SzYjyM2^PmJR9X8>U$u72i zWvc&&wfBx{YU}z&6;ZIE6hT2ikX|kHs?to5-g~d1BfTjg2uN?zrGy?JK!UWO(z}!d z2u-^5UPJkI&N^ZIjGevbT64}{nQOD#May2XVz?_dYbqx=cf8sF zagP*kJ~UNa*7tN%100Ucjb>$?RSZLUKh`4XLg$Bjh{>TC79xA|y-%Q36s@4t z>+Q%iESf~V_T{~mDhiL7K*-dOC2vjo$8jUswY*y;1N|%Z?wsk0x($j%#lx#thwgeA zoXyZ1&QbImjKJ2N$^*8H{-0t1CCk&`|_nt;YapWpcmDj})3NUYa@f z!tmlt_-)~^+IXOe69BdH#Up#o-?b>FN{RwXEx1N_wqUc!;5I)t~`^x~P(^)Mz6 znq-7+U4_-vj8ii)^vs@itU`vyybs6BZ(w-eCjzBTanx_K@bQ`u$v~~LNxFcIZa3dg zefH-m&*FGe9cp8=NI8a*pwmenX?gqc0e)?3$yOOb(fE{Y@J{^faD<|2-6PSrG~-F0 z$(>@S@gZy(*47jjpsjJEcp});gNua}Q16RA`rPFa5EnjT2eCuy^~1E&COyorp7Y!; znnrIRKGE*b;uBgzA!_=Qxc*2}?j2?4^K`ARetE5z*6`fHI~+cWA*Ua>jvWcQfrdGb z_~35@24865YprIW1l+H<>NYbDl;S@kf{Om!$tLh)Y#iDA^&bMnE)kwY7Y=QnEEBB( z4h_QBA+3__V1{B*yQH}5&xJlXZ?=TK8T_mQIOPbYr^3#3F3CU7z_MY$s<1p|GS)>A z)dr!bH3xHQ!r##%XZwTSZ@&$+5b9nX6Dj}bv@dtwLZ?NF&hYdth%>d1M4(y7^d?!C zQU}d|Nh_NzM8dsKn^*42wPLHkK7V_J8!0u{?j{e{*DX4fuWLz8>ARlObHY(zBcjT* zpejUpool9JOFxp-MoQ?2f>TC@Q&5AzDmDkIZtFZ))X0^>ljo8VqHNu~;oi@wx(-D9 z(h_6PE6;TLn;%j-x4E1*Eymoh-}LBb>w7xxpG$qEeOxSBf2k+cv5?|sDWipt^NM3v zZ8HUK(}-y~^PW#r;i4CisZci2CA*NEuM5(q$cr+v7>mYmO=SCbhJ&GmD}Y6W9|Ora9GKtHK;juO=8ffBNNb$E1uz0f&y zv9YJ$`WD*D)VnOIe(F2b;kg1UW%Ogv5RWF}ct5jmV|(Y8+}2^-QxImuSSs{%_9eof z{&%HI%lu2tEQ?%i8evz$?moHOR>s#QY2X;XpM8q2gEm%nO$ziJ`+%7GHXSQ>L`7r= zI9jmsL;^9y-CECkE?7oItQZ{WZMS-q>VoYcx3GW33oRa0+CMnJJhd>_z7XX2-vD>t z=-y*sdaDNb9tP+-J7L8B$_$+|sa^H6*)?+!Amc=>ga|gBQr(-h8BBp- z4%@Z9rUWhv3W$aBZ096JfHnEeNV(VZ8tk%g%>(B5J8LIi`SW_D)>6U?=%zPr`(19J zsA0nD3V}N@7Ox8P*k$|fx0Tx~C8)(YT3=24!nRwR?vzRHe5g7bHp$fm=vR(Q&Yw$G zUZN^IkjaZMy9O#aC=xDc%~W6i&hKEtu#3Hq{ubZ`SJz7?cf8Vt8BE=Sby#hO3YP2{ zd0jnaR=kn~u+(W?BMB|zw@_5dK#@Y9+8)!qyc4i@i6$7)AjfQNi~Di77P5IP zQAOt3=o@r|6(80g(!oYXoQA6A+$oX*3#>{l)Zapr^pC7-P(p7ypX9;fIv~!$(6JMx zix(dvj&yIwGAV*YlFSW2#N6|V%)uSMC=?CE4_2*ruJb5peTH)bdz>674CXtM#x;;6 zXfSu9yS*SuX>o}oJTCW+YGi2Jf(Tr*kHIFl5`_qTqcK>v%-G=Syb0#dSIyD_zO@J# zEFu;`{<^}^>|)PW9{ZSC5Xjq~y5Bk-JO|tHOs|6|ZOcLPZL7ouLtK~*!X_w!S9Y)xvH=Ys0;12dma4M@m+{nl2R>#%59%qWfMnc zpNLX!8{`P;%JK95{+xtaH&K_={fOeso-BSZS)Q$`nArOzSU`&;)}4IxJfo{W=iFfC zoi?XwL&wDB(=)bL0YA0_j&YDgV8ZsjzOb5X-^?|zL#ytb$2_{HJ00aKt3>S~U8*rX zFmx;`qJWD!-^4{W<;rX+F7^lcdOWaLJmCUn&tEh5p!xk5R9b_#%nPu-xC?P*4EFyM z%DC&~iYFI*FHc&Z0RR5iW&clu^_MAJed6nVe9>nv|ER_kwr$Qh78b(>UCcF#Y4Dzi zt@Idt!5j=oe6jF27S3mR6o4EUo1;@IUhf{I-YJ+zP#}ToFZ!BoYjjQ)2Dzwaux(;v z)zDmM0hC;r?FEbZ7JFE2Ug?8_3pbzK1n&uM5Mct zG5gNX+bU!Q5b@2^O~vwXhDZl1MJ4UYAmMFz4EWZ)@9LaOHK)bqiercDhO$sAY8)?X zi)xEjw9}@>ja%hPX!?gGv@65wnY<@zi9S>LFJj5L!F)=Y|zJC+36Y4wC;LABWmK1K5KWboHZ zjC0|?xtG5sZu-YFUBy%qFLgX;=Qpc(9>5KXrp<3#7OK# zD`Xm+xZw*m<}r2F^y-uDNuF&5ja4qboY{YqEB!_M^o+AkUvDAP<4x1MM>(E92JBbv z=V}9nySNXBO0=c!uHe#r3zY_rg4q)a?jqVUWHO2U;-)rbhR#8vQQ+N~`q#=IZ9X}( z;vchikBOiRzy$6jO=dAxF}HI zqsmF^FT88v;D1G90g3T0Fjm;()Hk!Tn&`Oc|p=S3qeCXz`h5R%hju*lG&r^Ar1 zNR@X!mfNp8DBbfU1|uU2NA4InDmz6AcxP!27%K73+Gk`BAr=Y7!F3SXK^X*#q5n&c zPWR2c&?41MDp;JpjOV22_IJpj{c+t`-!cFs40~|{6M4Z4-uHBDd&^qr$G~z+O=tMC z2T&=edq3W*)*n@w*{LUkwtiG00IC`^C8-rY1DXYt>Uo9)Ebf>uIBh|XW!NIno zOGQdZ1}0$7W6e7}XxzO1yp~^(%Ei%==VBL^BJ8o)lk&VjMU*Oj>AV0?VI`6K+ef^P z=xjGqcuF4a!EvThhWjkdLiKV&V+=k^7yd^4T?nmvR7w7Ply=(Lo-bHp1}o8ODEuW) z%+b*0sY1hs#f^DBOD$;B)qxDIa2EQ2+sqGLl1dh@pbVx~8J<3V$a3$_(f6-X@^FEL z1UU)Wy0> z_Hg&P+@%s;e!|-iWapN;#jz4F-D@n%3(!;M2;!vV=e*wEmXF|n5nnyvZ{w!xU5T7- z>Qz?#n199~bN#!-lLK6G`vYP8zieKX^8d;+e*Gs18iEIb?+(3t3G7uu3{IPkji65+ zlWxiJny4!5n(6v)ufr;9p;m`i-mTcTiCabd)+Ob6c8Nd06wj9lDLEX61je`*oEPI% zsj0KNRLv_U-F2P8T-&WiP?fo zFz7jzkisyx{xREC*%sBor{cSL9>2b*o=mQ$cj!yo6kL4&uDPmlb`K(xbnmj;@6p`! z8`vaq`PAZ%qsU#8G1(F=D_C}5G<}{ronueS1FUU1cMVs)CNqiBSIZQwC>wT+BI?-w z2Jv+d&xx`FO-p|XP^B}W{7ed!WMK^r8(iSYvnUpWi^{2TdnnxV=0XGZal#$ZQ!%i} z#*J~76Nn>lJEYSZ_rPv;APOb%eNDfI$i(xBT>HcC5d0qTg#5B&1j66nUxco<9ZUHU zft22&{sYOqMCglm+0dscU&$f?CR-_yg#7Jy{~L~eQV75mBpm(^fja)%)yrA|%I@&` zWr0mcQ+wBA670e3=CBy^LvIr1{xz?>lPSdsA^yQ%M;B@s5m z!XD#c>5Sq_4bJssko|ZU)uPjV^5UuLF2&Nx^DcXefUOiBs1m6CY<=2lXtbLyyP{>l zU9J=N%l`&_Ca9St3xa^vGDh!69StSMzsZ3a z`|gj-x1*O=ur`8#3i@kFrm89`w@vd0?yDKwS*hrrv;z!`Q!>C(os)B(@8}e3<51X_ zggm6RCu#z&fwn}fMIkLwdD}NLk>jn;V$rcex?Rh;7N>DhA;%2^0u0MApO2FUu z$Q<~Ky6zFgfYA-NB4v+H`Rd1P~5RAGA>?)jH(k70whRlW59Bfvex zXqUu(Bm4JS!}G%Q8QNDe0aE3P;*F3$4U5Laz_Yvk^!9zc@QR!Of+-!S>G}LrsvKu) z@q`S*%&amXVql7qi}*rAN9~D zPm?8nEN7VQ2?TLtFbn5Bu4iJASxxHn@wr`#%*o2wl$!A{#Gt^^{C`^kK|bTXhU+6SP48W%PoLkGJRt+8`_CBe&ul0H?$a4c*CUxjyT$3d0lO@$LkMj75r98r&GvhUjXjNtPbZ>4+rte>Q3gqf&eHO?{%zt50 z$v75x?+tIcaki=qu7wau$E<`9b!aedeby$3S&SRYrJ|zU=MerX6^MdKK|T0FVUPW@4&_R}W4& zI4-=dYE;_E7-Y=TKa_PIQp{~>?$3Sq^EFzQNe=XZDd{{f7_Q9XM<~;#a;YX6UR`yh zS2IT?p_pw;E`EMLNz{jaq)c-sx_DZM)ZIdf(a!n@8}qxX!FQm2`MS0+_J!S3;4FZ_ zObM30yy_vJ!6uFozc>3{tFQBv*bUb0x#IRaQ18W}etwO$Z9FB8l!tmMR^JK(VMaQ| z*7Tk4G;NUneq}0G@l`Z_{L`=6BFiKiVbWcqM!&t_Iidai=oL3XSJG^R|B{F;j6-?# zM|}H`a%O}{Xun3esORZ|WFt%nTvu*n{3L7Krr}KN#{4eLN5=MKh{>!Qukagmg0!xQ zUj4ccb#GB(Y`US1o^<9!=Z}@o@^qD^mSYYhR7wLI)0!?hJJ$6r*s>`1E|UQf+u@g7 ziv|w0X@*n}TyT&8W%hP6-hj8|ExOC4TSIa>hW20fggsXLAc+~9XBn-(jlm1Tm2Y}6 z$Zl2XF%re5UZIQ4q>>EGBruR_AG756rR6cN^6px-+SE_=x(u10gp`T7INN;3cwtHv z!$Gx-d!$Yaskh~OD&it!F4@%I@M-twQZU}zPf$ES=R;-^qlE_)L zim5kT+Yo+m1tnO)6#YwvD3NjTjJhzK|a92dUBhpemYZgd*8nh;IrjlOGb+Pb4KDqcILpp zr4OIefIZr^KPyFcvrL;a`Z6bWi@P;n>C4vdsrm4bVzOdx?90a_zt65(cxX|rW4CTI zo726{R%ryWx>;Nu*46-n$nOlPxVgPmo;fK;*Zta>8jeWK(YLiPgtj;nE!&G8M+*%) z?wFs;SXgiJ=9lbL9dGMpP-H#TaU37OzLKH2kbj*2P~km8_KCOpKVa)Wkn24_lu<@( zA_@>i#$>;LT|{HR#>QVX_s5|1rt6EWybB4pU*s-M$VkZ^o}*+S*a3Z|al^VWEH@LMecJjnn?(ZZwzvul5tu!VRk{6wpbe{w z!@x=bOj=Y9Czr1PRarXy5dU6kcrn#}TIC#f@pd?YTq8@JJ#B%jEwREEqF3!&VbCO4 zF7s`?3sfo9{_tgURC+-~YNcWDSdK>eMwcsAAEm~86yiz^?dV6&7Nz&|DC*NbT@?vW zaVnLdNTDI+9M?&RN)eLk41N~Ps7(|stzBJ`J0ZAX{N4Ljq|l76!B+eI=@m8{FYLF4t@R%)3+!>=B0({=4TvtNaatYtp~u-h zr`lpkR9kG*)_%`c)uCK_RW5c}Z5_q-B~qy^)At9z=8p;_>_Zb@Omi44?$N|_TpOtQ znCnTs-aH+*i{lHY%}sZ1@}a=OBzvMJr^hKSDwv_W;y$z{+4O>3vF>%o zvQqh!(ljqlGF&0;MRL>du4E1OK7X;j9OQY1+q6%D^L$b9`iRn$;_8%lu*KNpq1}cQc)x6YZJt=s0HRbH$zLyM~su6Gp`FetQ2WJ zE6zJv4Dgf$J%hHXm@9*V@4X+8eDX1sb4SQz-^7-ucXFsa3w)p;yg*qZH#8pAJ~^TQ z751g&TIB0C0NW)}^d@x?02s$`-dvga*aji?bl$>;PG_@#4nqIjCV$eTxT-087A=pa zYL*h-S0@W%X7}v)-3)5e?_O@aN-tS>5D#(v@q-GMQjw5)arrrWm#V4r3u{9DJgOciv!Gkn zeGCHiGDwA%w2Wd_7%4-f4)Un8miTB#RSI0_CwF=X!n=fmr`tz_ZC|+SrfduF^F-5_2LD zTq$&4e@iic7+E;aBSY37A677=OLH&(lsd}%sTGS$&a)lw8r;c@GBv5OJu9&F*heXd zzqmeqmCJu*=_22=Q`Y1`l2EEG6K#5{bvNT76ljx5^B@Wz(a7#(5}=-*D(AgP7%W?K zXuY$o1*tE|8$Z26|0O>Tc5)^&ZLJrJdoJH*V|DsIFq8%Bu&_6Iu|JV}?6+K4=(G1V zmwm>#R!)!gLc})O4Zog^1qh}nAqHmwcUyF;3|`*n{X>`lC`dv038>$G`j%e@)<&5R z?&*nlCq3IU6T)62R0jP8<%_r*xSm>@bS^z9)=Bs$mR^*41VUR-a?#L z;TF{}R^_TECagp0L=x(&?o@WrWFFBMXkPyVD{6uKC1)f0GYh%}-(9-M3}>DU_h>(| zPuRx`P$WSF(Dr=P8N zPr5U93nVUV39A=LYsNln))C{A8W>b&j@1apRG2*A8oTY0rl)09AD6~Fqp_$MEFM4^ zGRe*eics!u`fN7fS$W>!?Qt?Xg3RE)4ep?z+ws4vGMcgKWE9Pd^KjC&mG`16n5Qgy zYuKGI)wtYr+Fnz%R#0Oz`-7@&xKy&==T{+nn zQk#Z;I=+KfjFXddz2a3VLMrgyzcYm%K2u zHLmlD|NQtLe(G+;W1yQPxvuH?7e4h~=3mHEKE4m#Q~O8`e8w#X;41yBpE+|pGIkqg#} z!l`zMp5PD8e?Gj^8$4dUv(UZ&z9&sk=|7s=e@heT@y)IrE9PARFn{x1d?3T0l7#z# zKwU5O=E^l-e($f~Z@>wFd)yIJyqHxKUbS5EJYpBX%(kvw1{F`9j*6|=**kfEt$w~~ zoPBh^VEk{;9N07-k^*tO+74RPjqMj42Xqlh#D6vDK#c$W=Up@)^IkP0xBWE)SiF99 ze*gLBR&x!Q)`5N58XW{Q^KTyeROw*IVQTMXWxADKlcL|dJV*mPp!BpCxrK~#o@mJi~r)+IDRD^oKi2Z zJ;G4i2t1+uGlm}H&q~Z2`=$+CnH>P}BbWn6{`KpZ2&P!@h22=C#R)r)cEyYT{p~*4 zU)|?cD^NrOw;OP-miKY>0kbs!?rZRBk{&#IR%Z%4w|fkB{~mW752)TCJJ`#(5HXIr^N&xE%N~B7N_s?heoE#sAD;GhJFsaA3KSuw&?iXL^fyaMvg)H?J zF_74<1d?X_6P$mA=+PtKhY~_XLd^JOT6X?rO{$<+5%9;A_p;_U@Q6`Hbp$f1r@Ya`OhqX{~7Q41^~GRwD!ZA zdR-TZ@d3t9t_I)E{!%CeV23NaN29L+5JARmJYZNwI`2*Pw zq1aVU*umi)lH9^Q8_m@%U{J+3PvBE|TPs#pRf-Kiulx5%I#+zKZX7=!`V9oD4f2WR zpAXFuAFK*kA;3I%iFi-J*r*lThqUCl*tQ1%dI>j=YAh`m0Av7&`Qs0_yDP>QZ*ofO z7Wd;4Uzy4(zuwzw6k(2y6O`bSn-<)iZKZf>8hB29@9wA(F<+uXL0q}fmyJHfvxMgO zc9oq^C3_=52JFWtGU1s{52uG@z3kW&n8%BF4y~yD_gd*hLv%zotc#&-Ib7k?Zo~mL zk2|=U1$u-$P&kj`?&Y)D5P^!AQ3~oNqQyI1sA(q}mn6@2AXx4aR#?ixbCz z5s7!_@?w4{ksKFYKj@O!KMX;hC+|ppjV5Rg9c-a7d@Ly`S6KYJc$h;$N|t`5bj%+vVRf8U7+W3$^aU^ZrXn8n z`|T>)b{ILX#Dnj7i~$v2wg23Va$3}%JH;LV^`ZaQe1}GUCvgaxJy>nloW13|DN+0xwL9ayL0E#!fTXi z3dpX7$f^?e%K(*3B}J>fDBPU(K3y;Qtek?(Sa?u?^6NY8EuYRrxQCKbc$+rlOVNEk zOQNR|OMA-zknmH}>#YqF9M2!28?A?HFO~*ek!xayy^R zu%hbaV-{IwgcMZY8Eq@xUcL=5&C1FBAc@$_{(BOcbxO$&1qXFEZqSJ|SUr>?F&UP6{Wx|x=?G+2A}(hbe`@818F13wV_zvjUIIq%_l zo?gs_i|w2lSI|LMc^}E$w!!|-^5?L;90$dRJr+-4@WR8+5(fBVo72F8{Yj68Gpge0 zf?+ksIdv2%B?MN&sJDKy zcD=Y?&#LjI;W3f2d6&5@$C#p2yW$ec0X_avIc*oq7~_UnCZMOw<-z`*futdZeu1j zmuLmo`HH*G=x-V=XxcXeEYyDWc)}YSgvmR@*Bn;p@+_xE76mI$pY30w7Fi_LNOmn5 zJ58jvdUCVdg^pCLJStqDMq^d07|G4`vom*2ihL057UR_M@CGpn0;|x1+M%CjBwb>Z zRaB4DTMjUSS|*K{PsK+!r3NyZzE%a7U;@CCv@kK=0_C;KtUFLrb9C~;P0(9d_p!?U z5E}DiRzC!cO;{Zs@CUlC%3%ZJu@BU)J;7%CZabNf2{aBBdz;azo&Igzlx#@{LI+?n zhMCCd4r%U7B)kfZR1GU|p*_?%d5qBnxOLmgk)MEwMtB{Z*R_*1t&vkhyvjHl(ZLpm zQCS{J-&nG4o&sjZdaWjI@jSB-HIidI3uXC~6D-xAf7jpWtDdy=MCBSa8T`4o@8-nU z@#y+>51>E1aeO8|gI!8^y}WUb8$?--d#Il-JgfH!++#m@?ZR58q@j>1N8e^2sf z%qOWeEMMY+>Hw9}HsZ5=jY9AQu!{3Ohdp0IcHTIieLZ%^vDhaJWBmK`GT%-@nx`G_ zb~0F^N{A?jAw_Phapw?>a+v28o^Ql?FhA}_?X-Td_E*v>!;RX~p9@@Je&|jDP`0W` z7VDdw+#2=gti9 zJ}zwX`&y;<*!ew1m;rCy|$rDAr{BCrAk4=A7dJmX&>hBv*t^IAy)CLJdrju#=--Fi#mOJWDrMO%Q z8x>mnxT_xM)LBy=^ND$Rv>V~D2hG#k&^>13Ph6<@?OsO)I@9rnl#RYb(`d0fYq!w} za7j(eaWF=OYwNYf8LDH4GbzAHq1+ZtK!~xyHKph3CbHP0t{RcHSu`ZcF#VcE_ZPa} z7dd!M_CTkvF^v2fXTWg`<52!UN4%rck$;Rouwp2mSjB!>@ODv`-r@lS0*Rj=if^zn z3wrQjcJ3p$#RBs3hUe$X;p7>#`^>8Vyd*lFT4aq@Ew*4+5B3GwlZ1cD#;lOFmhmjH zGBb$8#brdk#K=E$J63Ys#T{uxH{405tw-c1AjO_%h0qE|$3@i+>r`Df;EnS>CpzQ| zDHEad@38<+jbOu0YnQjZ(!o=uFje_lB1P?^9B(5_-bU5VzNFiyLhs#nHk0C+EaW?V zF0#%D70F>zMJfpHYzdsR0OZ zxLctyE%E*2cQwG2OKbnY@0qGm>Uvnw}eW4|H#Tf3{3}{CjkES>H*x?$N+61!g^+8$DVdL!7z_ z7v{d71vLw0>^!1=cA`w1{n{fgoP#|h?vgD#2K<HwZSk;yv6 zmy^K$VL?O4?SA#>uCmVakoFq2R8fjSCbaA7?#Oa9$DJ9zZh)K`_5_+UZPSUK>+fmy zt6wf#?esbp$tB4fltoZm{?tx@wQ&&?P=KD_B92scTbH|Z(_$cF>wUM{H~<*6z@tFQVH*lyEREvNAa zY*5%EjyT6cnH%ueKY#-~GU_n0PF49QuxQZl7JcdNnt% z*sw9$0%=R_dh%SE_ux$K_)THq6mE!HpJs+$1DozXUw1Qt1gh!fxIQ1;qk`x1?jdub znL9d~z&*;@tGciofH0vn+0cvxl_@|+e|aU z7tH}hkl|;SvB-=Ch({|n@Ip*_XX?J&#s&P+I46;fUzd-2`?yDm`9QW=)Ual~zJt%U z2NT&*f}ZAAJJFci^VqSYpTg;;Vo}d{y^SB$yJNMMJ<8P{G#RPSwAh2vA|DFtbWZHh zCHPcL;1KI(JYFBmL!XM59~VrtGoRJMo#IhE2k+vKu_#a@kLhv!PV${Sd(y`&s*Lh* z6})O-Ubm?4JQZ6UkvPFaL!h%(BM)8ZhkzKPQuu~e{8%@MKns{W-P((AKHd>n-W|a$ zaYJbCCa4#2mL59?s<%zTTCgAbj58kQjIxVo(cI(OMxv8;me6h-Al(glbeg70ry#E` zsBPvkOCj$yKysU}YRx>OD<42#^Xoy0PufGJDYdIvVlDg<{eb#}WZrcsOU8VRC7n4V zt%?78mWtz{yfy$jiN<^0CTPRMZ5Z?g5umd@*bf}|6SsW#O#;Y5_5H*HFC_u6Zk?5l z@6UlO0F?ZqbaFHQA?q!Id`3K?m@ksze+y#($5eKkDwZd{Rbn?Q_nhE~9IAv_G-|Cq z0JthK`&tm1SwUd4(MMx4c1xWj`nP5FYw&Bk8Bb!FVdv?k5FOi^vlqwdU7Tc9A9aw?@#RO;KI*6F zX9#(xJ*UMZrIPmEnh`A(j9T*UfkU`4oM$&DK*wG3mm4X>!?g~w72`?y_yWxE6vPwF zfcqHC$_SdN`cY;T`&@RZNRFPkk_He~p%x^-xpHDiG{xURrHHle4qfJe<0XrH@~ z-2DdKvwOZJd3rbrYV=cSMt7z};PA*wldhtggS9SI7l>PIT*<0?DU`*(0XQZjLfc(p z5D8(v;~20Yz-%G{-b1_J4bjVLddWbsCsuXr#uPw_;Rkior<;J&W= zp8*d4-%^-!bL1zwQbVqH z=c(No_>l>tUK#nU@1kDg#N4PI zC=z87+!txVZ&yn)@+hph8w2y5b}ANpfivG)O;}z*3e1yilxoNj>hZ(4TBHJg4TsD;3IOTAr zPFbb&>=k!O?K&RZwu1Omy|~X(b3<#Xi5I6NiKVePrJ70POuM0C*eRW>22io3aqd{t z1hBsXKVns9rE`8yhNYz~2wBkOKGWa049J5K5KC^%$+pi7fg3%7!hGEwTlI<@a^>-y z_2545I6rx(4{OsVlnK5iVW(t^w2+E*U${x+CVE~lKPiBs?-qZPXZRqEWkUqVRlO#^ zau;GB1}J;)rvX)yt`;9K)q*j2{ZBmek+BN^@+nBXXQ7q=4oOg;4EdK3TLXBpF`R}7 zzgNGPxc=FolvaGxKZ&DYG{dZ1J56z}Oh3nQWL{Q>6tF`m{%TN|w$xj;^m-Hg{pXST z{%`y7^&RggExO&((=(^U`_e>=`2w2E2`=8bcrS!r=O;j^%7h|$;P)Ash8k|gW^-W- zSH0kx!Em75UvA$l$?3J&^HlVjXVTV!0-$f)DzmR={?uClaxRM!z#eVYrt{$lBCy-u zO?@0`$@;HsxDc{Y>EC|+Av z(zUR16~A7yonB_ACk?=?qu+8|%HML5Ih@PgaUyfQ!MZ-R%s1n9*v4Dvy_?)~C^7D^ zZrJU$akA#jOfYU=tuqs)U2ie=>c*#!`Hzy=4H6eCAI4R$oPW%S`<3aSxMJ!+Sp2C_^Z)v3X~zK|5tc2AzGDqRE(RnHesOXM1G!s7iiK&4SptAJpy zbY5(NyD!e3yA=zxlRpbxH#R&*QnfjaWU|lGA-z|6mrJ&?rG42A8YH#_f2!#0c%5-n9;SZY8S|dt7U&^S;NzKWw z=pAU3qFWZ&YZ{l-QJ6bziLms%qBvCmAJ&JBFrNv$SK~A*NG~ie={-(SlTO}a8ayHT zy@~*jMLRmDt_!A@`6M8V`=LfJ?%o#lEi<5D#!#Ni<}PYS1koxWz(8W}D$te69-N7KpgDNdIdDD$-HCqGo}>3~M2jt`91 zT7DX5=H9Y=KqmTQ0S>J25`l^iTneINb?4EzE}INV8^B1nzo@ArN<0g9I33VLvK1w|COH&~KV0?dzxY7k zcmRf;PS<*z37j(ZxbH^WzeM=>8B&o?Zr;BFh!&m`xGo*su;SD#b;9&mVF1?)?6nKc zF??e(osasd%QFkZy>h?QZXi3P3CVciFC*s`d7&|%nL_PL{Bh}kOg}~~ zDeGs=63UBJ2CC%B)(p-)$yhCnAvb2`_b>{74%a+M7}h5h3kqctdE=Ed-#g2jJaBYX z-hjm9Fdxm;;}16D(OIj6iJHRl&aMHDFi^YxN~Mtpjk&njgJYu5on!I2jWXPX#A;D@ zC-0NbEc$0_5{C=LK{rqb;aZZgRFDV+z|{@bbC98J1v=MPD=Ul4Y1Vz0=*SrKz)uPc zaaReIS2q~Bu()1bxWSLLUt5ZWI9en3Ho|8FM+% z{!N9~Rv_mvq%L=jtFEP*3bHu*vl}fdD$@aB;KRUZzHoA(ypGvqU;f(7ZW`S9R-^jl z0VRW^ay=fG554|5vQ=+*JBPLJQEbh_L;z#J0#!AF{ovbJf{Tk%aak_1QZY_Jk7E~Y zNopByX()4^E^Vu`vWpq&^SEdub1u;pUmTPxomVot3)z+Qk2yWP!oEMO$F0;jz5o6$ z!~=EcL8%xDKf-Wwi&DRE!%%Yo8dQab^LquIxdycB35~!kU2%Y<0gEd4ZXaklK(CK9 zO26k~6yc!d-f!qnJpFjmwB<8%NlxJeQN|0`6tONZpKqC@VP6;?x3*q1(ew)!OF``2 z=xW$9@{No{U@dW`M692?aL>HjG>~a)hV_pz;T3vqhu6HCa6}(Q_Yu6DE{07RsYiZd z3rLS+?<%F+Q^_bCwkD$KQpI+*uz8xm2yTQiLU)p0NY%%JDf0ggCrOoR=_GQ}Io7$Tpyxs)<`7 zB1lIxfp7ga-KL#=PF;G|*Ud|SM3}47PZWsmx7mW*9bQ}`BFQj|3zG9v;xIY~FYQJN zZBu*7rh@U+F0>ckoO!=kaXwUPe$385__~v$@PO`DJJVCOU~Ejf)aPk_WC#GJyBPo@YT#Hw{OxHD6iwaAED8; zzDDQLfStx!`(I{^vaaAJ!q`{3V z6Hz!~a4MRTKT9{JMYm5&EvO1hrq6aR!rKMYU9h;1J}IFYoEtMRaU0XPp8LILp)LPd zKZ+c1cPi^S2FRmwtDm12u1xkoJ$rXKma7rPFJL#7=#-?qctU6;v>GW@Do+b)?#Y1; z6I*&b7ll3vcg=N(tGN4Z=f#!c9_!n-Q^6eps7ht0=PHHhF`+%88A{yugY`-2;i1_T z2240b<2rO&OeLLMGo% z9u1>CxbpEOIeCD>xR#1TZ zLN+>Gfu_6M#IrSj0iz?a4Tl;gI{bE{*5|6s+$LfZBlM7cY7%=Q5`XnUuL{RMtvBZ3A6rDaU(Pfo4ylcy<{P;z|nRx-Mk-fmf8$xPW?G3HL1TiGywqt z>AjaE^aSa>_mTjiDM+sZp(K>wj^{h)^*!hO&b{}%-+i7u`GciN_TF=?HP)PCjClmp zD*L->6oGj0$7|~~fmPsWNcIlA5sav>EAvB(dfk?0&KWuqL~e609OY-iqf?R-6*--% z&G%9vX{4;WS$(^?8k@PBvBwOpISOgr5O5J1F*2Hmq=WZ5qCGcXw?*U@U?CE&B5?Or zD%li|`?^~#v&*Ei9hAw^a%XLn?k8M&pNurdlw)N_v=ks@QWM zUX~bfS6t6~BS;nOymhZh+GAab%GG?E(^j=N#x{Q|D)7$6qmzV1wb`_nLB=!nHlr_E zTE6DzF0BFpk`k{KP6;h?1Q}FXUCZSRo_wP%oUp1@P?OK9HQ=1tyL$h6ML@|{<9J2O z;g)4NnTJTG#p|6$6I#xz(C0Y{>YY)5&b1f0`QY@}TX@nKm`ZHp#Yc-Sd4BWS6B)_A z>$qA^&Y+kC9UY+b#g@$b^WzS@iaLK(Yp96tnk&pF%F;-aLs1lG2z{dw@$t51a8!G? zVA+}gE`#`iNB`W2bQdQ;8DDwR_{ep^18UTf)JAVtdbLX0B#LPWdEX#d=N8}nX*Nd9 zA(fCiP08l4uLM(p!ss`wqwtr_yc~jZL}gH>q0}tl@B|0J`C4!8kb>}1o#a^y!5F(# z{q!wXS@8{7W-V>6S5JQ^M(9cZppJ0pVLnCUqx|~!0@x6`Z_RL?Zu?J5+x@0Qie23^%s@sfV3H2+1X z`zoctm-#8>ZuJ7LQb0-Xy->nx_hF0QdDcn}#Z~alQoAj};|QfVTwpB{v+oL|mF(=X z(Xw9UQ(Q&TpT8J&AIn}1K={4>&V1E^NN)9!po&GsX-6mATZ5_c{!L=P-HUhfF1mYt zIo`^N)M3>-Eok0BScxb*Rnp&I28smS#~Y6b?0-PC{AxCm)=J~REy2F~67!O++nd6Z zlnN_WNDJl9No0q6_c-8B4wtA`YVU^>K%&HqwE7g>>OAzv(XVw2O)FWlJ`U8b?l6ZX z2FB(Fwe%Wi<&=FjNpqB~o2o9wiklmL!^>OI;#hM!Q;@sT zPx!!VXoiVs8^GN7i972+p`_+1KvIQ6RRK5ZU`pigJvMxNI)U6R|Ka%rvjbr6u1 zs?*yh4wk?9Y$w)s5z(!mwg`s}riTKz^pxc-MBuf6(D4EbXQ*ht?2K$HEO2f(j)asUH4 zow)!dl!Np?lMnRX040;iZ+{ZNWHVbl%J0aCSRQ_G%t3`A($t?Q^cy!(yrvg;img!omj-ejI1R4Kjo zOpSh+>nfmn`Jqn5IIQKiOL2wiRTsz6u7RRo51@Ks=$w3MZ=xw#<#pr}8-sP4s1zLk9ey2ilyq8A>VEk;zuNm38R89nH9 zdf*u{MkiLdZ?1+B?~4J73i7BVN%m1ifc@ft?y>Q-?&}Yh($J2QUH)=y85HwsLP(3x zPxbR0xu`#Nk`f~F19PqB8`afWnTNUdvTUrHnCq_Lz%d#WlXh(0(@L>Inlz-?GEo4L zSa|;9hT5Y%9rj4CNfq^%fZYFKbW!TJ^dO{e!D!?o-4-Hy@8FKvOzwlg<{aH5J#bf( zW9#Ykoa4M%^a+Py2}wN@xZ8erSSEg3b29>dKmJ-T~A! z*(*Y_jlR=?O|traUzb?h#z}W(c}-w<8Z(tfWSvOj>aN4mDm`oH54rP?a%1pjBE$}n zE_}H$as?IHOPmwTLe4iXZ}uKdJ8JHEh`&s*nk*l7a@Cq{zQDkZ#KGQ{*S{S3o&>l; zl^9<|CP8ko?js!@m4cq{(YHZpKdU)BG(H+vJ?svwI$$%j1N1RkTpP)&Rg8W6pX{1PEqFVqRiP^+X>BR5pbK3VoVZ?hu@zjWn@vKEYWpesPp>q}a>LW1LY z{}-)G*3xm&_jO*CqJlrxJi7R*n2bDp2&5{#@gh>Dl{swn_?+UOv=3q4hfo)vKX*OU z1hj9KXMc6iYo^kyc7}`RNRbOY2Mh^XbxWM@3Vr;+5`N9rAm}j>Q~FE^ z&!FN7kZRlP8~>}i(tTGuANVoI(ci@2@l+a~L7&)|Ol4I0Srf=r7w;2_Yz}MwkPid`S zNETy-+Vwo%0|!7!?jc;y9eHrPRIkze`N!O(piM3SB2~|Ke+iQ{dM(h2?|)?Q6)27- z1S7X@oXG)`_6|Xm-z3pSW!9|-opm8*O%1EurHYAde_}EF)5%^ei3FoM-0$W%X>0DeKVteW3e zx@-D&rbGIwpERWnoXe26CZyHz(CXFBif3dmJMSxE@9P% z@b^j=q<$|G{z)qG{wxcjP$6Q8o>t5=3D+yXsQ8n2KX(U}Gc8m_F|EDW2Prsc z&PJDy0)=901U>iPm;ieW00;$Y{+0o{qDT;d0QlIE2?~P$y}8j}FfD4Qb6EoHdr!S;#RsBYW;|m}`jTGp^75XW zLTDc|mY_Lx%&rjKEl#D*14!6S0mjPu2g>0QX0~Gr@am8UkDP+r!`_Ge?YDhWBJBO_ zOn_ZJRg?1{pdGkG9>NV_NqtI92K1i~V!15!J7s)}4H(pG4fO?TzBj-4+?RywR>#;> zEwfZ%(b~ic#r~R>1DDS?|L&+iRs>)P?7*(+e@;jMO!;9e1K97o_%y*vKe7BR2k`qc zuTqvcV^>fX@1z3B>G&G28^T`~QGWVem7(wbx4Lwc$Y;%J2}tOZ-);Nf9|M9K%&}nt z+1to}_?G;Q$q&5yoF(9$|M83xK1-#CD78Sb!G*uc0fu#}9z5r@fqovI|Mcjd5JVuj z!^36PnW-s)nf8BF69du$I~AV$zu#&p!h-eDyx}eot4Y7If2`G&wHP1?>@=%DxWX57 ze?C(2kOOz0J|Scc#zBGoWb@}l<0KHW3GOF7d~P2RCJCIMXnv39L_$1A34{UNPrh-T z1?;LZakY$Nk}#B+5$T_hQyU{eO0$kZ;5r%XI~f1oZ{fd`QM`Y~GN54yUmp;C2z(hL zJM_=W9iD?-v%pTH>p^xu2Ly(6>{E}Cs?1n%4w z*#^22kjMok5+u-BwMz5%f9K=#mLLj&=jRV9i4z(h{jD*}KRw9*55{4|Kv;N&bQGnq zxdW!zMz>!6dQ3F`@|gbSVukB;ad823=6_L%Lg3tY+Sn9L0|f<@D+%+Wz0G23;g&k10rA>``+35C-3658-HJhbgHYXu~i^|Nc!I!IZ<4-lgUFV zG6Vtbi~i;D6Ldse|Ba3acUc43!;BFnS_LdaGk%%tp82a{jtnmjBj`fLgtN?%+1aH>q`R&rkQRVFXB?D$FS5j4XEcHj#w<7`@dZo zph`Oa@xKry)W39iZv-nefV8ZeWFG3`m4Ek@z#2`_EBzPsGd>YO1EEU@+8cz9TK^J~ z1QRnr@hNd=+#R$0U#&=g#6}XOW|d=poiQL7bMs7N_XL7gDi761{C|6jg?)GaitfSp zs@;9Gn`$1a_*Xxh-hkRsyUapJW?U zV02f~L396R1Ns%~7}uSJW!8F+L;Jrj0gaE3$HgQi-2uQUK*Am^)RhyQa-^PeTZLbv zrhYsSxTN7tX^HnI4gGz6d)ff~`|`Co`oD>ya8oWb+3}A}$rF^JWdD9y`QLz2?{{|{ zJ!1(H+W#PY)z;F=p9>~valyb*=wG7v|26#hTi2}{M8B!?02ChnYs~`i-Cv{p09;LK z3W484$)_QWlCXby9lITi<|-x=_OHJNaW#=v@pZ<8HeP^?5-1KhnY`8e9q^m{0`UF) zO6{osy;z8M=5GNHE7D#3-G}a5GXW5r+5bNzH~zCK)~A|q*X6FP|BgU_=)Rah;I2!D zTwl&De)rSxuTQP+Snkn^Uq%9W3m}62FY@YOfFSbUqoun8tN<$VoNavZ2T%e)$IWYm z1GFEY+wYbV%hdkU7>^+EKNeCX9*5E!!sAUY8~y2|$N~&bXN4LO*uhU{fIGF-QuxkJE~pXY4PtDhM0^_^9|_1|I)FnQ`%iNDB)ir_%te z)$~T$UJ_cP{dp@9CqUwGMc7#-z>e`O>jkOb59d6D_Q?Tp7q0+H@iXVIy?=kzvRW9E z2SH`#R2e|z21ApfL-qou)Nt$UUjT^%J)I;#W_#Vz z@#H21NK3^b;1FG_OFMukotWWwuS6ju1)VH9?LkSb>MYgb1Y8go z92(w}&2_RL`vovj930@4q4n&zIivSW+iucJ>zVb~q-Ow_HUElGek;BL*^VakV$hAiB4*PdvDo8C=aN zW!U;Jr;VQ10QDcs^cL;m;bEnxBG4D$#XQC~?v&Fqn3$5S})7zR9++x*li)ZG2@-;u$y^M8ADJVyOQ313|Wna;F67zM< zlV^;7(ZYZlCje{U^U~Q+Ig=faQ#w@Ad8? z!HwGVO);Rj`<0O-yz6@d&N9y4^+a|jclE6ZNZD#_uv((Zlgg4g--$SvSC&-&Jtv@- z$3B?_BzP7@MOgwT;RpXCm_K~mU8fmb?*Yojc2$PfyWP61^vWjH#6^RZ2JQu(;r>40 zuqS*B+B{EFLHdL1l)5|a@q>+qD12>ERts{2i-`(0|9X;&BiurI=+i_&NIoD^0>s}0 zFF_Cy5;-;8{o(W|@q^aYy#P)2pwHFb_#_KWMeBw9PWy(Opb7AqpEsVI-VaN3^m zHZ+#t&5hhkl`fcLeUjk=N4BCo98&-Ano7t z?0f}4epwhiuW~O4A?)Lsck>mDCLi6;?Nc;gzu9~X>pcpnsdBp@;#onX^^zy=pB>K( z27+Z1oEv2*@*dL);aP%3(oVPQDGY8FtLFD>_d_mKsbWn*CC&}{Y4@6c2@p1G_gCaM zs-TPA4!BE&cY)?d7gzoiuHSrtaK(MgqTT%hBxM{8c?b#BzrWr;BZTWf?wNDI-2mdDFQM{!0~Hj z9FtdcnIyDSuA+SH9#CvieJhe*Vs<%qfF|;eAfLEyHsBD^g;&Mgc2<=$7DuSj6tpKo ze+))MjU3Dm?g7eu^6H3V**dR?0>L8Cgml7{?|#bNvt~yz6Vd`}7VF>B;ef-*qLGX_ zHy-ijc~8zPXVO(2>G$ao*P0xtQux9yJdw!7YnPH=2{+Mh3Qq_wr6G1*tD23AOOJc9 z-V!MAP8LSVWxA)Z+`;pxmPgg z1QpD7kB6*C$Z&Ey-Fm$5*e+Y=;<%EoVt(%FdqbAK;_;Q_*zNccmBv)6XxAfG%B&x6 zUm3XUji-ecByYAejmVJ(e=4)ww5VQVO{GF5)&rIe`3tYwbzcq6g-0m3{iL|$6dy2! z8tmKOBN7i6J-K4DAw;YwME0#;UPHR>&H!pULollU^5Lh?Lp{fxrr~x$vZ*nSKtV|lD`u=ydA zYmIiQDo~!WJ`}>ayq~YPJRei$E!By5kUABUEwN)euD8(~nZtFuVGf0+eIBC{CC+^K zakwp+rhBgIPM3}_n|-nq-v%i0N5W@srS!GizxMAJm;d7a-Jn|nqIZRS-R6yX=02}s zN=$NFJfKZy+m^Woz#S#ZE+UtUYnAlKe%Tj_!Z+*Y*6Wpz`yjicDpXXwCuxsIgi-Cc zy;Z^;(6p@t2Y_v(Qt4d;$9E1)*7m(J>6>o}#`b2Trb^15)53Tbj`ns@3Mp=mD#-^TEq^l>!CmBDKZ) zvzjiZBK|B{Q98sxeb&I7edK$b^iU+&h8dQ*fmK9>A zM~R5X=?mww;PKt?9dTzpZOai-hXIUIN-SB9+gih*w*boMv85YEoS|YVdjgg^sCPrG zynnQy_ri!WdztOgrabFi%hV!e-JY|+vqXVj!<|)hPI3X=VUZdCfHh| z2v>#=eBA7^iFQuV!JBs;#fEVdi2_zg9kT@;#F@2Q0L z*iKSQ(6=~XfKBiE2 zX>GXJ8gEp{(+?a{ko*i1thZ0_1+HR+nD;j~ zBPS>XyiX~#PE$3Ea}T%VV9diFY1z$hn=OyhFI0R$;K0QLHRxqa^D#p`_wuIt6Fq}t zF8vgCoEvqeX1$cID4O&QcjBS@jySebh~ubMPq#YN)AYwOFT;(ZqC;Y@SwWzV1Y(C(>a5ij89 zNzmwE=mPPLAE#Rk_xUA4?omBGbM`#tuQ!sqGmV&U{UsVNUKXR-A3u}$+n)(zH7rky z(Uy-Ty(yojFdGOh|!F9TLRX629th5lzl*yKzC91HMM!LZ01HprOwKtrQEmc z-MR~WU^}Q5zbU>SYIVk;*NTo5kqKM2)tOwp?>oxwDTUy_A{)W*7ggKI65wYlWZM>L z0{mifUGmIJoGiOA^$3wv`&!Z%`aAn6{G{lW&h8nHj!WVdA#vSwIfmPphKb2ak-}SV zR9!2hTsz0C)h|u$qBy9@W3v9a2mHF%BH>9V|A5XGf|rk7OFbv zHeGJn(=S^ zZPc4L%nKZ+`yN&6;kHkM{>NjFwyneTTlz`8*HQ!cSg8TQmT7ii#H>HO`@ggB*X! zAAm3&Qgb5;NMsn|n2vilmE#xA-NNY!?f--%%!Oo#S_p06IJ zwVPkSRE9&AYEs4*a}t6PzAx&(`FS~2i!Wj;87h|qY5CUQn*A`LA60Hx*I)nE=$o9< zn<6%0K0(HY#$1K{K2!66nd+kmBMy`6nF_S!+dnom+gdbhG-zjnnpm6KFJ5MZ85r)d(=b zOe8aDH{d)*gUsFM$+Qzzf`nsq7of>5*ZN2=e=Qd}(pk1!qd}M8!f_VNZ37k`&9y2Q zrdhQ-IR(?F;4D`(tB_SH2CEFI4*@A$>v64_aX+Vn#5J<%H}OTgJsNX3b=C2%t~0ZSqN0x<&ms>xP>S40&;^yvYhCU0>(b zxC@DYIyt;>?i}2Z?kYmTcjj`+t$B-L5ab@B%XEgFrOj~&P@XxwZNL__PBQS5ls#i7 z<9@dQrXCUN^^=lm70&8IT6dmy;O;)pjq=i+TRg3EWGNlW1DRSIes~XVofH*Ru#>n$5QH#d}+2ux3D$&_axacIWJeG`pZA;fKeE| zU9pUg8W}T`O?5{8MH#8)GB+5g8FkmSY+9m334vyxKFM_Tgct558%k~~RG(_nCh{&h zRJ7E1FT2~1x2^2kdG>Eu>fPgSxmC5~t~NMS1mAb}><`!3t<6QaDlWNi=GdN^9PTpk z_PW72C(4`DV95^?>)kg4hd)8O&nXt`E$$*-&+K67tN6NBjqaT8HkY`AZ!6?^&BfZr zT^g~5@0-I5p^a){5Z@$Pol$9tF9W?b0W8{t1wvw1O4O}hVWwuzqxhx7*R<%h+lj#| zRZD?HyF!Ka8cP`t>Cp@KyaR`3gm&F+Mb&DHOn>6U+tVcDJ*BlQj|g@{P*Q@z|Hp1+@qw{fusKI`1b=VTBKD!ae99q#jD z>EzvdrIMcE1<8B9h`pb*ceM80oTOVifJLJW?bn9(6mAw4g&LbKyEdLPV5~^a=~}GG zZ-yV!2CNuJCZ@}osUxnlC{HYB4Jz`3@n7w!6_afx-&89YYmuqY@hn8go#lfg3!+~* zExXUR#6|P1Te5%y_bP!qM)n?)J{CiqY)I6hAropa@qznIWqz0TF`_4DJ2^ir7jnUt z8;9tnjTvMf_5-^oSiDciyU<)d-er*po-;6H7uQJe;(XNhGFP3jo@08La zlTN>QDY%+0dv-EphCMuLkIH~Rr;jJAi zR7%m)QOdlF=<=@oi?s-0y9$Sm@`8pJ)0)YP5@NE#iL%iVkVZN;SU^{7?N4`VHcuw2 z6v=Q>>rob<0X-^`|1vB!`}x^C#DZm=OPrlj0p8QLa!zr=O@-LPMFyRfd_(WuCM zsI&|;Be#qg~$RjJ0*QdmJR8;6N@MZN)CC8a9w` zGs>1K%!;eive3KjIM`r0I&2$usTC};e^l102GjeAW`M~gD++v{Jr@;tx_&qmRledD zzOw;1wGeMq8e(Oe!M*Vdd-kMSkK!x2il*rxJ>Mk!ra3VE z%4eYg3Xc;jZjfPtnR*3{@f;il+$ScMTLy<#zNxP1qJ_&7tQ1lfagRk82X|l&Q5P)P z6;M`Cw!(aUm|S&cfb4X{4XyP7?_JmY`qAYKgKe*7RuP8tgJ~yS^`RAePND```8DD# zqTw?roP&K=a-4~WP|{AndS`o3hCygO zP2h+ghSJxB73HKFeW0T)@3a}7I#0#wr!bS$&Q)B1GKnh++7$GNRA1*_^AV#cPgnuY zV${dN2h%rBDbHLHLyCVuh$!%nyQ&uWHiNQT(dOjK@ zZlp`R><5YSmet9gGClgS7q7X*7o8jZW_?PfB(%5@9sqheWkF=r`9Y9<#$BgN-f38~ z5mQO+^-#C}KtWBPqtqLm{lt5SN2o!K9=#G)65~mR#;8+E6~Uv4MdDS?n9yj7 zf!I&X<8;o=cE&IlO#rIL3HX-QNBTb;Sl*#H z3Mlv~&|XZdr#lI%$wQZd;#1|=kE}m@3c3!*d|eAAHvX2kI7^SL|9}9ymK(NT-`R;a z_rJiul}lrZC@9qJ<+WkmTgwaAhl8Hz9?ims`urBbacn*O@WMnh4xFei_T)MHyZp2A zg0aD+O!4?J{~?ctlANxey-r@M{*P@UBT*O7o|rpsF>jDdlshS4I*;Re2y$=P@-1ZN zY*dFdz7Un;0z2TckIfRaF>qb@fepjls4}qqfPkJJesK-;?ydTCksEZZfch$&U@Uyx!NjjL1B zigv+6_))Gig%3C*iFQu19MZneos7y076~e3;^?Z<1%Pvjd`*jo-LqJZ9UU9%l;NM( z;V^BaK|DfacmKlx#VOyWOF6a<%J8Wq97T}i<4daJY!_(W3E6osE@T{@H^Gej5v`fRX-Vu#p zcdo>Je14~I_Wde9gcAFcl^tf*B8?uSeSXb}JY5Ra&K;{ojP|xfc?tuZLR=lgAUK)7 zvUI07w`6-tMxmiFyIc^(5XEUJ;ohj$p`)H@XQ1GVpp8KlyOxQcE}pNwip?}zj$Lqd z48-!!Mzo{&G^>BER=|sHY&tL4!sN`b#_#}4`6yLH?59Ib=oyNt4em%2HlH@|9*4F+vssyl=@w?oJa_+1Fs9&lTx7jKDyZyrXH87=hs!?+V$O5x;o5!r`#?Y?elgo5f6&oC zQ%x;&`R@sjr)S>#T&9GP9h`SJdv_k7x!-cU@Q<+uRbV+5+7&g>xK1DNI-@7#W$CljwKao#>w2_I1PgKDvd~3}}5y&8vNeK>wi?5zT6h+7L?F zbTO)6@!s^^@|6wbg;bdfmIN#Uv9+%AIzHukl#UvCmm6qpi{3Zuv_U=jP5M3%B zH18ggme_J%R0ebML-G|rq*X5}+k7+iWv0MX207fk8070Hw2n`>Ymbc!Q8;5aZn>YB z+IbLt?Vc@qJ5ALPgdCaM6VQY*Hneh2aaAT?OehF51*hXaO@dU^5ff?+T#-X$a@ku` z?J%|$y+X~~7TM1#wyiCV7Z*?}$hYy=;_Xbw+vYQh=s4vYkU1g8>RVt&FgvKK(kxEP z8?8-mm*FTrUnN|Npn)9^SE?8n(2P1SOKfX(S`7)Wl=nJJ$3`!>-eW1hUA6R1IQgCR z&{Ov%ORwB0Z)>7>R)0Mf6ZgT(6&+zsmAw1Rm@(`p?cSpV3ijt5>A-B4&7lgE7MmQ^ zhwDBZuPkW$)vg3s+F$v z$Cw@^u-y4;rBRUFrBwPBCQ?w(r2#macyDikYgP}8-3fs=->}JmvhbT9`Z|1f8QUGW zZ(gu+PZJ8+soNTdXdl~5x_-`Y!s$=yFX!0KL^bWpr*(6{DTJE+mJ5*>oRTN8B|itU z(a!|ma)5Kpjmk-fWEM77bp#{adL~J4$c;X>eT-5i_D?C*Sg#^MTgW)Ck6AQLW-@P{ za>am%Q?H@~;h;Pqb$9;afL6y#j(P zLN!qeFDi3M)q&>h#lp-_xoi6ylqB$t{#mtEYMIQc=;uK^1s zEi=somFVKSriOMh0<&IEYy^=z?U^G`t=^To+hKKTnE0R7m1fdL$A|Kuba!v8d85Oq z+%o0@dLF~z?oVpJfLa>D?L;L+&^WJEeN;9o%&)38n!l5e(KVopoxt8*c1GLIfgosK z!h*Hp`%rOy060W&C{)p1MHjuJuovD9y+vLauD@=xBMxV{QX=k}p%`l$nh^#+BV^U4omXMF5K~vzEI09HJu_hOJ>qgB<|P&Vy?-3%?o#pq0P$?1 zG6hATK0J^$u#oW|VHmaw9Kz)P&nibo4ie|m8yE#=KS|( zpZ&e-UdhTA%ikcQMvA}r=m{PJOMSgv@2ZXLJ=MW5IK=a90BZYsaS}3ar&Iq!HvG-T z=kT%IeM|9gV_&0}oNcu3?c|VG6c#b&y;0WzPE1_|!uhObH*=5QYQ$M&-a;SlNzl@R zahTdZjfDNWH#MY>PADVuH}$Rk^ZA~f=0~vH7uEsaOw{ZSQ$H+S>aWl|+oQ>tJYPo7 z3#m=v(p9V#M=v8VAdN=w`t!lkB88_1XP4bup9dYS?62pn%yhY&-1jU>x_SL($Xd68Esg72SCXa|;nyxKTd^gw zfG?f?%%WMavi;!CueHms4XM_?B5Y89RD=4Fvd5cP=Q--}^xNBIdmJaCpwu!IGJ#F- zR*1!(dW{QnLXBmXoqj%nUNwcSn(@!s@8FWt)zzf*eEIX>{n*}_+QlT3z)1cFH9!h0 z%ii=YRt)SEL%(o*uS`p1acrOssMU0A3o?`nn13xl9*p(dKw?A$iz3(MPAm%`3|8t< z)5xWnoJ+g4XmQW*^+P#T<|^I(yqz_&`3b?77ADS%lmHVV^#Sl2L$?ZEp zo70_B`PHD&Uq(H4%heB2s{pp1VYa-{*|b;y8m%P3#uRHfZqWphIoqW<;cKT zJKaR!K_2SnHF(55gKDfsF74A#6-EDGSGX|MlVgodFZ*H*Hm@ZXx-FlHYRpX-^_w#u z{B&DNa5L8SJV~|wIWHhp5ynz~SE4?wu*dih2uZnB0l-V|{?t@A0A4DUNkje^o4f|B zw>bj)l4ssyF8N(7FjTiFSjX0Qc>pO6@S#=rBt>?{8z>ev3$|8>ec|dU{}LMUc=8jA zb=LfQRxl)g!)kI^bFa;p1%}JVzN}ZNb4|S`-K`*q;*|_ zJ2r4Q>)qk#!ZZ}tOq*C_Ws6=sO)B~_qh9_BeY!|9et?}okJ{v#2t#0>A4Y*A{D2jC=JMP-&bEw%fjwOw-hHPh7_RFr`JYI1)zO>t697U?I ztkJw0Ih9jgelnOJ88a-;CWq|ogIo4KktnMR(A^hguuF2JvyT#xuAi^g*MmWoVv#0!pkO>0Q`^!pB`N4e8hOiJ-_g&ONFbZu7Z3s#O)Y%ovwG%iZ^CP zME&P((!v7!Om%{C0vGK8*!sguX}S8y1h9fenV4{4=zm^bee1tmf3bVyH59+1 zp;jRfW*ur&b!+AXjEwK{B;@h(Ck5L?DNeZ8N?UUZG6SS;BbF`N%Ee5uBJhhMr^_pL zHgeP(ugc9Dv^;mA1xB1W{?UAsBtlBl(xu6|d-`36+TQB?L96h)`5Afyk=#^YVd0mX zZaqVzn~&3Lezv~HmH?F4`w!HkQ!MF>f_aDPxtB;vBd0W_2} zNHAQOL#r5lY0>kEx|{B9asEv@dbQD_SEF_@7e}Jh@1j@og;LmrE{eP@rep~TAL-^=WSgQ3W}?ih(VGw#N|r8cn0=fH#(d3 ziqr7}ly)hqhIoVLtd{Ph#0tUwN~xZ}hlQnH&R7>1w(OKGu?OE%IIDo>#fj(izk+AM z_BrDmD-mM+k7aiG^=6=a2l+)eCT{c!6a{I+j&b2$9T~6so1aU4h4*YSR4w7B+*EJr zN@N*m)WJD8BZshZu;cjN9Z90zheI8H;S+b96?;YnSN)E+`Xe*W_@KPlIA#?RJkVb~cX$?e-S5ME#F3pBq5& z*UjMi(m5iM7V0>FG+bu6_3c|Ak;QFTGX4j%ia{N+jwK|(5U;Z*^|@JG=3KIz9uRJI zn2D=!{#{__+=ii{caHd-OhnHWso9RpYvhS5HYg2#pEE1-) zv<;~iQ0E6AU?2@TNHnMEyd$3vqWip0Baxkph7_(^#}=xu>4 zX?zIl{c2qbb1NcY+B3sjIRPc*lGy>10$ztXq&uM@uD8i<74bw{YR5eV0p(V5=-0gO z_sEtC@w3bi`DtEJt6NX1Y?Y91hauQx7Mz6!@^cElbCVfcAD(!!Yob?UDMXI*IJgm# z&it@^e`@1QGFl4=h`5xaXIwxPE}+ireeL=d%4ds7^_5Vj`EBTsSqy2~ zcnIi{u6ff0t;MS6PfcnIYvWCOG_CR#vbg0i)M=85`kfJFAiF6GqrDq`Wnx};Ojz;j#lD%!Z5*_s_OSBq;pv=I6;gqUt{fFT zqS51@tmr;}h&ld2wBu$Mr>^^mnVElWdPSf3z)_}>bjm}ET{`>)7 zY%>Y&i2QOvJl?{oyW=jB4u-l5&?Gv?-M9kPzM)Rw$Gfi7uv4%b1eY7vj~Z|fL<)Kx zhr!&uGf2ORGYG!>x@|iLXUkX_2Ga2GVg58>TMP+ws$GrJ_Kl=x)fhu53E7FZ2-C@+ z1ONH25^Sn6I>H-LWMIn+a~-MBcdTXyAl+RdC{2`6E$bM=z(Db`{Z83+%Vl%P#fV0G zPcpCtPUQ_zbtkYeuRDXB-a*dgg`93{Kh&*wFmB#=A|5Md;xFga+;l6a3ZFvZ@r1a= z-0Z8vK#`u~-o_&a<<8V6J)&VJY=?@h$6zp>VZ{-q*W5Tv$zX;yE3W1rDXwrF~Q|1(p`C|KWHL^35JxK#6#fdMR^*8ipNwGpPQ@ zn8pPXbX8YxFHlc@??;3nLl^R^ACy-mfnW;dX5ZwXi2%xf+0%^V9FWZpe*#gkV#s3r z3R|F)|F~ylsS2E2@>|?KIpPi)!=Y{I4@(M@ZXhSLXx|LS`&-tkBazjI)OqozwMZ2Mu!=#-GSf)>O32@yw20K-| z=`6hm^J+jPk-|%FSmpB|bafs%`Jk_B-FZI)Q!FdWdPebu#L#egBda-d^qY2(( zMr_AkMgsoCapl5kAUvwbf}Cu|Tpa>`llPr|;&pRcWikaN{86s@Qv~g|uKMFwvZGwn z4!WwH{XL-|2ZYpHXNJ9YFg^=q$*&AeSAy%0XRSU1+1bf8)?WpR=_fe;1zOsn0cTLi z9*Z)jPmO+B-&4BUtJbxwP9|}2u5zIgE2Ym5s>dF}`-4_i!aQNh$sl?(WsdHkhHvIx z>42YsocuRF$H7H~)NVd~46|by3fU}!tD(1BztW8ne|fG2D&f|KI~?+Xi$nOo$6CJtKp0K#>yu-f@?&R%Os~?dKp#6lB%|=~Z z^jB9yU)Fk7azkGF4Ygt@xW{8fBUnR21|^%go>SEbMd_8IHr(uA1bKu_(vGt#I=w1Dg7!u~Pp8Htd|7S(gXjcb*bw?Fij1=GHSVX+` zox&OT3@8_ZD+DE)0Vraiel+4UOHKygIE)`0z2iAGJo>F;(QjH+qNN1a{IG2=b>a1a zW$i;3>*R@{p2|LVGdsO=bBT4XG64UqW^Gzacb(7v3Qnhozo-Hyjw)|Y@3SE@D12<- zR{f~9>|RECI@mMS+oTRXV*zyZC&Py37GJ zm;%m0OSc5M(^>D_)QUQuK0USgR{5^7&Nc-5I0>eLyR`EdF2N3zYsND+kJlBRXhIg5 zVwqIe-J=ihe$)+>u&>AJJYsYftH>sm$W2%@UNWo?Tt*Ijg9mtHeKo+}#k!h#WSzoX)|hFU(Y`hUnJ*W14%JTQ&gf6kQD26P1pEi49g9i>`oSa z={x!YiMd}V^cUxZjlLaj*gep-ZPM?tc()p3fh=ophB#`CPFSccUKgaHA#V! zRiOGgiKph2Y+}`~LaQ^+*4Xc0ztJ#j%g+xY(eKJF-k9Yf+HOGS-_y!-@~V?M!K119 zzr-7TD1N5N_YyhiS4r)8TqD*OJhZN2(iAG3OS>>qR2>EguEkmHfd(l2JsJi?*=W%O z{j$QTIGObjEdQeLMb&hWH+^}et#wLZ#N2pdJB_h)+uL}WJk;l!fPAO*g^d3Bq0nwv zQCh#n;9!rjhU(c8b9hx6$_u-gQTnDD%fCzOthnbf@KisDG+EnVwp^ZFKi6QrqpKXT z@=}Zr7X7JPppd7?7TUXG5y&4%0P^2=YS)Kkcbv9y27YxKioxa?`y&ndbBexAAHLBF zqxCbr1{(F)y1V7`wnfY*4;$hPRKyg0tAIm!T-x+~Jm2W3Fblj2YVe%QVx|AXiIVR) z&TVx;#ik&0H3`_=SYGyx#Ala(T5BM1|(ftGu|2V5{?@^vm8O!rd8Il&o}3eZ|jkr-QHm-0C4^ZiegnX2UJK z9ARgw_c~50>`xTz|0@J1v#-z3fu2ED9&6rq)NZTrK94@Ktjb4!)h!Rcdzpx2q{t^A zdQssvW3p21Gw`lNj-p8B*+W-VnU@->y-3&8l}kBJZc}F_ zXaA_a0*Vx%N-#B(p~Ia5#PhpHRxGg|_x1h;XIeSY5iX8rz+xALCzrsa&t2LwWJ z?#ljoKFtcVw$P#P2hdf~mc{A3uhc{**EM&3I+S`2S^r^b1Hcl5tX2r^W+enxa#5j326@d(dpQ;R;*!9nBKTE>0ub8W5 z8w4=#%&L$&C8&-pA)pjQmk<*cf|o;cSS~qnG9CzNZ4+}VbsH1r#GztEa`>!D0kD&q z7M8aF(4c(-MEG1_&PqZX>W}l>ZwfuXvcI~oq@XBiq<_Vb|GR*p!}sFg;HZg5vPA?x z(wAWZ@DbJ=L|B`f)>e9~K0g{+XkA?^0cP29*xTuFa7Q^uv21xCJ{wL3ED$%U7)<=q z1}X!QJ)v1IxsvVBCBraOQC+MOh1aRiVK^?3?DpeNI5?nsWqXRO?Mp8Lii!MrY?6N{ zdhOMzFU@gKrUr`ixM*x^eKP1Zexqew0C02Pvbh$G_ z?3jMxKWE3zATu&9)*hpoU90vknDHy~>wG$GfD6tMvhKC<@J1D2!j2FmCI;vq;z}T% zt^V~aa&7os>$Rh2vbaD)K5(?+VV-$;<%a2?fPpOJ1Z*Bs$Ri16KC`nP{ZrvnMN~*> zebIkhH$H=uuB(wb`asMXQJ?@+IizEgU0=eAnGg5k1h7b8GK-rlj~DUKTZRQwOoz{0 zqk(k~bWCXC(mqskd;k8mvx{(X9kh9$@oT$2_z@T34`)UwG0^bza8+?wVi5{xiaqsMyeDHU;vTgqoo z*xELspWuhwQ-6VcmMbEHxvnKEk;zi!m^SXPfE;XSWin+DX^x$IWVO`T6X@Y35KRn^=%50(4`#z{~hr)Yh(Hk=I@BC|(R z=MJB_(nF-t6Y?ocKpLIB$Y+(BXYk3FOol(zuN)7(Fo=50C|SUFHI1w%IIjJ(eOdam zyg6kBS`z*OaT%|Q;E=99Ue;VWROurd6V}i+g2tw`0&$yJlQz&nA<<%T&hBZ)D8N~{ zJ(#dAM}dLfu5Zs_@1PM1f2k(ptJ8i_p73^@-daS1270};v1({>KxGE&H`g1-(fjce zol83>At4bIn!oxi1zo=mIv^UpR`#=&vpIDL;MjN83tnbZRp(K6!&u%gmzh`rFEu`>dF-E27VQ4}H0-NEMJUw(%W70ZMlibsS}h=i#%5S-^^B z!{Vc_xQd*Eu!W38$)Zgc7`~VoHPEYZ(YiI#f^UFq!l9(6aTK z;7@hk%gd!(*{^XnJ-02ae^16OzKKRPziHZ{W*KPS@mnj(Et3a*^W}5>`E5N}esQFN zS3&-4R$!Q|9MFEoc&cr5XFKD>>D{m3R=aU*N4lt0PU;vd&j%oWqbDzxI0$ZhV<{!qC;0z7C z1UcMxcBayJ-FW%1C`vnQ3T$&PPFQ#?PCFxB->2f}SrG#;O=H%I?@DvXdhO{v8^iDBo6$s#1)K37_&AK!2IcN14Fr+CfcNP! zj!XyxBJUaZoNFo$187#Ws(;$1I_I7I#tSsVNO3cVV6~`Il=K;iVZ$1^vVu3;@86?J zA$ekpj3Gu147P4~ze;8_C4IfWnwt7B)9C@yx(pxLcft8mqozw$%sCA?=4C$eE$Q>E zege)~)Jowbjs5g&LE#?$5rC5(jF9Tw>L)P`2!Wpx3OSjmFRrR6lhHDX`9m~SOc*9O zFoUM3@zYLqftO_ZOdjT-!?pbmwa-;V1VSKIPXu|Gfo8^>FFA%l@PPE2SHZhDbxJyF3$x?hR!%WWFV6 zn;x5e*9j_WwVB&HqAJ_dzB4P29wkX^+2+cUU%QB)%=1 z>aJ|;XBWJ{hFRC3H{<80@4AI%su@!elOa3(RLu*YeJsq?LGiM_Z3DM&nzU$yVn<`}b@wpQGaOJMDkSn3nxuhKZ;N|X* z-+~?cuI{Rx(L&!UHb4)KLaTq9e)KF8{|wSPEIJx$2*ASvTtAAf0C?#%N{3gwt*Wr1 zyvD%jtL1W!XU!G#UWA%zv8k}|DF=XLGaG^GB~b)TWgZHh9CMc^su3IXji0gx^SKNP z7Z{y91z8#Bo{<+D{|HW&5$&d77j|99?ZiLVk|g!%EsS=CnL)kbcrfV`&j#X7m?5<@ zocgzV*czh(Qu>HQ9|-ePS{CQy;e{d;jO>#^<&&?Lgk}4F_|94(dbHy+<+S;rAQ-|q zVc^oaAXy*(?6rI(etDXT-?;1S-ppJc#gMRl#T?hAehy-^LLw*_gI-?Ma#De97);1s zYgsJa$h7;U^{RGFglPjP&iO?Ds_AfD4S(+%)8N)!<;cFlTJj&EdMN~CC45mC?mIht zCF~K0P~wb8)evyPyMivxGlJEs!c7;Pj-Hu;rk;%G-hR+eX2f*EpqX+q^tJ~!gbvrG zveEM4P5d)YKt6*3g2yW<)O57%yQM{0XctVHUU3T68DXQIB=e(v#X8(v^Uv^5rmapN%yFDQ_J$($lnk;`Ik%=1;DM| zwQU6b+~M;+`=thI-nyunt34Sdk^9zMB$lPBou-_v(NFeLV1?nGG%{fX`_T-b;o<38 zZN~PDQ~u1i_miK*OXJnA+lhJMR1VDHfV%kaLRnXUV3f@|Q6(%qEKJlo-uoXmEQ>t7 zk>7wR;88IbpbcNys}%?R;S!Q4&?l+4V(TJnuReBCL#C8LAGZru-Mdg(Bo?*K!;!mv zlg0}hw&HC6I-kPPxx*X?0gMKQ<$tDmPiSwpxlWM#{o|1MW&uiWvX?^j^v-K5fxVe* zqvG|764k6{ld`#b&D-otN^E?cKC?5LL0t+V?h-ZcIs;@vWQ1u*jt6Md1FPCzq;*GC z*v+)c{cw>$5bH9o+Vg|O=8E&c7orD!ZygO|KV0u0YM zZu`x7mR-pPF6N-vXr)3tu{ zOujYn(iuCZrzuiw^AfLI$0U{bD^$?~r8W(q z8R0>l&1>K+G@$l;}$->ERjU*9P{M#~y=-H*B-9D5~IN*nmKd5VN{r95?JHi`AGa~I?RZ$vzx?(fJahq; z3%S41*tQ)kED7f1X7yLd{pL_r1`Uzf#-=62sF@+J2A-k-G~`!eXT^B@^|L7&H($1As)Q6 zQTlS9L8DaM1|V*dkI~2znIy)XT|VlPXy!nOfrrbqz^}oH_|@2>P+<+ZRJpKi`<{yL z!jDQ!a!|tTBK)A>*Hdg4hROn#d&}vfwqT}^fn0Y+l+}I?XEi4Ju9vf<^0fU=%6nMSkH2NBo&dP$l_aG{2G-I;i{)=8lcYRuzQk0qf&Xx?^%Pu#-q!&D;E!gk{`shl`dBF z<>0~lDAN9El6}|nwD~$XD6|nI*>cg^8Jbs=d!n|CDF5Wtr>NWlRYXw{N$B*Yr-!#vOMi|STsEQnOU$YnV?RgYivVg*5Xqa zxprDs_iLiogjx8N>@@_M)4D0FNBFw4w-QrCned4y*UFxI>fbd*{oYwFHG8)?(4Sr% zKA&5gIWl)LF)n2FzI4X?sW?!~enyDpviA#adxC*T3frPtTqRsa)L&dZq)ZfAV#8$a^Qr5jrL_Djof-Qm0CAR zVA7%km{RsKmc-;#m*@S<>Ubq6^jTAA7GPTU)TF#QIY|WGhM+Gs2C4E$Up$ZeL6Xx3s$BDZ-j~&lO zzGQ95aO>pPO*)bO`IsSzJWa6=WovIqO>VxKDt=4i!N2PmYW;cr+I~n6srZy(5_Ta@JiRtcb2xRMW!HJIt<}4_C`(i~hrsOhz zpGqU{4+)$aNI@!M`G%}xv@;fyeF=|f%A%_vfxGt9#Nz~p!!?m?o2>5jnX4JkQNXn@ z^yRmyro5hcM}DHoxb1$MrP>FA_D>}}AU^4(Xr?^%024ZwR5D7$6;}j^TOasX7v;e> zGTD1_>?=Z}6O8oR3xWpTmeO?`HZf@4C3euq=TNXFxDY4HMdyyHf8HH% zlqkBk0MpoV#Bl0xaz_b8F_#=;;1PiBQz|Yd1F<;pAs{I4P}?jdRxKCq(U#iIhb~O^ z7Y8UwI&OWf+(9FF`Zq&o&(YLr9twaS51o9AUfe82h3F?z2m9;3bjqcc9ydkE%^`UdaLTf_+Cw}mDM+5mdlcFw_6 z>IUtu!F}Vj5{;*w!=^D$&;1U70aXeuS3<&k6@ftfFC-^$7L=15Lnd^}vwdlaqer>f zNkBZSiG`>I#%qZwP2?Uu!2PZUQj5yT7TI!;(53Xe%{qE!0wr{hqa7}}iohY4r06?( zNX!BmfLawq_p$4~y!BiqPoMXHp!lIB-~F7O@<_-c2g=}i|Nk3; z-c{rY(1ce`-N$M}B2Lg-Qr*(`z4aMFu>XTFcz_AU2p(W*LL(1t_(Owm^P?vF?-5rHz*Zu0q z--wh$yQ%>$sJYb)P7Y3ibL0NQ^D(Nx=y59;b;O3>CnGw{e?-n46l|#YI)075spAQfL3t$Vn)0Dz z2c_bNz;;f?Diaa6Rl2zJ^n<82u*T+T%Zbnb_ZlklRvT_^o5Oo|j=j&+u<6lbx0zEm1Y7Zb^uX9VL8t_d)&}7@;YkKd^&z1Lu)HgHJ%XtZ_GZdpj+2MM3h(gEtB5h`-BC955zH!= zm9(5tW&3;E>&cNYf=;3JZXJs+qNE@DTkb=#&h0zc_|d*>oWs98;kI=SP%F{KF+bG+ z;TDAro0k!U^m?U@}i4vQ6a!X-~1MPYXg8KdF?4vH_;rN~KLIcWvq$8oV7S`JpX`T;Ut?{9~prk|1X?%`HJeQo8{3PS< z?O%>5g*K#Y6J_@1^1w`Zm{yM|+bN7~awMvD=_9FDor03aHOt9n6!%BoywF})onQn zmKlUY@0a+{JaTeD}@Z}oLc*5-i;(?v|2w~HLJ`Uhsf3|sGhEEw5FrE~l z84RlZbtTrbbHL1MDJ{Vf(tHZ`8w*qijwaz(yw%yR7P6%>yA`Mb=kM3=+261J zv%$?(4eY{PIE&iY)@)XULA(>!NOxXd-uOc4VmO6qnOs|YJ27=5)SW{s4jilpN3`#e zzoWf=ko6V+T;Do$vdb^qOEpA#A6}l#1-Aw`JpR0P8;43)Axm&ByXMJ)!4&{Y&Ts(Z zz8x+132+0ygOoFvP#gyb_S$q~6H(9oEOv+Huzz7=VF?@BU9e?$-g%amn)(tJ6dtax zP+UG4=Wvyto_@i64)_&q{0EUYs>!;iz9jx@jeGp)5oIO{NsLg(KH?5^8>2+t}Gm+W>_y4z<-|eSOkyTcEW;nTd%>Z>~G%t%4yc82)xVw~;l( zeDsq9xU}ya)h8i<)?Na)?fT$q%^?v7>T0#nE-x015{k|4Z7-r8{X zOY6q~@vtRO6rp$#8tZuNi~u^H%p(s~#5kO!oguiC5@#=IQapa4r_3%7eEC-BW0@d{ z5IPBfqJG!5VQ%mt&e1owj#ARrGY6a&^Ut=SX`V*Ud_Nw;FNuMMXo2s;9_&UP*CnK- zrJphLLm?{*+O4hAUxbewiRX1tF#*6Pz&cWRYwF5R8?%xJimMr9O32o^-=nq|rTKFx zYGV_SpFfZ@AX>=d3L`*>EhX#btnRInVfp14G|z!(*U-@OV(AD(18Dbk|Cyda=-dWz zQBhHg*^I)5vHB3bjfDa80dQy7SV5mjNS|q?Ms9BISL#|q(3=_nsrRfR_` z^YcHf97H!0s1Hh7R@T;2NltF$XYG9F3=;K5Xn)7Dcm|PvRakgv@VwV(whI@oY&uB@c2Z|2n1o$+pI&$JvU%HZ(Sl13QTTfT`Q4wx*3S;)p=$fJAv^DZo(n8Hzd5`Brn?a&$5=*Hhx1?cdgPdx3xY><(b5=#$+* zDtP#ZXXqeh1D6L`FSsn%)BiN(vO|tkC<6}g^^ITMch(Cl!`{Aq`#cUf(oAb(&|>mi z@E$zZir=|z0q*ncZmP<}Lu1<*kzG98YS#d$yLP5lCauvx34)G~* zL5Cms{}S_Y#L<53k>cLTM#sG%)pC@}tlYC#DKv?NybCbjFows;;){djItQ`rnHUhh z?Sy;Wu@7#22(8?oiXZ)^Vmdkcr?aBl_-Mu{keg(f&0DqzMznJC^Q$csPf{0;cv4&y z6cilEnY#zl5#sMti2*UuuAtM!LVQE6BJ8TTtO3BE`^pAFf z7N><%^78UL+;H5^Bs?@h?1T}G^|kk zhT<4VPuT62bvHL#T&REZuTE~jeNH9=c2Oq!_`ENGH1ck``&9R!=KhwV~_A@ zj=P^?{Vg*X_OGg^kDu$Gg8WD?$FWrb9OVfeQ2C}=VD!kOpWXngr1&h~wJm~&MsJ^Q zJ=Bg9Cj;;~@1&g#r`XC`e>OOBjDfYCG%a5X_a*0)#6NWkN~%3@h%RJU z@tX}-{kF1gt>NTo6AM;8z_6tJL3;r%xq+N&oOb1$2Mw>7cuESR2MN}Bw9Hsp;Sv)2z(cn#4nL0>fgf?qv_Go+k z3!e^~LOI^{(7tBWk1$*%gzE@AL30lX&e`opvn2=W#Ubxj1ypqglilRlssJ2j0vcS- zPP}^LTdH8-SEDU;{l%6UGbk;`Z=yRMpW}dYZwQeUVlap?zyCW^_9wlagAV+0A{lf1 z!xx-5DdnooB74~X36v0$rQiG$(}8k_LXeu=UI1X6fsrwnyH;JxtQreSX6hRoeGYQ< zhYoI#xznRe26_$K|L70g8Cx^dxDB2*hO_()HwBrZc0BOI3&b?^M+h4en#XCPvmI{; zW49O+w*#p@Z^$v0>+-bLtFZgNhes}QA2@&VvZ*#m@5TTlhE zlc~99(@7CAT!*#Z1D}xa2CztQ$d4a0g+Iy~QsRJ95MgPt)~VDOd`;@y`s%O;QMh4y za(#fy&gk>noMUCuAFnG8&hP)z35@mEtIXu*sXpMOUlh&pzv1jZ{q56kj1W3$ixZi}6XbuBxc=#1L;oqjv;-*UhNY33@o3WuiSAlz zLHjy@?Z=-J%ZNXt1er{Ns)$SGoG6oU-XGQbHmNwM$an&Z=kLmFKOFUu7PzKhfx5+5 zkQj9kC}+w_N=Xr~uPrySML?krXe=>xtqdl436wW*ThV+vR@Od&Q4N?#Xw=4od(s#8 zhbaGMHD_@1tKN$G=mO?pxy5Dg)(B5u0h}p7c&{kNWpDF9kqK0wSW1ygpmS8xJKzM$ zmK&IwtDL|2XhD-1e~P6?%Q*aLnCawh@7C{uEI4~8CDtbDK@5)^pY1}-5|7R0)-zau zcbPa{s#a+7XQ%++A%H_2uMPVDDyPFQa0Pd8p))m@AhH;ce>IB(-9Gpq+8Y?A6`RRWs8Y;O4KsTnyjd>`)s)yltb#Nb)b6vv zMQR4A<@Re9e-8W!_#CE#{bar947J!l&K$Yz8!QSXq+cHt@)u^fdh#6Zn~l~|S68bf z&{f39X!G#=J<+H~%n2CFkIqkX&3Su|vq=)4#Yz&77<7=ngMnwb`1z}e4R_(yQ1SP+ z&0k^%Uc=)D9KO`B$^HR(9BKfq(y0$0KT3evHK<$?92d8+rg`VioiSk8fxz%Jt>Qha zl9xV=JsD-2g-)>x6;g%hwf?#xN#&V!8)`(IzGJlLFX( z@q4tUAV@X!wM3L2C24>6sdjGp`5bnDAq=M{7#K)3DOuUVEq!oIA4B!If43td!@+01e;*AP?=grE z19)Y-Y{+K5w?35N@jJ;dMxn`@FGWl)ENzfB6mJd|+5BN^t3q5W_ldx0u!JA{KdopO zfYtj&>or8et9J35E0YmQns%abb`xZHgoNw75w|fd5+N09_S^Wtc@(`NpIm`C(HsjS zu$^kHo{6S%MrNt&y*InK%Ik4{U;9?jgs=z+06gFtM=eK{iXzR=yfMC0W4nmzS(_ z0KRKw@YcBhzqSuZ=bG1Oy=Eunog1};ad;QzmpoEOp<1*>* zo@qZeKMwwO86hGf;%W_>o}N}5nmdE!yrz7_DE=|R{kCK3%NPs{3=lLT1J$^zbaY#* z&p;F#^Wz>2OijHWzjE>3@RNi6CtX2V{&AbDdT_sQ?}K)BgT#hoiQnI;0#NCdiKYY6 z)E(=Tii(H?*rx z%;I|y(U`1(gAcUfnoha>M|0G`0_vumh1V&#;m{)sObVIU02e7;`u|6 zID)S~e%i-}f(|HP`3)O`dtHMgX6HoaJd7905<6YP66&={e6*z{4qKH<=0&z_=U_LQ!)i z$kA3z8_phkUmhj57((=?4)Eg_*6G3WQi!aa3<7ki zE;xE%8RP`N*{>>OkZ1-zt10b&Z9;J1oIZxd#hLuK-zqVj7$6ipSnkj`Qsd=Bo#V8< z4l!0~kCMDw>`q@cdxN>N`(pV8-=d4Px;tt=Okna@W>r-Rxz@Y^l?3^>Q3jhivFSJ2@ZXp-j0n>GKX zVicXg0Gxd|KsN`miFy}G5kO8Q0b&$n!EP%IHypp4&6@p!eL8!~4t4iqZ`qb^G25Yn zyY({%wu3WA6+w{J)%V)@u!z#79*h_dnv8Kd<_jx(?gY&A3l62x*wa)Jzy0A5hkD- zHc6>X;AVN|rLS-P`uYZ;DzT+Gh*GT1&(!&jmKR3?`6`f>F*ky}P<6_?`|-c9?ERps zz1{63u>k62;7q=kxxajg3xRX1#X*g^u=`F6A83E8?y%tV{ZK5RcIq4$yi~|F+tL3< z5k&~`pe_sC?uEX>mPsxKEb5oowRtk`qFzYjx%~k75C z>?$eRJaC#RPg?Httnr5X>_EdakD2>uq=ES^VEnQfm?#yVD06{(5 zEMY@ldxQg}&J~Q}+rtz0^~S?WXVfC1qQY7I;^Or(en+5S(ZJ4GWW8sPyUD*%^E`CvmS-SK23nHt-MjZJwieV;K~dWz=+^8nCTT3OYWMiD zahwYt?QPhuyT|U&4&86KPm=9V?691lPs1nsNdEi$9TXER>|vMY7e2=)7KqijiubCO zk^B|zsFEl1j~7`Q*T;!U$}_EuRI5jwL8o4B_DxdAGl>%UNFBtCB?jPFdx0ZU?Mie} z^DULjL9@I+vaY}Pw4|@AKx5Or{f|SSrZT?L&=A4KMocdgN?}q|4P|OKu;`?tbZwGA zrA1LV%O>|xj^dC*qNLoijIBXf`{pd6E>nVPy78sWd?hBFac-CS@Q6y)(Qcaxr3E9! z+nPlgnbzIU-<>z))h$3d-?Vkaf?0PC6V^;fe3n=g)*Y@W9IiU?nm@Jt-i6cVL}au7 za$TzNq>0#IUXl0-bhgspWVSzk=jJ0q%fcf4$&Z2_(EH)fpJT==S+xjm)OF|RB;9*; z4oV2ClIQ|Efgg3Pi*cJzQoffeYBghp$am87ze<;)(&uPxuc@X{Qjk6q+2+)%m8-jQ zwzgoUJQ&pXd#5{1(G3w&HhQm-dVXJ**RM#IHG|QEFi$siFipV~A#k1bfL5%^0-?L| z-h+ShroXMj6ocP(frHU!Z?#=^F!^F%BETh}O?bKL7ovlJ5D_e*2)GKpv zc5%8{_bw))2E-b!1_5HEVx`rN+OQr3`Y z@~{;?(4L`0j&1SyttH8ivjAR!2&ulDQ1swHpp}qa&-WMSSxd(|t-l7DzWjgAzGwq| zFoi&`gdONz8?QS%)XBzgHANdjFB=Z|{I{i}k1QnY25x`~Er?u}HOxDX}7sw@D zw@Y!jRg2ooev);1%P~wRIwg$pTFrR+pc0>Fg>u8Y=r{5eVY;6eDLe{P6E&5#bv^jl9(tK-i@J!0woX&iDLr9l=;d**CB8Fl5BWNnzrAuRF}Y1_&nRDJ4TZF7YuX(c+r|=EQIZ)2i_$3VRtrHUS*0nUT2l?Pn{f_w9amx zOn-cXLz(dc({;I#OAUN->y*-gAI3PeN}o}kQmhc|bVwf>NL_lU7s>4PWNnSEVLCLA zKUqj+y6y%8$!o3m%UJa#f;pe^R_xFAP`+dilr1;K@|_h7ie$#okv_<~YPrJ36q-Z(Q=Ld2w%P+X;RJR-vXVGF-P0VPjR z#w0kg>szGqK@L{;5kOhXZ#AQB$I#f{*;vsz;bg&(j#HiIU$V4I*b$Pr2)$FZJklX$H=y-e?7n-F_E5cSYQtcT9P` zI43-(axm2+RL^^?@RM~Idd)#6V@>BbN$BhuP-GOAIsQILg6(!*Qy19cgC#foRG zRL^0oMzjx{7;LG>wxZmksr8s#!Jl1ed;m*LZ?D(mel|*K_UUwQCSr;<&4e$Z*JMf{ zagjlJ`(tqI@~SnbpZRW9)As0CbB+(v+BEj;23II-*5J9-(4Jjle_N4b0f;9va1ir5 zoX6i8cD{Wruv)Am8yCKx(M_+#HUNKqxg1dZUZAhe>(Tl&!(8ow+oP&$HwDWB zCe*i=7bZx?Gbc#iN!I(i=2cY8dz~9wq^i|jE@NRVioU+S@o+J#<>ua`^!i=Bnb{Mo zP8p06ch~m%(urqZZ8_~bZ&JUmFe_~lF(V>*VyamlX+0O<+{Y@M(aXkn+CjGQ>6hCZ zxFnjLESfKD)XI5kqh_<(%T#YpcPIF=vrMNt8!x1I3~iBDDwjzWq_v1Cs-+~4k2k1Z z^IgQFQsj!>E1TIKd^foAdM2;nS;(RRxCtRt=U|K`un)@ubcyaav3>N`+p&EhKdDVd$NR)a3x^%URRA^SB>-EkHGUzH1WCP&Wjo3Iw}d-1^U zHC4P#f8sop<>wSKl`xb_vuAGH&cs*7x4O_Mf33;=^{0LcD^4k@+?~0A*o8}WQZKmF zx|o9uOH&9+&P}1R_Ja+@y~N`yll=Q_L^mJkED*Su3e&a7XtCZzxM!tsZMiijX~aH4 zw`ON`H3YaUhSd*5NtWXWp=}1fks_Ux6}DnI6Ed!J*w;?IxIf%&PTS|5nYz^&NchB4 z${Kgo^Xw^IZ$1}ACiINia(-n_ibWpCll#gsJmq(&*SH)dN0EpCXiu)6cUT9$KC`>LlfvYrc#n|iRCvT<*=O9D zEuPS`tP9^39+7Bg=sy>2Di+S_rQa1+G0fx(ufBcq{+TW+b=wD9wt7vO7wslI^ep6G zyca}`Y;fFopEc1@ja8B z#hWDGIiwUiO`>oM=b6C##*3{AvfWC8`a8?aQs1nhcUhb8>IxnB0s*wEP^<{WpL6fL$ZPH~k6O0}LG*`jo9L3#l_iC+aYKci&cOwjZK5wDA`a~e9Hq9Y;c1d7PW~wsnHY$>87VR; zsx^~fQJ30sh`21|dr*W6NqHOH5_U7?derGw_V{R&k*27G$gHQA#cLsc3<^G8E2O zF_BVax_=T^+ASB-P?_iibt-{Y*g|ZOA zdLOSC7H&#8>v(X={|HB3j zi_-G)s@(UdWcWQxXUl6gMqg4FEEEsA4A5gFHx_8N(jSO)CSA5~Gy%7Du`Ydo{2|pn^@90GJ{#Y&Cpt+i z`O$1wMB&w%Q8-Vv3PTb04s;22Dj&tgP~GheY3#qQ>sunGv^4g|gEi14 z3sZZcUAWR7$uF45$t`1Hscy#s9Kr3U9++m40ZyV6 zQxGfP%56hCmskpnvi1GF_w?;Y|Tla1sQ*RduWOm-tPa26-)y@{E3Sb*nHP+bhbm7k;IJ@IP%KSA>WYn8l4Mvg7~E~7vh5#% zg-%>xz`)7@U~Qa_rKjXScBoKL^{smEaV`oA4mIcO3Ub=Uz%v_y8VqC$E#$qVlAO~J=qGO#|k!B{Wkucs99M4Ji zA0UPEyhChf)}5atc*M3k+&9~h!MHPL66cP}FghRcjZqoKwd=etr(kJ)rhC9BoZ;%I ze3gucmBV}tOas~(|pDaj<1eRM4Y%*2zr&j*`sYrJ?i=0q@#=p`F5 z6P!phx(WDhzXQHo!~~q>6Wte2+x3Tjj30_}l=6$Po@?#2g`&{z_C`dvatjGpQ(y7s zM6}-f=Xj3_j8!a&8wH^24)%XRe?(54HfH;1te|5{?O%vM_6C?`A#i&aCwkYV+wA%; z_aq=mJtk z3cCeKhIGcZsQHg+$-V|?F_ zTn`i}z)>gvsalUa_NyDvibkkg4h(^;+C{v;CkZ}#<$fI)W?o3GnzE$Fw#=vk(@FXo z4wKEX8Gv?-k^ZO(zxjK<=X(1v6$nr- z5Z*=wLX5tA8$&mY6x~rE@ruZup~<_J=3SU>`wqx=^~%!N$?H=GCbr3sX(dsPcgAgPs;GS~7;^iAjY z<*mQ2BP4TroK=fuu^mg=)HyNUTH>Gz(bi&0FFV7YIC0vJ>j-vHA>nf6kq@4&;?LeF zG5SWJ$ylu#B0pI}&2mpkiYvNQGB-tg-g~}wEJ#A?vqmn;Q5h>BUh$-^1I6C_>l4{2 z2-Lb=+*UasI#8@vF~?IT<(*`0mrIb&H?k3JSS#9GX`}OQ`JfivDR@{09=f+`>Y!Xc zW(3jCThOuRvM#M58!kM=on^-|(#Z$Z7_z z6S$8s8sldKcNQ(&F#NJ~CNVdooN+wVPEGgyob>v@SQjb3_y`8srO&@=Whqp0IY;RD zr-Yq*aYv!^vBB`SYCM-ZL~L`bfsH#V0F}iktND039+u3`$h@5R8k0EQuK- zoQ$9C_WQ^#$;nptvW~h$ph}&Tn$}5>1cdm3n;v{Ti1l?x+cf6hXWb=)8a+y0cbf1s zOQKA+e_a7b1%WL`SLe2VQIK>%RIOx4H}LBNU$Gr#KXJD+Z=-XyyqoDw$q=vBc1f+( z!wryC}_mll6~)CwCtR0+imt&7@66Cj~IcO zs!dRP0uZ526kyP9~h51AB>!woHl6G22AC@+rC~&N>0uQb$Ed4h*X6mS*5!W zTa=k>glAO`HtZMqr)K{6sNTE&vkKV@gN4q8!+e|>v>ql|u#DMeszlNTvpd`zn%BDevq9}bhntTNtxwV#6nI}o#w~h-`ItS0&vF{w_-teW*51c^;;j((30_6 zj4$b~CW$v*%F9q$(1t&jNnZE9p4xV^3Ld%woCIsP z5s|Szz`kZc@RTVD-f5Y44(V4%!yML$x=%_J;XT8vz^vL@w1EE+U)fD(`&Iu4x|xL$ zf!}0}WH4uZ=#Yeu)=zTk+hF`6q;H7>)2diuFHSP&wN$neu^HVXMwb-Iym*T>mg_Bw z9MM$>Dx6M;|G=y`2Wo$epQLg2t};x3$|}-Uvn(;L-{!@w8}K21UQTI^eLRvuLApv) zKA;Lz#2N$Lk1b1!YI4Axm4(H3i-%bIuCO^5_flSPM_s_8Iv^_5St0TsG%c$>0S6g{ z{Fm&j*(*F|^`eJhc$F@iiO41#=Co9tvue>1+`v1}r1-gH3bYL<@0RuQ z_JJ$XFPcfgr~5DW-fsW4wrN32_obUFZI+}Bsp^@MY0_i(+0=hCj&aE5A&EjjjJU<; zm4fB^$1F)U#qZHezegnH*^-c0Z`7?gIE#XmD9^fZU)U$M&%vP`x9U}Fvu$Rpi5Ye0 z@|UcrU8;Mrzle_Q(z7$Zij#L6w7EMe`DFRENMdF_f+;g9V|MIX?gK39rtnzp48oU# zZSP|Gt?X17G_QXaxECG{w%Gr1nAlLB0`;2JFcKSfDqXUin}a!>aWXt)Ch3$NUuYK` zC|5iMOd^ScWUA4n-T)J7uuPd6n{URQDpUvmbQ$(Q@PdhULflE1TMhqR$~Yt^Y&w60I2? zK4@8LV9F}HoOs_a80zf6_`Q^52l|$;2?+Gh3Se7A9Kd-E+tGcamTSth4Cnd3mRd84 z7e2-xZ=nYixUD><)ApnvyLCn01i8c7JZPY6VUiXn|akNQj>qwUO@p_hwj zew!wl>~)vjKEO9)`0uvpi+Y_UCydmapCLrE?o1}E+7G$tDZ5mwI$>;ZZtRblZrXJ^ zGf^-2G+`6t&MHEB@K>-B;rHF*4(xfYhG${fhbPz;Tnv{U_F4Cn-?=2zp4go9sMMS z(OD%nh}eKgL#-W`g#798aeJVAawI>U#T9HR2XmN=v!3oZ5#JooDuE@e>nJj70Fpp? z1VVEIc0vb=7ncNw#Bfah)fMnrM_ixQs2sM#;bxVHa~ORcSw$or+pR$#G=q}=Pp0^y zVKTzU`AZSa(uI_Vj%$2Oz(#t7!b#NEq03%vWGUmo>m{@R{#;>z9T9B zo1U*VJ<*)NodxW?SR)kAJAqTYCz~kowQj{)u6@!`&gRM*uCThYG6CA$p^vc5Mn`kq zdhIK@Hn#4z?Wo-#gsE>e_gKHZcwl(=8s%F2D%QjuB+zTn+ht&MA?Dcdq+GFHw_-@A z`yIP}pXp%N4f7gs*jIrrx++7LcZN!+^4DyX;LDhL1U%Pph$$*ZQj2G=A~?ofXsDv1 zq1FglCv2WkULXp#S_Mj9?b(D!bw<-0SK|`b2G>GLPF=cnO*Fx^TM>Zs=LzKA%p#!QW$s5PXya4M_EZGA|!FiRHvh}ua)~*c(5(Z`8 z==KJkX6rxN;!Lwp9HpA;k&BX@`vt&IqxT;iuAlR#4Iw4@*8Po)>FMd`&KmihPn$0M zMS;Ylbjq5&De91a`R2o?R8&;1%;PQ_=pW<1n)#%hBpi*dg0AB<;P2qKNXFH4MJhj4 ztg}M>Zj4bRaTbolyyZgQ#8zLhzyemAm-kgsg<633R;L|IdkDB1pMocw zko(SYsQ8V4r0h+M*hH&Bkwcq_(tIF921RgS42>m$p6|QC1ob;X8lh@yEI=+^ax}&j z1b;4tvz#~_oj0ckos7MdH|xV|cd4nS*2n@x@8(9^BDOXu5JV;DYM*iyLzpz9m3njh zFLIpDxsla5jUtSjHXE5=+e9blX;0o(gA21=;AB~UD^Q8wA?~-_wYM)=X1m*XX*QyU zUKiLgbGZHt1{h1#|j5Nc4ui^+FYczMC4!1!-?SNK7cf#;5LN zMX*K8ZvLN##ZIUVtg`HaUeckCjN(+nLr4jB1~jN!!>`GQ#*JLWH~>J+&u>NR5I{ie zjv<}<0^1l*q&mOYQ-xe??du@XXbTM+fgx~jG*iA=<|6wgj4xSOjnlF_hPAsg9RtBI z0g^ng6A?wcOFA-{}Np`u7BkT6Oz;co2<87L5f}CDT4Do|A+NIUs zQ1}sSTZdQ0;lWcVj3IB*&TwsH#k|c226cE2Fe__IHDv>A)Qb^q{}}6=G`_>7 ze=l3d))1+H`H)EVc4gW!olFW0p&Z!z-hw@Bn#3daY(m%EShdWD(*8gUpA-IIsz!}O zK}g^t@HYvpo}SXvfH@s?%7X)@Hn+wmI8XhAo+pcGL!fP>qLZS$ei9V|!i}e^L#)cZWm9UO?NW_O$!EvCnaM7deGAx#E;*`D{>G{C#&q&|C`I z26M}iUCZxQ!^+UJw(G6dS1g6!ONoRWbm|C+f}Fn`rBQ91y7<{Oq>plIq#tz)`u;Sy z997JGc6t=nPLXWEgR>lbX$Tt>l7vAYbvmT^l&^ob0Tj|%#vex;Ob13Y4%@c*Sq(;( zN-!ZisdaK5zeBWYl{| zOmbewWZekG_~BmxN|=36bW;0#w4+m=j&A*%vjlTtxMhv=+H1!|KXAORIj^5tj z{(UQIXd8aPX|u-RZuKW!tfpa z_B)ZV#ijmh`S7BWKLYp9L8tecKK10=G3cJ__WiByInd8N_J0Tb|K1+VMXKamCX1XW zyZ$*%+MmwO$NOQEO!7j>+AqpeK0a-CbaD!(@Q@LzKJaYiKui~RI@+KIo76JzbukDX zN=th2p;XE4`}M{z>RaDM6-~#|_Mad6&0pe2yu_Z#LBkWaa+Vb0*B#U|N*?YM;6po; zA!G5^K2GQxTGiF%S3^X@Smh|-+%BO>Wfdc$jzWd^x~Jk_%xn7d6uQIfmpqF{cBE@PjFd)N+f zX6h_Ug}NCKKu)d(IeBc=Yc2C>S}+1Rs{x(etJ4q=bW8*-w5STdyq1%?7ulUt@5tLP zQxg>+n!di)%_Qm-hu$Am@7Ls=a*CVPUU9P1+=#7bI$0aedKM?ORZXThHdegP>SPSa zCpHayuk^BBRXtzF3{VOR?SWGYZud#$P_(iV=NI+hGc^(g?i*s|x^%I81!K1q)n?T6 z*90`7ZUVZ1HZml1kEL*;|Lb_C7O;FTebO}zW^f2Z0G?6V!m_!`^qS~9L*7_ zt+%{6ux`iLw)7Bx)Z1%}Z<)E@T?b&swA)v9&Qrn(M$l!k)f~|dcnzaMt-d1(uiEOk zLoJET8E)nOqjWm;m8{;Mv046$(n$|Nbb7`)<>xu9cjPK8x26OA$tmM4&v5GI>NbC@ zbd@uH`T35SV_o^vl|S81QC)_rwQkx?QK zl^eYC+^xVx=b0ktWrognYQFsGUT{BCcm^awQ;-llp(Y2hWYb+*CF;gh5p2)TyU-p- zz6h`IMNA)9rXX1xMy)EU)LXZ*5q;IJhYv<<9zC%aFAPMCE{Q`_UCm0#La{|myrVqU zt|wvD$l|&lum>Y9h9OdoalxtSPG>zVg_*;Y2<>`sF2Z?p+}sJyn#DAOOzSWUk-9Fr zUHP-JeedU_i5cQ5?F*=JA<9sPv8tpbBe1Btzp{PzCqO=f(EB5Pq?r1FyyWrG%sM9> zlRTdiCa&?jE4$z67Ae%B8oC4b?(S6xb?z`43vp;JOTL?sk}G+S!wY zwUdwS?bO`&lAxbz?ScYB$tn#A)rue8(HQqU+jty^*BT8-t^CxEr3sy_5ybfw6W7$H!5~4#i1Jz! zX!F?P*_+E7{^l#OHsiC5Q11QR-b?fL3h^eu#EgW5^Uu-&9du9)fc9Hy8E{T{^*3S6 z+tcc&jdz0&Gv`m~t(jTE-^6zre0+TV@F`#Yyn69cdv4F06zP*+S9`qPmcmzudsi1m z<_~hUkRIl%x1ijE1~wSt{>E?SPywaG!goR~xthC|_bTVpG(U!QMfeLN@{}NU(hn9sIb)SaGMGFkA%6z}aI0 z*J9{d6L+i5%ss5AOazW1Wb7;EA2!oWhrzbXYAG3&)ZdOA-DzZO zS)*6UeZO@G;Xml&HG^~*d@{1UMxCCV30ZJPj3)qNeEf*aTsLXaXkqu{P}-;|#MQFU zfj(SPYqDy?_N^xBiyNY)zMvl8LDC+g&;`S^<>s$)0B}8(6GL8y3S~*PWYjWLEF!~R z7$eGE7*2uk6QU45SIA?NH;hms=sMi{Yj58o@0%O=7`%fK#8ai)*Ru;xv~h7-b<3Yz zzuKk@J`f0fUv?mdO z%h(3kiKpelAOaeBYU`08XgMyO&+(roU!6j(X)!@BbI1ZgMF&eIK7&*}=#Je!u zw)ek<`=AVnsD2X%KBA8xYgkp2!?f+Eu*bLoaGo0UYJEWQfkJ#NETKTEVhRb##ygE8 zn_AZe-*&x@<994AK9B;WFt6HuQkmL9v-!~3hvxGVPRAIL^*h>Wh-;D$TLDfHYz9CJ zmpY;CGp&%XhvWX7!H}QU5(8SNzu*w7`nw3w_9DU$I;9Wvu!wfFMy{r$iKFNgh&V?? zSVCWPo_RF)szlNdoG`g;J`kM@dI%cs+EBVKtXts-HOo0kL$=yb)(>K=jXGgme?0T9 z0-`$r5@)1mBmM$NeEgN;b7JDD@x)aECx2u_M50ec`I%_7{yXEKc2jtjxji&8mfb6J zTb8&B_J_X0V!v3w1Z&Xd1bw~v$yGc3lfeCBA<)R^mB}=Ev!IYGQdLDzt$UtaE3<$S zpWfD5NF{$dnTGI|$b`I#(QK4)p?MpYZW@^bAvi4o~5akk;e#3zqViH5cU zlvzx3j(>6SDJZg6%DZs$_>ZQY{cYXIUBwfX;|k0~5}*#_Bx`PHU5sU57n3J5s-t*ydL9U|gOi%?8a67b1)4QMXG$jAWnHjjCb8RcWh-*4 zx0B$yBd7ufj_3;!>K!dqpV1*4%RZ#3X2fqD&*nV!*Oxpo$+1x1$g%p9B`u%^k^n0T z-nT+OSXef!fmlgGIjZ5ER8)DF#RV9+1~B*hw1S|AE8KESKj&H#MHRJR&W%gB5 zcL~zU7rPd7?m;rA{1~qUGnZC!ZE=jvRPrP*!|Q~x-+}i$^?(qoqaFtDl7%;gic|RkSQX2z-DgbL* zULf@M2UPZj{KxO#Kl{wb)@&Euorq4q_oV1G5% z_@Q@ZwA2zm)E)~k3ytOwmFF=Tn>lQQFtv@TYtez1Pa!&aP$@qC0|}jGzCFlmj|!y-MEUWR;|{AhO#{xn9T&KC}9d0bgI8{)p<1&#IO# zGrhAB0&H(e%wO%T+qy(}US@WcWG*0(`8+(Vm2x;~+s?hUJ7%poQgRb|*KPgl^m*z( z_3_T!Nn<1LuF;yu<0cNupR7IkIuBY?cz=%8tDo2FM3iBk!PpH|Q;#;=1R_-Y!aFhW zEh_EorsjXkV7{h2Rwgn3_KnZ|#yyGS=Qy`R0bna*-t!j(*fUPAcYv8_rWZQB0h{{q)s zuws1`fjd~OZx04`qpNKJ|HOp;ABi4hdr$V$PL*@bg+oDLHG2jB7q#Q<_gzG%?ms)L zBkH>wQybe_D4p_%JoOxf&Uk@;2#~-igI!m7+r&Dqo|0!aPKV)lLv<6y97~@kmX3gI zTwVX<=1o^w{Z=L_3#*92lTo%p*K&+b&cFB0{;4^bqW^=x0EMppyhilk!GqI=ixUum z0^6sF6>-0hAKRuIeXgz*{VZmxxI&{Opi`$ycYJzg1bY zW>g2-SaRgeYyt7i^MfBi=Q>NdTCSzetwlvX2b4u~%Ni{Xn*U<9pS3>4u9Af9vf&(+ zlg`M$*(31$>O{K_Jd?A4(Lsq*>7s)F!o?K~iu2Ux2N0R!6SNjQzotI%$uGT3FW7-y z93*f2BiSn4=2qom*0?J%`VyPUSgZW?0i|M;m^(N1+hqCPjz4P~ zETXRkOg1dKG5S9F=iRG%b*i>62}`E`i$y=(N268#F8T%9;S|oj1JTI64ZJ!cRtjpn zfDWQtAI!I^rne;~-l}C%}Dow3U^$ROoPHVCWyJ-qumN(Wy7~*ey zZCm90-l_N7={Kg8JFRDDTf!>WGtIh_0cZlEb(GOxUnITT0s_z3{LeKxmpRZ6t2DhSd0GyuUY911nS>AKmIB@ zP1julY-wpmk0YBnahHm26IyPa0n%UKk~II3?FWKWS^m8T|7B?4m3TV(v2-%=Ka#Qk zsU-b3Ih)7WYq>v15%{vr11Y^k;U8n&Q#T}g`!bMvUaQ=ekeD3313Di6S%d#?+2AOs z26go41ucqzGeF>9D(OM{bYF#-oJoR9MUqhFieJu==r&A!eD+kOvx6N}1g=P~U8eWV ziGbJ_^Bsr_kSQ?WZ?KJxoUi})t|PWBJ&mG-KTZ_mM}jtMe-WbQ?s$Q_ArJJ;rl30@ zv4Qya;kKb3d{I2@X>dOd`&|1PsCV?cgOLAGd{*%j1H?tQKu`FRLwBj4=i zJ1a4!znEk|(x3JIqo>|mv=Oe9GHj2yh~7vNEib>Ns&onvKpGu5QzbG9UGgO-62A8y z`VUcd5|pX~f}oG{ejx|~>zVnpaVv@&MB3N1AlAB2{wH~D;83{4vX*rAT> zFK!AjQKlh|h>SGd|2?yXMHVWksYMKl+iPWjsQA$MJ83|0@D8{{#9abf3C{SaTRK}= zw+sZ;`_vycM5f8KD>f(K<&UYNw^=L5o0Eq(D}8A=IMc$jy0DD!drqB8WBG2#Ng)NY z7!=Tx3A=dBo*Y4BVaIP?jWz{F$J!3G*5~6%8Z4W8DqKvkzF4TL z;@#B5n?x_E;^;hGNijeDt6Pk5twdr<{;|>LmIuHw`3zC^>8hRbIC0w^*y@p{(Egih zN>aTjB6=Y!e(%x-!frzM3a5TeSum5N!KwK-(8G3IT^iwI`H-`=d_bnMp@6k^nE;qFi$iR6 zt`nCW+;k*LHFiONHP)q9f2#gK zJ%mYQ)BfeZ7~tcldAA(ar>x?rIf@y2R)it={*{R6j8~BI;}g@xO!>%HUp>!K(b6t% zNrjWgve#&{0Q*#|g4G0#6O}K86f;+tV773f_lJf_P|ov$xqfj&=>6mBotu zyelFvQqfZNgN4&wmB9DX6=e1`li8-LRk^_Y%s?Z|C+IKi7S4E$vlcmS7%T(V9anHU zC3tJ!&orG{fMoQc#Ko|7Ig0OltY-7n)D2ip`>w~-LwK0}issD6#Z0**2d9vh4Z>=Y zsC;Pt{^S?fY;ORSW|{Yt+n3MVM6}FW$PFnES&J`Qxlw4mJcmYgaW}o9@J-GYc8S{p zwaVe2n}AD>_*i2dUA{Q{J<-{aE5?&8G?Ck#TTx+{47e+I0zhip^jciOlse|lVSD(_yCWimaw zDg)e+AI7~X7QA+m{y(Yc|NqsrG3}`)__TJio&I_@C3dt1Zhq>w3oQ4(E!HW*-vcNO zgBr@$?gy#03k(s5`whOSNwcKaiBkRZbQ0`Udy zmd!!=P|3RivJMLAWPQtSAc)I1+QNfZR8*A0JyVUsYF7xmC;0kXhC1R`kgYa<2oa?nel+d~LWr(}}T8gDQYZ!ti#f-~4+k$#Qr*r();5sVI-F@w{z>{){^H2 zh{V|1xBiKt;<@#@ZFGYXxV^~2n3zOX4tA4Zjp|F=}!X}&hhQvQMiLDHS6*7=fOM6{j!s8 zd-@p>>6Jm3uUv^f)hq!s6*fbOsk9r`Ek-VrSAl9t@bxV72%$d#ayg#T9d|dpK|>%9 zGk+5NIG&u{l91Uz_O+lg+y7a#`k*Mg?#gaYcy+Ob|GL`hRzfgz_C|_Cp?mqRj-6JZ zK#jJs(6JS<8!7~$p88xV@4cJ##Sn=3)aueo(P(l?OM3tV=dH02YU-jZyoRTdp34te zsoLUCWpj^DFW*bg0b7t&oUlBb4Ak1417rJNWXKH}=3ER`nceY=x9^@hW+3 z!Jg;bP0BLfW3My?EPREt+xO>t=ZGS(Uzx z`C@_6d0%J70Dnh01lijKUPhGE=wQ}|$T2>@@ilf~C!^9Ciwk#H%quFAlgLpmN88Bn z$US`~PVf^-uD=^-QBjnS!C5;}5<+9@x6U4N@M;PCId zOEw7xwT|}y1>2H?@gdpB0YQ%XsrbwMLwqdxdQ3g`3CHA8%=3Qb7KRwNhUe;2-9ZmS zmQ$_daU(pFbAn-#RjHCKKT`Nkj<0@{@I032hc;4hAE=R^;G&(ouc2lac%e|p7mgjszVgzv|Oo~f^~cqgt*$-e^BXv1Ls2W(zn=-5E^OxHMQFpp+_ zA(Y@sY4d-lR5!TfeKVo9#+pILpNl8G(aOn5bWp)n6>u)SlhwD}aus5j8z8@fNY5nq z!S+9bELAT6yhrMvvSFdoy|owYH{0MB3@2+i}E1y*~!6tyOK3nGY*f5 z{*T+?^HcKWhus=?;7p1sW+zP)8jpX!W{G0RL>woJltDuaj^vv(&eSz2xrMCk0C`x; zsNgIcbrXu6t)S|g+Zz+Y+;K?BTF@P=_`WKUkF;2qaLF&145AWu14`-@#ZL%#SNy(v zz!Z9vG%Lme-Vmkw3Y)H2iwL)!;T)XhE5)lJ&yNin2@y0K_L zUofZ*c}=izdT894563#ew(U7WEnA?s9b?Iyv4K65y;m4aXl-R+8JMAh1o98D_1HTZ z9%(1=={=RX=?$hsaiv$CoX{_24JMP>%iW0k>vvlO3FGDtN$HTu7#aY8WJmWnDrqX@^Un3fy=s#Pon9{jVh^1r)o`9c+GSCR zhTv2##85Fbc$Dhd{x2^8XE@wO1(izH2Sb}x;TwZ+CG(N>$=M&qv!$yCHHx(S7uUF7 zf0LSJTpbg`eH%0@-%653ZNOCQIxHPLfTtZ9@U;8Qc8Ub4WhrRK&MsG`{yjvx8u|wa z0>;h<4JU_^z+7?DncfQ#__ELd{c5=ArCL!c-}oCL!85Xk1jynD_`Be zB7nRQ`WQ9R#Udqu;vQvg$_K4gcLAox)q_ie}oKkONNf)ilR zdzV;4U4W4StH}MMw??j@n%~7sQ3WqMiceO2Yh(#4YjE6@22{Q`fAtH<4+UosoRitP zF1_3u1d*NGnzaxYdCf*S{XrPajbGP>dY`L*fzod9w|Lb)Uxs&X^@Dr-deC+>rV7&! zDWfml6ha!megF+Gu{dn$$XkTxA$_o9#mPE#&NO2hZz`+`yV>p=zRBhQM;&tHa$61l z7#u4Z?3DAaE{0lvya||Po{L0DD-i)%!(bF$Cn)zp|Z>n009)@l})_S{-JhBBkbhG?MO zKXu1W#{8c(8@l+JTHCFS!J)&Q{V9Upou-BBX+-65oN?wkZV)ZQ+3<@WbKE=}4Pj41 zbH}xm*AHc>b}cm;*Xt3^mX_x6$F3{gN#qK6^V(w}o%0Th@~D<6oQr`+OIz1|art&| zYVl-?`Uif|mNu*&!~W0)a->ZA2~?ok)4AbV*!sizgdN9J?WCF`c=scS8av|%8{Q6u zJePoa9H#@R6X_!jWz^-9b?BxuC(kRgyvZ@LB~c7}p{x`vR6mQ`D{?Qy)g0?l=S^Tn zyH}TfJ5oZ!MKj;a+eISE>I?>>-XzQ;n)ee>lE7T8Cp@T;rhPny?o< zQ^m364ePAz-)~G6q# zA7aLeKFoh3GuzF>Ff7PP1*>!NTq0}V&E9ZnsVvMh59K?y=$X2LH}Kw)%|#6RM{Va| z_6m;;Hg_1TC6m_ym*DabSj(dLrOou>6C2MyB%ph93d{P;J z!bN`1+PNV|1Jo}jMw(2rBpyN@xezbLamXN(YyYg6xEaBhgcXnRdgj^V?#^(mzvn=k z*LMKtP=(m}X|C06POxVkUFnveK};h3R~~1P;|D+NTejGhq^wx@lpoU6A)7uX1b0VN zelC^hK1)5Wr0Ru-Ae{3Hvwg}%t|v9TGR=t3D;RaHux!scHjH%fy*k-mQrX1XVrgL@)(&6In-mf+Ia-UA09r>;=e4(gV zYN)BOt;C!;&Z>OUw%mdLt9#*?G7 zQ()eBuX7Xj0z(Rpb%`9gC`)*`C1IoorLZ{jtl7+@8CM7{??ds7<`ct*9d zMjWOX4F_b2$d{sElFGGH12i!F5T&RM=9+>Q$ltJ|1x~{3#K7Y8boSCizylF>+Imhc zY%PSzQlz~JX5OAkB*vn|(1bL9#*+07!roLRaIT9S^C^$sa2}j3%pQ8#F`#ZkrCAq2 z#+-anGOqjmT7n}z^v1T#byx$lTLg=RX;*K%Pmm<+Nz<}gss(q3TAo|S>IrS*D4+q` ze2e01oVic^x}d-#q#CJ)baFd|whleqy0y4Rei=YFcO>lORvSl`#xCRq)^?&El$N^p zeR~F#WvD~pzK~<}hqF1qXS3cCN)903UjDo&LajAOt?~_ewP(`)3w&bVrQ6raa!_^6 zuHzWsada&}Vhc~zNGbFtE62aH8H;J%y~*o*1%q`9G06+;T7Oquvz1rj(BQvt01%KT z_Fwc!z7xtV`3%&~es9nGPF?Ae=nUju9(N@nrlXSUe8WhUT;zuWmqUp>!gu>k>X<>$ z?wP*Y8~s=u+JO78X&{Joysyg8t}9@~Tbs1KFpwEp;xL|M7Mjt7i^XX+8t|r++DXKT zcouk~=Vv8;q-{|{?y$u>Y&mP`JMBgxQuB5F=<#ylB5}x8tmC^_GR(@?g4$)Kd-pun z)ZI7OYa2()23~24W=E1`Ai>k{LegL?Hh(u@#F*7B!48CeJ0SA_?Beoc5LpCUmqdnT|R{ z|5CEzt2n@exp;;m!FT?z`;x$fvBG+a=hV!+BaW|SQG8hyMgD8j(eN2*_agb_1s$(( z#(bRS@_iO9dP|Lcex{z~YqE1p8DvOu^>Wxt1Rpg=r_JF*&_&Euqtndyrd%xzizA#c zYnc}=A$`o*bjM8$l(VzM#WbsQE@iyS5N>4zCJ8SuL0k2>2gxurnvFWp&0VRo%-O@> ztJ@c;4U~j$nj}g2-;fT9f>M9lQ!s_z8Dz*8Ao`)sw5_8wEbu6RzV5~-Cym1tj zLJ=i}P_Wp1RymwwhRw4UTQN4^6H_prc$#cmI2Z==)!-m zf4j)=GdYH)U{VUYS=Uv6kdHV2;h;8Hggj!Wj)aBPD?wc)EcG1M7@6|gip+?j&EPEV z4kC3&q9a1qB`Ml*{%B~$AYVw)Iy=FB#ME5Y@Q$W=UqceeMJkA*jfLgzDvDW0bSl{o z7<%JM*mehCLC-{BMVIu$?8GeXiOpTyV)7mq5^5imIOyWyM6SIP49h~sY#h1!zTh4i zU$B%f!X#WC117h6pmUgvynXn8@Qe6*QtHS!4QP4v2Fqyn&%UgzJ65n&bcT_&r{CRA zU&~DzXjBiVHAF~`UtuG8!!X*y5#^Br9?>RaJLar>f@EOrF$ZUODc8yw zHrM@JDsx<9N%80HAy`zyHVJ33!$~cL>JrD0T94-?i&gCg?LM0mCpa2&8rh4ZmzCNz#L!IG6~EeuUNYr4Rm`0DzjkpP=BoGO4H_DOyK2mAHxkEjwp#2 zKJiK3PF&wd)o2v<8pLHLA|!f!au-p2tpSEmYYp3zd_LcYKs#Z`r z^Kk$_Equhyp&6sUEvvp~&R9WZj%*KlGelphcH$DtIin=`z{js_V^LlEwRf~u!qL3q zT-Vz=%Ec+uqM=?TQ?B7PUH6oU?>cXjD(x8NEp)#Tty`3Drx{MB1=jHgGHmYmc5%f# z^l*!nL5l^}+ahE_aPLMP?OI1V+q17uUN6=REiv1?Q7?2i!Xr!_MKS8j&CP+i>%Mha zK7MnWhIK`&fQYIxA|JS?c3PU z5usdPJ<1QJ^)|M+qE*bhiIKsid3=9JJV{Rh$v7^g z&}f4<>S(_G9sPG5K7OsUXRp3_LS)H}5fK(%&WIHf(xUlP9`m$_{GYq_AA9$IeeQXC z(G`gM_<>qXL0-PtB^1o2pySrBiTZf?rg5ddY@z)Q$$Y50d(5mPjqzHt%%19eI2W7V zm70@tH0Q-}FQaXLz5Jolp2rIJAAKG5GroFRx@}aISA4Gy$F?OPXE1)SV5y<5`O{m6 z3x{?|o^0S+^*Fghz)dn=`)I3%ctLql$m~!@gsLH+xm{G=0A{7#H^iNth%(IWv=KTU zQhmvrDxLA#+c=WKm!N zCH!v8n44O$$J&aty9z2;LWS4d%+rmhTn5ZvqqZDRo@ysZrb{@Y-!^xbrTr{KOe9$k zE9FOhyFdayRNDww3|7KdwH$v?s#Ya&+&~y}d$#fxYB|xtpVC;cxE->Y3$oPKq9{ zUE^P(3arLThKx28hnPRQ2;cJ-&5QA~;{f|WNx!SA_q7mn_D~dU>5a+3d?jrMs(@fU z{X}F%Ey+jq@hjaCB<%Is?uXe5Rv3q+Hjd_*#n3)Yl*AsI4|;L=`>*52$w+;1LdWO; zM&recK0~b56RzdJ+nn96_b zdXJW;2|0%`i`ji?hMKA~$J~f3-*x=Xo`8^3Ms)U5IqD3x{@;v1V6^bX>$J4}!0AC5 z_}gcUj_M@Tf=tuP5+)|4B5}a#rEaz>^Xu})7#9MI<=Hk#;n)g&@7ogM( znxb;)8A1NB^`!}hH_lU32fJomz>byq`51P*(uVu!P;Wwty0sxMi@z9Z8@T@FMaAKF zu%kgu%C*XD@qyo?i`_Y>*-x5VlwmlDagWC-r5vjRGw;xdd$A=RC%(4FI*J;)(pzME zpCb#h3(Ur!@+8+Ilqi{4!uxOK6&xGvk!@t*-)~>JLuvQy+aDU{%Xs~>Q%s_()zHov}$`VDe_FicLT|-SSTN4 z4QN8KZzBrC$h$w^E7v~`&ur~cFJPlkRvrk{^UqXCo*%^XKcJxLC#v=cOSN*f+{$}o zN}_0(P`+?|_{3G&&Fv{_=m9OIPEbU}3mGf4>PBZk>{(ZC{_w*1mK4Gmr1?dkTawn7 zOQxavUotpT3>B{n*NXI9B3@lOhG-b-TqChi07-c{S6d#EGAU zEgVs8vrJzDYLvTpoIRdhl0R`tZZ>cXoH2hTLK0V@qo3B;dZIpjwn)0ComNPjq7J z%bC;bSqs|4?`=!<<#fLva~?4m-FJ`-uSs^RozY8bYH~d8V$y&eqq|hMGmoyOBOduT zA72*;3mWH?iO7*wt_$>ClTaSO__|laTx)QPc1yBW^^MqC=?MGzTdWs#7GA2`Xj4&9 z*cs=u?zag*CieN*RZvM;M}a#vcRrf_`h$vK|;Yc%brx#TfOI0f3J z&vGOzzThajKWiap8;Sl_o#FX)^QjSVIp+s+?MBPZV<-C8`*SF`wM%@vL^s50*F=m> zU%y5ZbC^(2P;7k4=>gX9g2fI)M=uhUzYL|Ce7erboNh{)_HeV`EPDT)wpkfZAvY7h zB{lUbAv#jL^O|h=F5yQ*b3pJ6mj+rzJ3*pHa3v+)HQVwhA;E9hdc{x6GNDt2rtepQ zON1fRy#^YIEn#L0huUD%GpKB4w6IMPMQ=q=8E$3H8P|2AbE~bwc}UGIxg}*1gKCf8 zDqq-Dg`PhYRNGqQ<4VYbb5jrOK$o(wl-u2(zzmqmF9k2Mj(AQ==UrkqdzYSVLHkm( zPm0Y_o$3)=<4{7DNO%f&v$}8!zp`F5>rm>k>>_Km;M=KAlLJxNi{{Kv+Tqt5N1MON zGC2sa(=+Y=ez0YHr*y3OntdybSTdZ9g0LkhWB4FC0@l#cT0PFgr5W(SnS|yNbMoB+ zSG87OX5BF=2PH?O@k>o&L!p!V5}51JJcvQXno_xB>VumDhoL94CjM`rnkn;Ki5sAJ z63HItV-7Tz@s$;3nqgxuLB=}abLC=58os0vH+-^_O}IF~Y!aKfk+#~&r2Zf$e7A01 z21#sIZN>ajQFwn|QGx%maoSkfqgoeThM}^_H`)c?CfR1?SeuAI_>;QF58V&?VroVCuF&9k8nB#F1k^{OtBG} z@59SDTZFG)qfkOZ3|>khaDojQwKoCVXvW zy4Uy!)a73YzaNiP5B-F-`kyxnFY}AeOcu%}zEbzaxWN7K8nbQn(TDU#znkRAHGN!- z=*GkJJEWeEbJ$MnZI;hh%^4`A#Q)y%2meVG3Y7uoMwtNbQI%=#)evpJMpJD$US+cb z%okK2KW=B$(qTNef>KE>Hnv>&L9t)HY7WJwqI>0uQZrBdk}Z-P*bW&+D&y2JU46|0 zC|>z69BJ^YfL+>h`G_MTlEgwPS{VlgZSkO|dINp0WoU5onO}!zj%sXZA{8jsU`_d~ zREVa+`?19BH{F5?moO zzB2910oCp{IjW?Jp%HKHWrbd&i)BBANJ<@PoU! zX2W8QWx4sLBsZ)(mbAjQL9>JyvUn%LV(z?&{qm3|Q;Gif5qp|I^EO2dg*V)MsE$Sc zA;iNi6R!tR{Yiv_WPV7*C&-@d%O-1uce|vdi}rnbG0y$M4+dtZG-eZaG?Y;kZ0S5T zwaH->z0>O7N4@sYV{e@9yR<{vMz| zWU=s!65A7OtB$Qj*AR zjB+l}z8{mGY_9w)WOh+!fiJwBZ4k5LeQ0%3B5zEB}JGFgd@jF9hAxM?a zRK?ONbU(V4g5Oe4Rcdp!@MbohYe=vZ(%+osw>mM%vHP`8>W=Z&i2m6TG0nA|$2vI5 zg9|7J_fkNSQBzIgWcu-fDXQuNKChZ}E8XUu`dRkup!vLK)YP$VlWl&uOF!lSBGmI3#rV6EQXC7`N04iFtJXoX1!)*wPNL7 zw5TIvGz-ZUx`7uTC+2JfHS;aEye>OLU4I__N`}!6cTv+gCbO#oPT5;fayuweiGs5i zY5-erJ8>d*WP#C?(CN&TFEHQNj9swXdP57BU`E9$psuVTi`SmUaCa(9+x>(Fy_~QVT;%GhB zXe+u0BV$0#%Ykl^P9~xBqqk#f`ykUtEnFHA8KwUy4ikC)SvC7p32V7L9^Uk=RUd_1 zYRZup3f9ti3uSuwooM0_E83}cqNV7M`tr=yN=|9o5mwynOEm1(u(y@j9L-z#3N;1c z_jy}uU1%no-KdeXJ4Sh$k-x4`j0e)o+$i{|sJ`c2nvkQw@36R%7LlMGWrarew|i`fAG*5+vA!*n%sHcoe`g-O zIwhGQEs4&m*}EK+QSaDoiIPq;JY87eQKXoPYSxiGkt8)nO|<(d{PVB>@#g>f>@^$m z*x6Y`DV{%|{%A|FHiz-*)yJi;JJZ29OFt>q<(Hp@p*g2LCoj|w&h`+%#! zAL*I7^rJx_oVlwZ!J9;XykpX0quy*&OSwoQlkWS(zTwt}4Pxy_E`R_|f47$=D@aFc z!i$L+DIvYOinlS?4@LjJEPwSv_F}$Hc_46Ql!}XslNF-lN^+cZDtpyRh3(G?dt!Mw z$qzKqZk~1v9lZelA^JYrTLi{Nx8cW;1_V-67J7YPV z_h{lUI&!H92T7-6yW z?3ex~E^?Ff2n@aB2lI3lKp!K>T&&6BrSkVy30PgysrmWAb72LA=v_J}3^r!5yt?`v*xzM=0hP(F zuC5jp<`mR`KiThJ{JN9Qt-6%wasFC9jArrte|?Ca@QdIxtjx`2&LWV={@C*KpUUYj z{#_W*^YJ-Si>dk~AoNfKboBBu5kbKi8Xi5lSVQ;f35S-FzFwxNu=!yySL3R=t`7uH z{NH!bYk|^JYfQ|2nEr1B-ao-PRM;y%o-SV8MNoXZgHJ<8=bfV%aGz4+s7y;sa~NX? zQUI6PTO{=2e|HJAJ)7ZdGvOfAm>u=D@oTe4gPURQm-7q2b(Gr1Sl z=E#+Um7ONKUiHnYwxWQGmv@K)jQz{wb;O)!#W-L%gSLtO>x(Y^Bp%hthkqygzgfy> z&XN#o=4(Bnkl4Qs!rF+XQ!_QJr^)Y99vEoiFqT#VCw-i6$xyIF{XZ^Vy!4-#BYEFf zYb+5N;P!X(+O#3j$jAsk7@3R*3wiC~=H_M^t)Xl9dc%pkt%F0wSVcJ}1DdG3JZuU> zkj}R>|MiIRf0VF~{-DW`k&zO)H8mn`+Pa=v$ndZ1|Ks2MACTp;GpA$Q`o0HT;}8%S zw6e}gaThrS7B5gRT2$(rYl`4~Y|R-DwRR@dj4dtUY*5D5xs#GsfPm`N9kq7y`s#@j zLYv>hb4@UVgK7X-!hdl~Cy7MTRxLmNXIOjRL8?JLul81x=!Ip-$PL$Yl1<0xh7rO1 z(;UJDHYj)dHS|9M!2jWc{`0NJwJfT7de8fFRC2&bO?694ROjX?`UGaCDf~g7K71Iq z7}BA>YECa(kzEp8QkkFr&BI+8K1i)8>f-zK6u`by$RnPQ75R1{+&GB*ScdV*#7~y{ zb@Dl^YFnX01^s(#@RpNsmC9p0ezWd#9iEyhPf;N@O(-0|&${PZ(o$fm@_5G5dKO+f z#mO0TXT{6&#PN!$kKpW6=Cye%JqZb8(Gvvq2KS_7K=>MVYt)rq|+x}4-5d~=hK|zoPr5mLO1f&^K zI);#LFleMp8l^jDXb@=-X^`$3ItLiy+_T^3ch-J?Yn|upy%vAC7A|0BzW04y*QYLn zmcwY^1PW~|WPSRtE+un=8%eyj*}yk604(sE$5X)1@%r+94FI8VYImn-^23S2B| z3vD-zaeCzo<Id6Moe}tQU9o3+iZRjkn zh-+A6t?UQU&a34MU*3vk8J&64{Fxm-T}{SKN9K`7gEIeq{4FhBEXnQ zuH;)hDo?T+S65!|)#sZ^rMAyRo0^ig7%jR$Z^%8V9_b^adoz*gVPzmp-H zroWy-5o!|3k43$O8UTYv1U3#AkRf_GyoMsBt;xyq3xc1XAQI^#fMyNX8{V*~#(OAoijRD4X;Iy{2g{Xj>HO8oSo3 z-04%SsOLXRL-`sqM_RSybUaAHvvPZ$SJi0N9rRA-c7*mtxk%{uP{X_3?U1-k3YP)p zKH8E1BY_s#(UtJE-6vNWm#E^Wq%I}u!dZjjXp5`5A;1GAGm$%-X9pu%A5Z6#=BK#m zbCSfUxn{GI@^_Rt0RirDr?d?LGTh5)PyK=lnD6;3kdUb*2;@?^a>BZko> zxTEToh}@Cy?}?(1v(qgOMS_^q7G`;dmHV{ytPUGfOt5|puzJvO@_NZYDP~ks#0ssU zh_wf|zF;~8K};|8=&xQ14(f{~?e70o-~PY5wW2q#2K!g~(iAZl)%Wi-b<%b7{uFCq z+gxT~V0+G|iLF1G`^gT!2gZ1;{-lHY<(C}@k1EwtOO}JO{8_p{Kyrz-cK^pqbQ!rk8~t_ze3j+_PUboXn~x`9hmY*tZy0FF_Kg>ZpB0J_#;| zEcR0cCedHB`21L>=pUg?`tG?z&f2pNCia$9+8I|fhynJNYMF8hD@c^(L=|vpo>Coz z2>Pjf5r&&0E9h3&x}QNk3nlWIx-us6@7bg9=)&jBk8~}Z-(oQXFzK2Y_ua}Dm~L5q z)%5hrJnpt(5gmTv=YK%sVv5--WltFN!DPx3Jy^vUm`6!83^Nui6(}aLo$?nXs$5MgpFd;tj2Ud9bwK{FvZT!b= zB_8^jCG^GaiNR3_=Y<0gc&CoSDcAhLwCQ z&BsX7+HotWL`J3Us`5aywdv%@y&j#$fzQJmB{$EK+q^EMZJ(8^|3u?OZtj$pz9I(9 z1yW>_x+0r~`SHn#9TViV!>X?Ee+WPCrV;0i2eB;HSzZ?cX)XFX)@-k2ZditF>Tq;ZmWFeBX0XR(Jjn5+kA3(;Nn1@pWctpF zt7fL#&{j)n!=fpQn#m@mRaNhkr*bg0B{GtN?a!quB^3mtk3)U>7RrbK{=Xk0JfNh~ zpx5qo5`MMEUz+^O=)JuYeMu?b{<4UeLcMaAqq|YG-!pX8+r1{#>+RzbhICZIQumGT zCU!@-Z^wr0>(*)-(Er}r1mb|BWR$2OzeENp0xK;WZ z1O1fZ6)MN2Xj{QNs`9<+?gq^t52vlX;w=45h(9{W^(%b+8QqI+2eqi$XfSM9{TXfQ z$YY^SwbIP7W)Y~?#ojUTq?E8CTAz(Bk^E!vO!Ec&qUC!i6h z1#;o<(>C%VRvGXmK4a;MHBKwOb$W0ro$4|_wK1CTz+#5RnwHLGY)a4-mr@FUb$Xn} zi>ETW`)5nc-lB49T9Hrs!sfiVZeMj!Nr#iVs1C#2snAid^^_&-Wgh6N4d9`!+KuFaK;D`xqwuZn--a(?552m$S2` z`dps=H4abL>1A5vaULBCB|g&7)0GmmDM=!@~Qq;ePX4SWb<=8NTtQ8C4d zoojQBYAndpWX5){Tbap@Iy}5n|Bh)?R(Y$~&E;W2=2Zd$uH$U*tz@>kEqTr|<&bo7)TLs?? zttFeO1$GA()j0|+^vfUjqaGu@d!M-zSjd~y80vNm>WT-`uHBQ4#MaITG>$uLT7|x= zkC1F5S^As8s7v-OP-X_O#SKp8UJAO5*pi-@-Lrk$zN-?VNT^VaUVJytm zgR7^xF$FUh*}g~#AD;ts0KXhF zYDsC~5#9w?&eQIPL*U?NKc{0ijnp=(P=r( zy;HkXl6o(sAVX4K2{wdK*S_x_xf|nEDktMY0dNEU(tQY>JKon5ga}sU@w}wB{N=uh z_Z_B9s&39o!J}FulAI{?+ScGH)$j2$zs6$L*83iskl#@;Y@4idRdPES{n5qBN!o^C z#hrcWzIabEEEUYEG?qN12D@3)f<84gG2DqmpY0x49DcrMK_9enlinwnz-Ad;TH{c8 zzH8WbqeBetDUG7KsGYAj;`jcKAfyO`UQK|#)<}Ag2mBOFbgvAHq;91B|6^+Z(~i8q ze;0$rU<6=2@$6L|j*;&$*@}NbF(V@*0E!_eG%wUFP^NIX%GC?eb!X5E`aD?Sv-8dL zXX;%spk7JJ(hqi|&&#F33x00`PQjD5Ji(Zg=j&NCQjnL#FcV$cH~0l_qHQIu?#;(& zlr|P?ULI#s-liipllLcj2VON1dq)k>dT`)wJ>-)s4OvP^3{9s%Mnr$`` zN|(1z79SBf4-#vY}y`{i-y`hhWv@he+S1Up?j)-V6$=wPTNzX7E zG~}%0?nkY1BXQ7xixbsUCH6@MOUv9(YiUF3lYHhp0li1+^*F%X!H8KL^UoU{TN%=gwLtYwZ73uj`eO+%t(byCjac$X4C0= zt1T>ct2Wv#?FpPtl=T+;Qyb5;vruSflu7CMORFL- zslp+PRHc0jw%A?Pwj^}kHOCYQ!# z!2qUk~X5~lzD%jVZBjkS7o7a|C=Sp=I zz0srUwHwjHcoxj)9*=(JTSI1q{NmbbM=OHKTKkXTE#02X` zu3ltg&O*P@l?NUJHT2F3k}}uV2J+HO5ZYVf7o-hxsH1m2ie#*Q4eHsSBHg?UlI2*) z`OQsn!riFb0a+bQ1lF^zFO7rw&e`gnw-^>)uqlpXMbB9{^PqG57#vV4mnb=MgmBs!RXIL~0 ziR2ppeC6?)RXZ47KA^g}cQ-6MwW_`|ubMi);ryB5*bJS~NNuL}@m#CQP!y2W)jE>5 zidhdYM;94OyM?-)@1v3W(!Xg&<}A`mE0+x>LV@7n4P+r^(B*yzjHQ|<>uXpIwc*ys z@azp`t6gl3@()7INT6EaPEc{%P}V6Jy5|d9s3=ECx_+sD&muS1u51DH8u_s4YIvBCovd=quh?2~t-C6LKxaPv;Q$-gHkf7zwvB&(~x=keYBgaAiw`F^pJZMPJf+ zA!ffyvP65pl8Qtm3wtlO2;=y@7{g3f{eRo4Q||eTH`Ny{P0eJOR&Y&sedXh^qGz;ca53cCU#?C5jx4!OY+=ooY5g9WI+j@1$7Lr2GpZ3gU zf3i8@f5wka9Oo68a}`NW;eDaA`W$oY2fn5N*oCS)Y8_duuQwY!1Yu}6uB|N~A@L`@~Q&Xx7{8z57)g$kyN42P%@BFh)>iR=Io?G4B z-D?SEso%yc%v7A5;JvS_tE>A#Ld!Zx&8D}toh*;(#l0-jtneRtdBxh|Pu9eyQ?PSC zjZznc#vguTdGgSP$<7agM)brBBH7xw|< za(|MncG;M)1%vjso-3~!u_^N&;_9U8i~r1$^=X}ta{0Hoe)EE7kViAU9EeEGI@tEs z@Wn)jW;cZ)%muD{RJO}T{;R7+D?h7&lALK&y=<<^ zdfw{jI1|dZ-5p#aYM->qcxnrBo#$M}Zd4C{jm+{N!ApfB5-mO_j zABe>?KUxYmvFJIyhD)lg)P(1ZMB|7uTwI|x5hzfNCt|hYh?ZIvQmpQrWxQf8EQu?p5?{%*NFJDba;Gt~Gc4%QtkQ+>4PXp%wG zRS~5;mC~j?oBPq75V9NN!R35nbjCB}S5G-xpgNyg^_y$js+t9oX>soEj{h-K7CcA| zayxVyAg1r)J`Zx#N*k(v1EK{l@>Q~6F|;;$ojuL}vrt8lIZ9n8rar}A=)_O_bXHw9Ow4s8dkMne`A>CH6A&wrRLEo~Z({824bBk;btt+bvA z%6Z^#i`n{bsqzJ{p;jL>Vb^aJJndJ&kS6q`H(LHb>DT{j;QM&|COtdbU(aKUJN6wj z1aaIABEZxpBO)Gp^cEtYf{U%J=CvL>TM1eGU_kU4`C0yWm5`3xG6bltwjP!mbB056%(9~xJq%w%F(5D!RTgjbovC3+RL(p!{ImzE58ROFIq zM{S^87P(Dt-_2HRQL2|X*xO~WnN8)EXtNo=H?(%LYh;UI8jp(($tX#dz4XK*BZf$k zK-C66Q^uBW(#pDCQImWT<+hqIE;}v?l1)4=jbyWQdjW8vrP)Q*p58NexnOwSY`ucp zm8bO0=Z*3<$@!CUlFA0rO`bvDi@(ZJizgm`j`k1J7>qzQ!O$J|5NG($f3}wo10JWn zmM*4ZOYVTld!|lT=-X@T`p}e&SWQ9noqQukcv+Tc+ULyY+9WDv&T~t6e5^b_%7f31y9&M|$9 ztYwJe>_q2!HVfa_B|`2%_vuUf3N|&PELLqS*cVOhZpK>lZ0h$~AZTf2EabEf&Z_b8 z=~+*=%|(2p*YBa(zU6hdHx_XimRKFpCT0#nDsYaEi04J048E4stChV=2>?$z z5jiGXV06e6McK-|D~>maFK1}#pMSLPT%0krrLVFRd1dwo0fgw?6B=E;O(C*8Je$># z6xzy#y%Xp7CYNW$?&@Af{#^F7y)d?*_JpQJaiBGN?LDn%u4jgOT)gb&ge8~PDpnX0 zP?BgXvEryoi$BG21UZrDk= zdJA0drKB3_|9*DC;ZKgoO&H5h;!+HtVj<6*zfa^w+ z9>dBILcEe$+Q$?Xfht1Q^m3$|lQLateRHkD7V3u9`-#wVq>~25D*!B`tzzPBTKsW3 zA@3A!JP>q}sKA>BPfTrn;Bs{xBOto+vNC&p@u*C&cRYcznMvT}G-L^%z(_;0h)r0m z4%)xrG}+@BepJ>&Z8tIm5K$OsUUeSO(bNG+Z6=V#aK=z<;dZB&)3r^UPm3zun=Md^ zpH-x$*D-isIXW4$KVsEAd-|CmV;U-Cvqgha0CobWM^`gu%A0{5*1;w45j9olSNYWD z>0kb8y6Q5JG!f}6vZI4aPw7^j1BTm&0x3fG&{0;J5G1n?tA#^Ooe-ge{~*> z;XlLB3Fs=dd+GUL*y5v)1ostqkxXcH@z9_~a>G#}(aC zKnhff)aXz|3ssCa`N#&GiZVWgadVv9`gkmP%@Ay%r+W0@pK{xdk1*W2BiQjW)E&#b z6*fLL7O&^ICz&YZ#=$Shy9wWO7Tlzb4JC$2y7$b&Q}g9;_{KRt1CWB5KyTiQ?_0lI z&cX_5wy`*<&u2W=^K+z}Q1$6_b;%{qqd`oT`CD?iOds~kPz~IA2Uy?f8hBV-e3r2xcIYCgp z`3BV|HjUIQW^Q?9s%0nIU#nxoqw|lkH(iS7VcQN@^Adk-k%R`qEei~XnFXDG`Uko# zgUXVxpQo)##RYP1pyw)oY`0J;_wY}S<}S5O= zo-#_rEe^Jki5+xK+s3YXZMJ|a#{EBJ6W>{6hod|!i>Zw@v9rn8aSsA5eP!mz0Ajn<&3Z@$qr zoh+l29`s~LffD?P0suq6c^C%-Q&uQ*8a|vS+Mklwe}i#R4sR>x<`dy|i%d>UrY+b+ z=(s&)lXnB(sqOxEq{0$B=S0X>hw;{>77X{CYlUdsDLaR zF@)P}GJbfmebpTGX<*ppm)QQ@FQwxppnE^YUfw!Mbq`O?NPU*k&hO(TIi5T-0SrB7 z2j=4n1PO#Q9v{vWHEmEjEGWW8z!s{aTXindP2l6Toyow>2Yf%%R(0#Lpt#bA?xgYt z(_O+&^eBzoA61xGXr#u*Kbrn7tioMv`OK#aW z+fgb>u(5$J?@w_l2&I00FUs-NPS`@k}o8N)91MkvHaESS2C~aNN#)he7li)WwH%)vxUF4&!To%hE`{V zUnqOox;m{>kK|XjK2B*`B~>^tQZ$Zl)jh@CMH1vx$C=RE6YQFDSHU`B+@^VtjZ>xB z=Z)tGM^^F|gapo4S5@2lGLLmtpb=R%4JD@I+0>Gme?(jwZAMgmf43^8sVx+!Wi{V{&{F=#o1omp5!Z4S>J!pd z@xFU%S0qQ>``t*0Oae8%UY>2=|M4bxWfa{uBMq+GhIp%;uB)@=_XNj$P;2|1nnBRK zZ$=vDD?emGxs@@3<ccadwGMOs9kw4@O=4Bv6@^~Z(YI6CTcJ`0Ug^Y#&Dtan$%zi{;|t;v zhfHQ;;eYH`ea~G~QI%YNtVU;eOwnUez|%dGg1#efae?DftE$&|niYn>RwjNJg*Yn$gbmPQ-&qdluK^j2}Fyc+h; zVv*PRv)#|eWpQIwf0qtPm8x#o9=xSl2#WX$l=Sw?jtY^nyJj%hO3dj zv&2}D;=-RY)Pfyv_hd#1tv54vg6^&h`?topr%A*5kEPT&GvTv*tjF2cVdx;=X!IDl zf`nf2E$JE!)p91z$l-xUjXrOdEv!X*6l<=)TLPtHl4HuosKptIOqEneC8O}D>=O() zOj+q!%*yY(0$Sa!mV*S07(_S!Bol?18`iPNPfqo^anmNW;&AHzkvLJkiBl z++#?IU6I}SjO53HlPjL(E?s<1sq?E}GK{lwYHg6>{No_I6EsFi9MfQ;N)CA zcZPKgir`(H-o}}=t=K)Kn#Gx!Sm8O1X&pa&LQ=kYQP;cZ_MW`z?twv0SpRM05(q5t zqE*r)w#Hp0GKBcWwk}uhtT^1Wikc}|NBK4m7=HuE1)^Yz7kKa%4_8Lcbn-?l(rC_l zrXF{%z7ych_G3*H~qvs}lsHOYG=UpSIP#@30-QXGDIiR(6KY6zbX`*RnlU*oT}YSp>E z{l}uAr~Qv^fNeFH)m8)B({)?hqb2&HTJ^3kF)BXyy4~IPUi_S#D*D@nIG|_Mj{4kb zK(ifFA+d@i{6%2!MK;B{%ZMwJ9p8ERXjF~GFnEo5@H_JrJwd$1Szbn?#GS&WvCkUu zE73A?_99Wq7ECZfWJcZ*jbW@Q9fO7XEg?Jw%0p9p#Ismg5}D18PE z$a(Pb{w6J*K}h;WmthVoHoVM>x3VEKySw4(SnD&ssGZN6N!W12S&XVtWXp2wfjz76 zlAhsu5w&FNR`;hjRN@39<&PNbi|>A6V|i4ihF=3ef6sw4hy}fi`;H8ORWm7rhI2pX z4<9^iU`fob;M&Q*HhW;H_elA+BBS;{rIG`dfE#)fyiV1^BAK1VnGbDk2E z{|cg+hvogEVJ6Kv&uC{uRjPwUz%@g>#}X|L1m1hL(>*tKUy&^2Sk}Q$b7;llD>PXR zD~Nb!-=;okIq|-0u?x4#d(GgEo`D-(r^`ICUhGZvst~H1%7xWa;Iayrr=VUv*0R*XMWct$95M z>bFXyT|fU{HSyI3KKR_!XO_Oj0>!ko(v`1fLB@}N=!?B}*OBUmg@pwsib1QwRQ|Jq ztgp_H=nG!+9Nf{nhSpeh?;f%Jt@Qq|dwtDt%g!#rF6y5W`28YxJTiix-Tp&ypCal0;t>rb#!$>v`Ap=Lzv)#TFckJ|4aeFzuY2w z|MC%weyCYxLn;6D#Yf!7eD6?S6!_+EY1KM1rnn>XfLgi|*a;}Nf(`2b{+4yz1d`K^ z7PWT%f1FexNcUDyR*1-AlJ>tl zMBdjw1W$-_YaqVBM4#xD&cB{c9!uXsSWilc2jFJq=QGurQIe8Mhmf#-mt$`jwy6ul zJh9Jo=)U0pO_@CBijja90U>`_b#bu*_?1upmEyF6?D`N83kn>8!x5c17Yg@ACS`9T=BQ2kDcXf0#aU?Z#Hnt0wP@;rFy~9$+*9Wy#jX)xf~u@NA=G z$hvCUv`W{b2pAvqO76G+-Q@CK2y;Uss;f0Swl+2j*kL#_g(EVU`R~76i+}r8n8OWV zC(6J)gZl>uTT#`>`~vglPq&E(35~$7EC9c9rns|=LQ&WH0rB&5DVs~(PQm)IGK#xl z_y6WZ!Pwvh#Bj?-@u`RZsXFtAoy1dS<`9h2idmz$(qlAglgp_6e(g>px)Xp(Hj~H7 z;6rTC2{IB51LDw$muUBUFI!9?nqUp{YpTPVkdu4E4QlCFGIazn2D>tmk!1!uU zlxeC-GNoF7GYE*4!x9L*3rlo<>%;Qi^|4z%0&-l2g?d2>?#$p%;xWftI{5{8>gYB- z6m5YNFii6sEA1gp64xC*5Mp-=wX;1^dW*$FB5NGy@dh03u@X>P3BLg!^KhiEnpcI55oIzYC){<5H&-^aXhDapx)^FSB1-ZOFIUtO7V ze9z{99S~HdzXqjGw{bex@P3oC@$&MHYzNV&J_XST)(#n>`e0+x8K_zif=sPvx2v9o zzyU1xcK+jR9thOpPTVM)`Ud1XbO>U4TeJAesB@2G8wWm<0K&ZN`mgTO$K|~|tZLNQ zG3y(o(Tc`C_sCrh z`he85`Syv3w!~eK=SoP-tT}0JzakiT zi**o0F=`c&%C`n+7T}j%BmmH0X<@tTptAx&@$C-g=-vlp9`}b&@_)ab|NFnK6@Nr( z7KEBFwuf@rOz}-rn1v&{b}PWL8H`v{U^TftC;vGuZGQx{IB1E!kg#e=fZa#DLQ)Pq zK#`Bzu(IW`wo0t3qVz^7K7syO(s3dtN^0w*SiV(jXc2K_??DWU9{aVRxBm&>Ly#?ba6R1x@^T!ojOy-( z4>TALPPC#(UbN4=AL+k#tNpN(nmgzd9qV%ih2yMzK+MF1uHj@MOv=`@^0IJy0Uj{x*Q0e`i9&))r; zyaUY3S9k}O4>2`3gH)e0o(w;m>Dqzw(}VR1SP6GN&m_WXoP!)hUyk!cI*_txzC#q% zFh3v$`kfvIj~>~mF&_|5F`wQXAElvLIH9VcAqN-;8hiqIxmRhNBO7z_RbBRKN^B-q zdt~4=zm>FMsyPj?OVr21&>CRww;tCi8dHtg1w_VFXTp8?RPV+X*ZaCwXo)Z#=!DRtuAN!>>8* zf`7?)v7(t8{RXgal?zb7nP3jNt~_^a=9Y0B_Y#G}r;)wnO`SWG=<2@2Y_1% zcDwFS(ka@ClD>^inAUkoAFWHfppPwIA$9Eo6mQ|uHadXF`&vFyj#m4Y+ z@cDfV#(MsScHb>CTKe6s*>GV-43^JHJ7HQ9>lcu)Y}uwvek$=G^9QIE$7*eEM<}B~ z9{W|ZH>ptlVqT^Z6UlQ=uQzn-9(m<+5dw%qV*8)O!LL{RQT!$~zWj-zXeqBQ1n{G% z(VfOrIB^qGorD^1a?qbh;eCJQow`iLM@0ZzuE)VU|CSmu`0GMdH(9Y*|>K#;`lK^-LYb)&YBcwGT{aNu!~(=!JrHU|cU={&w_*OLgrS!tjtR=-ds zUft(U$>gp&D=cEtSnQoW;1nfHKqfEM9Im%J;PlyITqa-A6s4E@*>`d`UPid_*SYao zhW#~8y#?oPLF%8%7p^~C>%V0QgT->8fvrEP}exAJgMCubQ|k5MMUaiJjr0U|+?9n4)_<9;T2J&s*+L2wGu zx1aK5-Z-)F0su@_wlI{;kmnbM-8)0!bjJHV_lZ*$)+8@994M!?##_ETVD(FJPI33E zf80_Ts2SV#$u=br&eEbz)s_80&+IGDsY^mz(?^=oWA0p|y!hpYN?W}g;0a@l@l%aN zNmLUglzot7iyZ&XmiFeO7jjvmN1+>f>-Y2}ciDsP8(aD;7bzv}Ng#}<`(%%GKWwvO zf1F?T{;x}G;x@gjm{=iGT1%E7JYwZ6zs`R;-3qmJf5QsewOQ(#jU#h zw)2{ajRCZEy1 z%afTmXNS->ttb=8r$l5L+pp(U+sBlbsxJxS7{^CT2|oiNX==AoK{kdz&9y$2r)lpN z#{Yo|)khI(UWR1K#`%V*T+Mszn<3qQGqk`Mo+%l!;?&U4hd8p1Q6mQ-w91BOE(c#B zF82UqN3giu2m%GXy+zo#1hH$(qQ>ffe)mkSP4jc13uy#TTGuw>uUb z?}AJ;op@xg00$HkK-hJ|9QbaSKk}5$y2*ZzabQ-sl*9gRHzq78>8Y=_l%)jX$dVrC z9k6s?)O%dYG@9DUo)8V_yN;C>Y5@fh-2j}(p*Q1PD8=R=6BsPleguS<-lvoS2Ew;} zzUL9IebJw$MO9GqLwU)oif&R1t~MM@_UtRWp3i?a{>u2xW}}+u^a^_ls4Z1MdI|=l z9w&mC%%~i2?JOb*Wy+qVrvJ<=ia8sxBC!)cp%M&F))ijsFWGquq*fKRRg!E9%lx%p zP^4u#X&I*zq?;FNy#w}7unzfq%ug(ne#v#|H)ci|-aJb!SmD9nF|mnyBBFYL`T!JJ zZdTzG$J7Mx7rJwD5#>6)wz4*6c{-`Y>*DRt9eRGCMQJtIeOg2+L-&OvK{XFlv6)b92W&S4frtyX)XX z!3+!xfnb}iNvtfh;I!vKZ>8l3Q_Dr4(7~GturF8k3zt=YXDBF;a2v^~$%ypgX9FI%Sy*eCN1(K+5Rf#`la--B>X%epnU1*oqiJL~NH2n!|BR!)o1j zm${5}mJet9kEj-CrPvFcX|kS|c>B4BddAj+KpH&=6rCu0gBW|`ZVsuG{?WCbpE=07 z7$9Kylq8*ABV$cF8m!7PXjh_bhD1+lMP!aGjj$Ii=^H#<56`A^SVSl1qbZN7P42i& zL@3Ko_ShfWrsdw6_Ya0=1uR$qS+>&7fWv)$2r^ry1f#o5W;x%vhUq;^5VBqAaYpu) zsXal70p5BFAb5u-W>TW{_xZ9llJ}BT;RAQm9mH8&WuLBtt;S&L-H%1Ow9TB09a*xj zhs&yOduYlxoBPb(^7X*OGB>`Yfy37~G8B$mQAh!NTne@#iaW}w?D(T}@=#`)m+kCH zofqN8A9u;ED=rgyP?0Z)f=WAj`y8}ZuQmLh5ip?c|vTSOh>Ke9rNNtbPOH;pK=+k&5z+!Dh{^5;q5?i5VJxM zHxu3T6|yZvUtR4%5e&yDDL}Z+fdl$h4cae}Qmj=!(r8(aL7=+#Z6WtGH9GvN%)BXS z$Odaq_z+i8=RKZZsv~?xLOF36i*N?t>(JUV>@s52oIN$8geNsa@x&X)?iJAr;U%AcY*B@s zQa6Ku&)g?st))64H!x%F1M0tYm#E+RmPfTnbO-xv=qb$Be-`808&r>68U`YkZ!<2x${FRk)e2)Z(pR_6Ut>dm z+oU4=e{_9;X}-Bohh!jVdB>rc4^m>{OWhtc&Z_Ru=1`?r>%^xM{nK+~Ny9LZ`p}xi zO_S4%%6j1MDr?#obV5w$_ipQM6V&YA4KWk8O&Q3I8Ep@SOF|}3wAkO}IR)MCDD6C< z{rD#&+SodFB@j;27;D-(`6h)(DySgU)NPybNWeqe=*2W!P#bzSK?;O*2HoDPdsCq0 z35}9ijF=lsQ3s+| zygI!lQmBvTPhVwvXfqZLR-M0p^?+D--KJH zu=o5(7hvE(q>f0Sv2p(m^fFR3Ng-Stn=1xdCI}YBJ~u&EwkJo4BQBv_z=ehzOTxz3 zBPGcf<8Z@9gCrtU7PNdL{OvjyAC$O9?CsqL>HBuW1ykukwpa_#gjA%TOT9a#+d;)p z|EcaIDaL@*!HyZ3b#=pkn}Cs7eePch%th|rrxZ{X9bnZ)to6u4|3Vz8TtCcsqpj=e zJlxy{IQxXe!QhwE{25Ed-Mx1DShv>kn-}_6>D8+b)6Ng_FjCsCLJyKDNW=DA<_|VI z^#I5mm*!Qqil%J+Kz{MNS*dPAC?u0rn(k<0OzmEQ(nR{^q-vQuf%<1GedLQ%m8D9M zVqBIiFjP#$1awlScDzDHUoFiygd_`NiGF`*G~18|;cFSl@}E*c8Z=f}UV`zyRSab1Rg5pFUKro(g4rM?O7j-mX@hh6EnSuE7yw;^Yg;!LfcD1 zFyxs$St<2m|AY*=DTiF4lE#}d<`1x~qyt7&S?8L4!{b;95-RRd!~}S41jUD|$mvpk z!;a*n+*NCKvTR&fM_#8KJ>;781Mn&wTn>^sK#RzoLCJbE={5&Y@Knvl27 zE5_E4thiefO=h~{UL7ozvftxs+)z`I!!Da*Bp1)_pIT6$n$Xv3f<3)1R3@GuB>?gp zE*uqYvK0&T#wy4$2XflcmGW!M2f2}VtsL)@X#>;9ZiP#N61-7fx!9$TB5xZqbj!5p zix zG-Ad4uZ;3xOc>wNzZ_0qea1fDZNcL*_<2kA&6~62MneT1y-Lz2vJU)C8VdcL9rC zvt%Z#Vl*t0eUR++?9}PW_b7uRT+6a=AkD+6&YY!5{X!@tF{6NHwAMk(`eeN7$@HHO zbdimgOu>xE@-BB+A2{=sgvtzuv*%wS7d zDiyUz*Hdb8WqIH|$7%0uS5XsQPvE|qOu?6O;76iZNQ|$^cYn^UMJaN%sJOVD?WVL> zCF%_5jTm7=0kZWa1_OG`3dP$?AjoZbJcy-_4FrD64Z1jdLi$+r4~N5bt-QMrXe_#b zhbgc}x36|&JDEPE`w@z@spPexHDfrlb1NZFhoKgAP`%(v=VPz$Q9<$>U*hNtsz5|0 zL+K8`)CdymQNY#7o9R`XqH8RHR$1!bxz?24;UL+Tu&W0 zY%45)Vhjw_s*y?Ud6}P&79sbtLIT34X*DAUXf2cp-lsqtH|%=u$2I*t5+Sbzx?%MV z?e@1&*RM=CxIlNxLBH0n0zgAd+y}6*y6je4$tCrI_VVSqsK@H{RLNMxJa0q5D*`c@ z8`s6K+kzXIkBk45GBf>gaspTN(U>mO<8`xMX}Y2Am|j_3uH#+bhfh;zeIxX)Q2Yk| zr&{-DuScz(kL}CzJDC0!<}};apEf~B~C>5!< zIq4M`sT5`Ri`|>a%^PkW*o(5CdcZV^YvrU}*m|U2rBpR$rZ2yz#W|`@YHUfqZ5;h! z#`LC^!TOhwFTn6h=m(Yga7!j#_*SiU;RTpDwps*Mz8Y;>z&-`RNw6=Yu3<;~ldo6o z&))AeX#2uJ%vHva#}#^~sb{Gx+T`;5baLwWH5MhU!|HD!pFpS=wkc>dIaK-5-H*PG zm1-7teSsje5T8_p?OR!wUU*ODul#dv#|6>)Viz`FRqZ-z{oA!k$st?oMUcX_c4qxL zi0Dgi$2t=Rj{uS90xE?^h!C|3+vt-9h1fL%4-akD2*{WxpM3NOUdzO_>2mKGv~ukn zCs}@)9^O{`k`skKPL*Wg(Wt4HNrE1|OTuB#rAOL!Q808AYFJc7`Kna+Xmr-(p>Z>{ zhikz?*?q=XvOYy_<@bZWj8q$f4zE9E^NB0J;YVx{ttR*76nrIpeiN^5c$L~wwNO%A zF17a69m=bCb(8My`sJuoq&}_n;LQ}aQT64Lm|tVIady1*&%7_Mi=h39q3&!qe`ZV) z!ICH_xW*A(HaI^|!}KDklJ|b9LWGZY2(rp^OUmay5}GV!aSCtmkjF~dO@GSpc^g>L z+iTxh(S%zCkei!6vt+;;UqiIVDc_t}#_Y+mh&&R`dXIEN9J+ZW}ZqUBNU$ZG2 zJ-tB?g`CD|({iCnroT?`^q+iv)DufDx=NoSdqhr7z66-qsJfj-ZIBjMmDdGAqPpBx z;ekckL;Z+AI5CVw25~Rt#8WU6E+(Jcx>~Ls?VpdMf!)d)_@?;`YNLOK;^ zVnp?H_<@!+tWArSn`YeU5C70a$~)xIH6Hd&%QENXLJGA);kJ#O@gyXS4&C4psw22` zSV#Mm@7H6s0o$EUclqGQ`CZutdwE5ajXkwt!El&}d%vf@@C%miEXvhi?XgX3@IC)8 z)pIXb4dd5~h+!140@~Gz4wGF-Rc+;}h|0+j#fr+V%z~AoMSjVEqx!|;hT!TV-M%f0 zf+B(C0-t!NC!*iKFWr}SIPS&w>UH%Frj`Gizp&^nk~B?T#^bZiT+WDgA@iPT(Q8xh z{RKPlor)}a(d~qbXys_lRm@u@FG&>!R zXmokjZ1;=U1ux>{5I?-sCAGpfo}RQi9fD&)?XxicDGkCz&$@x(5E&}KpBhg6sopoE zd~!97JgMFu>c~CG9PN)#9HMXHw&mQWY9hIg9L< zh6wIl_aZZnkQ06(Ccxo)Fe*Fa!Y=FJl`<2rQK{aW>1tO0-lVGYtcdEa2DlzJRd4-2 zoPA|flwZ5IA_yo-NQg8HASfW+-7z5D4bsvzlt@XJbi>eHLxUhlHx3=rHFW2D^MB5} z&U3z;<#X2J10N>tx%a*IzOG;Gx9~lc{7_U`q=!f6FaG!wz9=sr#!pNn@edCSuqo}9 zx7{`V9;Bh6k&%!H6cfM1Khm=D)b7-(NjY5pjZ?P~Oru$`_G)=jx`yVcRt@gOp}Wno z`etiforii==v&jz;d92TtXr1b@2-0Ztf1Qvg0QLC8G*E&DB}9%H7n{*tG+HXWsWV5 zZ!&Hqj*RUxkRJvaK@I1CtENmC+4PC@ySaG#p;Zg5xX>YJUp#fwdnH&4Erjs*Lh(&3cd?u#bN=;WOb@|W(p zTXkxE+kL0k2$!1bmDFc=Oo4qSV3)QAv~SyeM<~GsqVi4E%r?u7&Ly?zq71G+=8#2P`-5^28j*(BBEQGg~ z%fnQXy)PY?39vRR)lZ&J3U?)6vN#;Ek_OjKWm;dJ#~gPl2O57g5sc(G&=Ku$c3)?r zkBB@6vgxeoO}a{m!XCY8+mI%mHGaHj28!q0aURDrDkaQ0g@j29N53Q&qte$PaHBqDZ1;tA>4$V?Q`Zcj@)%jT1#`N4GXq-_2dVsD?MuMkCA3d@ zfT&xXArUwk5k+j3C7O>7+mYG*czo2))Ml-G%(>u}BmHAOSpue75`a;6SLYh;U+cYq zO5;3EN9)0x_p9-ZW^RVpq`90l_uf;2Kc#wI?K*KC^p5x`Vw&f;!e$-?p-#Vm^(g_^ zN*Et!MW0!EDz!NEPSV^mtBU^^@s>X0kyEjXq3-PM`EDQMwn-qI%M= zt<<{BN$AZo~YT*39qBcj(cAxnX9bD^h0P*2?tWD6nZV&qA}c`VWX+ldhbOA7NRYiqZcJJsn4M7ZSfQv4u~3w8ded zfQbAGlbIjX+YnG}5t!{6l9trTiaEoku^20QV*j#(LWxaM=fXelC{U}o6UXX_N~aw6 zl@^#~ewNz4HtSPtdUxF^mw@`^88-S>in;A9yz>{HU@@9&dEUF>s1dG7wtg54u?f-X zPb!}W2}4Noh#gD)JFU6pQ+M#CKPUudTxTMScR|=9t%{^kG`=IxO2&im~nl^8PZr+TG(Hee#nf2o#{(bCNxw9`kg z>9`kjahSi^usE*;dTi*WGnCaLLL0)yP^-}$EzH9x_HyC39?DZILGLNFIO|PV`DH$rw z&CQb*(k9@rmGydWN>s!ci-csCX0cO`C1K8UA9rOAy3qFgxiaIEg)@kpMsVY(#kI^) zv^r$Bn8mda?%rW1#eK$;V8d)2Tr(|-8y z5&yjgd5&b{o}KnAJzOMHWSLA%@tbngyIJLAA|jO=$j_eQC=pRM?26WADe+d%ScxRh zRh4q3B9GY=w%;yk&t$R0e!h|{0?mMGlS|OC87SRru)U+@c1knl_a=w?p5ob2h@+g7 zmY4uy0nj4`!%O?32NyX?k@!8?F`J7tedi^~x2&Eev8XnmG<2MaV)5oRY z6T-^2zJ@vv70tUF+&J&ynA5g4rr!aY^j9y~wpw5OUV|_mtH46zeCZh_F=zXYwa-zA z;=PMwfO8t-i>Y={#34IJ7_dz;B-jct9MEM5kuiKN(pYIFU4jqR*2fuM#rXXl2-#c;dnQ>oieM{|gH;D!_&{S6= zcP4rcT`cQ<+byfRD!K9az0c>6Gv_qN=x#QsWlxvXq;;wFz|HS(QMHZx75-VtW!!2V zu@Z!ZcENh*t({uXL=m-a{wb|sDZ*LHkhiN^sj}a;vh4kG<-1YBm~MZO8-$) z-ufiqcxIzicxzr;PJjI?;XR*86A$V+g%$4a84d zFR%U14c)jmc0=ZCgff>N{zK(#&h$8>7D3$w`I`diU$4=X$;`@X|4i0lsU8Q!-S#Ci z8$+|Rvz1-!rwoI7C-q(B;GGe5swMMqzizX2D;0PL?Ydviaya=K!&+_at0o*5~YE@n10+X>u1T-6LF^`#7#i^DNv zC>c^$cuWxR?);34_Uuba1LsjoDw?29jHr)s+NG;waM(_SvurxwFd95wXj=8UlRtRE z5-kkNmqH%4@#e>&P^!*RCx{CAYu~vDgU{MQo#azOZD`E~eG4Wzr!k+{{j7}Gsmq6` z+IMh977>QksRMtugb7RA*?J~Xhj+iazbx5#X&Q!clb-YF^4tD02iI~K*T@``kmN+8 z>4qLki+kxvw)3=#a=7HB*1=Kvj4eYZi#8)Fb9KgTS5CykK#?FPeH(INuJhugPsH{# z*H=ZuYYzkQPcP(BHxKjFH2~UKxZzZrTuH5>-B;v?;^Z&>AOw%|k-rUtT~)d7E>_ln zGpP0^)&U5I!7R;LEof$L!N?})Wqh1;W(qnvv*YD>EcKr+jzB;i-F)*oiIuC=u73s3 z*~~NoAE!RX-Y@y7NEyC zQ>_nOz0J-&X0}F?S2^ll+FxBS@S9*nzOXw#2Q%U+BHLyP;7H`{usod^DS7$$wf+QI zF){!CBlxGcaF|5Uj+77-a92qE8Mf`)EM%(VWv``m=)d%AQ~`Qkpsk0Ax|T2Hb3zY- z)J=c16UcP5n(d8r_xbHyBFhl?P+u;#yrp7F67Fr<$oPB~h0K#C-VL`q79T2bf(V1#eH3JsPWNWMpNj`T2E2LPB_or4w8}H>}|&ao8mH zSN-?pBlrFWR;bw49882W*T{Kt_Io_&_R-sUxSfj`=;KYdq*7c)Wn9o6 ztyecOqY-~I!~f3$P%Lb+Sv#8x`)9y1^Kk(91D|O^Be$VpI=RM&4nFgiOZcyPTi{7; z2^G@57j9s+_#PKW*vmmn+kGQa?|i=qS^;d=Vw4G7Q(#~vIUs1+-f*x+HR z$9z#os;3RTzlaQ})u!#fzDAX4(~XS(QDI(=aQrhQZeYA_tE5|FS^V~CjEg);W0d?k$EV0&kW-$dK>692fiww82o-oBf}VVM8i z?Y%2wrp6Am-Qs`XK2ywSKwr9wFg?g#@UZ2m{J-ViSxAQ=pnUxVq6OU<7UrhJgf>fr-}dJtjd(c%G8*p zlBeSR_rV+aiT1GsVMzOZp5kv1E#Ni2X>pH~^h$9E2+Y7|Q~JQIKAWgA{`XtW%j~;{ zZ>6lPY@-DTtbsmuiIgX80BkGZ)yYlZWP;2|6<0C0wWHuk+M zm%4f4M@{}->ua_V^#``1{Op|?Z+1>j>B~O--7`w1U(yDz8>WT0Ds|CRO0?gDPuX$! zoo-yF1zlwx?jgSK%$QCgonCQunNNZ^=B)M&5>lz<4Ye<+IcBlW46YT?E5#UlSle1Z3Tm$Rr^qryY63I&%$M+S98kt zJ{kk%a@AQ5s_F-u2AFb0i~R8EkC(NT)oMeYh);#{8gGruJWb6INRhLsz5pUp81@?E zHI8|vXgo{630ITZQy-Q(8dVQ%+biZw$P0u_*Fe(6K#`*fG}#`kA*I_MqvejE`zC^x z&%9?doYdrOV>>*IAm4PMhr3c!!$ze2=~Eu?bblbf6&G{9g{yuj79&#L&8)SSR1>$lZ1ZuRUe z_d|{N`w&uVilPLZ4yUqiDg{=I#}K^#^OAjRZsIMG`i*(#OzLpP_dgr_AVc(@azs%r zz%JBKLy*p;wCo}{WJ=h%^Fp@GS#zBXmlD9H<;DS(JXcBIaMZ74ncz27LH&2IPoKO}!P>chiM7=YhYTdAq4T^MU-dQm2DMx;g^* zzx^|FvvM?M@hQsw7DRrGvx$ui6E6w)ka!9w2^9U3cW_F?EBux68eK_XhZ9dW?M@*% zh5E9m5a$hNz2t$zz8J9ZC)en`Cv%>5O#YO-sh2zGj%MDV&u=psy0}wQD&JO1^vD1C z<8P&1Z9Y?mmGJ4FY)M)ffX#scXMM=FDjK>b(JXsYqF<-eEpL?X1QvxgWH_=G_UY5D zX|^Rz%#Dd>SV4}lfc}T}a7AGhjHI*uc}MQse$7CjRNOsTcMd-eTfgVmWL3QLJ?o6;+D*I^u$ zzu0j$i*tJaz8@59Jc(;n_Y-}Iu_^B1aRUy(tGVU`(v>}Ck`4aT`cW>uS^Um@uVDk? zxnCzy67XJCU(rZlP^a<0@uzuDXOk*DxYGR+HAp%$ZwiR_HQ@NIn$#5)2CUAyMQm^t zDPx=5miOdrGO;v25$c9#B_!sh9Bm5`i<((k67CbQ zgNpcT)S#W#oRVpmTX-CSwCaKb7@aZt$A}dAs3SJ88rFE**Gaod^d?4O!HUWuZZXMMXvLUPSU3=$>!9R zN}OpsF4N_JgESQd zYwPkHnl2(6W6~Vw&47KP-a+u1j&Cmlj|IRDQQCW?n#U(`EYyQz@9}4y4}#Cb2?gJb zPU;oB`twAxH*@8)%HiAIhAGoGRjNZ~_8ll4qzJo@=#YD2V< z7G!r5r)5aU$W{KgLowbf5hqg|JEd(+C%i7_E4iM(@1c4qx@PFIQsZpPM6=ZL+;uxW zY%w|%scL1~?^RLWg&{ws;AZGmg$xO!Y#8l0+A?POY02TLK53TKu=Z3b8d2Dl1 z;fP3JgcFqz2g=?o?UKB0 zTkX^06TP8Zqri~Ne!e1M95COi(V>eV{@qbL?%hS>g7WE^%WH+8jQa}rKiQjguDMG= znvl{78_jYiRSZGQ9ql2TfCw`zOQPa_1Wzl?jS81Mmq83@*CS67kI(j~)l0Z9-g~9; zB~wi2zH>4m?d_?z9aH@s-1{V|wM5CV{A(vKWV^pg@A`|k7E@!Ui1`f`q32jBj|3=% zKu2w;QPFgY*kktYI-R=9$9whgCQ^P@JtnesMpWQe;A{1$-3Y762Bs#(!*TnoN5>_u z2?=!*_G#G~JAHnR{3(yRX41X9r+NRj+nBNdN`0GKl{N3%65Qg8$=2n3q{zNN`VZ^{ zIyEL&4cp!v(+c=-QpAmKT1kr{>2mYzA~AEG*D#4&VW? zV)wHDz1!yAQ?Z8-W+d@k)<=Lk08Z)W3|&Bj?MkZTS4J+FI>h1gESwG5*bXfsf|JGE zZ5gdaZ#jHIHK|FAdK`0rcGcLGyU$D+t4^)Oy-APY1$_i*F8Vjo+{z-I+#zcES#KJ; zZap(Dg5oGN<{|BN@1u>@_rQ_lB7HAMCKk7|Rh3xomC;ondyWKirmURMz_VLQxbHur zyQZEjUOU+i7H6hWXxh#fPPV_#=>6X1bJN}Pol9TQ&o#~f?-bx#WxE;!lwiBO(p(3g zTWyntqzIx)mjw^tkk34P&aKOEfFsID*Ly^tPipLMIvmGscK;gxGm3C6=AT^%l< z@JOzFf}TK~92Snd_T9KFc5PTberi7Aw|m?(RVAC9#@#55>seljc%JErrrky19&5!l&3Par4im$ecboCU<_irBYyuosmuA#wR;wnx!8 zE7bnO0zc1V#{x1evd^@rdI)ZLB$v;V3OY_7DU*%4^;J%K@M1)o60!Qk?z--C^!B-F zX7cvO&Ie+qv6jldKcggR+Xnv^H{v3|^J@BuM(&mGA zO9Eb5E2!srAjBN%iTIb%Puw^~$E_AV+g__n^L%3^6xX6dz*`z?zd}!d?ubnqHUt5x z>}blC{4^96#xaZH=d5Xf6y`(RlBCW-qL7T<uH{hHhOclT7qRho}R zwSdo0)V%%*$Gz%|YJqp#&q8WTNB=aYOFVQp+>Yy0XteUF<_g-c03`E2Yj1XUt(&?F z3k%Pj6w)@$jTlULdkookCSPk-i;mbR~-`-6ycG&~rm95i9`(U6^$l>7r$I*#qUV zEWBY`HhuKOo?#`Ra7<%7W|;sd#Yl{sSm8GBl)jEZvCuL)&oq8|HoRqz0Ua&)!*P^w zH0d{|kHn5Py*$;;!w0vjJ=TTBHm@_4Y{F!$|0MHl>2X+)MZf)aq7PEl%2xB}oOv@( zi(^Yv!}OM-(ys^>1h)CpD0aaT!KxQ9?3)a+z&l{LafgNS;bY+xq9;nG78Q3Nz6? z8D=6M$$chppMJa0f-^_k-ea-QsihMs6$}P6KlGzC4c3vv?V>0C7y#w$Kvs5?%$en| z5|R;?xFcua!cik18y)>R#d9@osO#(`kXoMz-S(ijE(xmZ(Y21Qvme#_v_OZbcmp_U z`rbQU`o@{&{dLhS+yQhhGWR)B!>YD+>23uD$@WN5-GkUnbdW~#utPQZ%MAgzeE#=L z=UvzB_ft4xoo^}jWaz6Ea?C2Ai!rCP_YG_ML()PzlQ1!(R|#)u%hqROR`2?$!cRs* zhh?JPdPYFSD3Tt4v8xwll5%_*%d*_j4Q45DIdD>)#&l|Ds4of<{{5Q1vkHvC#?O*L8N`lErGOjGExREuB$-_OnWGAPB>!b$4 zfd&~s34WVR(j2FXDAmM~+Qy8YqC7Ke?|%z0bqws{(@L;q$)+-0$!=Y~I`SVY)JULf zp4sWlVI|NxJRZikQlV>?@pw%A8Vf(caxWUt>?C{O?2r$N^0?xMjlOP*+6~`$1=RzE ztOUGz?`LOAor}r8qraYuv~jiooMsNm=`iL0r-`w#hyLe1GY>tShxf%}49eHfVz#3O zrqZic3y;IGwi)4Cvy@skBADY&<{~En7$|op|br64MZbxPP zJ>EC3sO`BfEwnyBC^O^PF`x1w6h`h`mg?+>y-F?$DGuV1&1n1q^_2kCfz-6RA6H@o zr%CN#kbRibvcCW7`0Kg4Ovtl*udy>&LX(0J{qWtAK8sS9)P}nQd=|TNrt>F_2N>RE zzwUM1e3f;&-s(cinU^5w8X#?oC=V`Kkg1l50<;PxM~e>NC~rw5HWV0tE^pV&S2F!r zux4BThZgm@ZrqJZk(oKDlF1D8IxTe2O)F2jz#^8^t|6TwIFL5C|H~7Vig_KoK?ctQ zkaWgX6|xn*n>I>emRqIa+>3n(N&n1@w>G@|_5z!#5O%InXR6O|o-JT}LXGu(YCiIu zzQ*<=g%d&&(=z-Ml|^K;Q=aq?2a(NPK7gMAkO2k;(kFEP1AxvLH&sY7F@7)Baf$_Q z4tTp=Y;e>5oXGpmx2hjZc2TrmHOHf`@y$_icfe!Np68t^L23K|=jX}*&9GRhrBk(d zLBTF>bmSe19+6edNdl#kuPUZeR@lNYY>(i$5L>EBK%Lf+jx{J!5(Gq4^1tgbA-xY0*7+~x+g##Pu_@Vwv z6)tTrOKb3UHg=n7radf@GUOzqY zB2#p)aide6RH0rLlXxbw#96Gr*YMc+vzz9-9XwC}@N3Y-VnOguC>ig#^_b-Nw6cPIOI;}}ic+U>^ZD`ebESNW{ilK5 ziDm>!UWzy``4pb+`b5+Q4+Dt2z^I)#CTL{d$VN^s3|v`KGLR0VNz|~4USj$?1@j~H z6BeW)C`S(if6MMJaI9%{exW(n&9$va3f{Z{68RcC@3uzpt=Q+Wg6nh@ zEjd?{hJC5ptJfU27(9I6hYbf#e(s6ON`}8Kv9oAX9&%K-I5_3yom$o(b21|JFOS&i8C#2R=HkV=feFk$=5XV-f30!8 zWsLKBQ~?Lml3Rh4*Y*9|A7;~W-Ak`NyS$%gX{ZjVl~QNCFpLjtUM*xuJ7humMM%H2 z_sz&g*{k$D#3@@(;rfD@DOI;fgLP3V3F}koSey|&HSP9qMpsB;6r_A_57@ec3lo{qyXJqf|I&O?yMN_Sb(}e@%aR3 zzq1)$77vY1CfzU906y5cTj#d1j$SW;yK81NIf8gKK4KT}ukag>7__w3SF8)3%dX7? z=*_w^LjT1|nNvIrw)VXbR+pAu(!X;t|J(l~vgkFZWZymB#4peQig?rBkc2Ykd}i ze&chlcF#aQDP2cmeb`?1AQhUIea^gj8pRgO-1Ta)eZG~dp zR}c@9E-fMyTB#p2z)&JC4z=~p5;<+ty@=t+UH>6_mdIinGQX0@@0?v1Tss*4 zqDo4za=rvdN9;&LI^|^FhNpH`w4_u7vfMwJyb>Wr`0nRWtAg^Y+m^GRbV-1)Cnls` zTM4VKPUHEOD`1a6&M>eATk9T8ps-wYrto*p1SW&4Ru8MGz4}6Ni02or?n?u>_4#rg z)bk{b5J1scxXLbsg9#ksuzfmt)$C~n=xHmQ4%L+a;ER4qz-Xp7<2qy_etmOe^nSfo z_x<~iTUfmvK-<1i9Z^fUalExmhP$qewg{N~-(kBAu-jhXMzv@Dv#DRk@!wHKl;S0(+Fhh-x(xZ4_xT|(qYvmlyttBf|)*FwTU#Jrk~Oz21M!~nI}M`v~~G6$mlQ3lGpC&<$|c8(xyYp@erOp8gL@LeG}P6 zRob;2a9GLuI*n$@RyUS%r9!jNV~X0+ zU7SNqG>5`gI*-;8@AG>V$};x;`Eg3%S<(j7z5J6*Jq5Db1XBro?&&n53(FMnY~`f# zMaoeN583+`1=p=6$EUsD`ZF>trg!?NoO?0;Apj8g_a4!GLZ#-IGx(dEP6Zc7Gr zynxNJ-LZ*`Az9|8^ zIax=IXbu7yEfv6D=8R94ju1Sy?0;r5=WOc?ncaI~G^fY2g5+Bg9#gS6O+T5wuQ!<9 z?e#lzI3z0Z@fnNU#P`(#6_0#(HA8{7^zwnJ-U$nne$I0~T0pnQgr9-~phyo|XaRjY zAPlFAz92VJ}GAi4oEMntM6hn}A;N&YU zbv1LGwzRRL>b)~8t4Z@JND@s+4hHuvS+ZPf!f_PTMKrxt;~*rutP&6qJtrNC`a&U8 z8Bc)px3vI3m|3GD0TzIM)syLpRjau8J{9u*aRu&jPDv6D1AkH8}~^7!D4Y0&~slHdUqMa=gc? zfFKKTPH6w7Gg5HcI#5BD;Fd!&go3}Y#DCbid(XQWwCfm%>@ShbgOv!l2$aQ?A1ij8 zDDRq6y=75Dsu76D)kDcYDp_uKIc(SBn?-asrLF(tH)hih=PZvHm?{CtK7$3PS z6muEBnGmsht7sNw=7x_3^#U~j%eWN#{P)|SOJWXuw%?P|s(PWjLA)=+zj#Vazk$Qi~vdPNMH?lyv%+)w+T-w^(4W+v234PLwR? z@ohmU%%oHkzbspqjGy54Jjr~WB3HQMi6r#;3Q$!qMogZXIcY6}&LXW0PbLyhXAb3z z#V8r3KIJrt0WhK2zKGLU#X8Q_fxg@Q` zd!H1~!_PD-ol4(`SfF>|qb7~$aC7&}zzV^n>R|?1Z;$M!3+rxUDzfJz`>NIV>&N3q z3mn>Z_lKo4Xrk+71Df7@ulhQ2aYYR5mA2Y}alQ)R!XM7<069jZP6>nV zO)l=uK{8bTF16p@jksp^>#s&jO`vn;Sx?QZI=A?2rEAvC`BD5jv&Z`^qzu>UaIB+G zlT)V8p7V|S_(I_<@~V8;{-0nf1p8~&4+6$X$9i4QA7iEebjCPUO-@NMt<3Z94&%{K zQeoMTK(g>T<#nBHdbX92%_I>PbKtv0UmA!OV{R2vg)B!dk^=}StK8vB+{!28*0Fr^ z8rp_+qpkygVmwc30qGXVO%rK2iU!f78ucY&hr{xq3{H7XVEi$7A>nP5iLnG(b~kq3 zxnp4~d8Jz4iTgJK;g2|&EfYGtT$qGRdJJG^)lb~%&jDSnM99mK2u@?+@Q6iKcS5BW z?^^eTKiunb-5is#5z*i)2k|&kRvf$Ank1D2qLlYXYFb+OE!k9TaiGlb1OoRGNByXRWi_8T|Fo@|J!j8B58289 zvEWs){KQq8>jxP|)c78o2q8S7^g9?{UM`5wD z`Qm0U?w1$F2xBwn5xx)lkaE3-fv$#L+-P1aeegoP5aX!2$t~n=)stf$)NlqCoD#rI zO#x&lDwj=D-=?E7?MW##Q2oWYw&VKg!QU~6KIp_m)OX;cQXq@G_9KpW7;vsy7rf_i zVE1Q&s$bCqbRqRlDQ_4u>hw%P#m-!-UVtWAE7m$WSzsqbhg%Rypu+`J-dex{O!FOK>#8!WNm~@(hw3Mf)($~m8F@#NKE<8bwK{j`)$VS|nodD|WGhxuQHlm;v_$OF z7KWuz_sYML<7Ca7D*a?$@gRi2+jM5SN)))yAOr$ZOaT*b^2aKj7e?S6sPb&+HGuc2=z!4re0maD44j%W5o>#_ zg~D<@me2SBr-9X%NV>V}c!86N1qyClv<}@d-NJ|)J>?4AVzFgX%%t?61N^T$XV5t$ zFgufquo~tFv90#K(0dZM3sVV@Za4u`^LInD#eDRwrk)~B+ev22R>|K1DrHx7#a&w(igJ3NTYMEu@id7 z_?ijl>q#bZJI6PBbo901cG^v*_{;i31PWXEtpv83_3qDt8x%#)zH7u0=bUgUl6RK6 z-wWXFc%N_HuMg^YlUq@fcsDR;bE~UaY@6P>GFgr>ftb`EQ);ZqL2rK*MQt{hMQ=B) z|Fn>JRKrCXjUQZ5n145qrW{oT_d5C}6IIMnS6mnf`AmMJDgAY5Wol*%X!=@Sl1{A7 z5mUiL_(Y!>Wy-*UgLJH8*b@piCu0&fY5gMZL#5@M78e6e9jW(=ljs9EWXwB0#=Z`N zE^QiKCmJslY_&-7iMQ7#39M18)6jdDUJ50xGO`=l3z_=^j&;ImPVsZXtl-vA(zJrD z=-=4{$QnMOU#87qXu=mI76YW^4O!1WmWE5hN|5RxWl_RvOGX#^1yXD9f*AGX_1Pd(9 zh!xSSYrnFh*jx9y4g39lSRbuO`c>YAP9$EG`(&YKq?bfN#ni-9=0*;67M=t3%z^U@ zgA_o}lnfeM61Y{xQebnS7*o7O`l@B(01kQ?PGlYNc*7eoam;Q(>wjTn2s6+PVp(x+ zxuMW`)>H-IS_jvfKeDLsQ)uj}`8^{Tb$HzBE)T@gB!}vJws}J6RoKe+xSi*;rityg zdd(CG?Iy}Q`hw@C85Qg-6)S6|XZ>s0(9A0PWZk%SrpkNL>!=`tosd3tr~==4);2CL zd)@O88eyEYaNclv`6&7o-OtDESv0<`ryl1raWwBZIoT5tcBNE=&OH`90!12)!lp{! z@`tQQgR7+I0yB3?$?5pd`|}aFPG)IBU~WkWuTndOH1G4V z$;jcS<~r#8rxv~H#Wr=0E!k&MB(|mg+XAtXjeTK`YW!gV+!=zVznHC(j@`o^SkT`D zAJXfTeO}~4N7uQH!d2HV3lJ*nZUSVL`X`ez&EhHTJbTonp3$9Qe2=Ojn70K?oXt>U zjr1g21R0-gbaTW8@^kbP+y^MQFUdskuc2UC+9h197HW3H>ijX+4dCG>ePR6*$y1N` zh*)5U7=XH{tA*)*znluhuluZw*5qs&kX%-`@U2WLQ7k)GdR`^Cq6LM89{E>b(Tilh znZ*;@xAY6*OV+m9B&DdDu%Zvj*B^~md8Lv{z0zB95U!?PI;e3C{c@D={MEjxU4ZJ3 z^{j{Q4$)nE2BqA(8bl$+9!h*^Hlj#=AB)$sqXp6|a)uzf+~KS0&=blm{PQPbhUflM zuro}>YNakAQ2A4H78~=D1#JlU!lKP(U8x-D1jsHL@0@W(Ag`D0D#Shu#@gTEpqFgn zu!(qCSYLaa;#jzX0 zHo*$J@YklXf1b3*JFKt-ey>W5k=2C@euXo&T_(VV+8xud4ks7E>y*P;EeCru zGGY^R5QlM?Wl1T^IY=)REo5_cz3gKfj7{_ zJoT58!BhpZ*pqj9n-eY`%El;ytu)lfg3%}a8T$_0+(3uQHh)SKJ2$7;+rpXl>MZU- zqU-rjY{8_xMn4@~3v}_&nCLuf>u0{e&Eqb5zzD<4)UJsA_W?Vq6wPabDxkv+~rX zK>$mxHnc&r;|g=Dipu=6byRp#o76zhlO}62>%@oehWs-=w>LM|(7~%zJ0`gY<(vE8 zYG*d7|IvB#zjy+OZd@d$$#A9`(7%^ofvXnp6R-uvZ`0TFXbz8$69jTzeuq+(WvVne zX6TXf|I=a%p+0ErAH7$j{!58HAo=A1R)nSq25p)L#XSs-4bZsjYGysF4bLmm7s^DI z><-QF5zUXlDndT-L;L#qT7v$}I2`$v6$8%A-+ra9p2QMd+qTw&&t`_r zqcLCpLnSOfUGpsT-^LB#pZ)=`N&vIde+XbbI5L*ms$Ts&9L*mFD40lHM5ampb`${b zfgkXmv=zR?xBm{GK?ok^-t3hF>MJXc$fyB}K{0qJXX`K9PI|M8@E0?xKn7EPP5c|UTG7wltDf$T3X z`%$F?IZ)!%+&gWw0RTV&q$6}*MXZkt9fOLK2#xk%R{=QWuE5kvs)=-C6Ppeg*mTCH zns|t+FjnA3rpf+et%ykf&+RHxYL&3cGOY){8GP77KbgpqKheK4uV?AiJw4DTKuUJd zpObfe?z>YKxuTJl8u(JWjRRd3$IP&_O>x=t!-@X>dDszfCT4D66=>9H&^snPIPP35 z@_`~U5rBa`(L;78bFZgIiT1;oA(H#X>ZJPaa6V1`4aV}O*DgbB!4m|+5M_&!(wGqT z=O7kmS9G+O2(a#=#Z~hCyev+v_qV%wZfJi*1HGVVAHa}4MwQ#H^3r(W3P7D|YM&5V zMn*;t=|TUg?Ar5kEx{!cI7!Cf!T(}|XQkfe5&7Nhv$Xc@onYqOpDAlYOr!@L$%5{4Cbn-s>yP zSa@iXVgi4DZ*4Hi9xb$Ut~?!9_us|{WOSz|kD;9S_lH?D=Yz3%jc>MCJp~n;bbwqL zxpKovk1Ufv8%p}EdT*@g2RLroE7>XC2wXc?w)}LwM|+f4xRnm)C(sONto>aCH)E*}av<^KM4Q`!)|NHgYi5C`>j80UbGd+xw>6*?oqHiwxt%v zEcwXUO6c*3iWsAwMx|F0fkwQM@OJR~0ivfDFuFeMMa4vA_qU?c^~taLQjkIy(aTIdo;Fp0)62cJ1|iLw>=3Iby*%Es7-%4Aa<0 zMM{d>7}JSW2BuCYMpGD!{U3Ymj)0e(1i*^}DHt~3S0poe0Ip3FrB73sKS$vuu_;Tf zs{%ND)41$qldpjDr1>CSom!Y6oxjN7`Pa>9@%vF@p>0yGZQD}Y?FzBNv5KzHDmRkO zdd88PEE3FOvOG^8mp9dX!yeB3QQ3N4R`iqx3@c#?1)w}t?{Ch9U)lP9&B%CY0?iu$ ziO(J<+QG1aN?iHmO)iUT!$f@9t6feuMpd9ju~0s!ep6chHZFOYT}ioW$oduT^f1U` z`6BwuIsulss`F)+3*ZI@0iGn&c+7uU9yXP_XAgPbu}!?i1m8O00|cTe!J5v*x>Fj> zrs^8QJ5*Ywbqw!Z#VTEXj@g<5!Wx;Yi3CtR5tQlR-GjW} z(=H=yY&aXRvQObdwObJJht8$Q;wNzx{%q)QwiWm*)#$ZLumH3mMw`j zuwa-!ABHBMUWL6Kf^P^%3FrqVJ5zUHi`yaY23%Os@1n5$blwNm@ne?hJ{$>l|s zQMG?ok}CtNVU3;BbxQk!6z!WLj_rm4_{N-8`!Tm%hJBRDtPC;xBs9H0uKM!?N8iaC z(#(#lwp4J6#ZGJmUY!d&D*L&^Q6+@c?-Y%jFwZ1$QszRC6Evh*!du zFa{Bw|LOny-)8a%6&m2f2q>rpQm#~=&QrEsAz^bE)ME(lXW?Ipix;TU^8*ERZE+KA zt7(f@{sWQSLi!4T2BhXlX_HN(3e{TdQvhihY^M|99s`i6qu*N3MAE)2F$1;Q2P>N{%W!zAQ;!JUorS_D4at6el@HNKbZZ|NR!{ zo>cc(yfknW@HI)(^&yZ70cz9qOl`y6VLUwVo1wD*T7BL`v`LZ^M_w^Y5xWyXc+ zB}rxpdTrZ{$!u|JyI%mU?T~WvrGNkD^;LLUX7?XDI(Mrl8L~{82bIqxry*XrQg#`4 z^r@KmI{83CUzOpsD^64Y=mH0Ozun7^`JaH?9isqqBo@#i5W%O6&A71P0)M6x+vRho zPJaUVQTvAs*Af7z6;Y*4w)d2Bx_@g`k(vnZl5ITR$dN`VTuMYnC;K3B1sEguhXtYK zM+fRdd%2sF+z?yFXgD;FK5kKMuvPV!&S?=h$2muddl;)!Z2;O-0j0oeK&Z(q!U&?V z&DH6S0MvIWs=1*82?gy657{llk4M1``IohXD5*@;B5WEo^%l6A;7)*%vQrz{auc4HYkV}^CFc}(~{v65MncygwZt>9U)!I?AF1?n3fPVZEjT+-FV zVFLc#U(bmx@j)M$Rs!==K>hm!vsfdZMM%3>>|EW(>!;lpEp80^vpj#eIdNExWxH(t zWjcUXeh1Ewl06w-LCd<5dZ$0B!do&42pv@+BZ0d8hmi)>f^TxImkdk>so-A-@ z(u*fyxA+y`LAS!<=qM5X!n;mn`e`i?T*ZxVQ*3O^oVT$QDE-;+5V=Kz;4=iqD%6-Z z>MuNT;!S68N%nNmYg;ied60R{IHp^{M3gqk2CW1n__(G$U)T@=1StJ@^!SO82=|W3 zsg$qmh|&vtwYfl3j8XdM=y+*x3h|)BK8|^oOq~B7P{}!_l5Turxtp(XW6u$GQ?nE# zz-Ci=Mr@LaYi|{#+Hu%y$xOMks3J9|!%h!OcA2mA9*MKlIIOAN4;JX);z={w+ZVWR z67|^cUCZ#5hqyYEalyO$?cz0+@upB@wu5}l8Oc3CMua-VWXuvjJGnN)7hij2j7=b| z+#zf{@hMMNe4F#S;{;%0%nDT<_TT857NN2OM!1vyOiKJoBYxUG351WQkGeuSy)nte z6Ge+mZQo`AWWj>`T6|(?=N?g@d)107+<;Q4PX>bf474^UsguolfrNp&Eq%ng3`&6i z!m&hAiTPry8@0l%7E3^Fj-A)n6HL4K>};~A`=XmW6~dxL3Y>X*CGVAr#^=2Zf~cyy zbgQRhK0QBK52PJ(dQ<0|95Si_du~pr{U9m$@z?&}yQa=auOc98_7+CrW=pCePFNbe z(kCLtbXACsKLhdhg;b813l{EDI!CVf?XzQAslgGn>@%;Z>C7rsGBSI$4l+}F$Bo^| z-(ARws%&Igj6nHDWNuO?;0+MY%z^qO#R{1AF6s4`@2tiryUvwAy?!p5?nUl9r>CmL z79iuGSJ|I>9Y-}18@-CuxoB;Ih_IcSIhz+=j4g?RtrDW`=Y=y0oyW|N=42@Qvxkw0 zY$o26+>BgcoxxuTrz1U0tLbIxQA(=p3A8cs2g!F+#(T%6=Qna|+a8sj+#!j)2u+Cg zioUN`1i2MzoqH|H{Ef&Qwx5#^Q%S6g+4Z}V{p{npM-;J6d)6ne-M9M6q3%VU+%;ec z%tv*l9v^*~ozFPsv-;|8!a7I9B*V1NW+0_&yTI)B$^e!6Wp)Q(bO+_gsT?1YxaAB< zyOgygD;oLBfp2ISrnuONty4=V?Ld5Zoz^%%e$kHS{_Gp$V$IFlQ7tS(N9m&5mow;{ z$O&%VWMAJ~s++K#CRT|#Mm$T`A8y%a;GPiJ(WPZl-t?qk92m+e%zQASK(k)1K5At% zBmMTgNno`&A=fHh&r+TsI2)K0P8XTJ9>8quX2N?{(U=1$tg(u7Z=^e0#2{z&G_#~a zXXVW;eb35qe1|45QPAwOVUP_;92V%#B7KL#%AeU@&OV3v zEWpStj6{cb13YgmqPO26BN+h~j_`OSZ(9EK6Di{d9gK^6lDR!Fd4&$+T$Avw z(?3!&qITf;j1a?%%;lL8pbpFzXUsK#QGC;oq<55b*hy_Bbl7^mN%YN|q%)pa(P2rD zyYVcqX8J^@tC8b~>4R6&Ppdf!<$6sr2)9ALK?v2QsVHA3M|a)YffFIVP=mvMuQIJe z9h-$MI}n@k!Qw-_%EiZ@J;5L>eB&re^IEV$y5slytp9$L#uSK)K_X|`?V?K;iKHH< zrUC52aP!)J<7F?o0@>oL%B8K()%>Xg?gK?4d^t`^pl6r0ia%?y8;UjPmueI_M8C?7 z0vWyHph&xa)N>M@aJs1VwGUYlmyT9{-Kq4`nr*Fd?ZPi$*;qeJ2?x;NE?`5Oe(@17 z;*F*49pHT@Xlwr7Z*pfoR}aTidH+F(9XpWr-@!yREhkc5LQ& z1L)$2vVCaNUQ|$A8f)WRVh>ciEW~!POBv#-EVewNhgXuneLQnx+xl|SX3zTVbs|A7 zO=$9YHJ~rhj&zKpe>#XihK`5f1@ahcbfS)XshEz>IP%)0caF{~HHSmzOCobCD_W%@ zph-)y=SptaZzps5t3Mk)%%yteym+?zN;}Fh6buJiC6&%Ic{Lv9uy{pMJ|t%HeYWqp zanyzqL*~@~VCABdkDU0_Z0^#lTQgoHkRj&LE76GwAq!mww*p|4Pt>dBFPLADg0oa# zxSJm?94iRSA7WZK>fNP$s-=$nV7J4u91P5Daz&3! z{uFp$XZl*7MWqptx~dy%$x>hfm!WGPKjFy3z=eBx8$FOcE$FA3M+3G&8qj+oL9<`dAH!?4nd9E&2~} zQZF-Ys-ODzH z`{z_H)w1nd`UP{%ajx|6^E=PUnA|9VLDCBwVypSu@F<7#>DA4V6jyhF;jPX1C?3{J zk?5~nJvT@3fW}8W%`WK7iK@BF{o+c}A<jB>>)hnE=d&8T08{mW>k-h z6x5PJb>x~W4wz)QH==qDmW#gfUh$9xt5j7s?Q@Ki%=oOji;jJpLpk%xwJ|^h((4P7bDYfec z5gk?YAjRY8M@-prA{}Hg9d_%un^b#JB65~X%iN+(9z!Jj{jOHE8_1O}TJ2=CHm!L) z%0SblJy~Y6*?J3$ekqv)a?bKcW4$@QbR)+H)`6;y zn{wGGJ-a@|MEmm0%6FBaWqQ+8-f}w`vsYdo&c$4};&}e9pyI2r)f&CD9V|~SBlb=x z_&!U~L$n8|ZKfHN9+3BC=|UI9SyqPBFtm1qFtuStrsz?t46pQp{oSJd8%x4Ab<|AI z!O97%2WdHIURc5=koZWsIg#P!6Xm#)19|m1;n;LfPgF!+Kxt0~=ThMVj`SkwmumSt z26(cgay{COt*pe(zFpfBr_+@J73MP$$BSs3!!en8oJ`_FYKV0Za~mthjJ_E>{_wut z2+f0)M4BQueAaNjThtp}v`;cHV#Ewq$2G5iH+%U-nUZOd)NadZIC#QdBRJ6xh_ z)mKXwUgXt0clg+|>s`sPyCX3dfI|egt!-_!njX%-hcRpEVqCutvw;9Q;aIie>~l1AtB#n2Jb#7 z<~6Qq*qH=E@Bk^^orG6>d!r7Q>V(tnFPG>OrP{vD%-tnEm81a7{^*I<(T_1^^*$%D zARW0%WFcy-V%=MB|El&1HnV%t|IzS1j6>bXG|<+>4^uf%G0j`ch*vA>*N?;!5ttnx zRlg|f@FHWDe2|PkxC6a2uYlASVJgk9~>}#Hn8C^a86v(C+W$6*^ z8B(tT<7j-5M-_<1!KY_72K`_{>z*$D5%>c>x9ifA4QVG;r-5LBw|i_uB+PP0259U< z*~M@A#z}d_u zwwERxn5-VHUYMb~%Lx=OhIsWD^~=AP6=#%AleAq^k(m0F5z`@i{M!950){gC(m=V; zm~PT`esnonxR++Z6bI1!91(|>sPv} z`$t}VE*z*skOT&WE(yP&KF-lGC#y;maS4qImYgo>YUhb+B`Kmhom!N5FvsgzkuMT8 z9&Gohu(cxU!yC)Kq>7~UW?-c7w4uE^;*DEcbS~>wnNE~-)x(|3_#AhFwt*cgpVBT` zCu#qnT5zZJ0oa%<>dDQ5bzWA3CbNCEDVi6J7B}(-UoV35ajhoJ9Tce}F#{5lbS!Xw z--oHu2YcG~fg}seRP$vv%@sOu$l`L-y`%B4y}4b1pYni?C4purhvs`Nb(EIOZq3x| zC1YYdz#Isl4bGQQAxo1@Ft*yn*|~fcMutgR(#DDCoq!h=6I6Dr?wKijHw^;Tb+G#V z4=iqIeh&3JjBJe))68u_wsS`l2N8tl26cA4VU)y5^IU$wggLysBBh=Dq!#GOep2U* zf8Vh%YC56yOp(+p=a;Kv=j&7qhQZ+t5uE*v%f121g)gOy^H%#64f6UfV~q~hYJ#Z@ zK$Xfmw!=3Zar@j1;;-5q*Uwqo=ichja;39^~-4+PUx8OV%a=o3K(5LD+37v zrc*?X8&p813ee@@0;DEd*HvP{R`EdUOGrp)i7!1PW9Yw|QUtP?T_+)sqJD#JR<%Kz zB9Xq!rutWk9JGqA3325q%}U5|wD86}2Q}>|%o~)2a4N}{cH{Eg`f>eA2L0t7*ofz4 z9k)%M+ii`OAb@Gj-1mf8=`w&GW?`od2nwz>e93voDDe@pqPioouwhvGgvvyI8M?%m zwI9d`eMp}w@8kR`dzqpsCvYZTHm}`hDf1kZ^b$-Cp(kV_vk%Rx;53S3Jw^xXE|>0e z$iK~IzV$x3+Yh0YufVti>%Tlz47xH^Pd(gygC=;3J-`A=Qkt37iW?{LS zEQ$YbKvr2+E-DcHvbxjn9Nwd&C1tT? zM8IlO0!IF^1bE?nU_(RgGkeoAC{=r8`!X4ObD8V-2d=0w4CyoS@s%&;X5t;jdo_*) zIxQ8ukeheBS0@Q>ph4A{kRm%#UHj(*V@dZ%0{BEOyXqWKX@c07)Hp?JTo`W=@96_bNw^y}3JZ+1JB$8JI z!{8(^E&Jq}Tw>c0T)emRVFa68BhY~T(cf!iPdd_PCdT|09PalCg;*#_^fvZnymW#w z4_px%P_`5(sScpz_(>897TLdkQ${gcY6{j~M&ah&<1H%WnQNoVE)JHR1#grsm7VVA zQ;OwhzDs@GVtB*NYW-qy*bK~M(-8i3v)nqaPmbWVpx6f4bA-wpc*-wyJvUv#;dVWX za3eB95FUcbVI&uW*KL8F&+G;TD8AZZq|ClETyEF3Xk?+&<_L*t#TKK92X9L<-AoL} z<$Ts_6=N$jajUmwm~WHZfb%&c{@!!#2PI>@KE9T4`|aDqjcHu6J4&mgZ{`|OhkDvb(=Cj5GW)n0Ay{K=?HWR; z6*Y17LLwXYrA8{VJPvg!y~XWmayJvs0veFeKZ-H7)s4c zM2#$DmF6vutP$CKL1TS*_6bYos1xKkyV#UA`f&3m`N##``{h;7_Wi9gO;>d+yd139 zWkTSE8nK>+q^NM;RTFTp`+`wdF~*UG)2zqaRz#ONa{qJ44Zg!Je2zBMbzmUHSVweu zyM8{hf0M!JlpVk4y{fX^kiMJ!k6Mo9kQr zuj1S+W(&2sZYEoGE3j)oz5CWUwvo4J^HiyOgTWFaIKSLG)Rp!dqls}1L?n~}|Dr-+ zqHcqw-5`?wMo4@I%;+NqkD7X>crPUpl&6dl@=}*z+9@}m(M=xpUcKYVfYrt9*9*)| zyp`eI^l2lapOWe??b=1`%EBK@u@fy|x)8Xh!r?dXT+ z7ux$d^+u}UhS~$8yIYZji>_}DWw1QcKDeH#kqFP0Buxs!I+|>Oez=uhKl08=yP1PU zo`!nuxqO5{W7D*5zM)1vZ*>~NAk!eHBC(%CZ}($$MTP+qtGDRh-K&$dSY$uWh~+y0 z_r@&MF|}Fw;kwOdSMo!W$zh`wo_@?9cN(8HG`kw?GLl2>{7itk^9pX`m0;*eI(n{z z%JQD#EM{IN^cVSt4uo{ZpvahruWHW;ll`n>xwV9N73GUHpq#|dT$Ut0Nl@eQnKm|4 z2I_RhrOj07ffrZIy?e51$_B51Y#E9^Y{e}U0PQJ)qREXD@2TDx)578;*6Ql6_&Px; zS(in96_*Ysg!8LvVcrw8CaO57YSDnxp?7{j<3cfeZnx(~0hKauH{IEbB5+CU?Szss zD(c#b@m)(PolvmUT7GD^)$$DgHOF+>ZP+X7f?Vn*^!luM{J@*4##Q}zmv!jCo_x{6 zW$4t%qEEeqCY@XRu?}0mRAsAN?kc}9Q!qm(WqKIbrp>@W@@u(C1Rsxv?(Rr+svYCg zvaZfKm~?@M?_6qXbVQMniT52$z-~BIBK8qR29e?Mp!czD_q{BdryFir`Eeu@-`QLl(Ia0zSiIZt$lwe==bN2p;Ttqihno>E zSm{@*iN*EkoBV_ulIgwF1InruBsu>^#QlrXWP?dccb__s(H+p$4p&+_YR81W@2ht= z8DYPFk(!(twE>?%4!Otn=5rTsR#I=Q9wr9Z<`S=Fn(S0G;P0jI24#I7JMcSv&GbP8 z&oe_4%3MA3Yza1G)%StqO9x8m85eHflTHPbgxO5I*r^@USJu~(Yo7@S{;lmPINfZhSqcziVmty z+Og}2Ot!jbh9KkDFLsB46)V5`FLdzSS#nYm*o^g~4PCo&*nvx*{ED&^ttc9bLZdO^ zo*1MU=x|r92-gDB2cOwRg=Z_F){sOQlZnPIozz*>D8}uSK4~GRwyo>{bW@V_rz}T% zLe61Lj>mG>#fGgknZnEpE}BuO-Rf6TdJE2DLrb}?@d!ZpQ^Yh!jjlSwWZ5a!4Nzcvj_=?+whvPM(i_Hi@SHGPWkAspn0&i{pO^mJ(U3d+H{p zD048G+eYDKZ>~370ae?&UDdFwlP_X&syd$E13f4S3Rr@kD==PZBI%coJ|5xX*9{`_ zu!l2LX~9{Bq58-z!j#o|&bnB5PC@N(w&20;uCLCf(?ilF+(voihM1aV#PT# z&Z65Q5&a}DY3*=$oo(7rjEAGI3d@fNl-bdQzHbh|?icDIw_Z~fdgPr+sOPy8HpUO) zq>na1Z|g`%HCv@_kLrMFSOW_A)$t{VF#j{lABHLtG~4XIRh3)10( zHZb$x_-ZlGute(f6|9Af%CWX!oDy!|8adotx=(U)X(dZBJ~GXD_$3Bi^n5;bj>vM$ zavg>)8l0PQY>%C1nJh zE9?~$oWICpxY%A%_Q0vzT%Oxo4@Z7UYl>}~^!uQQGY<2dOA0X?S&E5o5dB!S8n9lO zo2VCvDOVj~E*~qfv8TD*h6=IL8Z1sMm-@V79*Obw+rIALb}*Q4a*d{AN43cQfPJd? z$R0ffh4^e2O-%~A#=?_=EVK#Xwtf~dlMyXN-WgT4y9?rxwnd#Ex9*ZYlh(4oxmwns z##K5jl})vK=~&SfN6foH+}E581ruBuV0#VfXrG5}`kTa2-%oRXl*=WT>a?)1&uLPw z|Ae30ZrptXh1$gEdgSkxPYn936T|rLEJN-W$-_$@sA~9c9N1w^PI))&_YL(;#NjPF zB~#$Xq_LA* RYTZAoz$M&(Succ3zb!LsYVWHbCIm&p2hUbig#iISe3KYLg4p^aY z2#d<|8FNr9@RVV{?n$sxS79wD3(fM~-Z01KyI+Oejg=X=q0qcNp4*`evg=$D8oYF@ zbhld^h2ANp()V_QB_(Z75oipu9xtjPL~AwwhgwT*RtaB_uh zmXTU}S18}Gs<3ib$Wfhj3!}E{s|@3Ru@NV|YAPUTbnR2M?Q*IZ=3YfLRxCNKyb}@L zIos_SnLcS_u1_GRK7}Xczwt=z-pm`RIRoq@!P zXjA<`lY3LQCwUfrtlE-JdJ~L#f#8AoeUN#zdtv4ciFacIZ66hMbW-&&flp=vS>4c=JwCT$YU0L`wk3Od6ayLtGeH}W)>t5^Zrnw>A` zIoU0m&T7n}-J7QbnJK*IwFxv$Qx9GsQ(ek%Q(}{=rsR@*kPb@MzG#VWiqHsvy|qoG zUd*djO6IQFc0tIZhSSZO6B91X1@}^X3MEbIk=2P4XldKMdm&3bdiKHxQO>I&3hMD@ zogC_tQB3a8fop!#FZPl}%(JTT1Y7N^;WZ8JN(76F;e)CUcBR9QVa&9Y>c+uYSi^5r#IS<1` zL$<;y5L^+my7;%P8q6L`v*v`UtF0%0FL+N5WN zc`0L5FCa*v6&S;O@5|KbETh+(K-LlK?6elKAC9*XmcrOO?Oem^8b8(~dN+xzyvp72 zz`(xRqHNw4zjdvF;Aa?B1l>7XB9Q5Su0O?VJ_kv!YwT(1pnI0uj_0(?&s?~ZB(4eX zXQTssl&x#%GtJ;C_&N8pjL3?Wf zr`EGvhWH-yO?Um^51eQ`R`b5Oy}-X6(BVFj3;qpV!DwlI*r5y;#cp+htiAD|E<0#w zR0xzX;)UzW)hjS8E<9tJuLPnUQ3dRmUh^iZ^UKD`J{f&CVdH9K6SR` zJuW(w;NxeWIm}qm49r9kKU#Cip=50#*1XSu+yIsF7~4$sTVCcMjKn2)$k=h;I&uc? zX3li%4KZe?R?wRISU1VCwpJj7E$m=Ry?_sFam_3ECHr-HMCALv0)$w8Ud)4P>1oPK z5rt+a3nxSe4;1`{_U8ok=xcMLQJBiStzoGf+BMQdlhb=MR+@CSBig*H@?v|s;B?ad zbAUZQC=5C`4ms4_TnUku+{i^_MUCCm>iZnp=BtfZvOAddgVyBL)7{D^x$I6JO4vvw zVZS3h%xJuMvmpW@TA@Rhq+F>Nt9)0h0kR~6>CSA zhSOYnN_4fs?GFxn0gBC;s*h*)_2x)!{VphHV;O$6{JByV-#A3uGjaq z9NTX7K}N#xSm`D|pR&FQxmUr5lP0^>$vUyix#7|h3j@G`dFFXl0gZiYKCOUz5@ z*p66Kyt=}5kLmcscX}x`13MC++EJ2RY1baiI>B;oPc);+z5YXv{-)5J(2#e?%3>gG zqt|pPA+~mGe1YNd4z1R2o>|3$_;qz=lRRbYi~ZMZQS>vJ{)rPVOtdbGK3muV}f3csKletOxsxu^zn5uC_3SOrN)wgmz6RcoBIaYzTkd}HSc4h;I?DqJFq@ShY;kU{Y zQ{kq%!lM@YLE^asw>KKZu!r`f{%Q!CDbGkc>*H&g^))Op3cfrrs ztm2Ng#ps4GPG!XNZbgPsdjr?r##SUkIo21aLgsY}TCPMrlsXKYJvAQn^w}z$1fkG; zweBtG>PmL~~p&0@R2(2V;!pqxUDQ&jAQLgvA%MX%2af@+7Q#@GFe*~VR5 zmic%Hjk}5oSKy+JboBrwS7DdYefYlO>{1l|%gfy0+;$5Uw&xf7?ATdo&9bxm>8N=u zMjIJ7Qp`hLRS-5I%26d+8xz@R2LFug?n{WsPj1>m5y}x79EFG{IDA`tCgD(%(tj>H zMpvg%rH?2+!}cj9O9Xd}#KBNe4)<68+@(geM9oXMxpV^e6^Cf<1z!n}?RYWIr`U)? z>YPiid$hH!$vwPZ4903C#&^g0QyyHBavCW$_Z*(_I3&5OSonA-Kv9c%lN;jMo&yaE z^~UwaT(Qbf_O*(S2&79#}0SHNMGf#ty&^Ic9%+)aXDb~x*uj3$x@kl6-g z_d+MX@=P#sfdoG&qB^}3-x9{7#=}z-A+=a(AXvtJ zH0nmagAa~*%dn9!Hud`B68o*L=Mn5gdMCFeC3j3cA=7rj6?> z6$g&niST)=o%gQEAFx|Bf{&SEg)QvkrGD7xbT<{6K!OJs^Vpt6NjF1ksT<(T%aA3_jULoX zTWoyFb5h_G_+y8c+>M>P8#nP<8qaPtros)Guw^ba?lu<%J9sv_p5xl0Cpj~5QTVo2 z95k=IKQyh%%jXoF?CQ?2?7Edb++%z<^{MT?C`{4%;I*rhoQYOoNZN5QU0#m4+sUTM zx|i9SBia~W8b0K7AG$=2l}wYxOq3Mk59R{=5Bn?**|VhxO}d2aH3kdD-Ab*hC#;#- z%?I`THHkGmDcsCWNM2u5y|gwhZM~J*K{EF4OwZ~Zp#$e^IlM;1zsKJ(BvHK z_siso&gPNyN7$FOuyqWv_cX{Z!7D3#oMdQ8`!_GN+WvzpDQhZEng=d~$k(_BeqgIC zx$*33aKvcMnd6)1Qtg`w3w8#SgW)3vif=Cm)KJ=ny}dU&>A=Fp{A&w<|9Lu?r>lut0K0$`OGL})kGZkj_R6k z<(V4|;Jir>y(Ak?QjJEu(EGw3ZGyHw8tlAXsg4Sb6czq-9VsIA4 zqd-FcqY!ZY%*1v>C+COR56k;Zog_kv6gL|MRVK^Ku3sjC4!9+*I$G6GoQFELsn##` zPQIZtTjqYkxZ6eDKaOnTZDGGkw=2R;RFM1GfDnGCa%k?xY$yZ2;1x-j#yQjfLK83fmF-xRx<+^uqpv>nsG=|%Oc>kQNMdcAL@MIA_~~BYHGMiucg{H4LdFPJqz6KoF$nZ; z8A!o>2W6~KSNvANt_7oRUjy0ho5xP#IL1#?9xA%ZrsSlu|61H~&f3?&o|^kX z^fx)%0<>SdY`RN7P!ZiAlY;9yd?b{D0i%3RfQU(n+J-$HJzyYH)#W~UvIqUvGN#7PiuCW+Lx}8dW)^^dzLF=h7^22VX4t?{INupnaJF{1 zDq`{TED)>vOn1c_`Q@a}HLohYBOkDjiP*6+ynL`*h%l~WUxMQaX?!HFFKI^!AYz`Y zaOIsu2&Kd_=**aNQh0wYHQ5Yp8;zt+*zmpr{gM>?EV*kTWE}0;XFzMw7}l}`e`o%W zIfG-z%V;R_@;6o-ij%z;gLSF!%Uh5x!wnyebc3@ugU;|0+?oq{Lr_{1T`fu}iNBjH4dVJ~Nt>Mj60J6ff558a9dkfgc zxwLHZpUdBD|0ky4v!^s@|Hu}eaX#8viuW?|!Qw;fRv7W z13)`@zLeic|IDMKo0gZH&jVli>iKiemLmHZuqfUjjVs?5Wy{H;XHasikMSRVNyh*L zCZAfoS>*TzQ(3FiXIu+6v(qA4-&c$}-}`0f8aUk387Og0iXU+Ull1qyJ=_TWmQ^*q zP6phwyvzDw!K0GbBOv+0@|f#a{vi`_`u9wP=t;W;k<=aeZ~3wN#K&rf#lupiza#E1 z-@H9_Jea{*X}JM7X7BaiEeJBz8vELA_R~A0k+61N{^gH9rySY0{Q$7an2eLzzb&0E z{rHh<(R5jFM6DVBbIM`4PX;Vq|4f?N_Z9c5m;%zdV%*D)MsnggyEDp`q+jR!^v~}z zd)+^jzebd>1sq}5zEmXw07$%eN8uZQt|t(k64x8Cz9FbvGW79Rx$Jj|%5Wr6HTGG* z?JoN%Kvs-*G?>4W)nC53e*)Oor8B8~-}gm9_w@)a)hl&mC4<{DFc^UHhGFHpH{S^2 z+hV^x>0eaO$oaU9x8f@kvs6l|oZ zgZYl%Qzh?ZiS0%n{C6}!_J!||6}|vS>Y*p|=e|jmZ)^P%;?JA|NT*gnZ8PTE1#e4E z0_5ur9HD9X*&;%W^H&X)&wKdJPN^Dz;#~f%i2sW)6}c4tvCm$_|#1C)u$o&Ca8Aqx*#_&_;ja?3IQ2VY&T`P~E z-V{zB-!Sv>^~+z?Jx6EoBAafGxoQDG2Mm>g=sx~$827KecKuWBFhu7U<4FK3G+duQ z`HfIy+X4AvC-S!HyH5Ki;J)epf6LLQ^0I}H$6+t4FMqpW_S%tAU<}>pyXdj@wdL2; z)+e*$Rxl`JdDSxBDDLl6;s0gb98e}qciZTX{a$ZAQd$z=;nHi6i5FLHY zCJpuaRlRZDbM5QsWGzH3QIF6`|Nj*t~_is1z zyLa(_uA%|kicSIgZMlD#Nzy^$Pt1ok_L{>mFEU|rsiJ^onMpY-_e+wt$9OaSO;d9nV* zg+D#jjhar{$76Z8JLBFjtKU0m(cYtgy8h4gyHQ&ca4biTHu?`|=`W%AHe41ZbG5<~ znf0Ste|`4kIf=zWbSH3nv%xQuyk+aF(a9XGtm*Po-^BP4P{l!jme*1=#{Bq%p92Z_ zl@~zvo1a(y3WPu2{09ZcBKx-BIIZF1Tg&E#}l~~Z*G3HkiVe;-jY;yKDf5_pv^La~8p32hx@cEC#{BNrJqtDq^17y$)+4MWp+Wm-HfHA`Fu)F6E*#kzyuk9ZQ|BRY3RNec57>I$gNB1aGFfqf) zDy2U@|I@mUsM}xX_=jNf&d_*1qr{O*KjI=g_x<`@kIMk3+M9%5+SQ-#K5Gs5LJ>^9 z$^W1>|3gN&M!X+Iy0}<1MKC7)@z8ht{LR1pM(lO>_ATu{J>^FZ1$bc82j7ltI-;Tf zN2SCCbx8r-L8(p8F9%1C#59xoYe9|*;U7ilryPJ%lf~C|j`}ZtnZ!Q5YEljJ{;@|TzX>%IUYRNjaR5IlC)=l&$ysz`5K3Lh;y3Y#IL zX%c_j(O*f46GYw25tE4KDZj3Le!uOu?NyMjQLF-F%x%DV`(PIbi#PI`%kUg?^qHjh z+-{C$Z<{*03||}xU9|8VW8R-toLZyi(fMkr$mIFZm;l9jn;82xF}lBMg8}t6=*7y( zh_;0k=T|AO7{XJ~ zykP7;=H|IQ+m+TfMa=B;*cj5KKs)7z*&V}8PssgAHB>GZx|EL?E2}} z)LJrRn2X76*u-lN$Vx@(w=6BP~{Cc;5uGXZ5|!lnP9oo^kd%mZzdvn_F8`D(_!C>ZmIA>`MRH8X&mE*c{Yo1U691SU s`%m=!|1JGnn*M(*{Z8+$rSA`kRg}&@hOr2`{|3D7DyZEqkTVVVU-Z~#MgRZ+ literal 0 HcmV?d00001 diff --git a/docs/images/PermissionsModel.png b/docs/images/PermissionsModel.png new file mode 100644 index 0000000000000000000000000000000000000000..935b10cb7ec6b032dde999ce0a0c193595c3ff5e GIT binary patch literal 348517 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%0Aob(x9Bhdm?TZ=ueQ5VB*t%PJ9NiHK>|u^6H(R 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%0D0>En*euaFvkA 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 YPh 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 z z$>q07Ig|;^3Mj1Z9BcA(&_-(Th~e@%pL%WfK2OnCkub$GWlL3f2(&@GZ|WhH^Naq@ zUY?!}uZ|2a(=Egv<4lc-o}LQF)Vl!U9|RiIN6$p0I<|ar30b&bS(mq4WXiIgwT6B& z&@%Hk8}olZwu(AZ)vb{niZdvm`)o0P9-$4wNQKb;{c>@T#1vmC&H`$}CyV(}Mx+C* zL#Ji%6K3{7ad`~yEc`S)l$5V-|0fnsxP~(*iUc0ogSFalc&gj}d2+9HEQbqyY-}r~ ztkGczX1cCahA4dbmOStZVo#->)Fr`u!ly`UUEizdS8;TK#z64iLm}W5n`Ts zlv=hvm*L^3CoVM0E&6p}4^$b?&CO9%b2+LR71TwUpJi_UTG{@?&fgwiWcNG2mucy= z;5Z{icJDh7fea@xzADoc0*zo<58XOsl$DjEbfOh99TZ^ukVngyLku#I^JB6U(=gZdXcA#g(I{ECuNk!^)x8U)fkdFXZNxi6 zRqr_3ZOI_4B4x4yk8M*Mb&5{~m3`vG3ARfw;P%`V(j!p4hcr7>q(YD8A>;M}Vi2DA zt=q2j*)3>%=spxFQ>CWpsv;v3!ibe~s(h6-cALmi_+D88_PP%ZQ=cCoEP1#-uNaTh{z+GlAO`>aAHuj#DzK*%>;^f5GtcqYUO3 zlrB=+H+4nEB~2U^pd{_394!Jae?(NS{prV6DMM(IP{eG2^wX*y`ysfmHo!^obPf3) z4(7*U3GA(!SVIg2%^ACPQBg=c)~X}jHe|M34NKWTmjLJRb#_jR5|qe%^T(iSDHYSo z))L~G>wJ635Fq>eiEXQ#`)(jKNYCbrVqW0E6s0(d_*fWdDnTV+L|E@gUV;g)7;u-Q zclkS2VR{HL`DPrw>qszPgd1-!?5_y7(=1>;3%d?+7|5``hTD_-koER83pp+ZVF~HQ za8`D~L}9<=QM&+9gU02ZgkPo$?7p8io=0p^-iAIU1ZuUhVS?bS@LO!3fKLB9|woVO-3F0B0vTib_eYN8iv;YP;SzqY4E`e>QGY@^umMW*td?`v9VZa$@cu z2o%B%F1GK@uS8*Ls82xJ#2!>Kq{C(f#v;vs1HDMoNu*9L*+kf08o6wW3refKQOZs` z=rFq6oHzoZ{C=+MpVkgn@Z&merSo(l)5_9Ty6hM_N}nWfC5N0&K)cM&%pCXLv0Rk~ z1oEz(slL59D%$~)o%WeIuY#A&|5(~Zwsq|6@mB-cr`P9()fzrFU)y=|Lej~WFBusb z&JZNl7kyDwI3;lT;ep8C1f8e@k9DFHf`wjy`_UtkQcNiEYAhS#)uyjn?HUm@_@gb= z>?FvoaFm2tYBv5Dh3~{^q#^=2>~U03auYyF2C%KNEg{K{U@E8 z$HR~}Dx9!%_yHFVk$zSidAe3t zDOjr0k3cKy2$vSXjvnEDh44P1p80s13L*8Ku{ogaEN?X9KVsIQ zSlG87ehdEkiNs9xK{!diecwiezrhfXn$CCXEaWD=WC3hFN37#ez}C&uS8}H(AVS0U z<|=QrPD1XsBrp@*hMVxTJFEOwWSqcKjfE?eBJ$)Cc;A@SbC>To^khT>wmgr3QIte$ z{wqK7W7~?M3=AQEXlw~C+6Kb2^Fy(P^#)Mais#IurMGX?7u7t37dB)6FjIq3KMW;b z^Ut650#r`nXd)M#CgbXv+Xd$4Ch4I=RrLh^Y`E`|;$X8tPg@dY1PI zJ)2*Ys!`9NRV;KTS#t;5@fhYvqO#?kd8_`!OAEVn5#>D4opKj&~t0^7nQ^pMJXkX|+zJ1ahr)zH!aMx**8O203Q<0ZL2OV;sk|8|*{ z=zrHLfPLe?!V-TJ5&jQ+RKCYLr@5 zkQznN?fYRwLu>UIGb$GMjdY*&-Q>NllH81DE;%jeBLL|l0fkZj3WmdzCf0th z3U;7$s@iTLxgvSNiK2?x+x$OtA`d*?Au39xapsBYDU+tBr=9m3ejx+vs+NzJSG)1- z$Ak0?D1_g*!K&gPO6(8$uJ3Qhf>6Y=!kv0$l>Ib{UA1>jU-l*YWzgp zayyF5mRI28Lt%E|ePYHXEUx?pLKs{hb30{XX7&hlH3RK>5BJO z4|CASzte0gczTD2rLSbEsj1nBu@G3s2JOwWE`7Uyjh96Aws4_#Q>jABz6uzH9M>Og zCI$dQj-XpL7VOGH5KfnPZ4x~#1Kj~(64e;0W`e6sQj-)I)>0C+d#HY)jJ4uyuHiOW zD9%)?-Avz)qh&$lOiB6G^>x~*N-0!IdCnO@HqjTwv2FAOO};i7U~7`JJH*V-a za8E6-Hb+6z-;GClq{AoDWNY2vCw!QYsh91I_p4Wzc91Z1DKrpI6z^W8aO9G2QpB4Y zrlsG0UGj4v$6^m~{;olmLwiVc%y`+@2!qt;!U5zZZL;NHB#El|L&iLA1xU=u;08Ir zMoV;*)!*BXI**|BZ+E@U+2F9|cj5!lpmfXdyfc6`>=MMDZq~$2YNB1o_V5JDwEN)< z=pVE@F4M}K9B={+@8{&i?DrBUFEm$r&;Ry<9r{Z6_4{`vwO4g3j;tNloJ)3@b}%$A znv!9E<=V44mE#t9bsAY*OKI($psSf4KDr%#cKJJ6hCc~XF-?%mB*?s5PU(;{s#6mv z?ATwDLn&N~&>Zdz-ysj*xRUqt5iw3c4^NsZ_}(yVJECZ^OWS}#ZmC>}J0lwulaCUX zzn&+};s_tf0U!D4=<6JQjtRxT6;An&HPN{8{$T?byj>0s?M7sF=83HHu%)ZI%bJVk zn~bTfc`IDKog~+nk7%}hiR%A4!Yj8z1{Z#Zn?|<>{?t5AH-Q4V)DX{`X7|fqI!4Jj zfS3S6^1mQ#X=3oo4t=pB%b|!Pi|eJ?+O(Cx7NYLuYms{FYnTF7e&_9~ez2G(Y15{S z*6l2nP?CLqV`Rj|?tS=jDEUWzW(VuGO|N9*8C>@Xivsvh8-%p0|pv1_VhRWCanGgTpXSyoECu6xy>x4-pR zN15FVB2AjmF&$7kTruzWFHa?1U>%>Bh({u(DLWluJsI#~FDnkS&N#tnZRdGf&c<kXwl%rW z#o|(KX5!~1s@?u!xdin1Ns#zFgQ-6=>pmR5i0plG-=${DN|-j1YLVBFzrJZ9pjwDf z7lj4MywwFJPujZ)wwm~R$FULpFAryvdu~p4PL__Dt)-9$X&!msZ!3LqC1G;QHZpz9 zqif!ERW|psy6f6D(w=U|k!yyj&+_qGs@*MbFxL8hG1NwCSLeCzx3QH`iU|3sXe4KaW4ebQ-?c4E>VNPzNywWnM{9g`w z`NWs(L=)S(_3NLlhLktqelmv`@~Pjf63}zu5fMj4bt8}fe;KS@!oV2E^RG{WT~IiP zUS# zGo+;THiye<7E_^$E&WiDM_SGZwCpc0jx|C1`u}NZ80Yk2sAVeH|FCR&ZF7P}VzXy3 zfS1V!yzIWuLSnAq(XP(xW!dTAi`!BUas#z;9&))8Rsqh{KU7- zgUhXW|La&0)lHI0hcO$k;riC34Qjtxx06hL(E}SH**k{Ri=h4Fzxc2JxZ0RkXoPBn zAPgWUR_kfjwosch`D8=?dQc;PR{LDX?z_(5ie{eweJJ7*NDqSZ6f~3rxgW;|)%=0o zK_Z*q?&Xn=w~F@30xWO|-us6cTG~q>5eL89@+rP-ZtJD%_HR=}((cTf1vQq=1^gs8 z(kHw-a$-KG`OIHvo7gr$@ER=f3R=HwCK}Rt?mJs3BdrZ{zi4AsQl}{I#$=(7WAgL+ zfnihbsGy$|r6Oye4y7>{oEhaPN|dgp6G{x(Pv4xhG}@_Z8la zD#tsDitgx_l@tD777M~2Op&Xb+w;_X=bq|;_E`!FA~)f4UIQ{kX%4<417UTN;l`@1 zm3N2Q-*c=n|0Snd1hbuU_JxLK^Ha#Ps6y>kCJVz+FwU=w;rfNzW}jJwrsCECQ8K()(P>9x8*^=L3F2TF7U+~mI;{~vP&A_6=S5kgF=%?^{uW98L1=R6 z`}}yXWXm1C|0qd|tFaC#ZuhfuV{e*JPjJ0KO}GHupag?tj;~@Qp+|~};TMEo=k>}o zRCT`(B6bw68rH11HMjUYTj=s>hIS8xkYMYPH;EO?M7+oI=V6gvGl|cUdR5Xlk3U@l z|E_%rWSqZM&@+ncPpMpAtJagnSu!UG0>+k!tA;NXHre>QSqW9=*{hf@WYr+bGN+Jf ze>StX`FIOVW`)xQ;d6OQXvT^+_DV7OBjV!~Y+E&f8~Wem9)3dB%2blKhTKW$Ql5R0 zd%nG|n!;I8w759-y^C;!iN7-svkOn4tMEHT6%~sw9Q`s2&(f12NeTKfslEu zbr^hXt(cv4M)7AduZ^>FUFfS)v7!HA@M$Lmq)t>wJvr8qV2{Alk|YyBI%Yr$V3{<|uPF`Q{gR9?wa&st=(!=y zoxpYdevG<}bR4k6kc$fajgJ8_jPHr^$-2CHuh4%t_aqVKEnI|I$7-1n&FUJ^}t`k`?L*%VZ1^3?O$;LlFv51&J*2=x4)&(p!&ghqZxKx#^A#Cp+-+rze zsRi=|BsYp$o1tBm;V^ zY}wm~DqyM~bW4D@DA`5vxHTfu_pUc#FE91L2G^A}fPc!8Q3}rAmM73IXm)N+qu%5R zwf>?f@aU4cuBQ*R`w=?kkFpQ44Wyo|9biOZ#bs;9dxqH&JpuXxZ;_MN_UbhdEy%>U zwM&VXy{}C)-T9|N`|mm;7K%gL3S0BCd^+1_OY3$~rF4Z!6bRy4wNV;IZctrr$$;9E zcb~@4Vm@rgc^x~{CVc4T@D{rPe?HEymhiUqYlb`NN&w3B!Jym7qn6+Qt2ZQNvC{rR zFgf8{67JM2n~bvn8tkf0NSeJ8Lr6_p5=vgtbmH&%eS7x2gia4V?n9==LFTM(2{Zm}8i(ln|018p8sz|svpgmLB`XR>Hp0PKJ3hXKga(&%*+V6kUe!*YT)(WQYPOE8>p6Eu@0?h9U>d*Z=^(n06TTZ3H}lXlCWsH@Xn zAAwsDu`b(FVK{*VTEBir#znP9nJMv}fC_k?$*RzBhARfnU~iTJtk)->Fv+Xs!` z|6A9~MG$vh$InINVI~UuQ|s&Tski$P>Kzc9Q9016B>VzU=f&{A9T<@v?CaOJ2~;Dr zZ9c`HgZxt`5YXKsw{HISKg#j{6qlG|D2_tOE0pP%sSY-c+5ExwXOYQkOsFoNN5F#t zs9l4Z4s?}$k0tt=KP)z9083@D)1mkEXf60iC<$ar&fmd2 zS*iks&JmmWjum>pR&8A59RAB`A=2Q==IrLi(*{t;a(x>*=;3np9LX5PV2M7>B|Zfn zLFIH8^%~EAbDqV#p-XHP(kD%wIm?I> z^e&SyT{7amni}-JzP?enQyUiSh!6?WwoTb_ducEZP@&@+Km0V*V7aCLl zlP7@EDFhh%_lv~|rt5&%yP!P1#?bAb3lXq> zO7+P<(LRzmtGdYRvW=m=7imR5UVoO(_1)_mYVpgICLLvQ#^=&9o5A1+Xe>LF$|@vgd*~=)dlxfFN`X{T0g^?Ds@77SW4_qq200LOo#=e#$}b#?GyFc zVv|m!0^ZiG#Xq?dd+>&kUbtE&U0y7&b1tCR?ttMgjs&ypqH?;2$4BNZ zf-Q0xvLVyi5U`eXoF9H~J2uchw@5Ln&OvFck~J*iGY2ZKsP#etBBmb&Wp0}ThLuRC zd-4@Ry_Lalkaj&O(o}^~Nj5M{yZRqBW5sU30*~xal_l_GJ9cU1+Ry(Ql=vqoL281= zp;w53ch7R5M)J!JO{za~ZJS2QEMX$RX3>1)CdHo~K^7Q}rMgS8pOYbUAYG8i_vx9D zuq!&Mg-=8wQWsC(w0;YUt#<<2ZK60eGp(=>YVyxSSc-ZIQro%NUh)7a_4j>&Ia6k+kx=9an$D#a2PuHU`hCW{#`~ zjY$e?)nlGeD3jW!soq7hSF(Z{S>@}db&J2kSwEp=@3W?He=3GLSy9lJotq-C<;GKkHc)6UP$Hy-##!t3O)GW!tZ+UJ7;Ukw( znLzGHncHOO<>#Q+4{G7?BdJOF%ff)BMMDDUWl{hT=chEG=QFop@1^80yPO`q;iR2d z7L~YIX#X}#NQM4T%|{fD-jwd%g}OZEwYh-uTg{(Tqic?vDbPm#Q!$fe;ebz&_fVu0(I(}IX6 zyu@u?)qMXg|xSt`9K&3#k<6S1@6L#lG7RQ17>&Z2~w$CqW+8xgl^;l z7y^g)+MtL+SOA%YDcXzw|adk}&u z{V!rAIeUXv=dGO#aIxL@-CKd-aAo%k9^2mS;g&WE-f>4Iq;@fRfmy_Dg}UAo7pNBu%iv zfVF3Zrr)wu0_|pjfJ4c7=_V3!fnBtq{4cZwP|S1k?j{T>P z5@a=X@<$eZ@7do#S9)FC9zzg*Dv^-)<&~u`sGwLhqY;?dZF``7;I+U{jR%)Jz$q#0 z`-%6CVzNm+WhrOpBtApuhg3<_z2XtS}q+e`#|eQzJ+C?~E&^`cg| zx5({!200a0*WVkri#NO0d`6O&0S=?Bb&=(wr`~^TSYSGmX4p0f(zX`!eGFCLDoGhW z!21{D8Ad_H?e;L#kJeIuvLUut36={(1567TUN+-SH{n|YjCBMjW>w)fsOhyh<=a z%CHov7#R#7{3-Oe@5IpR1GoFVXMfn5ynJ!tV@Tflk1~>I)nlpxSb@4~Z49gbM$aR? zN>5j@!hZ=o?9>%~5}?zIZH+@?3RrdzW$iMle_3x@=&|P9IU6@C*Zp~luVxh+pJ~?& zeShpUr2mcX(XAx7nNLd=f7IFXN-BQViJExeeJQp5z?jSC0`jm;uv0x`^WTW50W5zKC1}B@~UYeR(`2wN4 zfhe@&*pHZ=_J??p^JU|G4fXZGLA7UfRxammtY64ye5nbuJsq1m_V|b0%|{2;!9HRh z`>EzC>`b;#o&CnzpA@!nJ+iq1J}9_oTZYEk2G>N>#!bVoEq&KHRh;}PW+%LS=uzB` zci&i0n9d+S^N#wu2FH8n3%A;LKjvUU<@|N}g6LyxH77B^(YRzcXVdr9D~{|3Yl3)a z3FU3!x)yOiMd#k?AL}1-Fizmb zDNh}i8Y>aQr5i7Inx=X)Onp*d&uBFp_QU$YC#NkF*?P6I;bPaPGxpm8m-ZNWx8No{ z0bDRq+hDH2SoH{#X~>85ZKN}YVc9q|8m2r=Xy9Ooy-B~fSo)_@I)|M7Iu0iE9-){n zEr~<7(nm)fYn|*F3uee7GgCpOt&L4acl?gp^4tX>nnJ-<@`@fWy`n_sPtvZgLM6hY zj^S^=4>%Q*@#GEnE+cIJ-+Sa1HhV$eu1o9b>9wvQa$#a-?7T&X4kDVkIoq!!o4`z$ zUY$D=c3zidNNWQ~KOd9QWU9S*oA~u)yqNXUZsQ&@JGVW%l9Qq%C@ocZYxLeZxSIN| z6siBn16t7T+Ip2ap}WI~G|!0&1ol`!dEywEEPp^Pep&wD`-d>r#!rundMB?+RW{nO z)9tq8USuJ$V%6Wi^_{FT%RP5v*0??dc_}WH^%87BpgtC0XHE+`z2 zI?tr^I7PEIp;{M*cQT1c$~k3Y$YWlEm?LkFYTGwA>g!+JzAw!Z;c)>E ze&^)$H;)}?XVr6HVKlq$AGLn9Va59kv3jj1+e~Er24KQ0x5{6PXXosS;ml#{necaZ zxgUyb{W%j$xTcOEVv2t!DK1_quKgFn&C1%;kVQ176vgj5~BF zkhjuqcF)sKAL-t6M=YB$=MGsWa2D1df6B$h6=7ddDQKCt_!z7p6W7%7QqusZkDThg z#eW-s5QxN_+4R<|Q-0gccIi z`)-Oi>qpyvieSsmE%B_5Ie2fg>{Y}VfJJ+NV(aMlNffcOBXF4oxG=s}0bL#eZSw8? z@(K(ATKJdpOa-op;%bUUP(Kc2b^iFeg$b>?b2nVXCVNYpDOhjYwl%?TL1UbzTK8nm zqkyl;IE*jIXeQFDyi7wM~mF?)q z=?swU7g907;^N{GbO9+*V?#=t;?gk-;7QLaZDp99f~6T!roTy#DY)t5gJS`BP`10q zVE7;Zyg(GhRv+hd8S4qO+`f)!h26Jb+q*uz{r*N-|6~Eey;tLsOW%2g%bG~E;Hs=| zL@ZPB9lsD>{C-+Fhj6xD<%Z4FWlh_OfoRzHtlCu*c{jM8Z|8Wi8X~OUF-MaU9jXS; zSq*>ZBK_hPxEtQ`UWI5?lwR1(EqUr8Wz4GmkC0&AaaP~(2_Vw7vMa6dwAdxre*tYE zX^40F`GhUkpsM1QqSrwIEmZDd!Z~~}-oW6IR7~9BzXX|jYJp3u2#dIxlN9!8;PtrI zD;6+=kBX;QIbYNm9|-_S|Hc8U;B%YUf+9_ibsGb`jL|H?E?7~@v%(GZV_JFy4U=evE8u5lW=8oC_bPsoy5%>x+IQzo;?(Fr~3P zm{11F>p|wevKo1OOmuPY-)Ap99BaCVEP@jj0b_n5z-$;t?e)qsaoGMz?eye|%{XU( z3x2JotqnnecpEo2_XX$Q-;uBYS>t`4>W|H(I=cyrCqURv%X=#>_qn?n1uJ0IDzzb zh7|v3drQBW{lfB|$@}1Mi!y>6V(rcR7ON5TVQXjelk=JwbuFBPfX<6l8Lo3rAUbem z#&lk2j4lYoS$=zYUdE|xUC2Ysn~ar4O$#{UZf56maK4Z(ShT2Xn9S^( zyZs%#l6v~RU=83Dsu}|g4YIi$;7+wI6-RboT-Fp_=8#>+?Q5Ju6`~p1y@UCtw$_XI z_-m@W9;;hfV76o7XjTR0jUIx;hckzI{bBJS zci_MBw(`sU4>FI-2@@$NZy*wUwl1BF?46kKZYFL!5lR%ch&++as}{d;OG!HLUi z=ONU3%|3EfYDlJ}lvL#d4o=ua&cQu$~uPb`K*5{B7Vj-Cc zFD!T!$_A?^(73)^fr$}7-DPKr?MMoUR~a`c@;_tg?8}TK6Q(+ zP4Gu&mY>u^gWZP4XvElIANo~tB<_*oaa$vzrGi0=fzk|e-9w=EH8m=cLVm@?XiO*j=R1db68u6& z!xh~Kw<~Yk{IN3XM{vX!59LJ%@duM%zph)ee#@q3ZF^5HZayXh!Y+lKwDx?StasC& zlk^3Zjn+wyqH<#hw>aNPc9-OS;Md-bSHbZiP2A7?nzLetQ;_RF~QLc0zns zNUWrX=dZ`E`(QPi9ddt{@51ccFLMeijocHTrT+M|Q8OGdLCjkbl7gfwA*u@*4RS~V zktir3P#PLe)&}%z8*A;4tQ(KCLTTuf3Nbr;DlZ?s)P0m^Nw9GOQGQa_;4YPGn!uC{MUiC-WW%Yk{`JJZ{yF5$5+qYQiI|~cUp0~~hMOHq3M%8b7vrg1E9oDD= zQY#O8^UfLOtjd&^eG`fe@BVHOBVx?S%KMZhG>B{vH~-H?Ly=7KT?5n7S*HiKckX!W z@Lh9z-bVDFb$YCdo_lfe zb?SpzxX`>xM6u=x`YWL#xiZFDb>@tjk0;$97kzOY5^w<#*>RN;TitU=TAny^g4a3M z-$4vA5G8c~irNHZ{kR)YLf^R@n@_8kKC}*zs+#?49C4Sp;FOcp)0eB#pETUsU}3mb z6Y$?^xRWJ2E7&T$;uZdm2LOecd#=Lbz}XP1ED=z&fNP6ubu!e{CG$#Vox~r0TiGFL?Q` z%&W28RN1)7copTGF6dtMnAkt`?HNx`@Q?*tPxMigbGvW@$!PZV>qm{vefPF=Bn91; zrOP+eU|RU-AVsqRQ6j=bATPdtCiZp_yX+_Yg(MpeOyt67^7yI<=G{$Qjp(WI)fR%B zKhM$5-rCt|KsGrkO(Ox}gwcagal)Xg`dMNeC#=ZR5HJU0I!;Mi6n3=XOj+DdzNv^nD3*(gTK%bgEC+8Li9`;8gy%b}TlBTmr@>PAY~Is^-1hlcbD zuFAvLm_vQ^-~6+nrSo&>lO@+1GRDOnDFROsN)|TGg2_qKszRp+X<>SnP%1Vx4cDi& zUy7BRZ9K`72K9QAOWfaz1j|Bv?D+BG&IfE!jI%*Z*W$SD*F4=@sRT{<7?{fiJ?pKT zCRYgKF2&w11ct>vW>w0G-jD8YtSCmQwK?j#mGKJEppoU^CjzXJ?%aM(Nx!b?V?)}) zb+C)*)5eJ>OFcurM|^*5QxbLlOad;1ZtpAru;0BHxPDPiP03IVm*2Q9{To@pJ3VF3 zf_{)XzIQVE3iMC|%Z?PBq0}Q_rxtR+3$U@U5dUO3iDZ!9&RtGyCy<#s))Lc#D_^&% z3^N)aHog%O-m3;HV_O|&oPn%N=h=o*sKr?scoOgOd)xjA4PXgOvGpoYbnsP?3}s7O zxSzH)eD-@)K9H~krJBl;POv85xyIOtQX|pFul>~Uq#1iu-MzOpSdrt#=EhmhNqQWa z=?iN$h4kxs=y6RdWrm9fqf`l>IoaA zr6_T$Xm-uwD{0s6Ye22a^vnNYeg>l|5?M%#O(v$S^{;=S7y0)1#PmcKOibD=Fn*DG z_Tf+XOd&CT7K_8NvN?vN{1a3O*){if*9?mc&fFq=J=>}QQI#`;b}eYWVa zmB2kKg1~M?kbXV8H6^43Tz4=~_ZkF^a`fA(!o0l1t~exwAfcoE|M_qoz zT*xGF{BK!8d^HvzIQdY>>(_*BbZ&oah4>-yC9Tr#+!5B`D3RDgVGC67S;=m=>@>wU zf=^dSaxb`0-b~upY15H%XONhXGZsMf@X;Fbfe`v5wTa-W=94*dkyJ=*Rh50Gks;Jj zbgkj>@2zCKO9&bLKG=dKrK7RDd~{>D$(cP<{eHC7#T*w}Qkci9v0wj+AREHFD1GX@ z;e=#~y*H2JXw5Qy!LCu*ntO%>qIT6qxo?lHnW<{X$3N&Q5+9NSV7HIJNdV~v)<{ZDNy%`SS^Aqj zx|v@0!k_dqlH{qh28Z2d*xNgdG4IQfWUNLBQM{`!gmV+f|8trIRF+4y|=+zEj{F1ZgyLik!)MGm+k85xrNAr9E~1W($U^mJY&lg0$0&8v(#NEV-J z8d$igQ}^;bpUc-vSBsqN8pBwBzsPkdwAI7pQyF0D*G2ZKQV2I&zktmF=Fq+`-8Z@T zw|v;XoV~=#nhnfIV$0t(BOtWVMB*hM25)G3 z%)MEwj)kJ1&t=6NKENhbW%ch2%4m)v9a8c?HG07MAi%u*@0aQS?lS{Q=oxb7 zsd~leKU^SoJuj!KYNG$yf4HhN^X3}q--t;;n7dGm7qm?)D-)$KY&dp=I0kScudD%H z_u~_9s|S9>1cWGR#voc2<|w9C?bs%g(PpOCeGE_3|Ln>k(n1L!Xy^pniH8g+qc#6{ ztjVzlkBVej0NZ#KnLKWOk&(w;Q}}Z@JudEylwtLiy%&HFb5jPmSn}F)U-NtRc|UmmZWs_(G;;2`1Nb71?$9}L;zseaC?S3@$xoj? zo$O%{mH@JV40dAYvJRos88i$3-NRQp{^Ml!VdaP?$PW`)O9@e1lMFo>3gRN(+XBWJ z6zLd;T5c`*7;b@zoPgvtKz@LUPMVd0`~R`SGD0{b5Fe)(6%|!xIeG`o_?{=1Wl;E% zH`)#X*W)Ue+fP$6zK+;`@WsWwgpy1IVPFK9yPE%?&ffQTNT5~F7w1iuUQ{Hwd!fZo znd*e7p`X8v7H#W4D~*n=sPv^~!{08dzYO1JR3WG;{NUV9i;_PIoBS^RlZx$C^j*X8 z<}iK5AGOau)}8zP$Bfre!NI|Nrc1_bmo6P@OFlvR=Sk4{go-~*AnjV)2&zjlx@>kn zYXOs2Qc?;jlgKjKTNVgIXU@b1OD^>ywCV?9${O;T7h050aS-{E=>==(Ot5^+uZ4Z& zEE58m9{q+m*m>gDf_GX2>{+$R*;z?jVo#9#eP3fjxFXC#LNn?I5Bn;S9d;lg{1n^J zvcxQdx#1u1z(^TdIrLQt1mMvrrU*NFkA~4NqL?o5I-@eI@>u%tQz#-LBEH^~r|PPzC;bU{ZtwkMAGVcv!mY68$$^fSX^QTo zO}Zra89%bInpZt0;WKWHMQ_AY{rO!2!UcIW4HxUj*0#16fgMK8#0i&T$*!3ltFia3 zLu{b}*p9K)pGGT8V05%zk18qm_WmeJ=)D#OV*spDSO$0E9}fqT2UiJ4b)=V<4}?dA z-<$FJ?0plRd89^wW~S}$l2M{{zM+aA%D=^*zY}t(l*bv(NI^(EJoZ7t(3kieaOV6Z zm-uclYN8(7bez9a@q7J(*iZ(eqkM2oF|ClDafb9Wr@!g;F&d4DnH*~=a4<4aQoBM_ z6F_TpRw}@6?AytIxppS%*2y!AW6gPAzkUr02-0PuJPh{!UEr`E3d=As^)=aLh9 zRziA{p|En;k7s{4MoRQIG6JFp_FiRaX@`#fvxe;#TJd;uvMApoxLEg2pV)+e3PF18 zW%nw=)Z}F1e0}G?P!TvP49ec#{_B_S!bz8M_}@%;YIlPV%EXNG!C>{7m)1yu#=2x5 z;u^|pcKj_qje+FAUQX{h-deXTA1|ej!36&>`y1Kzp?(~1%}yg7<+I5a?EkWVRy*?u zj#*}?s*K=HJHbE3H-LJ6oFmt}`5@SQ`B4@YmMnmsY^U zg{?MP!Ua2sM=zj}g#7Dc)Cv-?&+q`M4vB0kI{OC*?ZXhq8>F0WP!c~!kVdCqr%hjPZxwe!DV zf!Sa>LH@T_?M2fXaU4)o*1eDja{4#)e@kZ+m9dG5HJgO>Pgk9UTlR2L(M1lvzW@`> zn2wT>eTNrf9Zl>EZT`s2m783f?gzvNW%-B8Km-sYmM2Gd_`oBy2aGXsLGodT#F+p7oOwD<}DJs7v%352nJg1%gl}qtVP!2*>DsyM# zPq@G)lgUx@Pf7*-{KGe_v!nCyjdUK~)~U=g+3?jk^IG(uAmr)EiS?FcbbLY8_>L*4 z0g2tV9}BNNIaD`l!p#ql49M2fGt|x-Ektyz27@4yKmJ6C!TQ$Uh9g8yW31zy_d(xl zFMNBl#hMnu*(3%ku!*i_`AgZ>hkYd%893FP0c7?UcSQ#Wc1I`#zel) zpIf}l(IeBvx6+?E@C3~QVfD#E78eVl9@&JyySEKoN2hO9nZEZv=$k}KhMxc!35L

HuxoBQGXH&5pTTEMt8u;}YH31JZTFKL(K4O_wuW@cstd6+MF{eB^k z8}qYYkd8ElY*QpEZ}_*t9P|dlw>#jZuaG+4EZ+T`AO#>?KPs5_e>@(TWzARtV9B`; zeHT~sYfVBsITe|F3XynpVBM840@*Qbh`QVLUYV3n{SX{to^Ko6(|-QW86Lv}d&I~( zb1Xk=jo-;@nA9!drN$F`3tcNr5apSXnORWty7&`(_{aNDJCOD_Z1va(uQG%AX(TO3(%un&JloC1 z_&f4&0mQM(r03w^c=E3hq4Y>AclzRZ6Hk<1;(1Ok^KP!xD3KnOqgR}S>HpabbUqka z)Xw^N;-&rMSQb*h6PK$r)4l5p3oB#-+j-k5ASnxTKr9ZKI0$K`X@yrwsqR5Gw4(E6w@h` zF3kyk_fr28m(NUpyzdJ1BojRQ5h0aB)C8Q^8_mInWKs3Be@qB^tpNTlPZVTjalI-r z(B5-WaFOd*V{>vk3|pct`ZYCQoUlqfsH&x9+4<^%fpft$#h#TSo7m10`~0YQ3||v+ z#7QAdv80X;it2)FF7#5c_Eqr^%dujx1e>1o>?nB}NE6w`>x=PXv5MyB4rqwWtlLc&L@XXzDz<%|JxqJBVE#h-x3yE z$Cr(lUZRAOFf(ZzDq|Xq06hr^y`c9=o6EAzL<#k_H-C%MqZsCVCV>;b`3~&q<2tH6 zr^O2YlPLUx28`?|$f;@X-(O~TlS)^J+LsP4kUMnXpP~xNTZP|>kf4ZH`bsa3oe+7L zC4)F3dY~6dWc}OFKo+Lf0xp%a+;r{DEp^*|)hER-lmn9wus(gb&YY6C1d@Fg15=F;dLPPJLECC}O2++9?hEoo z-!e&&v4NQ!dJ%zOpT!e@o*5qLDN|73T%SL^Xs@Io!=Ih`^{|{+RUV^WXcH`$wKwuj zA>yyu`amS%Zm2+Sjd;Wd-gZl%8JfQ8<*r4v^%hoEQh!3}&D*iAYY!p>tj{#mU3gbh z^N)|MQPn1`&g5R7_`>`3Tb_3X19?6IRe$dUV-iv^PcNEum;+rP$jf!y~ap`Z1Ir1fh=+L5ta9P-c3;;!|ClEGXK!D_ePbIsI!uOSpaV{-OmpG z3nb97sP%<%O&LIxA;CnZQbv1!f}}`FI;{8da=vj}+{B^K7m`W{LKLmwg*vOY8H)w0 zz5;J8xmbAFlzpQGw$K=8f(IG@j<^A{~ zTMKJ5vk(!Zm&;&1n*M$)TuDXc1jhqO5PJRnwUachQ*`Omz&F#O)RyH_#gWq8;P*T2}tcN$gpK=E>ApV>r~UNR~J;R zZ{4z#eyR$4lYngN#{A`ngkDEfVB(@FnzunIP34HR&(a=rdT}h)6myP(_R(LbtkuN| zHgjh@k0P6l$4dsD)Q^|+_gy%4LinHcBuO6?@jrAuHY=<3LgyD1dHFVU@%Q(L zQRqO#*dL#8mN1STv}z_fk#e)yv$Mu`AGiI^_2}DshMcsdLJ!d9?^gXd(uz~EHEhX; zucc|mrZU{^7r0^EZG-{Y3vBSO3HI13T^^&x2{$V3vq7(sj+D~yV{0-}(wEMsX_2@2 zaSR9wSX9@)Ko!j#aZRT(&cE~os)m}>S~C3WkKnBuipzt&w9S@*!h`qyCHn`C78Ja)Dy{T?&zk&JRE zH6bNkd|X^yY;gj^zjjm`ggzEx$Ifx_eO0j9bJ3^$$HM-oTUBDduunMxWzP&6u zW&9fUytiCU0G%1!9APUCC%L!f_gM;W&N@~!u->e*UHnC(0@Xj^_3^IwdUf1`@4Cc= z3pT_;nY{0dd+R|TV6!6)1aaJX;EmKiKW{q|L`_guC*I}M;lo_1`rRn$KPMpMkeewr zkr#7)_-(tL>EGqQFNsc7>+I?>GBmn4ZQw<97?_)z-(QFz>_P2aEOecF;IJ1n3XyqF z(Y0@n0B+$Em?Q(~Enpg>WG1gmD}OjZ*oMiW-Aja#1q+vx4Gy?2Ha+gAv#vhkFcxNX z0slmphclK8^;OHoqJ>V|WhO6wd!^6C^7Dc3$K~WR;94cTmfJFBHP2g1`-!8MUn`dnx8xSs5$;(Y%o1@=a+6SC7owu1oyuX zkGzFYC?YZ;eG;okn0tC)S~W-7igd4(W-LZQ%*k%kuet7s@;m+4I|&Fi2sF`yVA(?C z7!I`t5}S$tSn*2rZ`!*XZ=&Eb#g%6YC%KX#7ASEPPn_BO8R&6Z@y*gBXrW=u+}B6n zP+4Zitl!}%I`^FqALaz&(QOf*lHHxn{&|lvsapDjtg*J+1q05hnogs^E6u`lYqOUA zykE0EQi$UZi!RC0io2K2eLkP_9g#$i`JJp2d2F$WMze{s`l+j^gdWT>@C62m4FaI; z=uK`4LT<*^{{ERKNbSs%#qY3JZb^{64t~=IN)WGEI3VGlu+B(^Qfs=+oMzAD7TWtD zi8~|YZqlzrf9^PJDaG{2tGoG0(ax+tpX@JG{!q)7QCP*-Z`VPvRCVphO}IJU(nf24 zj~cZM%mGAaJ^$W(+vMH5cO(Trie8~D1Fu`Um#+@E%uMIBZ-5ArgCnI=#C?z5^f<42Fl{X&7RuU~q?w(HC zsCk*6U%8nG?Z{tGa5Kg;gFc$up4CbtAuu%hpZs52h*nm9BeT0@+u`D%Ytq?#!*jIx z({Gjk8tRRfb4rxcSXi_~@tWvbh14Ct-AUz&?8Ro`mfc6)N3jG@deZIFdPxx_;*{MK zDai9Zo}*-%n|~|jK|JT&xu7Yji_U#4x#^VY?#I1MaiNx2k#wfMi;GopiAf2NHSvBEQE7uCvpWpdn3Bit&hDc(fNkKbzY*+Fv0>gRZ>>g z4~jW@6%V^(GFb42?qvD+-*|~w04!|%GN6FhM5m6kbF+J2{hg?=56Jwi2TGHNnw~#k zI4Aj+3-PSnM>y6JVFaTD`zM$}eQ?|vtRw$%q#I<$B(on63pZMp%;fJl8cu|itq%0f z77icocsYE9upNn5n%Uc%=Y#qNAFC_T2y9Hm&sceE_D%91Sc}?;5!u~Z%@ROlcmYwZL?Gk@sY;Kz+C97Kr$>5Dqc#!Ta+U4D#9N}!DFSm^7TkB=zlj|zb6&&(7I$`xhs>dfWNk@9U_#;{?Y_j z?b2`Gb$&6Zu+OxSl~}TY0sHovPcL+zI*gF#3L-<|)^`@}gTQb=+_K1tlCuQ0E3xFq zy_O0ZH5@gm7_68ye*S*3ZxL^%}<~T$RTiEdY0p zz)jAUZ_Xy3|FFpy^~MRV6`dK2u*yg7WL+v7RMOBew<`VlB)w#|*qx!u0g%L1Z0!Cb zrpPnbZp(k`s@TcXeDHxNI#6lfy*|r=euw-I2WUfauS^Xzw&&VEo%7flX0U+%boBPb zt}n-N61}`b+v1zk9d|`n>kbq##bW50m6Ri*H<5M$Rs&Hkvq`;lVnj#;|0L#K3$f_e zK01YaBtqoz)`%0l&7IT#TS77rL?PzhlAfBwGyIBPOa8l(RpVMf50a@tPZP!8W15;i zJ^Ds_MfA3}qgBQBNiAHp1QG1%f;W+uKZIsC3YU^=L}vZ`S|o$ zY`Oy~0H`7opLmPeqH+2@^PHw3OJ!|stIgSx%(Ati=hhI(hZh<+3tq_zrHuCxxa};x zx~mf9i1uoGn1#YaryNPYH}ot05ZUtlMUW^n9|Ho@Q=FjeM<(-_zbdZ!yVYxR?_ZD` zZAmuK^gP8Z?E^_LUaYb4@ZVI64Mp8~bLlelS?E8z^1`X3lZh`b#y}Dyr`crbVr^S5?t|hq+l5gZWyM7Wk z7{hd^82|MMW04K<#fshSmL;B%PEZt2Voj)Zjd?GjuZOXy5;g`YPpI&eNVA1}I5dC%!mAV~qDm9>adh$>1;yM*6wU2)+|drk4WTyb=ZPV5@_~hOcw4Jb$S)nmi=3=`#S;qc;e2< zZcgX;m2(y}ca<9o75(DNDA%r{8(ggNI+e-=%GaB$ddWCTb)ea>nCBMfza*}+Ia5$D z9^)a_W|%tbGV(&o{EeoA>ats_cB4JV(O+IV94PLPdbv4*za>#N%2a%Jy~QHJBL8Pz z3EZt+J6o~q9wFvdoFY#B_(dm->zQw@{mdT?QSXJFwgmi9zCq?34+j&vtn?UJ`F2n|>#}|gq3AJf}z+)VQnV*#^#81Tp%pDe<{CE6j0;w2BIy>KN7~1+E)!RlIKv^I~p@jJ{SF>Yo{K zA8;BkBIp~Sy}0D`^Ak;96aS$3`{pB>Hg)G6CR37D+-ps>;R+J`&PqW=5d#vxOjkc` zBqk(OgYjD_RFqwFan6)}Tk+5W*r1i~J`6P_!rx~|kJOLDX6Hk{`f=Y%nF39R$CUbD zcE3YklS99~vZLTydEdE>^8Ea-$5fto9lNhcTX*UhLKnzfoQ;hH{(b(t&U zPsy+=ohzQ=SY4}FYQJ+!REbtuNvW7XfzE|!hNa=25q-3 ztI0M89S7a=m%plKPAX#+yq}cyS`_q$*aT^NyqPUslr8y@7=eFamSoG(W7YTIBYA(! zXDV5N4=^&cC1##Cv$U#2uycJTNqjqHv!p%8|LUs8+D8Wba5`m)GE5yjohcj+m>sNy zI&#o#5k1#6D4hA6>Z__zl)DE*>4CSye843tNMt;ep}BRA6!qCfBdu@Q;~LG0b{i>l zYKo%p?yE zynjI_zWmX(S4K-q48uL8IbVgqOKtC||+^e_<;KbCo(bfg?=CWp1}J}ys$ z^q133!$~)m6}LNgldoenFx?nl^$M9?WzMptdyaw+F_PrCi=i$6fD427Z!e|jM6%k} znAuDeaY+TM*&o6f2n6TPZ*5a?`K(i zyKU+AIL_F8+XCae=`j_YZ87XTNKw=XQfdVV+$WE;zA`AAw=y+vtljDUtp!?V;X?8d zrsjVj1{#e5T__*t2b(;JizXK>qjdg*Q?5+&a93v^z036X=hwbxrRVq7cjecaFM;2M z<8E!3;2ctXgWjug12GqLSLnyNl1W@D^nQCSexiz2@wS0<4=M@vm&ab;PR>qM_Pi8^ z&Im~!^w`~2ASKP@TNfC7Eu5-#@m#^D1U1nEmY4==m;&U>6j0y$LW24T`lY=s4LEcH2CtjBmsVNMRnxZDG3{vMC6lf!r z_&vnve`ia|EYE?gE*tUxUEtUPPcMNeI=V6|(yb}^=Im~@Q~ynV&wE#1Op4TdqwQYA z>{Atsla0vmwFWSr@3sLacMr?)_D*G1h>bba5!!SHUVZMamWIy21UbtieB&LeVEN>J)<5~Rs6cC}oV@9qbklWLHgB*Rcy&%$HSvr9iZEEb#i`Mq-< z8M~(nj_WbP$U=+gDxUEK)e6%vgtdaf!N)AhwNY>l`wSA|fsQyA>4I~_Rb^d`b!S`I zARpP;8W(r`I4VJuwal;Nakiu1PWN%wpd4nlQ;K^At_Hb+xpw!9W!bWl@I>sRqZTi} zxNY?45)CBOUd?+S-Iu)K4o437BBk(11cVq@;h{zv;INEMVg;KqcF#gsNk4F%MEzHZ zy*L^=q`3bCG^G-18g>4u?$M0fsOReH{aMOFs|k~ZxR?KtrfXMqUdiyi2iVl`YPefJ zFwZQbsK&NLkzZgcEoVCJImd!)Ax>I0f{%U7!F_)bt|pZ<#$A07Jqv3*t7J1XJG;{7 zJ?=o7=MG_pgzeG>tf%iHX}log*JA_2Im1r)=Ap$H1}sFV}4lichUZ9P3F(N=J} zGqSE|7#tz3JQp|`x1j#C=O2C{Xb?rJYX9!1n?U;4w;197@Sh>673-lCR&OntJ5S7h z%-iJw;{146;M+d!{?vP!tUb#X?x-RfjR)8i?zkA!Qqk?z!y~xxVF-IoxtP}J9;37t z_yyoK<1Pk`C8bo*IpW()&CFy7@?bs;O3*Ag$rjkZ8D4SC!ak(VSt*-y zPXO4pci7V60$5`j-y1u(_}EmhZLkHyD$O;Lkqgs0`y93GJ28p%CGsZA%geL7EEvvJ zQ`{N1X2J1?79n4@p>c~Je49XDU872a$h)9OxTUPyyis`)SwYHJFx-8Ye?YJ3B~@#L zJR+O>^qhuy6`lXPse$bzyl^+#{L}gKsr@zlzazshFztyBMBlN^fve^+$NMV9y9C~z zje7WBv<)qT1h?XE<@%B4)7d}~y^`td=b07?JvT8*1$dh~+7xbpp87|7HZ7-_gWxV9 z74<9~i9w$WTjh?7tAQR{@lkFoJtPHlMLEzPQN*e&woBcORU(jNR~L8NSc;Z$bDMQ? zE%m2P#1!636~AD5s*74#L)VASK?U#YiTj#bAHk|J+$k$KdaMKx&9G(2Z3qw7lcd9j zc3fF=lTAb52)GP*3!`$>$SJ?EA~@6hF-FYxVvq}h>fl<$ldA$t_@6-2^rbtbn`XTa zzd8=EJ}k3*Y3(GBVd2}^=yI{0HT{BO)0S1ym_UIc;?;*st_)L)faxqQH=em4?E+Z27Cw4B@&WMuCQ;6bMEK z2x}$csqP!99^1<^{`>b zQz>Ut;8ur>gyenEF^ktpKU}QdO1E-j8{@zbOLj76maX)Lu6{0VV++~@tXS79Fzly7 zp*fR}M8g1}{W>k5FZ<(&*|KKxyhg+}r}be0t$OaXCWyS<)G?>97Idr#qu$ zcJhGj<^auw+Xn9B-lU+7-KKzv`!LK0Qs}jPcO=*d8iD)u<7LGl)nEa9g zf~ogvyYI_?u^C8cga(F+V~IFf#rBMqOmN}$mF*^>h1#>jmf_}%1+lS}9HsMD6>hrM z1~F}Kluc!nOhY}g%&RP_g~?ei;F7ig+bMuPgz!72nXHe8R{+U;E~8|6CtKkv_vjUa zT(Fkf6~d+6T$}2r#)m@W&wzWHfXXAnP^TEstOrVM@1oB(~wYZ<<^<5 zS^!T9ub!Fipgw4&XoA784(HuR6_uqP`8;(u*pqr6=7w};;_XW2$Ol*PO$ScZ`uDy6 zOh@Vg#6rMI6&dG4^YzYt+&5>4jjs0BGBXv|6~!5}WF(9*ZhBT7IU|AQzGSL! zp=YV2{6a-v7vHi9osDEYj5Fr3#0#wEa5#4ZCyh5y-@erI6nf~$i|8Jg0~NJRhqc5O zs4Z^Z!K87yaKjKOjNDe*cWI8N-ov4S0YU$StF#@&sm1bmh*b13UNYx{O8P8Idf>`z zijLD|y?lM<`YqzSrCo+AD}7ddPiQSCiZoje_?)(RnzE3hyhu9YzCEQ~00ak%EETo7~I!%8#nFZ2hkZ`kKOm<+yj?;jACY#4*ByJn#0P< zD}VoS9pk+jpiJ$L>46>r;7FNH@iH}Tf;$*V4o=Qh5gHt8%jeU!eq9;teo#A=WTd3L zUs+jsJgm&M4!lMIH4P0jK4UeCR4&G4wy4a?cilb?Z3`&h+p|Svu`zUW!X=*7FZEuU zvdfQmZ_J;w=g;?EieF`>t?eYDfvt<*bXOHR*gI0H3qN&k(~pyntu}6>FH#^;c`FP-~Hqt+MCXKK!l5ATLN9(qXWnuz?f56%|pmN zGuVUlTUo?_9Pm}Lp|--2Y4B8DtzO{jXH-9D{zWP?5q1$;+uhkCVksfBEudL`mYyF15FZ-5D*W zb416vJMARu^^D%(;M_!;N5|m;G|H#ho`aR4UeWHj7l*&-A#fUFwPZ>V+I} zw7Zfzy#3ZB!|vMWUk#l#>e`xT78UyXCDkbB%#U~9%_z#=W**>KHN1zWabwYlf3=Hy zJyvk>LHune(t-q+Fi>?Mrx1h;zFi-X?d0vjlmKLR!r?|mEA4}-5*&4OB^~=y4YOCFgayLWK+gr3{Jbz zD}R(WqzTZu{XvE|?0>fB?cREITjncEj?lCy@p$809=NP3 zArWO1KwY@9=_s{$^O(q7iMF>l(94?x__@v0jN*E?*}=JhO9Mfsj0Hxu#l}MrL2XmT zSMkTI#}6d++Q6Bul$vc)l_>qlLEQ@7Wlu*LN5s3%K?s!`;<|j3a6timhqoz)pOd{| zVl;^*=NF)@J&)CGzK6zLz4434nc$42ia;`WJN4_0)nmKIqjXA#eA!$v8oq;MtBgUB z=)}9`%>2dpUNz?J5NHcOxF=LMHU2nNh$$!{hx4_*oIlaj7I8KW%ko_)rA-u;b{A>s+VWiColL{ zz~tAvUH|Y`JDC?u!w!wGR^xn2)UpRsiH_9vTYsjTfkZps+iAMW@bDYf0g8%DBzf|6 z>+E+Kk8<1?D4pDtF1IWKI#F8xtL$Q*c)MvLA+*QO+$5r%lK4?GWJy-riHc4N?oc}t7Bq71i+ zi_2zB@kt@S0w!giU3VezIkT5Wn-$z7lwZ3Z>n(+D(Yzp3G3-7_M$%Gy5+Qj0925lq zOhEhOXtbG+lhzsZ_umqG+4NueTx&s)fo`4|ZkUGbWls==7g}uO*-vrm)2SC#_bN6z zGxd~S_~wZgFmcIYrK7v)Csg8h9%42l1#JzhOp-UEs&?H^VKu~Wx8cV+?uzFzY<)X; z3sb!up2FJE57LfAu4_WQ0O-Fc5}YN|j#-jT%FB^O|pv z|1c#bnDn9$m-$em!iHTVAHhvdA%(b+a%#RH_)CA#5RO*Q^(|=yw0^YwTuQB+A(vS| z!E&=uw-{AKPENkkCdE+104edU$)!2y2~@pbD(88Mo`rgFS~VqiRctvgdJuu~vo4FK zgHuLI;w3-T6156MpkrYPhW@?2LZY%*yQscu^kjCs9dcHuugpzU`h|FJo^TP_M) zQJ%k?(}psVPD`GWV&&;OCU`^df?%dRna|;-#=||xtU0AFqRJL~c!&;B_>y%YbE9|M z_6Cx^kzskG_*Y5E$iDwlNUYsM>lW}d3w%tM3pIHiA0SjO`s}pX#cJt5@9oiibfT>J zcz#?(&ym{Y@z-;^gL%@tkq zz7FIfQb z0&*3i&M3G+400!shtb-MUF{3igI7{wI4Xsrn z6CV*K>2AzyDywxI7W}mH6At$+M!I7Ka+E`r59IE1r4QMuGS!zv%v00zxzqE1B*7eJ z7^?uA0KH;|Qv?5?>o2_8aa&YqR%j>3sD*z1MinqK5F|_T0gO8zO|8miWl!n_&YW(u zT6LL8UKnUhq(LxI@C;}oq=}_&S!7W0nYmb^&jnK{w%2|8B9lDZ(XxU7)&sWNho+%E z%ZB#(KucnD9}B}bjCFSo6(8|+bm!z}Vckv8SRQO=h(c0e5eMYQu0XEEYm8Eab~a_8 zM9uJOcrje}-_Y-Y3$bi3lHk zA#xKHCh$IL(|5=4CSzBOf|%7Z)D#i!%pI!lZ?&vb6V59bTnf{FyV@gmE3Q2_rd-OO z-XcEgzhPj{B8eLnG>UlVsdR@{iG%O_XOJQc$iWWfUD9^9VcNlog7iVOWhvUK;;>79 z>|~y^MqFZ0W>tC06>(~>SKz<*Mxf=a)1~cER<=;jmgtrc5BpRGfpI3`mF#WPhq!>L zJksm=P(+qmmamT?>U?cmI0+)lhrzu&J#lJ^fP_!&TV!e}@W}X}!mA%Z(0Dh?e$w#< zZ&2!FvU^o1ur>RgXA7J7`a(I3Z+;oto|&hu#dNy^(=VO-+GC-TU^kZ{YzJxWBz&(a2}EWj%#@=N^3g=rI?cAj{9i}PdHVPS8ZIpoM;JDC{bLg>r#tUiK`wEZfN zf8|9(icLo86|1*4l&||fih$?=#M?|y9SAo^gOpC(>*Ig0EYLpEi4WgGn9P%u9ldiwLRe{Ari?d{X zEMf-yXHny&dmcf;nhYgeoU$5p?eHyALS2dxKH+f^jJG02csrlgs)HR2DBfE&tV)n+zTTb6l(Wa3=as!jKWS25jyg~A@tV(k5?8JB5m zHQ^+eA8u>+)qs;Xh_zkBnQp*J;rqt<+-f`OPuj0M{~YHmu2L$h~nv z)GswHqaXyYIw#~XJQz&1ayEYE3&$o=`aStAoD6cp_97E9>`hw%J!g?TOXjNjr1e`4%HaH_hB#dCfSMGG-U@n zZ%1`8^EOW%`vp@gX;AJ}dcF6)UtsT#&dBdnQtx@rSw7LT4T7*Cr7gd_w@`|4EXif@ zhvg5tZ+<$|xIC+$6y=Z&;>FTcneqy)!Uu0R!#UgbZxJG+kmk^p&xcsVBd=UO+hNuU z{l>nJq&;(CFWpeeRA1&YGsMn+!+?{KLh!qO$H9KP zGs#vRpFE%rPFCN($vp6~=tNdwVK>s{=%`bGO}VbjI6>9d7OXSkMs!TCvqcK7TN^Cd zaLeR+&0Eaz8X>kA(B(4YofP*M-4$C;pbeK55FBq-tjZ|c!~=mb4TZep zT*QW(8>lP7cifjPil9eEsYF9@!4xsfx(mUH&yRwTQ=!F23z0Z^43`SEO{JT}xQ*qV zTuqXQjf<<&+^)VWAWmMA1Sc+_8JQ6oLACDvqr`APiIyv;O@`&ymrTF=Tnjg13lplz z_l-2Th9TS+zp3zcS`1~$n^X3Ci#dS+0iG1lB3hYy?31(=0UmGZ4co^k#pN z6?D(=73a&yp;_t%12TW1de>hD-naebmF1AMHht$s!JA~! z4UA2;8B1SDoPHPPMI2n&xcaULts*$T5bz?%AVMuPDff2*R>oOlGwqtssB%`tz8%Vls z;(oOVH|^db!|$~6rttvGU#w_w2!`!k5az=j`|o^85De(%P>64}zPg5~!JKylRrEam z>)ZjDG`8LU!5#NL)i;Cn{pXV8Gf_Ze3HL(;6is?(FpjYo>lrgr-2`EPIJE=sh3#Eo zge$G4x_gD_X&IC+IS3uIYBt@#QPS8y(2zI21AwA2Jz8z(7~hGTn{{{H^`QDsGNQq` zr{NNi`h7gVml4+6IXbQ4qLxgsonyD|!OW(i0c};)AF9FX;`~TCTp?y77?gT@02()U zDg;-{CB!pvb`iHDMhWkmnVE?)I73%)vpk4N%Lo^zF~@U=A(O&#l{5Ca7A|T~Q>$g2 zU;me%y@2l0bs;<`H(wlS&88N51`{nO!!Gm4A^QfS&PPIF`~#OSfz;w~bRfo5%W0Ha z`;gEFBrhzb-X59yP{wyVk^7}=c?B^0`v;6N`xno{(K*O$_ks6kbJ;MZ%L?ySpybJ+ zt^LW92a>zqjj2p4+`iyse_K{+IJ7{#?ZU0Wu5XI8((l4`OX*U=+d+&s+}|{V#K{4Y zi8G?!FSl}$U`_8j|DjS#+&Gv5a~rxd_DcZud`nD(_7{POBSrnjmD%Qs(raQAqDw(t zhN=CT<(M0`FqxU!Kd>5c9gB~FJm!G#n{KtHgKV{1h>jYHr(4K=26 zoPLJtclMAYGCRtPNmhJUe?L6>b2aJZmDzZhs$V*NK}*3~C9~5U%4kHBqrjz?T|~b@qwD>g$L{7fU&AOmV}QA1)8JV+ z>J5mTFQ!i}LEvs!TJ26vxw;8u&|DrsDC$`)d~f&z+Sx;rXpdJH1Um5wDc2bqi6@Al zSz8OY(-jptN{1amIkCl(7TGsHdj^wmrMx;ru+&f=aArMOOtfL`q_fq2auRqeF_KcK z%Mci{9=-rwRvDM?-Zav8d?<2LxQ779SRo8^W(K{}$dQ)%bLB$5Ic*w7?TKveF^@Utw-OIHvAu3UmX_J7WFL%s36D{FbKf{83dG68dMBg z7`jUu>5@{hNJXSWkO77g>7flkx`z(w7U}-h8NBa%-{<-M@wwL+&YZK)-fR78O_S&g zz?j(fIiNZ0f?uL)u1u+d(HAZ6w~d(XFwr(Ms&Z}j4WkNuKDh6}O)KfO!#7t#Y^t10 z#TuiF=ZD4h@^w)cw{8~s3#6WgeI5l>HXnz5yj)h+ztqTz2ZMtf^Z2RQibvwiJ?vQW z=SKq3Uh%7insl)$9~CN=$s?w^XV&kIwlAUSGOf7cryot*?lxI!j2fdTHZ`7V)V~Cz ziDXNYWy(bVr7#^){#8Lj6$*hRbSITeoJ74>+o1$xR37i}E%4{U)n<0hq%iMhcP@9` zZeDLcTifYyNHo~e%1ZWzwrEAW!!7Z!vmQbZo!rD_Fl+~Cy-WJ(^_8=;%U;{_kFYDz zvda!RDPO;Do~!M&v=vob)e5-VY)eN%mDsxiaLIi7)AYD+Gfuff7<`czYF(N?gySWG zZDLrQ5;2N}gD-#6?9KND$4@r#bPa`pd8qtEA(Uk^jK#X*ZaS|XBXR(4uO)vk0bN0D z&>*eV>+Q8!@`8F9;!u-<*ZR3y$>P2Kyq@;Fq3I3?`hJzWw?ww!f!e(ak;68j_f{J9IjlGEe(uEMrt?48U>uE{hSUZJ$C zV88%M7QbzKX47aO8k3S3v&ELU4POUpVyS#UMqDXIcY>V`?wmx+7w*A(I z10O#x0V!~5HVa+I0LI6EO`q5zJ9;!eG1aVbL&WO}ndbo;Auwlu%CCbjj5uT;zDKwrG?Xm}HD z6dQlORhC*R?}tb%B|9G`Bq>VXm6d#qRVark-8=SiG160qx=50Jr)?+$!LTfmp?IU^ zwA#(ot>h?FJ_^PnzD>)6rPGy}nqFt@)hiM1g$_{&yUW}8S8bRt%qfh0Jcj@&?sCkx zmFaZQzm@LY9K3I`D`p;@5G@srO&w@|dLw6`T`i-T{E%gjTDJb(jGDFb|5X^?E+n^G z+%7F&b1>BUs2rQ1rtG6Lf<|x17qCa9R|JwTn_{QW%(!%N&?d&a?ar~a8!yE!KB-wg zk4Ws=PM>vk+R9O8*Kwf0BJC08G5No{rjFGoG^0w+plv(pEAlR^eZ~+5`>N)gN5-_& zb&y};9Y02L-H_?nDYa2z##YBakTE5t)#=74X2pfpSh&Z2@;`^(ZMF4Z$K5$CxOq%- zhByz9(wfDEe*aT=EnCs%`Q>7%EZw`aUo}0~+EpYs0ms!|)$D9GDlJ%|!Qd@DD~#rP zhOXBz8X+u^M|t4(&02{p-4nYY6MbEhJ?KKRgu8>TVpE8l%W7%`d`559P%v{VX>!dg z8kId`8>`mtacHRknAAJFf&d{j@0YE0ZhMuHJpnVKJE-Po0n%^ED&Ly%Dm>!!O!ssg zU^8(8v3AvGG3yaK0u_sX)1F5%-FZUZq;JIwG;92L{Q*YRJiMq=b#(jIoZ-#=brSOpn%J*1ec!`(j{^e#~Lf$iB0H( zi=I^tU1`t8&ZJ&2&X}0|?ySI~Ml=TYi=SDz8LYYv5c#DN3joX+fvLx5@_tUIkpEKP zmXZmc<#4f(MlPs`QfO&|u7CFuoc2z|j&7v2{1OaF$6lMshFJ%;DPp#YerGvf&Y*vy z2gWT}*7tK=m>=7to%U-K-p!XSVqPkKedb8<^!eZz(KPwP?{^hRKE3IvNKEi~@HTP7 z{S*1eS8cbc+5em*A-RbDl>F`szg8~)&;2Kh-<~&`nl8llu&)np#^5dWN`xKiix-7^ z8e+FaD;xmz5DH6Bru)t$lRa|}C&_G$YfCs{zZ&_{CSYdB1l0%fOQzi0*cSKV9HwJq zi10t{#wpv!zTu;-jaGgX)egD%dat|yVl;rdS^l#zu8}WXS6--W_RE-PP^#YhLEDhD zURJpv{MMo_2_LwYDwZt|nMo6Kq03glFGa;xTf$p+SV6gmc1k6rGn4(*!YPYj zt6OLtx)!yT_RM6SkaSOrL&h1BZ<4m(y^+W&aQX9-P53Z{w5@P&v)bDOn3?i(|>hm$LL6W3zk~!_;)A z3vNzs-hNizDu8Pk99k^!rZ7u8-NJ7jT4uWZXPsr$nI11=!xnXwLyZ!d&|663nf za_Rj0F;ESKB1BY;UCH+Yj~Cz_IWYluvBXA?dtPV5`}cF}FP|c8#{S zKT_XMMD(n@$g4JM5yh%Hc{$7)*hfrup`c0h)j~4xOUd-Cb%X1ah5D55Qt4y_NMLD1 z(EReG`;Ha2=&tZD`-Z1|OFBEVZ^ZpkF>`htXCmUOJ%8)tILO7c#7#?okdI+6@`O8; zVrKopUdlc*oSidkZc0{msx%MO^Ec=Mj5ueV2NG9l^+iUW(->M`m>ETgkek3oC5fGO zQQr+QAYgScuq~hRA22?ox^cR8L&ImyV4URX1U$) zNX&?jn#I1c6hfVoX5UkA6;-CW&f?CO_+Z~~P>T#oK40w7Q0ae)*WLQY6Mxi<+A@hU zU5(fE4-Kssl1$Qu%=QW_vVxVh17j#D=;dmnUG`&W+zEDqkRpk)*dXq=)8sTmhb@tk zbnkRGFtLpld#l{|APWmAbl!cncFJSi%G=YX;V5QlOI;f)j*t>Ce4IsZtn^ls+3SHA zDdpWPj8MeO6>+6RH(~XY88A7TrLZ8KXtk9;uQCanxU)u~ddmUhv2z)BHquhwwxEBI zEm-(#!Kx!v7gMaTR_$yoh_lNYmd5k~onz^!ofCz{VK2N3kH+Q{ysaI@{Y+;FP3m*~ zdOfL-ckL1SQTyzrwueqe!e2y5?Zf~mWbk8e?{REj0O#j*fQ&+BZA$yQRV$_T2S-V7 zXuI&463J=og00I9t1E2U`P>WLBI*0mwUP4%jinB^@`ZE@w2-N9+uXyS&tDla`P&TJ z8XUeInX1W{enJFEe&0}%_(Mpen_UJ+v5S#5*cT%1U5CmZ4S>Z^yW}JFBGkc?&mS0ZW(=32gwh{m;+>%izae?A za2#Rs@Rt2KeJu^=-x|qHI{D)*T4v(EE`m=UA3IaKrQzA(spBWSD&z%iO!YbGj-l1F z0bT4|TtQo<=T__o633r1)*?jgsLDBomGYv!7t>L9@s>Ey%5LnRK>%Kn=E~o*Q z6U4;-5*ZWl@oKq>s`#(*a6{DB!KddS@6!F^Fl_OPcPh%Jp(Q zRcQw$4_aZXMtm=)^-s<@MZa)Zt(;x$aW+;p+HQ;rR~&Z%l=?m(6+v7Kt*$Aq?EI%i z-KeI>uNTSbW+$*VR5Pq2@Vw@VabLQ;Ax}Y|TZj5^F)j^@uZQiftSaZz>}hnk>SyoV zMgjj4ifqAxQJYIY+0Y{jVS8;oDiAmNAQIEJ2bRbWih{IVU3_23>1r(Xc7C01jNe;H zarM8nstuIaav@(@m{G>kTy&gAifb9J)q$=l?pJ|_TTa2>E1QB7i2ypUB*$Rg9 z_4Q6NDA-K~l}VKvtKVWV37@3Aem2d0l#B!3BPwMfb!O_HyNn|Zml9{`bPBOwKas7P zv1lfa2ozS`Ah8#XJ=IJRNI7P4r|hl=UUg=rEidC~PZWCsc(pP#^XqQzy9Z}jcHKU5 z-h%qGRI$xGbhggKRW|iM+{FOsqa5yZiXl5>oH#wyfDkb|3;~7W*?3M#=#w|Re?Mc6 zVBVd&yL9E@Rt#!>250A(JZD$dWPS+ z?5o-9yxOgtuGU6QKaSA>Mm%l?58XXQQrZIgGMlDyzAk!j<>4+``8vofJ6i=tMJC3p z*Sf>d$Lzu8V5b{T&WXCR1>E=z!J#se+I&%_6e)Ug@oEbLIEuEG0e@niRm6+$6*qe} zr6G#!R#0T)wH*Retj%}t_@BD@aiO+A<>nPl>OTP5**D!aE;bvgSPHbg5tfxGnqtwA z^hn^IiC;e=SxWnS3S?Kz%6=Cq&ney!D+}+aI8S-9MWq<&?I$1PlSiQ#lM(EqWB|gN;o$tjJR18Gze;Vi`1WKRheWW-91rX*~q`zuYM>VIRM$ zt6$3br(936#}&^An_LI8&NG`9K-@=oW-pH>HsyW5;cwvt`i7c`$i?vuQzUMer&|`^7RTS4@R?|go>b{|*22#^$+W=BM%Ed?M^7EHPypO( z6r4ucP5hIt>#J4Ui_t1gzxf9DNZdR3J_}#fjNnBV!{-WBFe1)9^i!ahb0%{lp&6qUw5Y@MnWv*$XJ!LxT=o7$oORVeM#L%E5mE@yL z$LKm+0>#D;+~&Q8v!_-xi=cZJRfx@~&_Lkyh5`4o9Ht%#UER1%1d^xy@LDzVF5Ns> z=x!_2U{}%n!e+{k5p|CUwdQgV*Rb89TW#C90Ar zSM`8Wzb$XtJ@{H2ASszu5jZM26A4)ZO>W*hQ@h(!lDbKpN5_J?&g?h05*PQ*K;7~P zNgY^P)bBV|8nbT{bhG-3{!G`(IrXsnG)xi?dagFikL)5Nfa`F)#4SmMcJScDI%RKf?UF@!OR%(#4L0;( zx=)bh)dm4^Fjtfd0b##=eWXuu=L+tZ_J98)=`#J-Pi6Xo(rcQPz{J<0iO{PzW>S+x zn96N_Rj2dKm|wIz)h6diTEXX3s?{FojCNt_gTm!pNs!l&p+9GgxiTFII@QjxUCxm7 zA-~Tp!9~PN(5i5ES0hY^j=T@lUrA!(Tasuy75=;2jZpb3RxWz2mlQ>}1^xg{i0A@O zQhdL8O00IuAyubya!F^>-JsReaB<}SRcmBaG0Pf9oPgb$?ov6n5y0E@s<_+raPf7) zxj)adqSyOu#g_{!b{kE8D#RfS_S|z8F}JbMco3s!pD4s69{kuvBySs4YAFlW;sG9F2hwJi?pPIGJ z(o)t(3qE_+)}crFw8gR7rg7f(S>M)D++yCg!re}B(it>6A(R->C5J(I=JYfLEHO57 ze$|@+d;4A6E@kWT1#ZPQ_f1#?+Z0Gk`TAZCo^U-jVZrih&}9hxybQ;i7;Rb9c8mA6 zW*ZU1%ye&2xh=#>OhB-~GsO6yeS`*eJR|aSB2tL!4s8bwmJeFuD23W(*`nw!smiS3 zO!js*<@r0+`{X7^bAXCGIwN%JnO9BU3O!oAG%f9CF($ZBv~aeobrvMr>kU}xXtR3A zZ})8T7)%Nl>lN7?3w`Z;ec=x-tD}OA8~^kzrCXWJv0E%^H5tvBK&LX_cy_*Qhcobo z+h$fJE(>j8VNrT@0T+-ZhF-;u3gv_E)y8Z#QG>XTj zzTQGhl=kl&?eulHMqn^}X1Z_vbJ|-U{PYDUqc7>{9Cthd%g%CxT)x1@ z=WaU5EONM&F*~+M$~&E7O44e7pND%rPw<8%MSs=p!QDA5fe`shEF9gF*`di&!lQ?Iu^dA8ICT4$!Se8l@;@eY}lzNi=AJ{ar{ z$`|DhPPb1XW?aIO2M+}GtzZ!YZx3k6YqAPj7hjWHrMu0|&Fzw@jj6kjy*JslQqG}U zD>3^BCzXZO;n-;z8e%To#+}V1zXuVhcHs=WpNKoij}+y*ex!mLEdK-u<;C}(6b{^M zPXAg&EMvo|tN+7#Kvq1vqLKX4m6(Mtu=@xm)iq6H1^P^md`41+GZ~HnU0BXLUvZH@ z!b&_Lq7-U%YC<9}6nM415B0KvX8SGbJ4!uL7TvEp#>{$(1;+e_%V&v!$4(U!KW zZ9g7t2u&=v{em2IFjYnnb227<_|&SdDp*S%2b=b|g8tw_iT|d~fVmu~wv<~nw z^pqK$9+EoQHJ0uJ7701{vn;f8_=M8iLwFNZNV*aFno1as8>rAv99z;2E4EV*q2M59 z`5Jvk=*wL9BJ6QrPu2!9?jy8__Of}%H`hMckEeG;I|3xqEVev$%VSMyt=B?S=D7p< z(rnGH!6X3l66fPdXKRr3zE3hhX5x%{xQLIEJV@vp%)lSHS^D!thj~&iQnoc6n|e_o zX7vd%8x*64`LAITQo=1hjXL$it{!V4XVa&2Mo<&20p=gafa(7+=Pdwl=b_XK5qM16J-Wd_wZJ>sA3^ALV}aG_u;%%b*>d=0@&pTk z7+20(-+rKQ>KTElSfXlnlMj0Ybg3eKT$($fPH#(aR>0{?)8efYqI~Y1tKuGIIho6O zj?)h(rAM~HMt2fMZ|?m5HhOi*TY){*;rl;#i@3rYN%^krJQClIT<%?aXrQyWOVwqnkT4suemQWX8uzfhlvq2Zwy=O>D6UKu|*zWi3xS} z-K-UQy9kN1c2bS>RxSG9UjF2RZoq(IOgh7Hhh7`&lZCG^(p1~8VFWF=JheNBiG!@T zOor5)99`)@M|@#=VRkF(hv^%pgkL5vVyKw}ULt_Rh9-@P3xg+Q$)_*_Jli7y zm|uhig*dx>&+Mt8|V7#b%ejMP)IttKJ0?J4SNBe7b5F2j0)e*EqZUY z#|MPZh#>8dX{n87jU`xQrK>`3>qftwhdy`69yNRio`_CWFqKCVpXPAy>=0Ao@MiZe zDr9WDIuYBL_Mkv7n(Qe;fAb*$N1`rD?G?$bi-Z?D8$F8z`gj@g8MlD{=Xt0l2wOu4{QHyQw0JDYunxLnd3-&-bm9uIY%BZC&7ZQ*vW)C0UYh`d zOr4Hem|>06l7W>XNQ`I#OXe+}O@dEFo!54-l=2+Iw!cl+Y_(0sho1+WLB}HCVoIO(G}MKnP&nIy%?YK${nOpdeaN67dr1kuJ1ReUW#u}32Tb27`gxWy z-^+6=o@mPtHRV4r*BalI2y+iN)z|lQ4&w6k=o}8FXTT~y@ej1x{c{M4rqTT8ogSbd0A^!=!*`z z(_uLPo!@E6qNY4`4#NK4>bP%}7gIWU{jNG<7Y@z?5c^(V;ED8lD2WH^i2WlL8Q(Yo zc3ykTug2Tn{HxBEGBUl+=yf}j+`M@oO2X|U(Umx?*iS}_ct$6He&DB{8_A#E3(9g^ zDZj4k0iWFnqHucKf8q!o$GxOVLyy>OR6Cz7v0FjgYF?VMTuzzu!6vz(3_GZJGesGI zzsyI?gx;Gt3tcIE+aorG`U}ea<0~yp_YwbFEhyx11i&vw#E2hsvwu=-ayk{Phc^+C zyPKv!q#u$GkPAU6uA1nPPJpdFl1$1V5ClAaNoiv==H!QvTpc^Ln~>1b2vJI>Tq4yK zP}FJW6r=e|WcG-PF6m7y@^&=7be@qSz0OaUN~Rc;k_>LGmP(*YA{7Pmb^xR~tz;sJvJ}KDw_9E5U-AT=_+^e*hvS#TCMY5;UyNpC?WW$u02qI zdeT?NWuP;k*qNtYuBK=wDe|!X|++iZQ#x&GJPxm7x(wwGZ?eAEGKvF$vYU=bLtm>gM-$EP0zXz>*A{ zv-}|p94#fSWOqfuG@!|?t6ZyQFk~DRPG0pIY)@4)u%vh(F2c4!hP%wTRDM3rY+o7V z&|q3_gz%!UmMk=r8rps|-|C1xo$CO+YmGd@Mgid;!owfY1}O3mED4}bmVtjG2C)o` zQVv$nC@6v|R(v-Pgk+wEOkG638)S1 zi^VQPM!O6-sZl+-k4iXaj?W1}Mb-$@o<_OSD;G-LmVa@51AGx`(Ppx;k)R%eObXN2Z^zVoRy>Bu;2`uQr#8Fvx#bxIsvlyP9E2%no);GBn z(dh92uO>S(DrVR$iB}9`x2#&9sbol z!5^{>V!N7D3zG|tGA!$e8WL8j)`jQ+eGMk%Qp-zlKN=s{gV`+_aj-c(*rF5)8RJfa zD5wg(?Oy!J8Q-D9#V~_MzVjja(`qkb!b>4e#g8X(rr_5*)%2{rw)=*ns;a8Y{6DSa zB*3Fx(hSQU&3__noqXIWiK_>r_y+s)hvi*HyXS78P8ZPpZpl&zle{{*x@_{iN{>7} zS&NR)rrU#{%uLspxm6BZ-oLQvSv-iXsK#kQpxcbN!r0JV9c|m&@#1sZulJR&4U~|* zzJ`QKY(sw;aQ4>KRQ}pq&x-hNeEIzOand;2cpQ|CE?J#?6o#dkb$O^9W{ONtzbf=R z*uh?Lf5v5VFI<&e!Z*b}TBaax;1iC1pk!yaz{qzO8M8v74ShzX0?Pn&w++Vv0s_vU zDO)=t|Eiw9oKG-cF>Q#64AjY0fGepKB-Z_EIFo^~!gtJ1TOi;Tf(y@1Kti%a%CARx zq_AyyxVr}sYrW0`GZxB1-)2Q%ZOGeu8J=II-Ns_dEJ3U?Yw;1xqehqkk~cSLAoc*3b4#;Vy@jO z)i1=)FTzGO@#C}}-`4ucY*K(l>a0PrVO4s|L5dyQBoqfSq?$-j9SAS5B5}jZ5R+k( z7l4<@GCltw534{;T#Q{n!id;tuMUBxssVidzlyiErKi|khYxGzbaQ@w|8(HSc`LMI zBGPREe=0W&l$5ing^za9qb%5|`8C8wCsXqZLDiry0RD(kYl7xb=kf$}&W9SgovET7mR*0ZDIxjI_j@OV_=*+1amS^SnTAZk&v=`DA2? z&*ER~MRi7+Vf!;s#aQWkgaccGCCbNiv1L0z<#^Ydg5B0&bDwcUYLJR{zRO+He6U6R z(=vRF?rY+m(=Dr^Pm7}X-x8`@4C@nC)T@o*#|QADPcX?u zw|)<#6MA-B#34PDu_~-3v1>?7cSndlQKt^UuyLF$=b~9 zY!}Ki(tSl((cLjN@z-k|TQw*SjzCNh-Y58W9~_e=5XrYulwM3~@06=Uce#v@G!*Q4 z3T%~WEICh$l;<5iagx_@yBjs)tRWzBlW(!jlPQgF27#voaA(z8#?L0f0MCLj34!TC z{wRW#8&h2D_RP9w>rRzB=^eWASU9j9_L9(nR1Pfbz+9>|R9sFPfE|f*IZeUSV&&Gc z-HecBZ*AhJ)4Hw(9TnUl_z*?Tj4i=J2>tn!>s_}o*mziW%vNh6QPj@jU*F?k9c^21vrcaYyDtBC3 zAwU1f!%w^+=?p!3n{{gaxG7oT?CD7wYh6r!@afvshXw#8%Kbsu{}@=5(nN-Z(k%E0 z2b!Z}x( z(Z9M>?nC9a?xb~fVi{XLsv4%19Sw={9!b_?nk;JZ6oiH~Q~I25+acmz&Jy6#JROYC zlkUY#kK=v{7){6~kx%~Jiw%#7KuGjNYElr-vuDq8PTikb0`E>FBK6k>`b@=2;Xz0k zQnz#*HDm1+Fii@4qoJ&9L_aqtZgeE!u1>@ef#ORh?&xJIMav4Hj&cvR`mOC$AIKKz6=sYPg_HSlcAsLl!UEAz%&eOD30j@{fxr`!^63wc4 zPj?oybT`nMN!H?jy1|lj*a2ceq`l;(wjmwBYMxKIjsC9m!LL62u}19cS^?g!Q55 z?l&V?)!Aen$JRU2VahdqAj3nYXr_nHrzZY@$v(eSiDVzKsEw52a6JtS|K(VK)Wj(IK9aKn({_!w*=yor%mwN%o@?FPIBI`OBRb!N$x-2`d zlS|l# zrjl5PrkgcpERvAli*eezi6NvR}QZ%UVPg4AleLZI*IF_c4J4Xq-EKH?roF!~uGQ?XM z8O>B3$(|RG!S5K^NW+!0Ob1d7M!31(?9SaJC$La9u7$v-2dz0Xue{(Q2+g0P6CfPJ z%7UZgpouuW0R)~6G!P=q$6u>_2`EtV6G55*_pD(%@D@dYN9SrUrc3+-h?t!d(>n4` z6bd|QVqAudj!r&){$frGTGJgQfk=}{jp5DdT6Dfkqrl1R%MMM@!!j&)Y1#hh%TOK= z4CffDyX#9LxPLSe+XSIkxf8kZyH;Z#?L7AputHPkhPe0;33?EO_8f$54&dc{K*asM&CzEtb}4JBfJ*C?_j`BP&`@6z^sDQYp_TWWykt zqI$?E-kU(YYB<>}5_>xNAyEB_>@s!e;}9+49Hc8LHGbJl&<$OLVm)qOPsT)#e|Ltp z;DJq^z6)yoTLGae`g-xR^StIVnB*c!DNfzUJ#!VNC2tPeEY_%?(Pt@rTJ=wO;++Bq zPg_v45gtILIPn&vpfW@|mV4st1xlZ+f@fQ+2XiY}M3Cp>z;zQQwf=tXBfXmT zFdW1E7uF1+@@*{ae%jhL?PC%R2g?;Azg3kbGcfYSZF|<9e|e)*nI^3c-`QzW4vP{w z>uQ$0RG8Mqi@3+`{hI|KF!qVPZZzNVh&^N;xUspO%|7vVQiWgjqxQhjS6$FA8mWjb zLs1^Q=GakV2ziNNoiZ&Cm8&4dVMM8rXxw}+iWRnYy9uOGgXQHZE9EB);mFPofHg(IoRf(9J08D~)|q@Chum$tLx^=>uGHdl z(st^DhvfWT(=vKIQER$%yn0WT?j%`+AYZis!G+xI@bN~Z_MO}Vu8$eMPa*PE`52@= zgGj0~yNVt04$vk%E=G-lNk3XiCs8!Du4QPWS};*GY{iJ&5mh_W#dkPRD^>IhCE5us zp-0!&uZaRedlK32S>3baQ4ODk>|cD$5gtnWua;g2E+vL>g*_h z6aLc`)25hd5`|Skbd@-1sEV&WgjO}Fq(USv*n8G#$vX?$nQA-5Xf>hYDO)wF)`GNF zp$iTgHJ0SENKAAbh7WH!3`Uut!s6BD#z@|pH2u;&-|ONq8!93$F7A4;%|<$L07S8U zeQ^S}13}jKNGOMd7ao#JaTf@t8Rm088KIDu5b9cX-+^FPeyo%*j$PZclITbT!q2UI zv-2*WO7w34N}Jy0Y_`J0Drk0jI*|k8FyMgS~C4RA-Rh%tZ zCWv;#0p1xQBG=t>nQ1&(BBf7k?4a6?0zWH9uW3xpS5PvvLh{+@^Up>XK5f26JeOvl zrBG42GKY6})4EmK`V=c&F_~N1R_XtpRS#8i3^7h`u+-k<#tAOpq_(R9a-nR(@ux3+ zruQfC&LoJR@sI+&j`Sg4{bOcAUE}p1B7J>*^_^k{34dWjRf4(S%HZ4Wg9>rP544*KC9FjLX z^vfkurO?X9)1U(LTb`0q#Jp+3KAg?hvHL+c0ofvtb)LZS&d*)?`{}HG(rHC>M{N!k zyD~MCnnpfm;jNo4X{q5igmjU@oo`ojw~89Pq?h1aySZP0I6pZjdTDQT2`xPhg|r6? zpGr7N=PbgSND&9bMfE%hsrRbmg_2@|zK z*on|iS96$u9ROniN`4Ip28ozAYw2HNSt0dv^cebDvkFULdU|~t%NB?{c}>K~AE3qx z-B)KK`T|ZrK`b2RAPLWlm<{rh668c&LkQ~=#VVW}FICB5Z9<3U_5|1{0F`;Ejg~b? zQ0@ZwWcdcdnILzL9_jJj@J448>roM+*1denT3VK>nVRD<-hSffCBfEcck)rx``NA_ zu`M$;>bU~#j7jkKp?{2mBD3-AA!^J0v?tp8rn<0GP7djp&c6^1NxwD+W%I5piMcly z+P7bRd+}aa%x>F?iwkyFQ2wBwKG<+zQti}ow4XCeW|o0NzPV}$O!HROQ8rrnd*%wl zW;0RkHgV-2iApx&^zE$%9%0Ve+TWiQ+;0mKHms*8MM#N~wWaOYYqv%2cqcKry4N^| z-gSh^!3xgf%0O)MO$3HJU|^P_Q%@^}G0+E|7LSJk8#jSyguqsvdoz7kqq9knnLPU~fA0 zq0oQ(xOa3BeCF?Zp7?W~LC0QYnT0;=3aK>o3`j(t4VY5{n1&$4+XOiWSyxBgSq~Qz zPtVQq!T-jMhMJ+3GPCu^kth`;KR#*yWi?H0=bEnT2x%^0x=|yvRO%`bUGoyLOAn{biLiWv={RQ8F42(SPD~9YmZY=xqrOZ$Ac6i`*rI>9^BTRvd-VI zr;;@!-dNu;CESg__X~Ni4(Dj`T=VJ3e!%bif*D<%jLOn$rrsrJ=bSJ7S;z5hTrnNQ*yPcr%Wf zuwNpHDONDjBkSW$KVKIhGg3<~hA@O(o<0J_1X^bk5ns7MAY$mCv+LRTFt?2@G%=sf3OQ}GCR7BNKj%jmh%IssLehG%XDR-2EqSLt-suFAfND>;{_W2@8ORe z@06rlbBFMkWjZT8o&QV?<- zAFG1yZ)N(a3i5;_1B?i~4dK%wqsLEm$eu$aIr_nAYZJbE!97sIH2|km+`2DFubw&+ zX&=-{XjDMP``z7rcU0&uGV3G|^^Ub&C3D?UZ##Wf6?b zrS^zbhv15w|HyL$*2uKuB6&>S6fadXG$IxcT7e-bq<&?6#Ajmfr1z$UWAyit{Q^Sy z7EG2_>ybT#$%6G9dPY^9x93gy+o0K@5UIwY?ZI`(feX4SyygK|jeV@B$6EKTrj12d z$y^)1Z{Z~=&We9l626M!5};p^x}2tTW#`qu3mNW|1j&mRFB&d*?0%Z<(6-zXN&87< z(>bX^c)|Y<#ld_u^+FgnG_RLoNEfTTnNaUYggnH`yTsAf_-$*#=KINZe#p14IDHJ7f6NAtcX%7e+XyHiJN=?%m2WKw{no zqH5g$$zY{z7yyr0BV+}Qs=RDOG%EZzZkS=y)8)Lqy^Y(IDuzJLh1BT*TiSU?_#@V! zWZ+pJ@~&_L&j@Hc;g=9rBEQF{ zdu9XAdsxTGSi^uXd20NLTm-vyDZ+L8v9eaol?3? z9^@MNTMvJj`8`ED6~b)w&AyL#O93qxmqO*;E!fi@?=?ZPJiRA-Ub@(f%;H5lE7i+$ z5I=65TQVnni@1Jn-_zZi^9h zuI)!Az9ii0NNS+wj+v|>A^NVgEkEAagyg3@exMUvVtU~0^dZ0U>JzG1cACD0=3XHj z^@7Av4;8{hzICWDb!R?Im8$)z^85G0fpy@t>@j60LfLB&l$-=DVK8?>e1k`#$h8Slp|7?Yq?jFgO zHEDuL0eQz~O47d!HKKwW`x`?W(TeGWHjRYush)e%q%aG=ia*Ft{aW@1v0N| z0=SabC3VmQm;n*gQdIx@5}|)JC5f`WPW)gvwT zOLlVdkN5B2-}a0O8vnwh z&4im{d@rGsD#Xmvvc6^TVFd%)E?&%t?3u_zh5AzmVV#72_MT=!QrQ4s->-+oEh>~Q zbscG#)YL1dslttrtEE1Z0<5te@fRVub0Now&^#LEDW~QZX6n8#bRQu+zeA*{?-(jW zrNiMveUBd{Xv&ds0kd)R^z;od%}<}|=2%Fo@}Prq>3Yn9wD<_;0g%8-2P_@YDkW`xhw-)`o~!W zwTywdO3(@9JYx9){g3kTx(TGTaHL56@{?Tn*XP0%wt*7EZNk4NqG_R=X@oTp&_UJx zI;jMHQzD8Ka<~K>z||Wqdweb$N*=&p_D<&4*+iWPZ6xSz0{%HePtSws$(9oWuBUJR zQA3Sy{mE-#Ke&m=k7N9&Hmt4)oNLmgibeQ$7rCvd5FX-Q4m@_+XJ2k2m#0ju|AjKv+V=m#%^Gf!AZrN?B3; zOoDDZ8u@5n*`xnuaM%Z8QF-w&Uv~n+!UUq44n%Yzp1xw+8m$1ke;Inqw+dsQ&5>8U zt&MNqxA8x(xR1o`gtE*==w@$wQI5Nye^{GY@omNUA2cbIu2B93-3@j^E+_t|A}5}W z?Wqm25XAmzk(-7Uz4b}Z@i6j@D;0fQudwU3jEab}x-K^dww5 z?Xe7ad9H5!{`P(+RzWGe?aNt8=@=d-Y#Izqu3zi9@^_gL*4mkNI8}vu`)+m5p9<%*(`?a8HzCNf^v0wd>DTAX;PrX8=m;+h>R@WI%` z3R!E~TztIp_k)m^f9#cyRFS_`=Q03Cj5mK#p2%%$qUM1aS-b{cpHs#U3nGvA-NOr7!w*~61KS-nJ9L>sbD(lyH;9gu{}d&nt~->>5TMHIOJbz)?j%M~2xnEJ;0e|pU4 z@GdqH#8eJtbhNY))4ZltMU3zCeV29d*-E^;OWTTga9Dd-r@_`Pf8oYk#gh zPDy#^T;1j(eZ&o?85Lzs)ep<34iUc5!7szCEs#2;85KQnilTpcb92-5OXiz;C&^)X zCMM+e5OYE++>#R9ge>mYh$1Ho2!AyEv9z${r{{Q$fQH(%oH5XF=wFQ zw8H^?+%QOxT>!${l12^WjpB;Jl?|@?CTkul_I(m>u#o@!g{FYr2royZD z!prP#5df%KO5f5_5njtsxd4p$U;PcTtYPVWCMDb2ZcM!6-+*(Ped@__cFNPh;A5nK zC$6>e-<&_fMHF+j^z~VO=!+C^thga7muu9~!;Ss*VmibAD)Kr1p)Vv@l8HUno>~GS zWa{dABe{=oYJgRr_6iDRFI7y#D*OAiu&-E2YLiCjXX>NhtbhR2NW0ELT z)YPJ($oR(cV@gZ}X^;*c2DLm9-J^%-{?7BbpcW5z^mnw0_TbRVWv6;2WN(p#%8=oE zu5>)IDe@hgBDVVRXWZ1x?24R+KH@q#MC|nskkXIEKK+sLo+1=q|9-S9P0J%e(9R8> zGEGY*j=E_)lV^@eNMM;+7Wr@E96{nfACN{qnx&D;%J&j&l|EuYhRn@qVWc^N^a?E0 zRG`8cxe?5WOfm`KAwt)8@?Ew*AC0|aB4KqD*6`7{KG-p==6~-m93kfunk_ZwuinjD zqL7Wb(VF&N3ytRA3(O&KA%9=eCsz`B_~E^iyZg%Ye&_avyVm2|yn4vi$}NOLEH^Cr zFlXfgVK;n*x_0BnluG^l;$rZY$cY0uUQdEqwJ`#asP`Yp_Vr<0_`mNyOo8BP>FgX= z$tT}5Fx~kL!&PJJG+~pf+bAbYF+NzappHCwhVjg`dMmW{z%r!_NABW4bX1hAmzS41 z)$38h4?g-4PD$!G6)G6QOMNfQM_SG~OVdQtYMc(;bTCEhxq^gX?4zcrA9?a4!ugE< zJJVa@70K4tRzurmnE_fqVIH1$U#!2JC;Slaqh@c|{Osxe z-jIW(4fB{u$maNR32UpGnW@fKcdGYZr@hPr8HZuBo45bxVflVOn$eb#(%AU%Z0-MR z?@QyMT;so)h6WL3sVGXT5|v#vEwmCbC~K!kmO-|%WgYlxvZgK)&1^nK;Qj8xV|dELYXopQq?0JWWOxz z_|*>%D;*XmhN@opb{hPSu){W54=8O35}Pq_(?o2I@UauQZuSP__xq!TMMP8yPCPt3 zdiiHF>AZgpz|rbj#7e{-v@bQvB1WGDXFfQ7co*&Exy7r=i*v2&b%Qv7ePvTFR%TcU=x#Jz&CUuAKJn|UYs#!Oh$+oJxhYg1yw!@xh-{I+ zf<*+UP+)cdg0`mTY0q?l;u4A+aCzVn1O}Ez$Wyqex`;Pky>#QojgC@XHW3D_BjX+! z;t47G%fl)O9|m@|B!}I;9UlAk7H@U$b;FxubGorapm%W4m3uAk;>8=DML2|&XHAH& zZOcu?7Y8(9@7ryjpdOST@JujVAbq4Kk+3bSoePzPHr&Q*s@|^`5fv8p z+u_*;D)*hy;EACsO!)D0wmxqVPhm4?W zM8o07aDS_oz3Ix~$2+7dE6|l}Uk6ms`|t&+JHz!NKAw_i!7Xa)Nq<29d`X&|a9pTV zdh1rcaZ;5ha~04$xv{Fc*&gnv7LM3-#`{22=2mz`#$AvEz2nF4W_qWcWIhW49;<)_ zKG@c{Z&}5f5>&L?)(Kk#gZkn@Xk55na*HzPKgT|}oQE}=U1 z?)KOa?jLs_(PC9pM0}Q1E!w-H>IhG!?9mPl!;ZquF%(-EeRGE*vga}N5gpo1<{6SKK`TN13q2ETl9F_x39 z6cH9y;ZT>0#L|EZ$pqqz$irtMPa$m}UJ^)?PTb^SPtV-N9(zU5P23dPC?lh&7ppCw z^XUj{wUFHblkuA)5t^pKhLQD0F8niFf zRGzfXIiq6;*(w{GWn|%irKQ`@XVxMwSUS1g05voRE~CK{<(y@FtjWR4JdMb=m)7d& z>z|IT3@>tdvRmcscOj5inpu*t#Y}EF-FI^xg63?!ElTc+RJq=Y?FDF6K3##{zmLkA zudfV;oNYj2duB#vfQ{9AXwUA+PvwlGbw}{ST>@~2tw*;q5e9|=XS1m(bk!>Bi$tnF zc#LoZuZjKk?b|!(idj^xZRsD0zWIX25Uf6u{&`|luv3nZit$+Stihh++<@qcBTi0E z22({9bLIguO16Hrp~5@ltRWZ&$I6vzh!pRU zByTc0F^JRAdP_??L8lG8DgH=I@(+FcIPyHOObx(DyGcBYB|ly*!A{`SlQn$6F=r6q znzZj@W6MoN7cE-k-%WOPAVc2yAwIW%xKzev-a|Lat1e7@!6HCS<6z%Qaf0 z5KU-Yy0i|J0_{l6j5v#E1rOvBBvgPTZu~)-o%PvpO?Btas1E6LiY%A4>?upj#|i0# zSGeu|eecjX0Datd+l=@^rxyzNqdU|#UNJT>czu>0vXV9eE{GwIAQ!0l;>S4zU)NZ_ zC#+ogX?T$uN|yr%ETAl5_3iei3jHTs$#04oJA;A!@#Osc=I5Eu!(9hzFSl7M`5(b4 z6`2@s%hDEdPLK`dIya7j4@4LrY2p1wT|&~~;x_xKH?IT6?h%F!Z3jitKU;P#N<$7| zu#w2foj#>^AKpjSa-AF47Jeu5M2hBLblbcRDYjp`-SdKC5v|Bdi6~!A5#&|$-^ahN z&0?=Dy+9f(g11=Ra@ZU~mvv+>mn72~TFUHfZFx-j4bRZHq3~^$ypqg*4>Xv#p#chU z{N)+Af*zLKg8E9hW@-8I$Bv zvn+czGUAxyR^;Y=zmhMXYlnP1mGgdQ;MXtbj-WhXE#64n5GI+aesi$|j%2da96w$b3ztHjj#z(GK}blb zs8=>0#XP9w!dX%{G;#Ln{e!&$J9*(Wc>FP`*#LY{aY(%=7wrE*%=X47RB*Oef$ zY}G2a#CA6~w}=eex>%ou>h%xRV;rolW$zFO0qo}LN~>vgR*4Z%+65Q6mD$ieaP?j? zx^p%sHQOovRH-9r<(%s zhwG~x7Pj@xTnvd$-tmrulsL$iIyvdVedfoPvHk8S$1Wjhocf-S7Svo_6EJG7J7dsb zG1Nw-hM)O?x+rQYCNZ?pI<6Sv#Zg<4KD3(>HA8qlo<*M$vp2_IjeL>n+a~65;Q~cZ zKI_qQIi={>IFz#RKi{KR!8}5{IET~1$tmv-N#9-e4vR#t5Y;-VtLx!LHK4f`C@x?q z%3j};U4RA>PcS(aL(lX|p4TTruH^~Wz{ztaFcetdsIyPMEc7L~o!Bzx7$D&1uj=6$ z92|^I&XE5|csgyNC4OwPj**eIjg76ArRBP6zPQlPWE$&z@i?T91p%v8cV<3Ro+Ltc zEB3t)pE)t;G`(Plmrw(iRCkurR_7%_mL(b+NA{&DR?>2yMf@8fVR&o9Q3Z~1&h4yO z6gw{Ks|`Y%4Z`6Bo}DXcW{oV7o!9HhbH7zdP^sR%yC^%Wgp+AvWVxPX4*wJ?9(+o0 zl3ynC4yhT(Lin}(xjZC3WyPgRXqj?+Eo5G-W(2EfPR51D+U9L{w^emx^{pY(r}X4E zu6IGviK%w7y2R%fMS{N1P#{h-QkAq^&G-&%b9mfp{`I5}&$e$sss^iKUvwBTm*bE9 z?o$XJ>q&p_o4ZBs5qDAw9u$EwSaSr#iESV2Kb|iA5`2o4OMSw<{a@q&)jYT#tI&MiuC*1;a2P$fCS@!irV~(D zDU?sgXQYo@i})5P`3(uaCTvs`iLi>P?iqmhic%c2#gMlVfyx#LK$mW$-fo&(hhsIH z&ZyYmiG=hO+;bIiB{d>pi)yce7>=$2{a(R3ACI+3<<%%*@RD zd)?cxdp40j9gzE>+upQ2u{+?Kn6nN#6Yg`4@1?9}1>eTA3tPHAczW|vZPMW^Nki%owqnnv7guPb6Fid!d5Prha;x8TmL@N=B30!b4LK@$XA0@vXmqpsmAf~c zWMC}derIL&;k^=J9QvCSkI5UdGrEc(({P&ovI8M14uJBR#P)u#K4)idA2U5;Tj=mz z_F3;hD{W7>=fD^IeRUPI6;RfUR8+LP`a_eQho@&r?xtE=1<#i)W@?A;yRA%y-{7$x z7rX2zuM_skd5_OCwrS7J~aVW#fRcUj$ z=cuSg55ukSC;s%lUt3>qef3Aw&N^+i5)@ChodRQ`uCDBYP9c$w$({}rPnXc-3MX-62NL>MEK&x^R(5_Twh@!C1OjTrXlvf7 z%N{>;N2-yYQYW28lDk@Q`Shx-O~|KjChQDQGMV1vS4uXjEsTk6TJvUJn_(P1S0Zfa`(oub4b_4EdaRxkGW zuR=}Xk9}0i*)vI9{T=tv1-D&fZ(d}u(XicwxM=E^*L#FvG_MzpNxWTSwXiXzztc(X9+gMe zAz?||ty_C&U7D~e(jqSF+DJap;+l7glXqeDeIh!K6|}-kPQIWdvUu#9LRFqWT3XEF zjI{61R2&I?eY^247u4I2?B2cm*^?)$ciXvLM*JGT9qHb^Rfz6D`xIpC zza#mbHv;V5_=LV({ilC2mfGeYtY^a;}M@b1t|aM)(D5g;pe_nL`7! z`p_m*M$B1=>&^E{&0iR2lg-_^J#FY$1q4@5&sy7kR=Z|S3BqHM*|Ih^>Ai~nVCZ1E`^ z_AvgAbD6!Yp*d89u-cbgCwrx7MCIbz=+bEWBCB~k2@V0T^UvLOzc`D#9WH9qVWxoR z1EU}NEF2xHp35mlnoXUgzd~;r28nzteBLA^6viv@Uvt)!p?eo7%)4|JIM+y>$&7%8 zm8Q#WZv=36efMmD%!2lqiFZ%KmeU);U!X?h%|Z5jb3>dV!4Z19!q0B6NFsmmQ7~<- zvXF~pW2kNMYCvgXJ%7>Cm~dW5-AG5)9a1yQGz$?knWk5>5MCIa{c|AT)hLb7!0!MK z>`~T#&cnMy1@i3KZP2Tt?7)tykRW^Wm*j+G zdALGKQ}GfDD*m)ohmZ{CJkm>jwk6w-S1j<JgdDA}$jiUubkl0h$ z+GOJ%tb?Z=&alQYFd*RdmZH@6SV5|Nnvm1s!8Y0*Z7`!h+;T!xs@%LE)!?=T?B2^B zNU7T=C+mOxTJ#e&vc87wmz|RAHfF`f1|$^cJ$x!glLoN(P%W)JCf~GGwTe(zgAfCc ziTJdy$mFu2zAmxYpNopxVU(J3r!?*-wl&CjpW);g-hdyr><6uT`0&!iww6yuOK9i} z4{nh6^Vt|$$#VCSs)b7i$E_X`H=f(E?ZBDq1@QWy6rNtrRCNhLjY%wD*_h#i64YzM zj{Ag-?Bg=*9c-OrDOwW+_3CJ=f1M3?SLi24;$7Z8sWy7|4jbt^4nk@rAxBSpwk*g} ztEqB*HP`^*6Lg$Jbu3=Ak^AeP-E_5H25C}vLC#$?Wxb)zu9XG%9Co=iBvMf3!^w?a ztJF)BoOYII=RmM8XY#mZ+`^ZPq=vz8?q)o^M2EZZcDzT* zj8q1D^B&P!TKx%_Wyj8YQ?JYTvcr@ef0$JE)8ssL#2xnc4`@NR3<5J~*ciKKEvVPN z4Yz2Oa$Kly?9a1jiEip`ID^VQ)Mh}0MHu(1Suu6TVJ}l#z&EoNKSdPbLC&Crv2E5m%I)cb=?wm<<)2#%mE!F%@N;EB91WKK08)HP-i4F zF0O>DBgHJ=i9;O=(ej`9oBsEtTT6drwMh#v8^*Ezu5ieiBV3pD;1j=o|>i@(O zoRbn0-+=)?*AcFKfC(5veTm=Pp(Kc0;QHpxfhVudBLlrj#5*~Copem`Sx=6vsivnD zkF7=81<$x?5()`8Lm{WL@QMV_KqM1??AXo8;B*c8sJJH}Kh%3FDo7)V1ivObf$zh| z=)~|c-ZI&HC$B>(^4x9<&{oarTZFog%e*(viSoIFc)iw?XS+=ZuTb#-oy;)#D?ea! z#)B0cwpRy5*qbGycTXZ&qt7Y6LmLvlC68Jz$o3QTIXDosTWEqHV7P;kW(Dx^6kKG< z)e%*i0a52S%5_WDI~Wgls93M1pEU`G(B_Dc^Jb~d2@#_2^bVxbeFN3c7sHn5pOkts z(cuFBDQJ8E;aCc9A9dmG3B4Vv(#qA#*$(Hj5du$RB7*;LVGHBVz6-CBfFKp=vwdPX zyp-98gO>v~z1KgFbS{B7-p6eWZ+zcEY#0plp)sr|TpOu&svFY8V3*3G1zE{+g z?GxzDAUFyYKVCr;6k7#1=jm`;S3L$tU4JNNGR1R2gY< z&^zOoEtQAoS9Biwf>eKj9Aw1a_1}$YMF&@2N0y>+cS%L%5}R|PRNVN4;VE1se)n#Y zu58u^gYud{n$1CeEO7vn=qs8KkW`wD*dd621m8$!wwn;%6Yz#4Mm4BYph}HAJ3BkZ zZZh-k$kk2(EuUt9$#;=}%6?bb<3m2*u0Qz`kqWS^$f=f$9Ti_utARa%S5$3mYwz%*2)8o@(lrBN2d3m24YgwE^I?Ypl7huo>d(8JvKtj3XWm)51mZ;C$| zy@pU(Q&&>svi!>O=BxWrUd|rH*ElS+>oq7c_U?1%PCq?S^Waw{QlSc-S#u?_*}15N z9+^D^xs|vlKS^s+9mPakk1ywRR<)-$B=LK(6O7~I<7Mx-HSB24X4o$ztI<0!;JhbW zO-)Vnfe9K(L(!Z2vkH52h+hu(mnB07oBonVI3SCQ@4dPwD`r7i)>V_vJ!BmfZ28*QP6+6Eh_AbNd}%t14|5H=$4l5qU2)R(Z>U2{vh zE2yK9Li7wy7&yYqN&EVd8M(@AV$&nhgxI83Aq*{%@4p|vyAgW0crn>|h2uRxYkn00 z1c-&oj?Sl+`#o38XgL`EwIH{(cgl9((A}p(u-##GYe! zR`2Y&BS{Ons1BIKkB`|>E@gA`(p=m2&14CkwNV3D*PyEis<%=tYC&`Xds7&x+P(LV z7`x*z=-I!!#c;#m-M2zXcKlfta8Kg38wXv-QMBNT&xYhmz|=ILcSI1B*ONu#xVy(2 z`u5R)OS?c-`6o!2=$%dKhSM&3%A0n^h0+%UwHruKZBrX>(B0hxRkGs)3suns+?B1e zP96JVN+}u&QAw%AA%%Je6>~&F5UISoq-x5#IY_t7pmpr=r$s`gk2&_^@2A(+)a_tf zuM~If9?jvwg(6^sl?k+)MA+DeF)J<)Vx2ub^HX2mL|01UuhKex`5ZysaJ4D%HD|~3 z_XiP$gv=jYh~zBqo8DNF^1(J$gp2n_$MY&A9VD@u{j!T>d(#1}~3 zGBPq*Wxv)psl>WSNaBiUlk@&cy6|2F;U!0Hnxw1O5)70coTqTz>mQV$r*?mF)CM}+ zYXm|zxR^4#%kn!v%_v;sQCe-{snzT62t|K>;_IXAsz@&P!`2&cUI?0swBE;G&H2f} zakf=P6unmnDeafxoFuz|z0r!>+DJ=u zLZu7Ps;ZFlRCvJ04QKq({?P;x9gRoN4s@9mQxXlp4)25`npAeUL}c<@dgB|jYLr}l^VQIfd2CqG}SLOWE{Fn^U&x)jL9a8tu~X6~a{ zn%r-ipSdJuPxhoXS)!>YG6o5KZVEYG%Hi&ldNTDj>{2d={zt9Q+hf3~K+Gw>tiRZX zWQ&Z&?32T6Dn5E`co=a&$VReoaJ1wiA7BezmfQ>btZRJV}r zIr1C{mo2*eNhd|!zt)}bfuZbpB`l;zqqwuV+xsW4^AnXSHt$D_!|A>Fy6b=WrWB~w zxDL7#KGrxR<4{8|9=}v`KG?54uX@@q>v@x)4hcheDgCUbor(JK3P`uc-e_;y8rznV z)QvY~C1>2RNI6=uuo>b02WfI-Jj7|SO`OhUUjnO-5F&_9nKV$0@8^(9CWc70kADyM z;XEF@DqI>J$WDShaKKbG@zM~dxp<)KuZx}&51JJ!lGz3Oht~aU{lzi7c1UBUL-wJj zQ|Zg6`*c6QJ|T8&tp=N@S-RNN=zDiX&)vRkq?NeaHAKnNxfG3z#y*!Ezg24A_&Kmn zi=Aq&-DP9PU~zJK@M`V512zU&9KQs<%@k9q96ojN*YvGFQUxUNzIadU!(;of&XQzL z7q6y!e?~%O0iINnAmJqP^6~`Pn@Yrr34;T^!j(E){1R1;Bv&Ivsr~}4FOv(Z0%QvM z1nQsRy(&f78_TKo7q+N2yY!Z5uFucDbPZSgm-Yn~VfxGWT? zEho51J`yc?I^j^U_k`A|b!jU}Kkj8du@PO}xZP3I^Fia_vaG&MA|fJvaGj?4impow zR-gmJdbD9Zt|xd;twz@)FK{J94c2q?r${0C$n&ETK29qhG^Lv;D`x&!m#B%X8jJg4 z&^9)f@k7xF>)08xP9C9=MAd1MS?Yu|d1`&UvA^3WB|Akx!qEtm{^<#>Rx{ge$9dzt ziXP#hS0}aJSle!Lbh_|U`buO{I&CwscNK2j=UOMiwLj4rKJJrH7nYamel6pV4sV@` z$DWf6_grDj*RN@TQVSNMzMh}t|3mW4j|l@i0gEbx!Z4BpMt8S+`a`0A{a|Ww?pH3E zr$4h2QiU-!TwB7**4Ry%_Ks_fC=9*FeL2*24ql$d-7$2v-Wm9b{8*X`Zs_Lva0(p@ ze~aVcF+Hra__vbBHs~gaB-gPfv3J3~LvI!rHO_FH97nz$*-H8mQxX>!x8{my$sV5J z4(A;xfq!U|7jUoNb2a*L%FSgUD(~Wko3dHMg4y2i_CPfXVQDJeulg% z?L5D7!Wuii+VO%bLI33#m)TTR-3A(;MihZf7h}5BP|lMdV>DzZ?qB@yV#fP0$B{^c zU@hD)Wt3wef2YQf4_~Sx>Bsq&_)EtAj?VmsH;N27(ZS*kBxd8~W}{DVx|DUU$!;8Y zY*rxrpjj!kgP36(lhw@qGH%<;iF=me3gebkw;U(29(jzbVD*;GsO^fF|jIwGW)m>8EO?9F-6QBjY6gzE;QynU`A zv1f6mF1ve%*7{qSN1At{q^B0~yeu@A3^(R@KVnK%z-0WK zs&H*nC^QpK-IJ~UXFEBx&cYD$^;Zq9!)Lbj*9QqhV$oWdcsZ{R;Mj*3%)^Ayp*f_(fCX2s**9UWZcj0Q_0bouRFfuDni>E z$~#|4S*TXFnx}*)?#c3*ZK+7ToB2*<_SboD?`U=JS(E9L`;5Eo@1bk+#qZ$2o{OZU zSZSaWNC{mDIXN@gbvTDY5qOuZZ*~SAQ`$npb!yf${So9#p6lv5m~j>P31Gh3@7{mw??#%Jxyex+O=jjWr=ot&8+zOdgb zRit&ntetUznt97qkYn<&XshIKivsTDuc?$>-iPjg6E0zz2riI4Eh7zQn#qzE2=5Ac zJvljMoAcIq+V>cZFojF6n6J>>II%X+8L>oPgEVNY{-`057^=ahnArAu{M)xA)|=Sr;k0$=PyR19;w1ypzr1pG&JIn!{yCgd$Xl0UmKtEO--%pgfyi$&*YRIGZG?3&WN)ggtFu>YaAt@b!pSNdQjx_C^^3DnTT@f8 zPR28LEWXjC?-S6k+{`?kMk!CBD^e6iMa8~>Fqut0Pm>Y1!$z9mzNQ)DKyZn0 zc2d)en%$Gr#zZtEXpV!Sv|SZ#+YOrkV>jfV-2%c1R9h4+*Jj)KwpU@0MY- z!Vi{%ALQt$R)uEEtAnl?6MwGCFjrWxmL~tm0^0B#nm=!)&4&49_w@8!%3hcg5THey zH_sd|F)?GsSjO~YJlM{m;p$zKKZfe}7tTI@n1$?@YD{`|mFVv*`9w5THM*j)F>gIW z1Yxe1g=%J_g~|#GvTwb8q=AV&MBffdqZwS(=cAOXSF_KYIWx7~*NkSc*)g7i{BN2i z3m{fR)*i{RN?bhXDy6cr(%wqe9id`93GeSz=14rQ*>u^iUylL<10$}z zkwqRO|B1;rlUdo*FIMt1=37S?MxZ{}868;c9@S1^b8%Mc&(?aUI*Q?vKl=e_0YUl zEBC&drWmoRVEg9{Nsp$Cw~GKZbSTu*+Ydq)>njDbLCG6QsHoA^&zCxj?O2+alA2l_ zC-!n|^!ZG(-#r>dNt0mOYaO(%T|pQ2{Dg%{bZjbEPiN;&Nh^k6*N5Qs%cWmXEREci z#A1J}^FyIQ?oy+zVF|dV?p+^)O0!Zgh^G((J|Y}h%BXAlpNFo?3!z;D}rllT*|KIG!xy; z_kNIp9r2xzC@2g`%(8sdsC4~Mwm@kOgL*U-^ug$IC?>X>nVPQKwKS=9a+v^)3_9YV zCX-Jt|AkVK9kWZ|%2gvEY~NwNZtYPSNUNFqC1%Q6L6F zZSs1I0QSmNio3h}CaGQ&E#cevIXGXOT+tNqc}Lzv(f`54Y6mW}r^SBpOK z;q!*bwn36iO8YzsfqqA#qN%BQ93myVXD{5Q<4!>Bn<^PRcho zH9h+2Wp+zMJ1e;&F&E7obBloTBuaNg1ilkZ|!3T|f-&?EfXZL1p_ucH$ zI4QH3jW!ld+V_!Lhec`}Q&UoorPkTLeWG=XPKPvOkd@|14;8xTJivST4-F35>&hG6 zAn!SEipCFJ7!4!$mUO%b%zy)uPEUM>>>+4Vz?3FMgT%Iojjm zbfNFefx+n|vbHo@S_Hx_RbP%-)Bm{(BcOi%{P~TSDDVoMspbAO+ecl+@v!)<#6q_q z?%bpsM1fk<=%w||ogKXq)KF|k$or0vs#;^dPbndzKYs{vG5JQ5pW7HPqi~e_XrJ6L zO&}1X*o?z{9(rA)N4EqKxP1~6WnnUX?Xv~zCATA}iC-e^B56(9)Gadc_{prs!J&&c zH1Xsv%;?YQT;D+zyIk&;*RH?KHLWc%yK!o}Ve!oE&GSUaA`AAJJ2vJrCqfoK5NMH4 zIjF03gdx1rRRd$k{M~}2FXcK#O>|LkL$B4O24@?pgfN9mt{io~(w~tYPZXW1ae7)= z^3~f`Z0g>a;iU>zk@BTpmysx~E+XwLX`DpwfQ&!?VWdmKaNALBmqEU=t3)1XK>FMcf5HpZ7xZiUX z-3<6rRl(e}lDZ7&1ip)byEp)(&v@_HU`-E#sn}As;l?(i;-0(<18%vmd`6Wj&SHJm z@!!9xgSBb)MgwwOg_`0K%jQSy9y#G>cq=SyQm<(G$^q|^PP1b?Cbj>w^&(vMju{Q~sGMETuZyck1 zYj~~R5;xD!0$(?+6c-0ewkvLQbhP6P{}CEBfQJ1WByJcN%5Pgk=Z+@k=+UEnwkZ)) zKSp$7beD6}=v=jygqzgFD>gLFbW^;xdFKwaPWia1RqWr~@gzydb~$n86Q!dicw}I* zrG|p54DGqPaBA^<7D=QzlYS@{y?UjgE1-y(13R!^?74w_bxmj~Kz{LYpT+jOf30I@|#9e-le@`9vZlb$w`&5shNQC3Kzz{$`PbA)DW?pwuZC?qs5)Nw{H(>sPzZXv|0jhA%fT*ov|Zy;uA2pzAAZx;c=&& zBkEVpM-U7>Lp8h**?AxA+qBDGcG>ih0WhPF0)%|yJ0 zXySL#m|Ls@2jKAPF|fyL3||eps6>W|G3}RFHs}#ahRkr1V}j>BJftpB7B5~rCPvo% z*Fo>#_Kl2peB16_y1NM?@k5gzxfo)BAA{Z3L=OB#BZu{0R2LO3BrH*I82y>2u|ttC zPsJH(1aS@#iF0Un)Fa<4ciX#rbc$ACz(ERcdA4Z@?dd5Iz=D0Vvjy=HQ{TQl`^CPT zoiRIu2Mn^NEhSY~SGzK%^fksJ@olMK5r17Rk7P)zxJY5*`L}iIBv9YK*Uc#?&=v^`+r$zy;5|W)8gs|3wCQ?upslYj0X9Cus>r`D6X1*i zxw;S1intDlS_<>O$TMcfABF*qb4Ft6k<~{%K;bD#-4#~p9(*6-8H=BjAM_hM4@ba@ zle)YU5K4@BZa+X*pmGcZZMg21=9bu>UM*JK&Jbb#&S>5En_K7_f6*!J zxaz1s?=pp)S^-3K*M72qzGmt;$Lmff1Y7_}P3$J#uUksfQwEV3%Oz`IblE5R`x9{; ze4Kv5rd6K9XdcAqPhj#s-;6g?=Du z^1z0AyX2J_8yZA5l(m*~AD!9t1=MqtBVd{~C3dT;so57UILer7{!r`~c>%Z}`lw-D zUElZba;_@T5!Xu5I2s)(VyncB#_vK3%pHo7`dlL5%99|+Av*<6=bFR+Ofd<^^OzUy zX}ESsV8q5>n=>W+@h8BR*f`BF?4`{beu8t%2}ndhj>2}k)C(q+e*187J%5dZ%sDoY z2r0;9PJfDQqGjt4W?1Y8u~oe^X2jscYOZ~co1kTKO_b{Lki}(vx8{S90*iTcHuTsQEz zEIz=~J6bd5eL-N%#W@P?0$@Lj@4zzV$K$pL2f19lXbxGJe|1ZwL=NrBimNtAo+qKY zPro^TmLYyv-1Jir9C1Ag-GfL}nUTPHCff`R+DDXI4PKUYo|~OjwCgEUN2M)$vPCFs zhAd?3FI-faqjnlExDfk|9<&e+V#;->kpefLEB4MCqU5h9{#no1G2%i{GwJK-cnGHS zew5dDCze2&d=7>!ed~IFE~3@}P*6EKF)^Xh)l?T2W_6@=%iO-0^n?%OW29Tv)nKZ8 zeD1Be%_2%l`Y_^NQ{_%1afQ(I;{l7EtAImDqTpXSG=0cIcA4Pnrn00YL1umxqOSG8 z9EFoY3H$JaFE814fJB&+>o>dTi?Z})@{aQ3%pcQS0{e@q7}y6 z2>uYf*@l}jCU$%c|H&pu)48~NM#6>Ajj#hMj(;dhZ&mf39h<^xz zqW+1gG4V8kIjM*T<31i$uK!=q(nt)|TJDelH9tG=$cy%o z645AHT@_v1-;gJ^f6K_X>8K&d%B^;QI%&mTd4+$pnO{s0yTRU6CiW8UQy9$KwQ^2u ztz(d+sbO;z1EENxj8_hH9v&V#re9&YMOgYS zr8$GFM=u>1iqUFIv&;5J{DJf_QUsgEEXvl zpqOp`PELBD327uAQvB_y@VyjwiVgA0KZ}xBBHo_}nf&TkT}b!g(qgrbm*t2I8j<`& z0D=Bk2YqvN=95BjkTZt(b=X;HVw2&&1aUg#m!MOJ`xzzZ1D0tQ{`+{gXO5b z<9z?Jv+dLMOe8qR7(Ce?BT%endfBn^vSVZBboXHfsU0lZhjDR^KddJZ--z=${_>8$TEFakP2_3_VY=-C{ma@HRil8*1q2w-O zOV(r1l}TWBjFw>i6Mxv_OCf~~j6aiN0gNhmUoH<}m@|trnCd<`wVgX31&UP>l-BnCm0H{qtP;D-| zPgUgrH|ufLap=X~r>|`P30;z2Ea{z?>e~|NDD%zj=HBdR?Vhyt7SCCzZ>I$<>9)65 zF@gXf^f0v242@P-t3;_rmd_6DZeg-@P5|I$eGX2)-Dq(J;0{mwkcr8{xncPr_@9ui zeY=qWAz_$RN>N4}#;+;fp*iW8TPrYBcV>LLV-2|9cE{{HXFPB$y!IN!g2UsOT0n#C6|bRo^0q#bulTl;7b8`0l!YG&4F;UlzWNnZiqA)o*` zw9H~|wO&iZ%dPspe%+>_q&QyIwS-afVGN0`cvuiY!&?F!Bz-+0Htxt^O_h)e1;DL~ z$`8*iNJoW{ww9Dx|@b4uM6dJF|Bz-6T4f*P z!AxhfkxE9<}~ zox{67H4-bW3jVuRkx5YAPQ|s|>w*IquDQ*e6(4T1h=`I4aBHvm?#?;xr|m@onS0K! zpl|M7Fn7+ax2FU1FUQej!hogom$6tUehJ4a#OddIan6-~$@jp! z>{RR08PZFM5*2belYU%np^g6BlnlP83Lyc5P!j;2&r;b?F^`+Mpu{9Qd>CH``7D_W zGjlEia=|~wL?-{3aY=`%xG4@USKounsvyA;60Oj|cU9pJMVQAzgs~!x3 zFR*Woh}<@})CO+I*h3C&Wfg>V87q@WbI~f@CO52g^g^1(kk*m?KaGT%6p{-lbL5j4 z*#PXi`0z7piEexi5-gTdLeSbmbY+j{@<8o5V?_7g_DioMW`RK{XK$*X@W{^;2uGS5 zm|JQAR!wc)%IE|^{*ZQ*1ieV#p95vrHOI%ZWGLv1#d(>K8wX==#rx)RxAO(Q2-)>< zDRV&h@OOyCZ+(;c$I}Bc%D0UTDuD)C5%(x8_=3hSx2-^fyp&6#CDGbvdc6DRaZ?Ma z|MZteh%gsV3gvodl@6Vg@ef7+A)P_Gh@b!!HPtEM;&KG2wiJr2oJV(RAS5()z3eHU zqXuNjB&51EWfe1f@-#I59yV63M~q;1n>~d$;Dv%#s|hQ)brJxSKWZWlEuxAC|0+L?gouSWQL6W?qy7vXucLbMn}?Wn#?Dvtx4k zuh>vzDk}%La|CKxGXOLu1#WbVT96HGL7k`<;B#8>niVYnJ$d-Zy1R&^Up#S2x&>ot2p;^oQm#qbsm8M6KW}hCD-Ow2F`tMjU zZ87MmKGxwV0G319`DPB{FRJJ*s&qY`M%>{=Hp;vW;6AH&^;0bI?h28+|7K6W?6ZId zqBUNTNo}tST8D=pi7%e#(ny0~sEKve%tkC&t~Cidn~n!M$J|WuCGrS23$pSSOz?Fq zr(aPP83|m}RgPbFI3?qo>wJzSM*uEV7;I985hv2#$JjMl3uy*$9IBRjw3*x(TcgMR^P_qiAV*F(Rq9$?E)J=vtVr&t6{JR!)V|Yizyd8-!`7#*<$H_k6ycCKIDaO z>+S6|W>YjQRI7+&8(JuvKhLf3Ld;`d^+yD~?u{EZ2dy3hqWUB$DOxsx!l~``r1c!nO)X`qbz0(B(oM2DATP^D~iE+_-;MVzE@3Q1PCEylpl%S z`F*)n!r(ZkOn;0k1v+;AZUx;|17zSKRI-+JVE=2b!KwF2(*vO8HFmcH7^!FahGxwq z5}WURPR!E%sZg91^L``LdkQa--B}zbqDAhI3NKhtmdwf!a7a*`uGCd?C+t?lY{<;vt2SpqKyC#C{rT~4vCjExik`&V!|sTDN0e|F5U5P&`C@r8z}O$r2; z)}&sadHPv@8LwX$3@wFYjkwN4pIn}^^Y+U|Dg-Y#W2`*PN^3k1_Tg3Haad)Ju7*3s zB-5fhmQi$|(P3)I6|%iRK{Kum#!RiLn&;qg)8Lkd?jNEs^C+mY9@BrnvPWlVH1QJA z-<9xw?DBjS5ElT5*UI6zKjyFgEOGWRv-$f7f+5Z7UFYHxpmI0#bwLCX+GwkOz3q4L zZsGp!k-x^vQ?SOt&^U_K?7|kP4vde%(YpcX0o;V^!81d9LNllhip?4 z=R*;EE*1f~Dk>)yI!OA9);P{XcVGyxc8y4&2N_EIc`nh~QH5&Xe% zo}RWzVnC4W4GMzmesB5o#fyTKZ%ixgW~D!A1=3UMD%2cL7G2%^$)0^@bhO=q~thIJa#-FUBOP)nLtB6<^^HKHdlG*dO56!mF zcfYv3(JVEqkiCy~7Ky3IA9cXq2L%0bfK})vMp8lQXM`)D3v{b+&_xHwx!ek}662*; zMh4#}b_{;C5$~DbdkV=Hq)W1J!fBp$#oBC?y?dmV;1Xn$qx>Z4CXrX9^acw(<1?r# zUeLa$$q#MPA3fg9rD|zDqaT8M&v+(Gy9G@;$1)U-Tprn^vt9 z7b$97;~yCUSW!Ljk;A+tNmQK&4!xFn%EihdUurBIAu977IxqAw`pEjoEG5?L8MO!p z9r$a`t4eKd?am(=EZTCPH1F4VKcuAgJUn)OAdQePen-}EI zGc?A+kcv6G!^QKqU-s9W>OMQlh7eYpf$VA)x)3KEKIWn4445ogAp>1r zrkk{G%o#99R6`TR!~Q{CzNXOCO+^+GUb(H7?^WjsGyjidP=1FCCiCneQY?Z#JUKH$ zRd5>7DaxF21PlG``Bc1q)=G`Xjf4zD2||AF8;2zXLLB00G+@b^0E8~-y`=cqT)sZU zMpY-b|FL{du}ErMw+RkGSF@7Xh8&gj$J~w%JTRWmvcIQ#(A5|raf4h1!NnX}$8Nn{ ztKmD>T?nY=E=HrK5snz?8|0e~LVkP420L0)BSTlgF@v)j;9*o&>F7s)BTyFC6)NN! z-h-J=f^@{Y%*5zg025qtaaNIq0o~Q#&Pmz9l&6?t~77e_< zz`Dpmg!>owW{I*l5wmieukU2}BT6{yD1bekp&$L{Et1TO(a-@XvGVBp0qW3N!&-uF z7H^Wnb*ABgD*FCcjVA4G`MiN=!_6TG4N-5HVuiGblMY1yg-g5E{6u-grnKX_UDV6?Q_GVA$khrUmMX$bQB5bS-N zpm<#*=#|0LH`zI16c<3+8b=fon=~^TaqX|2^o#zE0HL)t4m3-BZ0t9PYqLc*TKgC8 zKnez$g`>-@6Dory4@6@i!)xyB;5#o!LH(-k{EErYNLe+vv_ zQ72LnXXwzgZgo`dg4qF$#3qVCks1(6y{njrVXCUEN3xT+nVH_vU2d z_S33c{IYb%6vX!n%}=JGkG2g%O7T}qh3anX)YaB&SHY$=DvxVo?%;_AkPz02a>olf6C;jMjaCk)5G;2|h@YJ(sLx~^2`K10_ zw1|#Ltt0XNHf7+{2i=5nq$|2kks33-HRdO(K$vwlfD2Yh4tP3Wr6E5eV6@Q9S!W`* zjfiz4)F+p#ET`2`AhS~V#BR!JmkEah2Ql(_!|wuxlS7h#XE)oZ)9J^MV?5F&^evY> zWGD2odC~A|HHPv?VBw6=B%w_~s!4Oqm}G1|*T}$N!3#j~YE2nC&i$PR>7VRYHo(c1 zq&iC=EZs>`+j;igfWxSkX_@tf3FjII#`rEiw4%Eemc5P~hW(p=$o|`3>XY&MRlzz# zm6vk&mI2{}mGCFKly?rWYaC(<37^*vvU$}Jz**hEqe z?%S=8Cyv&ByvDE{j6HF3*#)?jN#$x>aaYl*#*KD+=b3F0=8ecmpqW)0Aj?orqP;+h z>1Df^2K(b*4eB!^GOBnO1Z5~jTNTLNVsDP%d5Lpmnj0KzZm2?HcH9z{zi~yor&ClKvPc`N|A4CR?Cpx90Id0VrBM+cmLM*J-~ilBGIR9zhIl=@wkeBnG_9`DzRGM!;5 zYVJnAyr<@-LC&-Z0wwqf)`|<#n{gj!znCn4ZaUcM&Cp@`+F@uQeCxkI7aTod~jmdYoUgrE%rsaO>ub!{{ zExVT8G(NFjhx4@L$D9i${wGH%^&)j0=SS~tUz?i~=j9-f2B%MIoKL*A&H4M@Ajzx? zN#>9rIjpf3ed?;yB;3esnmyKY^wq_^1-o+HJ54SOZ})q(L(x1nq;r-{x^?1Kr$gM; z+}a5r_pSG$jo}!f zzl=@OG3F-kfF2kWKY`0|{&@qxO+xc6u}H4X)v|nE2>ibdKwbjQ@=&`j3Mqi($^OST{I>3Y zT^dTs|CEYJuK$#Zp{4&R6;tv4Q!0j4{LfP{)C2dQr($^F|2!2#J^25Fe+=;RAN*se zhs1yIj{!gbi>Vmuf&VY2Vgx|{#Z(OS_%BhxkO?-@|Ib7P>DNNX>ec(EPPHv!gZ~a{ MXzxqeV{z&K031%b*8l(j literal 0 HcmV?d00001 diff --git a/docs/images/logo-48x48.png b/docs/images/logo-48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..ac0dad1843806698354490052855144c50a7fb1e GIT binary patch literal 1717 zcmV;m21@yfP)MQ+TC>?r zGUIpVp8GSii5im!ALhd0-aB)5_xtWS=R5bV5LwGw*0PqhtYz(g+?qwCP0d{qI_PsW zcdd6W_q^_4vk0%ECp%<+A3iTc$(Kg0VaC1Ap}hSYs#k&PfquwoV&>B`@)vF_FNNW7V$)0hf0i^E%iT*tI-oPlRgSTI_t#A_>fs@i>63 zr!|kPnO9(W$Gtj?w}DiH@qo9gVWf6;H>?D!z@`DTLy>Sb(QqBDX^D3|n!|XG36wD3 zKx?{aZNNJp_zwecfcYHyiUYz5%e&fiYES(IQFsApi?6-kTe;ZA-})+N`y zsMh6v7*spo1i)qS>qrEk3*!86Bz`$U;~hGjR$=$^+;_K0AQg`7O1qpt&F>3Vq7#`H zV3V*Z?EFhEe^2bGl9y+IUE=a60iK10ATuj|KN_Kbp5GT%97+~}HU>QF%GfUNlk+E1 z>+H``zSPwSLf|U`yTxxu6@hu!jQC@W2=s9h7giyJLM4|3=4=N*x57F&u3?)@9_U0) zD-=8u8WLK8{B^L?qC6gn^Djr@>KKu^0BcMn`M=S5*Ze?^c9TtkSFzm)AYe7P1@do#jle#Iy#;c2CE{P!i#(f=Sml|&)A^JF<(3LDmB6kX zi$sC5mBfH?G^oXz0bl!@R5$GJvl36~`5hQP4r|BG)}@pvXAyE#+%KhEt|DOXSS_Hu z229eb3Y+l|<-uN9FKi3vQ1bh%5ZOZ#NovChdzQi`MM8y#!=J4O(F1sP0^=T7!7h9? z-~+D}Ajj~mAN>s)Y$@R>1->5kNvuqlAhpxOlp~L7vVm`s6#Yj0=wwkAAd<>iPSi05 zl&|$xM4$Pb))h@+ziT!oR8>_08Ww*Zi(=iUzT|%kYe-dPp+hV12E@!bt*ZcRg$c}H z&CU8V&1NUJVq7H;u+Go7N-3}6Azs&N66 zs?*P4@`*f=Q>@Az(iGMqquUU!N*~0P9 zIq(zgw$vJ7s%p5Giy3*X+G36u+qAp}I-VP2_y0^g7@vDW_P{=!%qCBA+;77BGvdmt zQB0PO8G(O*iAptcQ*n*{9y%W2c`y0~8@#RYRz4hQ5H06h|3ARL>)*JDpj2L-F*ODM1Nm%Iad-YWJ1HK1!L8TIR3p_Pte&Zi0gr) z?+PjK`BY^U>Fc6h#MC-TCQ{*&=QYU+Z(k4Pm_VnG1$k?nyjt3X?8+@GdE(IKxE7Jr z{WfPkUsH3xO&v-8u_e4>9Tx(BZNfXITBk#(kdAYzq+i3nf%VxWTwUm*Ye+Wn>^qSC z63;vB+t{)QnB8Ty@pr*K!?W*U$6?o-3T=DP>%sghE`ZO*p@kps@8lygnY@5U113y# z9=y@TGFj9z3+cD+0?Pxhm1(EA@QRd3()rorB$Xd7QWGAFt2fE;ITXaoYoua>g8%kV z7x1dNfQRcX4>j@qc7fN;a>4pYoqLw$fxt5a0{_ie|c}oxtvoV7%6nQFZdX5#x90?-W=5$J1vLJxZw7GQvoK?8Z)0 z0#Cs{fZfWVa|y*N`Ojfp3C|}nejVfb?7!2jWi4x2%Uag5wu1H-D4S>R>|YIC00000 LNkvXXu0mjf?Hfd2 literal 0 HcmV?d00001 diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3b19076800e6169af190a01dcba9ac24fbec7e GIT binary patch literal 206848 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 z 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

R|Vaq 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 literal 0 HcmV?d00001 diff --git a/docs/images/qubernetes/k8s-logo.png b/docs/images/qubernetes/k8s-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..05fc5e1d2d2c61d5c96a2d806c8ddc7f9a8f9fbb GIT binary patch literal 286328 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/theme/404.html b/docs/theme/404.html new file mode 100644 index 0000000000..52beb3b8b3 --- /dev/null +++ b/docs/theme/404.html @@ -0,0 +1,4 @@ +{% extends "base.html" %} +{% block content %} +

404 - Not found

+{% endblock %} diff --git a/docs/theme/assets/javascripts/application.81068b3a.js b/docs/theme/assets/javascripts/application.81068b3a.js new file mode 100644 index 0000000000..476bcf8aeb --- /dev/null +++ b/docs/theme/assets/javascripts/application.81068b3a.js @@ -0,0 +1,6 @@ +!function(e,t){for(var n in t)e[n]=t[n]}(window,function(n){var r={};function i(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,i),t.l=!0,t.exports}return i.m=n,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=13)}([function(e,t,n){"use strict";var r={Listener:function(){function e(e,t,n){var r=this;this.els_=Array.prototype.slice.call("string"==typeof e?document.querySelectorAll(e):[].concat(e)),this.handler_="function"==typeof n?{update:n}:n,this.events_=[].concat(t),this.update_=function(e){return r.handler_.update(e)}}var t=e.prototype;return t.listen=function(){var n=this;this.els_.forEach(function(t){n.events_.forEach(function(e){t.addEventListener(e,n.update_,!1)})}),"function"==typeof this.handler_.setup&&this.handler_.setup()},t.unlisten=function(){var n=this;this.els_.forEach(function(t){n.events_.forEach(function(e){t.removeEventListener(e,n.update_)})}),"function"==typeof this.handler_.reset&&this.handler_.reset()},e}(),MatchMedia:function(e,t){this.handler_=function(e){e.matches?t.listen():t.unlisten()};var n=window.matchMedia(e);n.addListener(this.handler_),this.handler_(n)}},i={Shadow:function(){function e(e,t){var n="string"==typeof e?document.querySelector(e):e;if(!(n instanceof HTMLElement&&n.parentNode instanceof HTMLElement))throw new ReferenceError;if(this.el_=n.parentNode,!((n="string"==typeof t?document.querySelector(t):t)instanceof HTMLElement))throw new ReferenceError;this.header_=n,this.height_=0,this.active_=!1}var t=e.prototype;return t.setup=function(){for(var e=this.el_;e=e.previousElementSibling;){if(!(e instanceof HTMLElement))throw new ReferenceError;this.height_+=e.offsetHeight}this.update()},t.update=function(e){if(!e||"resize"!==e.type&&"orientationchange"!==e.type){var t=window.pageYOffset>=this.height_;t!==this.active_&&(this.header_.dataset.mdState=(this.active_=t)?"shadow":"")}else this.height_=0,this.setup()},t.reset=function(){this.header_.dataset.mdState="",this.height_=0,this.active_=!1},e}(),Title:function(){function e(e,t){var n="string"==typeof e?document.querySelector(e):e;if(!(n instanceof HTMLElement))throw new ReferenceError;if(this.el_=n,!((n="string"==typeof t?document.querySelector(t):t)instanceof HTMLHeadingElement))throw new ReferenceError;this.header_=n,this.active_=!1}var t=e.prototype;return t.setup=function(){var t=this;Array.prototype.forEach.call(this.el_.children,function(e){e.style.width=t.el_.offsetWidth-20+"px"})},t.update=function(e){var t=this,n=window.pageYOffset>=this.header_.offsetTop;n!==this.active_&&(this.el_.dataset.mdState=(this.active_=n)?"active":""),"resize"!==e.type&&"orientationchange"!==e.type||Array.prototype.forEach.call(this.el_.children,function(e){e.style.width=t.el_.offsetWidth-20+"px"})},t.reset=function(){this.el_.dataset.mdState="",this.el_.style.width="",this.active_=!1},e}()},o={Blur:function(){function e(e){this.els_="string"==typeof e?document.querySelectorAll(e):e,this.index_=0,this.offset_=window.pageYOffset,this.dir_=!1,this.anchors_=[].reduce.call(this.els_,function(e,t){var n=decodeURIComponent(t.hash);return e.concat(document.getElementById(n.substring(1))||[])},[])}var t=e.prototype;return t.setup=function(){this.update()},t.update=function(){var e=window.pageYOffset,t=this.offset_-e<0;if(this.dir_!==t&&(this.index_=this.index_=t?0:this.els_.length-1),0!==this.anchors_.length){if(this.offset_<=e)for(var n=this.index_+1;ne)){this.index_=r;break}0=this.offset_?"lock"!==this.el_.dataset.mdState&&(this.el_.dataset.mdState="lock"):"lock"===this.el_.dataset.mdState&&(this.el_.dataset.mdState="")},t.reset=function(){this.el_.dataset.mdState="",this.el_.style.height="",this.height_=0},e}()},c=n(6),l=n.n(c);var u={Adapter:{GitHub:function(o){var e,t;function n(e){var t;t=o.call(this,e)||this;var n=/^.+github\.com\/([^/]+)\/?([^/]+)?.*$/.exec(t.base_);if(n&&3===n.length){var r=n[1],i=n[2];t.base_="https://api.github.com/users/"+r+"/repos",t.name_=i}return t}return t=o,(e=n).prototype=Object.create(t.prototype),(e.prototype.constructor=e).__proto__=t,n.prototype.fetch_=function(){var i=this;return function n(r){return void 0===r&&(r=0),fetch(i.base_+"?per_page=30&page="+r).then(function(e){return e.json()}).then(function(e){if(!(e instanceof Array))throw new TypeError;if(i.name_){var t=e.find(function(e){return e.name===i.name_});return t||30!==e.length?t?[i.format_(t.stargazers_count)+" Stars",i.format_(t.forks_count)+" Forks"]:[]:n(r+1)}return[e.length+" Repositories"]})}()},n}(function(){function e(e){var t="string"==typeof e?document.querySelector(e):e;if(!(t instanceof HTMLAnchorElement))throw new ReferenceError;this.el_=t,this.base_=this.el_.href,this.salt_=this.hash_(this.base_)}var t=e.prototype;return t.fetch=function(){var n=this;return new Promise(function(t){var e=l.a.getJSON(n.salt_+".cache-source");void 0!==e?t(e):n.fetch_().then(function(e){l.a.set(n.salt_+".cache-source",e,{expires:1/96}),t(e)})})},t.fetch_=function(){throw new Error("fetch_(): Not implemented")},t.format_=function(e){return 1e4=this.el_.children[0].offsetTop+-43;e!==this.active_&&(this.el_.dataset.mdState=(this.active_=e)?"hidden":"")},t.reset=function(){this.el_.dataset.mdState="",this.active_=!1},e}()};t.a={Event:r,Header:i,Nav:o,Search:a,Sidebar:s,Source:u,Tabs:f}},function(t,e,n){(function(e){t.exports=e.lunr=n(24)}).call(this,n(4))},function(e,f,d){"use strict";(function(t){var e=d(8),n=setTimeout;function r(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],u(e,this)}function i(n,r){for(;3===n._state;)n=n._value;0!==n._state?(n._handled=!0,o._immediateFn(function(){var e=1===n._state?r.onFulfilled:r.onRejected;if(null!==e){var t;try{t=e(n._value)}catch(e){return void s(r.promise,e)}a(r.promise,t)}else(1===n._state?a:s)(r.promise,n._value)})):n._deferreds.push(r)}function a(t,e){try{if(e===t)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==typeof e||"function"==typeof e)){var n=e.then;if(e instanceof o)return t._state=3,t._value=e,void c(t);if("function"==typeof n)return void u((r=n,i=e,function(){r.apply(i,arguments)}),t)}t._state=1,t._value=e,c(t)}catch(e){s(t,e)}var r,i}function s(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var t=0,n=e._deferreds.length;t"+n+""};this.stack_=[],r.forEach(function(e,t){var n,r=a.docs_.get(t),i=f.createElement("li",{class:"md-search-result__item"},f.createElement("a",{href:r.location,title:r.title,class:"md-search-result__link",tabindex:"-1"},f.createElement("article",{class:"md-search-result__article md-search-result__article--document"},f.createElement("h1",{class:"md-search-result__title"},{__html:r.title.replace(s,c)}),r.text.length?f.createElement("p",{class:"md-search-result__teaser"},{__html:r.text.replace(s,c)}):{}))),o=e.map(function(t){return function(){var e=a.docs_.get(t.ref);i.appendChild(f.createElement("a",{href:e.location,title:e.title,class:"md-search-result__link","data-md-rel":"anchor",tabindex:"-1"},f.createElement("article",{class:"md-search-result__article"},f.createElement("h1",{class:"md-search-result__title"},{__html:e.title.replace(s,c)}),e.text.length?f.createElement("p",{class:"md-search-result__teaser"},{__html:function(e,t){var n=t;if(e.length>n){for(;" "!==e[n]&&0<--n;);return e.substring(0,n)+"..."}return e}(e.text.replace(s,c),400)}):{})))}});(n=a.stack_).push.apply(n,[function(){return a.list_.appendChild(i)}].concat(o))});var o=this.el_.parentNode;if(!(o instanceof HTMLElement))throw new ReferenceError;for(;this.stack_.length&&o.offsetHeight>=o.scrollHeight-16;)this.stack_.shift()();var l=this.list_.querySelectorAll("[data-md-rel=anchor]");switch(Array.prototype.forEach.call(l,function(r){["click","keydown"].forEach(function(n){r.addEventListener(n,function(e){if("keydown"!==n||13===e.keyCode){var t=document.querySelector("[data-md-toggle=search]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t.checked&&(t.checked=!1,t.dispatchEvent(new CustomEvent("change"))),e.preventDefault(),setTimeout(function(){document.location.href=r.href},100)}})})}),r.size){case 0:this.meta_.textContent=this.message_.none;break;case 1:this.meta_.textContent=this.message_.one;break;default:this.meta_.textContent=this.message_.other.replace("#",r.size)}}}else{var u=function(e){a.docs_=e.reduce(function(e,t){var n,r,i,o=t.location.split("#"),a=o[0],s=o[1];return t.text=(n=t.text,r=document.createTextNode(n),(i=document.createElement("p")).appendChild(r),i.innerHTML),s&&(t.parent=e.get(a),t.parent&&!t.parent.done&&(t.parent.title=t.title,t.parent.text=t.text,t.parent.done=!0)),t.text=t.text.replace(/\n/g," ").replace(/\s+/g," ").replace(/\s+([,.:;!?])/g,function(e,t){return t}),t.parent&&t.parent.title===t.title||e.set(t.location,t),e},new Map);var i=a.docs_,o=a.lang_;a.stack_=[],a.index_=d()(function(){var e,t=this,n={"search.pipeline.trimmer":d.a.trimmer,"search.pipeline.stopwords":d.a.stopWordFilter},r=Object.keys(n).reduce(function(e,t){return h(t).match(/^false$/i)||e.push(n[t]),e},[]);this.pipeline.reset(),r&&(e=this.pipeline).add.apply(e,r),1===o.length&&"en"!==o[0]&&d.a[o[0]]?this.use(d.a[o[0]]):1=t.scrollHeight-16;)a.stack_.splice(0,10).forEach(function(e){return e()})})};setTimeout(function(){return"function"==typeof a.data_?a.data_().then(u):u(a.data_)},250)}},e}()}).call(this,r(3))},function(e,n,r){"use strict";(function(t){r.d(n,"a",function(){return e});var e=function(){function e(e){var t="string"==typeof e?document.querySelector(e):e;if(!(t instanceof HTMLElement))throw new ReferenceError;this.el_=t}return e.prototype.initialize=function(e){e.length&&this.el_.children.length&&this.el_.children[this.el_.children.length-1].appendChild(t.createElement("ul",{class:"md-source__facts"},e.map(function(e){return t.createElement("li",{class:"md-source__fact"},e)}))),this.el_.dataset.mdState="done"},e}()}).call(this,r(3))},,,function(e,n,c){"use strict";c.r(n),function(o){c.d(n,"app",function(){return t});c(14),c(15),c(16),c(17),c(18),c(19),c(20);var r=c(2),e=c(5),a=c.n(e),i=c(0);window.Promise=window.Promise||r.a;var s=function(e){var t=document.getElementsByName("lang:"+e)[0];if(!(t instanceof HTMLMetaElement))throw new ReferenceError;return t.content};var t={initialize:function(t){new i.a.Event.Listener(document,"DOMContentLoaded",function(){if(!(document.body instanceof HTMLElement))throw new ReferenceError;Modernizr.addTest("ios",function(){return!!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)});var e=document.querySelectorAll("table:not([class])");if(Array.prototype.forEach.call(e,function(e){var t=o.createElement("div",{class:"md-typeset__scrollwrap"},o.createElement("div",{class:"md-typeset__table"}));e.nextSibling?e.parentNode.insertBefore(t,e.nextSibling):e.parentNode.appendChild(t),t.children[0].appendChild(e)}),a.a.isSupported()){var t=document.querySelectorAll(".codehilite > pre, pre > code");Array.prototype.forEach.call(t,function(e,t){var n="__code_"+t,r=o.createElement("button",{class:"md-clipboard",title:s("clipboard.copy"),"data-clipboard-target":"#"+n+" pre, #"+n+" code"},o.createElement("span",{class:"md-clipboard__message"})),i=e.parentNode;i.id=n,i.insertBefore(r,e)}),new a.a(".md-clipboard").on("success",function(e){var t=e.trigger.querySelector(".md-clipboard__message");if(!(t instanceof HTMLElement))throw new ReferenceError;e.clearSelection(),t.dataset.mdTimer&&clearTimeout(parseInt(t.dataset.mdTimer,10)),t.classList.add("md-clipboard__message--active"),t.innerHTML=s("clipboard.copied"),t.dataset.mdTimer=setTimeout(function(){t.classList.remove("md-clipboard__message--active"),t.dataset.mdTimer=""},2e3).toString()})}if(!Modernizr.details){var n=document.querySelectorAll("details > summary");Array.prototype.forEach.call(n,function(e){e.addEventListener("click",function(e){var t=e.target.parentNode;t.hasAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","")})})}var r=function(){if(document.location.hash){var e=document.getElementById(document.location.hash.substring(1));if(!e)return;for(var t=e.parentNode;t&&!(t instanceof HTMLDetailsElement);)t=t.parentNode;if(t&&!t.open){t.open=!0;var n=location.hash;location.hash=" ",location.hash=n}}};if(window.addEventListener("hashchange",r),r(),Modernizr.ios){var i=document.querySelectorAll("[data-md-scrollfix]");Array.prototype.forEach.call(i,function(t){t.addEventListener("touchstart",function(){var e=t.scrollTop;0===e?t.scrollTop=1:e+t.offsetHeight===t.scrollHeight&&(t.scrollTop=e-1)})})}}).listen(),new i.a.Event.Listener(window,["scroll","resize","orientationchange"],new i.a.Header.Shadow("[data-md-component=container]","[data-md-component=header]")).listen(),new i.a.Event.Listener(window,["scroll","resize","orientationchange"],new i.a.Header.Title("[data-md-component=title]",".md-typeset h1")).listen(),document.querySelector("[data-md-component=hero]")&&new i.a.Event.Listener(window,["scroll","resize","orientationchange"],new i.a.Tabs.Toggle("[data-md-component=hero]")).listen(),document.querySelector("[data-md-component=tabs]")&&new i.a.Event.Listener(window,["scroll","resize","orientationchange"],new i.a.Tabs.Toggle("[data-md-component=tabs]")).listen(),new i.a.Event.MatchMedia("(min-width: 1220px)",new i.a.Event.Listener(window,["scroll","resize","orientationchange"],new i.a.Sidebar.Position("[data-md-component=navigation]","[data-md-component=header]"))),document.querySelector("[data-md-component=toc]")&&new i.a.Event.MatchMedia("(min-width: 960px)",new i.a.Event.Listener(window,["scroll","resize","orientationchange"],new i.a.Sidebar.Position("[data-md-component=toc]","[data-md-component=header]"))),new i.a.Event.MatchMedia("(min-width: 960px)",new i.a.Event.Listener(window,"scroll",new i.a.Nav.Blur("[data-md-component=toc] .md-nav__link")));var e=document.querySelectorAll("[data-md-component=collapsible]");Array.prototype.forEach.call(e,function(e){new i.a.Event.MatchMedia("(min-width: 1220px)",new i.a.Event.Listener(e.previousElementSibling,"click",new i.a.Nav.Collapse(e)))}),new i.a.Event.MatchMedia("(max-width: 1219px)",new i.a.Event.Listener("[data-md-component=navigation] [data-md-toggle]","change",new i.a.Nav.Scrolling("[data-md-component=navigation] nav"))),document.querySelector("[data-md-component=search]")&&(new i.a.Event.MatchMedia("(max-width: 959px)",new i.a.Event.Listener("[data-md-toggle=search]","change",new i.a.Search.Lock("[data-md-toggle=search]"))),new i.a.Event.Listener("[data-md-component=query]",["focus","keyup","change"],new i.a.Search.Result("[data-md-component=result]",function(){return fetch(t.url.base+"/search/search_index.json",{credentials:"same-origin"}).then(function(e){return e.json()}).then(function(e){return e.docs.map(function(e){return e.location=t.url.base+"/"+e.location,e})})})).listen(),new i.a.Event.Listener("[data-md-component=reset]","click",function(){setTimeout(function(){var e=document.querySelector("[data-md-component=query]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.focus()},10)}).listen(),new i.a.Event.Listener("[data-md-toggle=search]","change",function(e){setTimeout(function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=document.querySelector("[data-md-component=query]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t.focus()}},400,e.target)}).listen(),new i.a.Event.Listener("[data-md-component=query]","focus",function(){var e=document.querySelector("[data-md-toggle=search]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.checked||(e.checked=!0,e.dispatchEvent(new CustomEvent("change")))}).listen(),new i.a.Event.Listener(window,"keydown",function(e){var t=document.querySelector("[data-md-toggle=search]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;var n=document.querySelector("[data-md-component=query]");if(!(n instanceof HTMLInputElement))throw new ReferenceError;if(!(document.activeElement instanceof HTMLElement&&document.activeElement.isContentEditable||e.metaKey||e.ctrlKey))if(t.checked){if(13===e.keyCode){if(n===document.activeElement){e.preventDefault();var r=document.querySelector("[data-md-component=search] [href][data-md-state=active]");r instanceof HTMLLinkElement&&(window.location=r.getAttribute("href"),t.checked=!1,t.dispatchEvent(new CustomEvent("change")),n.blur())}}else if(9===e.keyCode||27===e.keyCode)t.checked=!1,t.dispatchEvent(new CustomEvent("change")),n.blur();else if(-1!==[8,37,39].indexOf(e.keyCode))n!==document.activeElement&&n.focus();else if(-1!==[38,40].indexOf(e.keyCode)){var i=e.keyCode,o=Array.prototype.slice.call(document.querySelectorAll("[data-md-component=query], [data-md-component=search] [href]")),a=o.find(function(e){if(!(e instanceof HTMLElement))throw new ReferenceError;return"active"===e.dataset.mdState});a&&(a.dataset.mdState="");var s=Math.max(0,(o.indexOf(a)+o.length+(38===i?-1:1))%o.length);return o[s]&&(o[s].dataset.mdState="active",o[s].focus()),e.preventDefault(),e.stopPropagation(),!1}}else if(document.activeElement&&!document.activeElement.form){if("TEXTAREA"===document.activeElement.tagName||"INPUT"===document.activeElement.tagName)return;70!==e.keyCode&&83!==e.keyCode||(n.focus(),e.preventDefault())}}).listen(),new i.a.Event.Listener(window,"keypress",function(){var e=document.querySelector("[data-md-toggle=search]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=document.querySelector("[data-md-component=query]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t!==document.activeElement&&t.focus()}}).listen()),new i.a.Event.Listener(document.body,"keydown",function(e){if(9===e.keyCode){var t=document.querySelectorAll("[data-md-component=navigation] .md-nav__link[for]:not([tabindex])");Array.prototype.forEach.call(t,function(e){e.offsetHeight&&(e.tabIndex=0)})}}).listen(),new i.a.Event.Listener(document.body,"mousedown",function(){var e=document.querySelectorAll("[data-md-component=navigation] .md-nav__link[tabindex]");Array.prototype.forEach.call(e,function(e){e.removeAttribute("tabIndex")})}).listen(),document.body.addEventListener("click",function(){"tabbing"===document.body.dataset.mdState&&(document.body.dataset.mdState="")}),new i.a.Event.MatchMedia("(max-width: 959px)",new i.a.Event.Listener("[data-md-component=navigation] [href^='#']","click",function(){var e=document.querySelector("[data-md-toggle=drawer]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.checked&&(e.checked=!1,e.dispatchEvent(new CustomEvent("change")))})),function(){var e=document.querySelector("[data-md-source]");if(!e)return r.a.resolve([]);if(!(e instanceof HTMLAnchorElement))throw new ReferenceError;switch(e.dataset.mdSource){case"github":return new i.a.Source.Adapter.GitHub(e).fetch();default:return r.a.resolve([])}}().then(function(t){var e=document.querySelectorAll("[data-md-source]");Array.prototype.forEach.call(e,function(e){new i.a.Source.Repository(e).initialize(t)})});var n=function(){var e=document.querySelectorAll("details");Array.prototype.forEach.call(e,function(e){e.setAttribute("open","")})};new i.a.Event.MatchMedia("print",{listen:n,unlisten:function(){}}),window.onbeforeprint=n}}}.call(this,c(3))},function(e,t,n){e.exports=n.p+"assets/images/icons/bitbucket.1b09e088.svg"},function(e,t,n){e.exports=n.p+"assets/images/icons/github.f0b8504a.svg"},function(e,t,n){e.exports=n.p+"assets/images/icons/gitlab.6dd19c00.svg"},function(e,t){e.exports="/Users/chrishounsom/mkdocs-material/material/application.668e8dde.css"},function(e,t){e.exports="/Users/chrishounsom/mkdocs-material/material/application-palette.224b79ff.css"},function(e,t){!function(){if("undefined"!=typeof window)try{var e=new window.CustomEvent("test",{cancelable:!0});if(e.preventDefault(),!0!==e.defaultPrevented)throw new Error("Could not prevent default")}catch(e){var t=function(e,t){var n,r;return(t=t||{}).bubbles=!!t.bubbles,t.cancelable=!!t.cancelable,(n=document.createEvent("CustomEvent")).initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r=n.preventDefault,n.preventDefault=function(){r.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(e){this.defaultPrevented=!0}},n};t.prototype=window.Event.prototype,window.CustomEvent=t}}()},function(e,t,n){window.fetch||(window.fetch=n(7).default||n(7))},function(e,i,o){(function(e){var t=void 0!==e&&e||"undefined"!=typeof self&&self||window,n=Function.prototype.apply;function r(e,t){this._id=e,this._clearFn=t}i.setTimeout=function(){return new r(n.call(setTimeout,t,arguments),clearTimeout)},i.setInterval=function(){return new r(n.call(setInterval,t,arguments),clearInterval)},i.clearTimeout=i.clearInterval=function(e){e&&e.close()},r.prototype.unref=r.prototype.ref=function(){},r.prototype.close=function(){this._clearFn.call(t,this._id)},i.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},i.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},i._unrefActive=i.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;0<=t&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},o(22),i.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,i.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,o(4))},function(e,t,n){(function(e,p){!function(n,r){"use strict";if(!n.setImmediate){var i,o,t,a,e,s=1,c={},l=!1,u=n.document,f=Object.getPrototypeOf&&Object.getPrototypeOf(n);f=f&&f.setTimeout?f:n,i="[object process]"==={}.toString.call(n.process)?function(e){p.nextTick(function(){h(e)})}:function(){if(n.postMessage&&!n.importScripts){var e=!0,t=n.onmessage;return n.onmessage=function(){e=!1},n.postMessage("","*"),n.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",e=function(e){e.source===n&&"string"==typeof e.data&&0===e.data.indexOf(a)&&h(+e.data.slice(a.length))},n.addEventListener?n.addEventListener("message",e,!1):n.attachEvent("onmessage",e),function(e){n.postMessage(a+e,"*")}):n.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){h(e.data)},function(e){t.port2.postMessage(e)}):u&&"onreadystatechange"in u.createElement("script")?(o=u.documentElement,function(e){var t=u.createElement("script");t.onreadystatechange=function(){h(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):function(e){setTimeout(h,0,e)},f.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n=this.length)return D.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},D.QueryLexer.prototype.width=function(){return this.pos-this.start},D.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},D.QueryLexer.prototype.backup=function(){this.pos-=1},D.QueryLexer.prototype.acceptDigitRun=function(){for(var e,t;47<(t=(e=this.next()).charCodeAt(0))&&t<58;);e!=D.QueryLexer.EOS&&this.backup()},D.QueryLexer.prototype.more=function(){return this.pos.admonition-title:before,.md-typeset .admonition>summary:before,.md-typeset .critic.comment:before,.md-typeset .footnote-backref,.md-typeset .task-list-control .task-list-indicator:before,.md-typeset details>.admonition-title:before,.md-typeset details>summary:before,.md-typeset summary:after{font-family:Material Icons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;text-transform:none;white-space:nowrap;speak:none;word-wrap:normal;direction:ltr}.md-content__icon,.md-footer-nav__button,.md-header-nav__button,.md-nav__button,.md-nav__title:before,.md-search-result__article--document:before{display:inline-block;margin:.2rem;padding:.4rem;font-size:1.2rem;cursor:pointer}.md-icon--arrow-back:before{content:""}.md-icon--arrow-forward:before{content:""}.md-icon--menu:before{content:""}.md-icon--search:before{content:""}[dir=rtl] .md-icon--arrow-back:before{content:""}[dir=rtl] .md-icon--arrow-forward:before{content:""}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body,input{color:rgba(0,0,0,.87);-webkit-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";font-family:Helvetica Neue,Helvetica,Arial,sans-serif}code,kbd,pre{color:rgba(0,0,0,.87);-webkit-font-feature-settings:"kern";font-feature-settings:"kern";font-family:Courier New,Courier,monospace}.md-typeset{font-size:.8rem;line-height:1.6;-webkit-print-color-adjust:exact}.md-typeset blockquote,.md-typeset ol,.md-typeset p,.md-typeset ul{margin:1em 0}.md-typeset h1{margin:0 0 2rem;color:rgba(0,0,0,.54);font-size:1.5625rem;line-height:1.3}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{margin:2rem 0 .8rem;font-size:1.25rem;line-height:1.4}.md-typeset h3{margin:1.6rem 0 .8rem;font-size:1rem;font-weight:400;letter-spacing:-.01em;line-height:1.5}.md-typeset h2+h3{margin-top:.8rem}.md-typeset h4{font-size:.8rem}.md-typeset h4,.md-typeset h5,.md-typeset h6{margin:.8rem 0;font-weight:700;letter-spacing:-.01em}.md-typeset h5,.md-typeset h6{color:rgba(0,0,0,.54);font-size:.64rem}.md-typeset h5{text-transform:uppercase}.md-typeset hr{margin:1.5em 0;border-bottom:.05rem dotted rgba(0,0,0,.26)}.md-typeset a{color:#5700ff;word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color .125s}.md-typeset a:active,.md-typeset a:hover{color:#00e290}.md-typeset code,.md-typeset pre{background-color:hsla(0,0%,92.5%,.5);color:#37474f;font-size:85%;direction:ltr}.md-typeset code{margin:0 .29412em;padding:.07353em 0;border-radius:.1rem;box-shadow:.29412em 0 0 hsla(0,0%,92.5%,.5),-.29412em 0 0 hsla(0,0%,92.5%,.5);word-break:break-word;-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset h1 code,.md-typeset h2 code,.md-typeset h3 code,.md-typeset h4 code,.md-typeset h5 code,.md-typeset h6 code{margin:0;background-color:transparent;box-shadow:none}.md-typeset a>code{margin:inherit;padding:inherit;border-radius:initial;background-color:inherit;color:inherit;box-shadow:none}.md-typeset pre{position:relative;margin:1em 0;border-radius:.1rem;line-height:1.4;-webkit-overflow-scrolling:touch}.md-typeset pre>code{display:block;margin:0;padding:.525rem .6rem;background-color:transparent;font-size:inherit;box-shadow:none;-webkit-box-decoration-break:slice;box-decoration-break:slice;overflow:auto}.md-typeset pre>code::-webkit-scrollbar{width:.2rem;height:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:#00e290}.md-typeset kbd{padding:0 .29412em;border-radius:.15rem;border:.05rem solid #c9c9c9;border-bottom-color:#bcbcbc;background-color:#fcfcfc;color:#555;font-size:85%;box-shadow:0 .05rem 0 #b0b0b0;word-break:break-word}.md-typeset mark{margin:0 .25em;padding:.0625em 0;border-radius:.1rem;background-color:rgba(255,235,59,.5);box-shadow:.25em 0 0 rgba(255,235,59,.5),-.25em 0 0 rgba(255,235,59,.5);word-break:break-word;-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset abbr{border-bottom:.05rem dotted rgba(0,0,0,.54);text-decoration:none;cursor:help}.md-typeset small{opacity:.75}.md-typeset sub,.md-typeset sup{margin-left:.07812em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.07812em;margin-left:0}.md-typeset blockquote{padding-left:.6rem;border-left:.2rem solid rgba(0,0,0,.26);color:rgba(0,0,0,.54)}[dir=rtl] .md-typeset blockquote{padding-right:.6rem;padding-left:0;border-right:.2rem solid rgba(0,0,0,.26);border-left:initial}.md-typeset ul{list-style-type:disc}.md-typeset ol,.md-typeset ul{margin-left:.625em;padding:0}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em;margin-left:0}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em;margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em;margin-left:0}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin:.5em 0 .5em .625em}[dir=rtl] .md-typeset ol li ol,[dir=rtl] .md-typeset ol li ul,[dir=rtl] .md-typeset ul li ol,[dir=rtl] .md-typeset ul li ul{margin-right:.625em;margin-left:0}.md-typeset dd{margin:1em 0 1em 1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em;margin-left:0}.md-typeset iframe,.md-typeset img,.md-typeset svg{max-width:100%}.md-typeset table:not([class]){box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2);display:inline-block;max-width:100%;border-radius:.1rem;font-size:.64rem;overflow:auto;-webkit-overflow-scrolling:touch}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) td:not([align]),[dir=rtl] .md-typeset table:not([class]) th:not([align]){text-align:right}.md-typeset table:not([class]) th{min-width:5rem;padding:.6rem .8rem;background-color:rgba(0,0,0,.54);color:#fff;vertical-align:top}.md-typeset table:not([class]) td{padding:.6rem .8rem;border-top:.05rem solid rgba(0,0,0,.07);vertical-align:top}.md-typeset table:not([class]) tr{transition:background-color .125s}.md-typeset table:not([class]) tr:hover{background-color:rgba(0,0,0,.035);box-shadow:inset 0 .05rem 0 #fff}.md-typeset table:not([class]) tr:first-child td{border-top:0}.md-typeset table:not([class]) a{word-break:normal}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;-webkit-overflow-scrolling:touch}.md-typeset .md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}.md-typeset .md-typeset__table table{display:table;width:100%;margin:0;overflow:hidden}html{font-size:125%;overflow-x:hidden}body,html{height:100%}body{position:relative;font-size:.5rem}hr{display:block;height:.05rem;padding:0;border:0}.md-svg{display:none}.md-grid{max-width:61rem;margin-right:auto;margin-left:auto}.md-container,.md-main{overflow:auto}.md-container{display:table;width:100%;height:100%;padding-top:2.4rem;table-layout:fixed}.md-main{display:table-row;height:100%}.md-main__inner{height:100%;padding-top:1.5rem;padding-bottom:.05rem}.md-toggle{display:none}.md-overlay{position:fixed;top:0;width:0;height:0;transition:width 0s .25s,height 0s .25s,opacity .25s;background-color:rgba(0,0,0,.54);opacity:0;z-index:3}.md-flex{display:table}.md-flex__cell{display:table-cell;position:relative;vertical-align:top}.md-flex__cell--shrink{width:0}.md-flex__cell--stretch{display:table;width:100%;table-layout:fixed}.md-flex__ellipsis{display:table-cell;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.md-skip{position:fixed;width:.05rem;height:.05rem;margin:.5rem;padding:.3rem .5rem;-webkit-transform:translateY(.4rem);transform:translateY(.4rem);border-radius:.1rem;background-color:rgba(0,0,0,.87);color:#fff;font-size:.64rem;opacity:0;overflow:hidden}.md-skip:focus{width:auto;height:auto;clip:auto;-webkit-transform:translateX(0);transform:translateX(0);transition:opacity .175s 75ms,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .175s 75ms;transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .175s 75ms,-webkit-transform .25s cubic-bezier(.4,0,.2,1);opacity:1;z-index:10}@page{margin:25mm}.md-clipboard{position:absolute;top:.3rem;right:.3rem;width:1.4rem;height:1.4rem;border-radius:.1rem;font-size:.8rem;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;backface-visibility:hidden}.md-clipboard:before{transition:color .25s,opacity .25s;color:rgba(0,0,0,.07);content:"\E14D"}.codehilite:hover .md-clipboard:before,.md-typeset .highlight:hover .md-clipboard:before,pre:hover .md-clipboard:before{color:rgba(0,0,0,.54)}.md-clipboard:focus:before,.md-clipboard:hover:before{color:#00e290}.md-clipboard__message{display:block;position:absolute;top:0;right:1.7rem;padding:.3rem .5rem;-webkit-transform:translateX(.4rem);transform:translateX(.4rem);transition:opacity .175s,-webkit-transform .25s cubic-bezier(.9,.1,.9,0);transition:transform .25s cubic-bezier(.9,.1,.9,0),opacity .175s;transition:transform .25s cubic-bezier(.9,.1,.9,0),opacity .175s,-webkit-transform .25s cubic-bezier(.9,.1,.9,0);border-radius:.1rem;background-color:rgba(0,0,0,.54);color:#fff;font-size:.64rem;white-space:nowrap;opacity:0;pointer-events:none}.md-clipboard__message--active{-webkit-transform:translateX(0);transform:translateX(0);transition:opacity .175s 75ms,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .175s 75ms;transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .175s 75ms,-webkit-transform .25s cubic-bezier(.4,0,.2,1);opacity:1;pointer-events:auto}.md-clipboard__message:before{content:attr(aria-label)}.md-clipboard__message:after{display:block;position:absolute;top:50%;right:-.2rem;width:0;margin-top:-.2rem;border-color:transparent rgba(0,0,0,.54);border-style:solid;border-width:.2rem 0 .2rem .2rem;content:""}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}.md-content__inner:before{display:block;height:.4rem;content:""}.md-content__inner>:last-child{margin-bottom:0}.md-content__icon{position:relative;margin:.4rem 0;padding:0;float:right}.md-typeset .md-content__icon{color:rgba(0,0,0,.26)}.md-header{position:fixed;top:0;right:0;left:0;height:2.4rem;transition:background-color .25s,color .25s;background-color:#5700ff;color:#fff;box-shadow:none;z-index:2;-webkit-backface-visibility:hidden;backface-visibility:hidden}.no-js .md-header{transition:none;box-shadow:none}.md-header[data-md-state=shadow]{transition:background-color .25s,color .25s,box-shadow .25s;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.md-header-nav{padding:0 .2rem}.md-header-nav__button{position:relative;transition:opacity .25s;z-index:1}.md-header-nav__button:hover{opacity:.7}.md-header-nav__button.md-logo *{display:block}.no-js .md-header-nav__button.md-icon--search{display:none}.md-header-nav__topic{display:block;position:absolute;transition:opacity .15s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.md-header-nav__topic+.md-header-nav__topic{-webkit-transform:translateX(1.25rem);transform:translateX(1.25rem);transition:opacity .15s,-webkit-transform .4s cubic-bezier(1,.7,.1,.1);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s,-webkit-transform .4s cubic-bezier(1,.7,.1,.1);opacity:0;z-index:-1;pointer-events:none}[dir=rtl] .md-header-nav__topic+.md-header-nav__topic{-webkit-transform:translateX(-1.25rem);transform:translateX(-1.25rem)}.no-js .md-header-nav__topic{position:static}.no-js .md-header-nav__topic+.md-header-nav__topic{display:none}.md-header-nav__title{padding:0 1rem;font-size:.9rem;line-height:2.4rem}.md-header-nav__title[data-md-state=active] .md-header-nav__topic{-webkit-transform:translateX(-1.25rem);transform:translateX(-1.25rem);transition:opacity .15s,-webkit-transform .4s cubic-bezier(1,.7,.1,.1);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s,-webkit-transform .4s cubic-bezier(1,.7,.1,.1);opacity:0;z-index:-1;pointer-events:none}[dir=rtl] .md-header-nav__title[data-md-state=active] .md-header-nav__topic{-webkit-transform:translateX(1.25rem);transform:translateX(1.25rem)}.md-header-nav__title[data-md-state=active] .md-header-nav__topic+.md-header-nav__topic{-webkit-transform:translateX(0);transform:translateX(0);transition:opacity .15s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);opacity:1;z-index:0;pointer-events:auto}.md-header-nav__source{display:none}.md-hero{transition:background .25s;background-color:#5700ff;color:#fff;font-size:1rem;overflow:hidden}.md-hero__inner{margin-top:1rem;padding:.8rem .8rem .4rem;transition:opacity .25s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition-delay:.1s}[data-md-state=hidden] .md-hero__inner{pointer-events:none;-webkit-transform:translateY(.625rem);transform:translateY(.625rem);transition:opacity .1s 0s,-webkit-transform 0s .4s;transition:transform 0s .4s,opacity .1s 0s;transition:transform 0s .4s,opacity .1s 0s,-webkit-transform 0s .4s;opacity:0}.md-hero--expand .md-hero__inner{margin-bottom:1.2rem}.md-footer-nav{background-color:rgba(0,0,0,.87);color:#fff}.md-footer-nav__inner{padding:.2rem;overflow:auto}.md-footer-nav__link{padding-top:1.4rem;padding-bottom:.4rem;transition:opacity .25s}.md-footer-nav__link:hover{opacity:.7}.md-footer-nav__link--prev{width:25%;float:left}[dir=rtl] .md-footer-nav__link--prev{float:right}.md-footer-nav__link--next{width:75%;float:right;text-align:right}[dir=rtl] .md-footer-nav__link--next{float:left;text-align:left}.md-footer-nav__button{transition:background .25s}.md-footer-nav__title{position:relative;padding:0 1rem;font-size:.9rem;line-height:2.4rem}.md-footer-nav__direction{position:absolute;right:0;left:0;margin-top:-1rem;padding:0 1rem;color:hsla(0,0%,100%,.7);font-size:.75rem}.md-footer-meta{background-color:rgba(0,0,0,.895)}.md-footer-meta__inner{padding:.2rem;overflow:auto}.md-footer-meta__help{background-color:#00e290}html .md-footer-meta.md-typeset .md-footer-meta__help a{margin:0 .6rem;color:rgba(0,0,0,.54)}html .md-footer-meta.md-typeset .md-footer-meta__help a:focus,html .md-footer-meta.md-typeset .md-footer-meta__help a:hover{color:#fff}html .md-footer-meta.md-typeset a{color:hsla(0,0%,100%,.7)}html .md-footer-meta.md-typeset a:focus,html .md-footer-meta.md-typeset a:hover{color:#fff}.md-footer-copyright{margin:0 .6rem;padding:.4rem 0;color:hsla(0,0%,100%,.3);font-size:.64rem}.md-footer-copyright__highlight{color:hsla(0,0%,100%,.7)}.md-footer-social{margin:0 .4rem;padding:.2rem 0 .6rem}.md-footer-social__link{display:inline-block;width:1.6rem;height:1.6rem;font-size:.8rem;text-align:center}.md-footer-social__link:before{line-height:1.9}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{display:block;padding:0 .6rem;font-weight:700;text-overflow:ellipsis;overflow:hidden}.md-nav__title:before{display:none;content:"\E5C4"}[dir=rtl] .md-nav__title:before{content:"\E5C8"}.md-nav__title .md-nav__button{display:none}.md-nav__list{margin:0;padding:0;list-style:none}.md-nav__item{padding:0 .6rem}.md-nav__item:last-child{padding-bottom:.6rem}.md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-right:.6rem;padding-left:0}.md-nav__item .md-nav__item:last-child{padding-bottom:0}.md-nav__button img{width:100%;height:auto}.md-nav__link{display:block;margin-top:.625em;transition:color .125s;text-overflow:ellipsis;cursor:pointer;overflow:hidden}.md-nav__item--nested>.md-nav__link:after{content:"\E313"}html .md-nav__link[for=__toc],html .md-nav__link[for=__toc]+.md-nav__link:after,html .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__link[data-md-state=blur]{color:rgba(0,0,0,.54)}.md-nav__link--active,.md-nav__link:active{color:#5700ff}.md-nav__item--nested>.md-nav__link{color:inherit}.md-nav__link:focus,.md-nav__link:hover{color:#00e290}.md-nav__source,.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}.md-search__form{position:relative}.md-search__input{position:relative;padding:0 2.2rem 0 3.6rem;text-overflow:ellipsis;z-index:2}[dir=rtl] .md-search__input{padding:0 3.6rem 0 2.2rem}.md-search__input::-webkit-input-placeholder{transition:color .25s cubic-bezier(.1,.7,.1,1)}.md-search__input:-ms-input-placeholder{transition:color .25s cubic-bezier(.1,.7,.1,1)}.md-search__input::-ms-input-placeholder{transition:color .25s cubic-bezier(.1,.7,.1,1)}.md-search__input::placeholder{transition:color .25s cubic-bezier(.1,.7,.1,1)}.md-search__input::-webkit-input-placeholder,.md-search__input~.md-search__icon{color:rgba(0,0,0,.54)}.md-search__input:-ms-input-placeholder,.md-search__input~.md-search__icon{color:rgba(0,0,0,.54)}.md-search__input::-ms-input-placeholder,.md-search__input~.md-search__icon{color:rgba(0,0,0,.54)}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:rgba(0,0,0,.54)}.md-search__input::-ms-clear{display:none}.md-search__icon{position:absolute;transition:color .25s cubic-bezier(.1,.7,.1,1),opacity .25s;font-size:1.2rem;cursor:pointer;z-index:2}.md-search__icon:hover{opacity:.7}.md-search__icon[for=__search]{top:.3rem;left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem;left:auto}.md-search__icon[for=__search]:before{content:"\E8B6"}.md-search__icon[type=reset]{top:.3rem;right:.5rem;-webkit-transform:scale(.125);transform:scale(.125);transition:opacity .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s;transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1);opacity:0}[dir=rtl] .md-search__icon[type=reset]{right:auto;left:.5rem}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__icon[type=reset]{-webkit-transform:scale(1);transform:scale(1);opacity:1}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__icon[type=reset]:hover{opacity:.7}.md-search__output{position:absolute;width:100%;border-radius:0 0 .1rem .1rem;overflow:hidden;z-index:1}.md-search__scrollwrap{height:100%;background-color:#fff;box-shadow:inset 0 .05rem 0 rgba(0,0,0,.07);overflow-y:auto;-webkit-overflow-scrolling:touch}.md-search-result{color:rgba(0,0,0,.87);word-break:break-word}.md-search-result__meta{padding:0 .8rem;background-color:rgba(0,0,0,.07);color:rgba(0,0,0,.54);font-size:.64rem;line-height:1.8rem}.md-search-result__list{margin:0;padding:0;border-top:.05rem solid rgba(0,0,0,.07);list-style:none}.md-search-result__item{box-shadow:0 -.05rem 0 rgba(0,0,0,.07)}.md-search-result__link{display:block;transition:background .25s;outline:0;overflow:hidden}.md-search-result__link:hover,.md-search-result__link[data-md-state=active]{background-color:rgba(0,226,144,.1)}.md-search-result__link:hover .md-search-result__article:before,.md-search-result__link[data-md-state=active] .md-search-result__article:before{opacity:.7}.md-search-result__link:last-child .md-search-result__teaser{margin-bottom:.6rem}.md-search-result__article{position:relative;padding:0 .8rem;overflow:auto}.md-search-result__article--document:before{position:absolute;left:0;margin:.1rem;transition:opacity .25s;color:rgba(0,0,0,.54);content:"\E880"}[dir=rtl] .md-search-result__article--document:before{right:0;left:auto}.md-search-result__article--document .md-search-result__title{margin:.55rem 0;font-size:.8rem;font-weight:400;line-height:1.4}.md-search-result__title{margin:.5em 0;font-size:.64rem;font-weight:700;line-height:1.4}.md-search-result__teaser{display:-webkit-box;max-height:1.65rem;margin:.5em 0;color:rgba(0,0,0,.54);font-size:.64rem;line-height:1.4;text-overflow:ellipsis;overflow:hidden;-webkit-line-clamp:2}.md-search-result em{font-style:normal;font-weight:700;text-decoration:underline}.md-sidebar{position:absolute;width:12.1rem;padding:1.2rem 0;overflow:hidden}.md-sidebar[data-md-state=lock]{position:fixed;top:2.4rem}.md-sidebar--secondary{display:none}.md-sidebar__scrollwrap{max-height:100%;margin:0 .2rem;overflow-y:auto;-webkit-backface-visibility:hidden;backface-visibility:hidden}.md-sidebar__scrollwrap::-webkit-scrollbar{width:.2rem;height:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:#00e290}@-webkit-keyframes md-source__facts--done{0%{height:0}to{height:.65rem}}@keyframes md-source__facts--done{0%{height:0}to{height:.65rem}}@-webkit-keyframes md-source__fact--done{0%{-webkit-transform:translateY(100%);transform:translateY(100%);opacity:0}50%{opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes md-source__fact--done{0%{-webkit-transform:translateY(100%);transform:translateY(100%);opacity:0}50%{opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.md-source{display:block;padding-right:.6rem;transition:opacity .25s;font-size:.65rem;line-height:1.2;white-space:nowrap}[dir=rtl] .md-source{padding-right:0;padding-left:.6rem}.md-source:hover{opacity:.7}.md-source:after,.md-source__icon{display:inline-block;height:2.4rem;content:"";vertical-align:middle}.md-source__icon{width:2.4rem}.md-source__icon svg{width:1.2rem;height:1.2rem;margin-top:.6rem;margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem;margin-left:0}.md-source__icon+.md-source__repository{margin-left:-2.2rem;padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2.2rem;margin-left:0;padding-right:2rem;padding-left:0}.md-source__repository{display:inline-block;max-width:100%;margin-left:.6rem;font-weight:700;text-overflow:ellipsis;overflow:hidden;vertical-align:middle}.md-source__facts{margin:0;padding:0;font-size:.55rem;font-weight:700;list-style-type:none;opacity:.75;overflow:hidden}[data-md-state=done] .md-source__facts{-webkit-animation:md-source__facts--done .25s ease-in;animation:md-source__facts--done .25s ease-in}.md-source__fact{float:left}[dir=rtl] .md-source__fact{float:right}[data-md-state=done] .md-source__fact{-webkit-animation:md-source__fact--done .4s ease-out;animation:md-source__fact--done .4s ease-out}.md-source__fact:before{margin:0 .1rem;content:"\00B7"}.md-source__fact:first-child:before{display:none}.md-source-file{display:inline-block;margin:1em .5em 1em 0;padding-right:.25rem;border-radius:.1rem;background-color:rgba(0,0,0,.07);font-size:.64rem;list-style-type:none;cursor:pointer;overflow:hidden}.md-source-file:before{display:inline-block;margin-right:.25rem;padding:.25rem;background-color:rgba(0,0,0,.26);color:#fff;font-size:.8rem;content:"\E86F";vertical-align:middle}html .md-source-file{transition:background .4s,color .4s,box-shadow .4s cubic-bezier(.4,0,.2,1)}html .md-source-file:before{transition:inherit}html body .md-typeset .md-source-file{color:rgba(0,0,0,.54)}.md-source-file:hover{box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36)}.md-source-file:hover:before{background-color:#00e290}.md-tabs{width:100%;transition:background .25s;background-color:#5700ff;color:#fff;overflow:auto}.md-tabs__list{margin:0 0 0 .2rem;padding:0;list-style:none;white-space:nowrap}.md-tabs__item{display:inline-block;height:2.4rem;padding-right:.6rem;padding-left:.6rem}.md-tabs__link{display:block;margin-top:.8rem;transition:opacity .25s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s,-webkit-transform .4s cubic-bezier(.1,.7,.1,1);font-size:.7rem;opacity:.7}.md-tabs__link--active,.md-tabs__link:hover{color:inherit;opacity:1}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:.02s}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:.04s}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:.06s}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:.08s}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[data-md-state=hidden]{pointer-events:none}.md-tabs[data-md-state=hidden] .md-tabs__link{-webkit-transform:translateY(50%);transform:translateY(50%);transition:color .25s,opacity .1s,-webkit-transform 0s .4s;transition:color .25s,transform 0s .4s,opacity .1s;transition:color .25s,transform 0s .4s,opacity .1s,-webkit-transform 0s .4s;opacity:0}.md-typeset .admonition,.md-typeset details{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2);position:relative;margin:1.5625em 0;padding:0 .6rem;border-left:.2rem solid #448aff;border-radius:.1rem;font-size:.64rem;overflow:auto}[dir=rtl] .md-typeset .admonition,[dir=rtl] .md-typeset details{border-right:.2rem solid #448aff;border-left:none}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}.md-typeset .admonition .admonition,.md-typeset .admonition details,.md-typeset details .admonition,.md-typeset details details{margin:1em 0}.md-typeset .admonition>.admonition-title,.md-typeset .admonition>summary,.md-typeset details>.admonition-title,.md-typeset details>summary{margin:0 -.6rem;padding:.4rem .6rem .4rem 2rem;border-bottom:.05rem solid rgba(68,138,255,.1);background-color:rgba(68,138,255,.1);font-weight:700}[dir=rtl] .md-typeset .admonition>.admonition-title,[dir=rtl] .md-typeset .admonition>summary,[dir=rtl] .md-typeset details>.admonition-title,[dir=rtl] .md-typeset details>summary{padding:.4rem 2rem .4rem .6rem}.md-typeset .admonition>.admonition-title:last-child,.md-typeset .admonition>summary:last-child,.md-typeset details>.admonition-title:last-child,.md-typeset details>summary:last-child{margin-bottom:0}.md-typeset .admonition>.admonition-title:before,.md-typeset .admonition>summary:before,.md-typeset details>.admonition-title:before,.md-typeset details>summary:before{position:absolute;left:.6rem;color:#448aff;font-size:1rem;content:"\E3C9"}[dir=rtl] .md-typeset .admonition>.admonition-title:before,[dir=rtl] .md-typeset .admonition>summary:before,[dir=rtl] .md-typeset details>.admonition-title:before,[dir=rtl] .md-typeset details>summary:before{right:.6rem;left:auto}.md-typeset .admonition.abstract,.md-typeset .admonition.summary,.md-typeset .admonition.tldr,.md-typeset details.abstract,.md-typeset details.summary,.md-typeset details.tldr{border-left-color:#00b0ff}[dir=rtl] .md-typeset .admonition.abstract,[dir=rtl] .md-typeset .admonition.summary,[dir=rtl] .md-typeset .admonition.tldr,[dir=rtl] .md-typeset details.abstract,[dir=rtl] .md-typeset details.summary,[dir=rtl] .md-typeset details.tldr{border-right-color:#00b0ff}.md-typeset .admonition.abstract>.admonition-title,.md-typeset .admonition.abstract>summary,.md-typeset .admonition.summary>.admonition-title,.md-typeset .admonition.summary>summary,.md-typeset .admonition.tldr>.admonition-title,.md-typeset .admonition.tldr>summary,.md-typeset details.abstract>.admonition-title,.md-typeset details.abstract>summary,.md-typeset details.summary>.admonition-title,.md-typeset details.summary>summary,.md-typeset details.tldr>.admonition-title,.md-typeset details.tldr>summary{border-bottom-color:rgba(0,176,255,.1);background-color:rgba(0,176,255,.1)}.md-typeset .admonition.abstract>.admonition-title:before,.md-typeset .admonition.abstract>summary:before,.md-typeset .admonition.summary>.admonition-title:before,.md-typeset .admonition.summary>summary:before,.md-typeset .admonition.tldr>.admonition-title:before,.md-typeset .admonition.tldr>summary:before,.md-typeset details.abstract>.admonition-title:before,.md-typeset details.abstract>summary:before,.md-typeset details.summary>.admonition-title:before,.md-typeset details.summary>summary:before,.md-typeset details.tldr>.admonition-title:before,.md-typeset details.tldr>summary:before{color:#00b0ff;content:""}.md-typeset .admonition.info,.md-typeset .admonition.todo,.md-typeset details.info,.md-typeset details.todo{border-left-color:#00b8d4}[dir=rtl] .md-typeset .admonition.info,[dir=rtl] .md-typeset .admonition.todo,[dir=rtl] .md-typeset details.info,[dir=rtl] .md-typeset details.todo{border-right-color:#00b8d4}.md-typeset .admonition.info>.admonition-title,.md-typeset .admonition.info>summary,.md-typeset .admonition.todo>.admonition-title,.md-typeset .admonition.todo>summary,.md-typeset details.info>.admonition-title,.md-typeset details.info>summary,.md-typeset details.todo>.admonition-title,.md-typeset details.todo>summary{border-bottom-color:rgba(0,184,212,.1);background-color:rgba(0,184,212,.1)}.md-typeset .admonition.info>.admonition-title:before,.md-typeset .admonition.info>summary:before,.md-typeset .admonition.todo>.admonition-title:before,.md-typeset .admonition.todo>summary:before,.md-typeset details.info>.admonition-title:before,.md-typeset details.info>summary:before,.md-typeset details.todo>.admonition-title:before,.md-typeset details.todo>summary:before{color:#00b8d4;content:""}.md-typeset .admonition.hint,.md-typeset .admonition.important,.md-typeset .admonition.tip,.md-typeset details.hint,.md-typeset details.important,.md-typeset details.tip{border-left-color:#00bfa5}[dir=rtl] .md-typeset .admonition.hint,[dir=rtl] .md-typeset .admonition.important,[dir=rtl] .md-typeset .admonition.tip,[dir=rtl] .md-typeset details.hint,[dir=rtl] .md-typeset details.important,[dir=rtl] .md-typeset details.tip{border-right-color:#00bfa5}.md-typeset .admonition.hint>.admonition-title,.md-typeset .admonition.hint>summary,.md-typeset .admonition.important>.admonition-title,.md-typeset .admonition.important>summary,.md-typeset .admonition.tip>.admonition-title,.md-typeset .admonition.tip>summary,.md-typeset details.hint>.admonition-title,.md-typeset details.hint>summary,.md-typeset details.important>.admonition-title,.md-typeset details.important>summary,.md-typeset details.tip>.admonition-title,.md-typeset details.tip>summary{border-bottom-color:rgba(0,191,165,.1);background-color:rgba(0,191,165,.1)}.md-typeset .admonition.hint>.admonition-title:before,.md-typeset .admonition.hint>summary:before,.md-typeset .admonition.important>.admonition-title:before,.md-typeset .admonition.important>summary:before,.md-typeset .admonition.tip>.admonition-title:before,.md-typeset .admonition.tip>summary:before,.md-typeset details.hint>.admonition-title:before,.md-typeset details.hint>summary:before,.md-typeset details.important>.admonition-title:before,.md-typeset details.important>summary:before,.md-typeset details.tip>.admonition-title:before,.md-typeset details.tip>summary:before{color:#00bfa5;content:""}.md-typeset .admonition.check,.md-typeset .admonition.done,.md-typeset .admonition.success,.md-typeset details.check,.md-typeset details.done,.md-typeset details.success{border-left-color:#00c853}[dir=rtl] .md-typeset .admonition.check,[dir=rtl] .md-typeset .admonition.done,[dir=rtl] .md-typeset .admonition.success,[dir=rtl] .md-typeset details.check,[dir=rtl] .md-typeset details.done,[dir=rtl] .md-typeset details.success{border-right-color:#00c853}.md-typeset .admonition.check>.admonition-title,.md-typeset .admonition.check>summary,.md-typeset .admonition.done>.admonition-title,.md-typeset .admonition.done>summary,.md-typeset .admonition.success>.admonition-title,.md-typeset .admonition.success>summary,.md-typeset details.check>.admonition-title,.md-typeset details.check>summary,.md-typeset details.done>.admonition-title,.md-typeset details.done>summary,.md-typeset details.success>.admonition-title,.md-typeset details.success>summary{border-bottom-color:rgba(0,200,83,.1);background-color:rgba(0,200,83,.1)}.md-typeset .admonition.check>.admonition-title:before,.md-typeset .admonition.check>summary:before,.md-typeset .admonition.done>.admonition-title:before,.md-typeset .admonition.done>summary:before,.md-typeset .admonition.success>.admonition-title:before,.md-typeset .admonition.success>summary:before,.md-typeset details.check>.admonition-title:before,.md-typeset details.check>summary:before,.md-typeset details.done>.admonition-title:before,.md-typeset details.done>summary:before,.md-typeset details.success>.admonition-title:before,.md-typeset details.success>summary:before{color:#00c853;content:""}.md-typeset .admonition.faq,.md-typeset .admonition.help,.md-typeset .admonition.question,.md-typeset details.faq,.md-typeset details.help,.md-typeset details.question{border-left-color:#64dd17}[dir=rtl] .md-typeset .admonition.faq,[dir=rtl] .md-typeset .admonition.help,[dir=rtl] .md-typeset .admonition.question,[dir=rtl] .md-typeset details.faq,[dir=rtl] .md-typeset details.help,[dir=rtl] .md-typeset details.question{border-right-color:#64dd17}.md-typeset .admonition.faq>.admonition-title,.md-typeset .admonition.faq>summary,.md-typeset .admonition.help>.admonition-title,.md-typeset .admonition.help>summary,.md-typeset .admonition.question>.admonition-title,.md-typeset .admonition.question>summary,.md-typeset details.faq>.admonition-title,.md-typeset details.faq>summary,.md-typeset details.help>.admonition-title,.md-typeset details.help>summary,.md-typeset details.question>.admonition-title,.md-typeset details.question>summary{border-bottom-color:rgba(100,221,23,.1);background-color:rgba(100,221,23,.1)}.md-typeset .admonition.faq>.admonition-title:before,.md-typeset .admonition.faq>summary:before,.md-typeset .admonition.help>.admonition-title:before,.md-typeset .admonition.help>summary:before,.md-typeset .admonition.question>.admonition-title:before,.md-typeset .admonition.question>summary:before,.md-typeset details.faq>.admonition-title:before,.md-typeset details.faq>summary:before,.md-typeset details.help>.admonition-title:before,.md-typeset details.help>summary:before,.md-typeset details.question>.admonition-title:before,.md-typeset details.question>summary:before{color:#64dd17;content:""}.md-typeset .admonition.attention,.md-typeset .admonition.caution,.md-typeset .admonition.warning,.md-typeset details.attention,.md-typeset details.caution,.md-typeset details.warning{border-left-color:#ff9100}[dir=rtl] .md-typeset .admonition.attention,[dir=rtl] .md-typeset .admonition.caution,[dir=rtl] .md-typeset .admonition.warning,[dir=rtl] .md-typeset details.attention,[dir=rtl] .md-typeset details.caution,[dir=rtl] .md-typeset details.warning{border-right-color:#ff9100}.md-typeset .admonition.attention>.admonition-title,.md-typeset .admonition.attention>summary,.md-typeset .admonition.caution>.admonition-title,.md-typeset .admonition.caution>summary,.md-typeset .admonition.warning>.admonition-title,.md-typeset .admonition.warning>summary,.md-typeset details.attention>.admonition-title,.md-typeset details.attention>summary,.md-typeset details.caution>.admonition-title,.md-typeset details.caution>summary,.md-typeset details.warning>.admonition-title,.md-typeset details.warning>summary{border-bottom-color:rgba(255,145,0,.1);background-color:rgba(255,145,0,.1)}.md-typeset .admonition.attention>.admonition-title:before,.md-typeset .admonition.attention>summary:before,.md-typeset .admonition.caution>.admonition-title:before,.md-typeset .admonition.caution>summary:before,.md-typeset .admonition.warning>.admonition-title:before,.md-typeset .admonition.warning>summary:before,.md-typeset details.attention>.admonition-title:before,.md-typeset details.attention>summary:before,.md-typeset details.caution>.admonition-title:before,.md-typeset details.caution>summary:before,.md-typeset details.warning>.admonition-title:before,.md-typeset details.warning>summary:before{color:#ff9100;content:""}.md-typeset .admonition.fail,.md-typeset .admonition.failure,.md-typeset .admonition.missing,.md-typeset details.fail,.md-typeset details.failure,.md-typeset details.missing{border-left-color:#ff5252}[dir=rtl] .md-typeset .admonition.fail,[dir=rtl] .md-typeset .admonition.failure,[dir=rtl] .md-typeset .admonition.missing,[dir=rtl] .md-typeset details.fail,[dir=rtl] .md-typeset details.failure,[dir=rtl] .md-typeset details.missing{border-right-color:#ff5252}.md-typeset .admonition.fail>.admonition-title,.md-typeset .admonition.fail>summary,.md-typeset .admonition.failure>.admonition-title,.md-typeset .admonition.failure>summary,.md-typeset .admonition.missing>.admonition-title,.md-typeset .admonition.missing>summary,.md-typeset details.fail>.admonition-title,.md-typeset details.fail>summary,.md-typeset details.failure>.admonition-title,.md-typeset details.failure>summary,.md-typeset details.missing>.admonition-title,.md-typeset details.missing>summary{border-bottom-color:rgba(255,82,82,.1);background-color:rgba(255,82,82,.1)}.md-typeset .admonition.fail>.admonition-title:before,.md-typeset .admonition.fail>summary:before,.md-typeset .admonition.failure>.admonition-title:before,.md-typeset .admonition.failure>summary:before,.md-typeset .admonition.missing>.admonition-title:before,.md-typeset .admonition.missing>summary:before,.md-typeset details.fail>.admonition-title:before,.md-typeset details.fail>summary:before,.md-typeset details.failure>.admonition-title:before,.md-typeset details.failure>summary:before,.md-typeset details.missing>.admonition-title:before,.md-typeset details.missing>summary:before{color:#ff5252;content:""}.md-typeset .admonition.danger,.md-typeset .admonition.error,.md-typeset details.danger,.md-typeset details.error{border-left-color:#ff1744}[dir=rtl] .md-typeset .admonition.danger,[dir=rtl] .md-typeset .admonition.error,[dir=rtl] .md-typeset details.danger,[dir=rtl] .md-typeset details.error{border-right-color:#ff1744}.md-typeset .admonition.danger>.admonition-title,.md-typeset .admonition.danger>summary,.md-typeset .admonition.error>.admonition-title,.md-typeset .admonition.error>summary,.md-typeset details.danger>.admonition-title,.md-typeset details.danger>summary,.md-typeset details.error>.admonition-title,.md-typeset details.error>summary{border-bottom-color:rgba(255,23,68,.1);background-color:rgba(255,23,68,.1)}.md-typeset .admonition.danger>.admonition-title:before,.md-typeset .admonition.danger>summary:before,.md-typeset .admonition.error>.admonition-title:before,.md-typeset .admonition.error>summary:before,.md-typeset details.danger>.admonition-title:before,.md-typeset details.danger>summary:before,.md-typeset details.error>.admonition-title:before,.md-typeset details.error>summary:before{color:#ff1744;content:""}.md-typeset .admonition.bug,.md-typeset details.bug{border-left-color:#f50057}[dir=rtl] .md-typeset .admonition.bug,[dir=rtl] .md-typeset details.bug{border-right-color:#f50057}.md-typeset .admonition.bug>.admonition-title,.md-typeset .admonition.bug>summary,.md-typeset details.bug>.admonition-title,.md-typeset details.bug>summary{border-bottom-color:rgba(245,0,87,.1);background-color:rgba(245,0,87,.1)}.md-typeset .admonition.bug>.admonition-title:before,.md-typeset .admonition.bug>summary:before,.md-typeset details.bug>.admonition-title:before,.md-typeset details.bug>summary:before{color:#f50057;content:""}.md-typeset .admonition.example,.md-typeset details.example{border-left-color:#651fff}[dir=rtl] .md-typeset .admonition.example,[dir=rtl] .md-typeset details.example{border-right-color:#651fff}.md-typeset .admonition.example>.admonition-title,.md-typeset .admonition.example>summary,.md-typeset details.example>.admonition-title,.md-typeset details.example>summary{border-bottom-color:rgba(101,31,255,.1);background-color:rgba(101,31,255,.1)}.md-typeset .admonition.example>.admonition-title:before,.md-typeset .admonition.example>summary:before,.md-typeset details.example>.admonition-title:before,.md-typeset details.example>summary:before{color:#651fff;content:""}.md-typeset .admonition.cite,.md-typeset .admonition.quote,.md-typeset details.cite,.md-typeset details.quote{border-left-color:#9e9e9e}[dir=rtl] .md-typeset .admonition.cite,[dir=rtl] .md-typeset .admonition.quote,[dir=rtl] .md-typeset details.cite,[dir=rtl] .md-typeset details.quote{border-right-color:#9e9e9e}.md-typeset .admonition.cite>.admonition-title,.md-typeset .admonition.cite>summary,.md-typeset .admonition.quote>.admonition-title,.md-typeset .admonition.quote>summary,.md-typeset details.cite>.admonition-title,.md-typeset details.cite>summary,.md-typeset details.quote>.admonition-title,.md-typeset details.quote>summary{border-bottom-color:hsla(0,0%,62%,.1);background-color:hsla(0,0%,62%,.1)}.md-typeset .admonition.cite>.admonition-title:before,.md-typeset .admonition.cite>summary:before,.md-typeset .admonition.quote>.admonition-title:before,.md-typeset .admonition.quote>summary:before,.md-typeset details.cite>.admonition-title:before,.md-typeset details.cite>summary:before,.md-typeset details.quote>.admonition-title:before,.md-typeset details.quote>summary:before{color:#9e9e9e;content:""}.codehilite .o,.codehilite .ow,.md-typeset .highlight .o,.md-typeset .highlight .ow{color:inherit}.codehilite .ge,.md-typeset .highlight .ge{color:#000}.codehilite .gr,.md-typeset .highlight .gr{color:#a00}.codehilite .gh,.md-typeset .highlight .gh{color:#999}.codehilite .go,.md-typeset .highlight .go{color:#888}.codehilite .gp,.md-typeset .highlight .gp{color:#555}.codehilite .gs,.md-typeset .highlight .gs{color:inherit}.codehilite .gu,.md-typeset .highlight .gu{color:#aaa}.codehilite .gt,.md-typeset .highlight .gt{color:#a00}.codehilite .gd,.md-typeset .highlight .gd{background-color:#fdd}.codehilite .gi,.md-typeset .highlight .gi{background-color:#dfd}.codehilite .k,.md-typeset .highlight .k{color:#3b78e7}.codehilite .kc,.md-typeset .highlight .kc{color:#a71d5d}.codehilite .kd,.codehilite .kn,.md-typeset .highlight .kd,.md-typeset .highlight .kn{color:#3b78e7}.codehilite .kp,.md-typeset .highlight .kp{color:#a71d5d}.codehilite .kr,.codehilite .kt,.md-typeset .highlight .kr,.md-typeset .highlight .kt{color:#3e61a2}.codehilite .c,.codehilite .cm,.md-typeset .highlight .c,.md-typeset .highlight .cm{color:#999}.codehilite .cp,.md-typeset .highlight .cp{color:#666}.codehilite .c1,.codehilite .ch,.codehilite .cs,.md-typeset .highlight .c1,.md-typeset .highlight .ch,.md-typeset .highlight .cs{color:#999}.codehilite .na,.codehilite .nb,.md-typeset .highlight .na,.md-typeset .highlight .nb{color:#c2185b}.codehilite .bp,.md-typeset .highlight .bp{color:#3e61a2}.codehilite .nc,.md-typeset .highlight .nc{color:#c2185b}.codehilite .no,.md-typeset .highlight .no{color:#3e61a2}.codehilite .nd,.codehilite .ni,.md-typeset .highlight .nd,.md-typeset .highlight .ni{color:#666}.codehilite .ne,.codehilite .nf,.md-typeset .highlight .ne,.md-typeset .highlight .nf{color:#c2185b}.codehilite .nl,.md-typeset .highlight .nl{color:#3b5179}.codehilite .nn,.md-typeset .highlight .nn{color:#ec407a}.codehilite .nt,.md-typeset .highlight .nt{color:#3b78e7}.codehilite .nv,.codehilite .vc,.codehilite .vg,.codehilite .vi,.md-typeset .highlight .nv,.md-typeset .highlight .vc,.md-typeset .highlight .vg,.md-typeset .highlight .vi{color:#3e61a2}.codehilite .nx,.md-typeset .highlight .nx{color:#ec407a}.codehilite .il,.codehilite .m,.codehilite .mf,.codehilite .mh,.codehilite .mi,.codehilite .mo,.md-typeset .highlight .il,.md-typeset .highlight .m,.md-typeset .highlight .mf,.md-typeset .highlight .mh,.md-typeset .highlight .mi,.md-typeset .highlight .mo{color:#e74c3c}.codehilite .s,.codehilite .sb,.codehilite .sc,.md-typeset .highlight .s,.md-typeset .highlight .sb,.md-typeset .highlight .sc{color:#0d904f}.codehilite .sd,.md-typeset .highlight .sd{color:#999}.codehilite .s2,.md-typeset .highlight .s2{color:#0d904f}.codehilite .se,.codehilite .sh,.codehilite .si,.codehilite .sx,.md-typeset .highlight .se,.md-typeset .highlight .sh,.md-typeset .highlight .si,.md-typeset .highlight .sx{color:#183691}.codehilite .sr,.md-typeset .highlight .sr{color:#009926}.codehilite .s1,.codehilite .ss,.md-typeset .highlight .s1,.md-typeset .highlight .ss{color:#0d904f}.codehilite .err,.md-typeset .highlight .err{color:#a61717}.codehilite .w,.md-typeset .highlight .w{color:transparent}.codehilite .hll,.md-typeset .highlight .hll{display:block;margin:0 -.6rem;padding:0 .6rem;background-color:rgba(255,235,59,.5)}.md-typeset .codehilite,.md-typeset .highlight{position:relative;margin:1em 0;padding:0;border-radius:.1rem;background-color:hsla(0,0%,92.5%,.5);color:#37474f;line-height:1.4;-webkit-overflow-scrolling:touch}.md-typeset .codehilite code,.md-typeset .codehilite pre,.md-typeset .highlight code,.md-typeset .highlight pre{display:block;margin:0;padding:.525rem .6rem;background-color:transparent;overflow:auto;vertical-align:top}.md-typeset .codehilite code::-webkit-scrollbar,.md-typeset .codehilite pre::-webkit-scrollbar,.md-typeset .highlight code::-webkit-scrollbar,.md-typeset .highlight pre::-webkit-scrollbar{width:.2rem;height:.2rem}.md-typeset .codehilite code::-webkit-scrollbar-thumb,.md-typeset .codehilite pre::-webkit-scrollbar-thumb,.md-typeset .highlight code::-webkit-scrollbar-thumb,.md-typeset .highlight pre::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-typeset .codehilite code::-webkit-scrollbar-thumb:hover,.md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover,.md-typeset .highlight code::-webkit-scrollbar-thumb:hover,.md-typeset .highlight pre::-webkit-scrollbar-thumb:hover{background-color:#00e290}.md-typeset pre.codehilite,.md-typeset pre.highlight{overflow:visible}.md-typeset pre.codehilite code,.md-typeset pre.highlight code{display:block;padding:.525rem .6rem;overflow:auto}.md-typeset .codehilitetable,.md-typeset .highlighttable{display:block;margin:1em 0;border-radius:.2em;font-size:.8rem;overflow:hidden}.md-typeset .codehilitetable tbody,.md-typeset .codehilitetable td,.md-typeset .highlighttable tbody,.md-typeset .highlighttable td{display:block;padding:0}.md-typeset .codehilitetable tr,.md-typeset .highlighttable tr{display:flex}.md-typeset .codehilitetable .codehilite,.md-typeset .codehilitetable .highlight,.md-typeset .codehilitetable .linenodiv,.md-typeset .highlighttable .codehilite,.md-typeset .highlighttable .highlight,.md-typeset .highlighttable .linenodiv{margin:0;border-radius:0}.md-typeset .codehilitetable .linenodiv,.md-typeset .highlighttable .linenodiv{padding:.525rem .6rem}.md-typeset .codehilitetable .linenos,.md-typeset .highlighttable .linenos{background-color:rgba(0,0,0,.07);color:rgba(0,0,0,.26);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-typeset .codehilitetable .linenos pre,.md-typeset .highlighttable .linenos pre{margin:0;padding:0;background-color:transparent;color:inherit;text-align:right}.md-typeset .codehilitetable .code,.md-typeset .highlighttable .code{flex:1;overflow:hidden}.md-typeset>.codehilitetable,.md-typeset>.highlighttable{box-shadow:none}.md-typeset [id^="fnref:"]{display:inline-block}.md-typeset [id^="fnref:"]:target{margin-top:-3.8rem;padding-top:3.8rem;pointer-events:none}.md-typeset [id^="fn:"]:before{display:none;height:0;content:""}.md-typeset [id^="fn:"]:target:before{display:block;margin-top:-3.5rem;padding-top:3.5rem;pointer-events:none}.md-typeset .footnote{color:rgba(0,0,0,.54);font-size:.64rem}.md-typeset .footnote ol{margin-left:0}.md-typeset .footnote li{transition:color .25s}.md-typeset .footnote li:target{color:rgba(0,0,0,.87)}.md-typeset .footnote li :first-child{margin-top:0}.md-typeset .footnote li:hover .footnote-backref,.md-typeset .footnote li:target .footnote-backref{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}.md-typeset .footnote li:hover .footnote-backref:hover,.md-typeset .footnote li:target .footnote-backref{color:#00e290}.md-typeset .footnote-ref{display:inline-block;pointer-events:auto}.md-typeset .footnote-ref:before{display:inline;margin:0 .2em;border-left:.05rem solid rgba(0,0,0,.26);font-size:1.25em;content:"";vertical-align:-.25rem}.md-typeset .footnote-backref{display:inline-block;-webkit-transform:translateX(.25rem);transform:translateX(.25rem);transition:color .25s,opacity .125s .125s,-webkit-transform .25s .125s;transition:transform .25s .125s,color .25s,opacity .125s .125s;transition:transform .25s .125s,color .25s,opacity .125s .125s,-webkit-transform .25s .125s;color:rgba(0,0,0,.26);font-size:0;opacity:0;vertical-align:text-bottom}[dir=rtl] .md-typeset .footnote-backref{-webkit-transform:translateX(-.25rem);transform:translateX(-.25rem)}.md-typeset .footnote-backref:before{display:inline-block;font-size:.8rem;content:"\E31B"}[dir=rtl] .md-typeset .footnote-backref:before{-webkit-transform:scaleX(-1);transform:scaleX(-1)}.md-typeset .headerlink{display:inline-block;margin-left:.5rem;-webkit-transform:translateY(.25rem);transform:translateY(.25rem);transition:color .25s,opacity .125s .25s,-webkit-transform .25s .25s;transition:transform .25s .25s,color .25s,opacity .125s .25s;transition:transform .25s .25s,color .25s,opacity .125s .25s,-webkit-transform .25s .25s;opacity:0}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem;margin-left:0}html body .md-typeset .headerlink{color:rgba(0,0,0,.26)}.md-typeset h1[id]:before{display:block;margin-top:-9px;padding-top:9px;content:""}.md-typeset h1[id]:target:before{margin-top:-3.45rem;padding-top:3.45rem}.md-typeset h1[id] .headerlink:focus,.md-typeset h1[id]:hover .headerlink,.md-typeset h1[id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset h1[id] .headerlink:focus,.md-typeset h1[id]:hover .headerlink:hover,.md-typeset h1[id]:target .headerlink{color:#00e290}.md-typeset h2[id]:before{display:block;margin-top:-8px;padding-top:8px;content:""}.md-typeset h2[id]:target:before{margin-top:-3.4rem;padding-top:3.4rem}.md-typeset h2[id] .headerlink:focus,.md-typeset h2[id]:hover .headerlink,.md-typeset h2[id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset h2[id] .headerlink:focus,.md-typeset h2[id]:hover .headerlink:hover,.md-typeset h2[id]:target .headerlink{color:#00e290}.md-typeset h3[id]:before{display:block;margin-top:-9px;padding-top:9px;content:""}.md-typeset h3[id]:target:before{margin-top:-3.45rem;padding-top:3.45rem}.md-typeset h3[id] .headerlink:focus,.md-typeset h3[id]:hover .headerlink,.md-typeset h3[id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset h3[id] .headerlink:focus,.md-typeset h3[id]:hover .headerlink:hover,.md-typeset h3[id]:target .headerlink{color:#00e290}.md-typeset h4[id]:before{display:block;margin-top:-9px;padding-top:9px;content:""}.md-typeset h4[id]:target:before{margin-top:-3.45rem;padding-top:3.45rem}.md-typeset h4[id] .headerlink:focus,.md-typeset h4[id]:hover .headerlink,.md-typeset h4[id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset h4[id] .headerlink:focus,.md-typeset h4[id]:hover .headerlink:hover,.md-typeset h4[id]:target .headerlink{color:#00e290}.md-typeset h5[id]:before{display:block;margin-top:-11px;padding-top:11px;content:""}.md-typeset h5[id]:target:before{margin-top:-3.55rem;padding-top:3.55rem}.md-typeset h5[id] .headerlink:focus,.md-typeset h5[id]:hover .headerlink,.md-typeset h5[id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset h5[id] .headerlink:focus,.md-typeset h5[id]:hover .headerlink:hover,.md-typeset h5[id]:target .headerlink{color:#00e290}.md-typeset h6[id]:before{display:block;margin-top:-11px;padding-top:11px;content:""}.md-typeset h6[id]:target:before{margin-top:-3.55rem;padding-top:3.55rem}.md-typeset h6[id] .headerlink:focus,.md-typeset h6[id]:hover .headerlink,.md-typeset h6[id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset h6[id] .headerlink:focus,.md-typeset h6[id]:hover .headerlink:hover,.md-typeset h6[id]:target .headerlink{color:#00e290}.md-typeset .MJXc-display{margin:.75em 0;padding:.75em 0;overflow:auto;-webkit-overflow-scrolling:touch}.md-typeset .MathJax_CHTML{outline:0}.md-typeset .critic.comment,.md-typeset del.critic,.md-typeset ins.critic{margin:0 .25em;padding:.0625em 0;border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:#fdd;box-shadow:.25em 0 0 #fdd,-.25em 0 0 #fdd}.md-typeset ins.critic{background-color:#dfd;box-shadow:.25em 0 0 #dfd,-.25em 0 0 #dfd}.md-typeset .critic.comment{background-color:hsla(0,0%,92.5%,.5);color:#37474f;box-shadow:.25em 0 0 hsla(0,0%,92.5%,.5),-.25em 0 0 hsla(0,0%,92.5%,.5)}.md-typeset .critic.comment:before{padding-right:.125em;color:rgba(0,0,0,.26);content:"\E0B7";vertical-align:-.125em}.md-typeset .critic.block{display:block;margin:1em 0;padding-right:.8rem;padding-left:.8rem;box-shadow:none}.md-typeset .critic.block :first-child{margin-top:.5em}.md-typeset .critic.block :last-child{margin-bottom:.5em}.md-typeset details{display:block;padding-top:0}.md-typeset details[open]>summary:after{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.md-typeset details:not([open]){padding-bottom:0}.md-typeset details:not([open])>summary{border-bottom:none}.md-typeset details summary{padding-right:2rem}[dir=rtl] .md-typeset details summary{padding-left:2rem}.no-details .md-typeset details:not([open])>*{display:none}.no-details .md-typeset details:not([open]) summary{display:block}.md-typeset summary{display:block;outline:none;cursor:pointer}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset summary:after{position:absolute;top:.4rem;right:.6rem;color:rgba(0,0,0,.26);font-size:1rem;content:"\E313"}[dir=rtl] .md-typeset summary:after{right:auto;left:.6rem}.md-typeset .emojione{width:1rem;vertical-align:text-top}.md-typeset code.codehilite,.md-typeset code.highlight{margin:0 .29412em;padding:.07353em 0}.md-typeset .superfences-content{display:none;order:99;width:100%;background-color:#fff}.md-typeset .superfences-content>*{margin:0;border-radius:0}.md-typeset .superfences-tabs{display:flex;position:relative;flex-wrap:wrap;margin:1em 0;border:.05rem solid rgba(0,0,0,.07);border-radius:.2em}.md-typeset .superfences-tabs>input{display:none}.md-typeset .superfences-tabs>input:checked+label{font-weight:700}.md-typeset .superfences-tabs>input:checked+label+.superfences-content{display:block}.md-typeset .superfences-tabs>label{width:auto;padding:.6rem;transition:color .125s;font-size:.64rem;cursor:pointer}html .md-typeset .superfences-tabs>label:hover{color:#00e290}.md-typeset .task-list-item{position:relative;list-style-type:none}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em;left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em;left:auto}.md-typeset .task-list-control .task-list-indicator:before{position:absolute;top:.15em;left:-1.25em;color:rgba(0,0,0,.26);font-size:1.25em;content:"\E835";vertical-align:-.25em}[dir=rtl] .md-typeset .task-list-control .task-list-indicator:before{right:-1.25em;left:auto}.md-typeset .task-list-control [type=checkbox]:checked+.task-list-indicator:before{content:"\E834"}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}@media print{.md-typeset a:after{color:rgba(0,0,0,.54);content:" [" attr(href) "]"}.md-typeset code,.md-typeset pre{white-space:pre-wrap}.md-typeset code{box-shadow:none;-webkit-box-decoration-break:initial;box-decoration-break:slice}.md-clipboard,.md-content__icon,.md-footer,.md-header,.md-sidebar,.md-tabs,.md-typeset .headerlink{display:none}}@media only screen and (max-width:44.9375em){.md-typeset pre{margin:1em -.8rem;border-radius:0}.md-typeset pre>code{padding:.525rem .8rem}.md-footer-nav__link--prev .md-footer-nav__title{display:none}.md-search-result__teaser{max-height:2.5rem;-webkit-line-clamp:3}.codehilite .hll,.md-typeset .highlight .hll{margin:0 -.8rem;padding:0 .8rem}.md-typeset>.codehilite,.md-typeset>.highlight{margin:1em -.8rem;border-radius:0}.md-typeset>.codehilite code,.md-typeset>.codehilite pre,.md-typeset>.highlight code,.md-typeset>.highlight pre{padding:.525rem .8rem}.md-typeset>.codehilitetable,.md-typeset>.highlighttable{margin:1em -.8rem;border-radius:0}.md-typeset>.codehilitetable .codehilite>code,.md-typeset>.codehilitetable .codehilite>pre,.md-typeset>.codehilitetable .highlight>code,.md-typeset>.codehilitetable .highlight>pre,.md-typeset>.codehilitetable .linenodiv,.md-typeset>.highlighttable .codehilite>code,.md-typeset>.highlighttable .codehilite>pre,.md-typeset>.highlighttable .highlight>code,.md-typeset>.highlighttable .highlight>pre,.md-typeset>.highlighttable .linenodiv{padding:.5rem .8rem}.md-typeset>p>.MJXc-display{margin:.75em -.8rem;padding:.25em .8rem}.md-typeset>.superfences-tabs{margin:1em -.8rem;border:0;border-top:.05rem solid rgba(0,0,0,.07);border-radius:0}.md-typeset>.superfences-tabs code,.md-typeset>.superfences-tabs pre{padding:.525rem .8rem}}@media only screen and (min-width:100em){html{font-size:137.5%}}@media only screen and (min-width:125em){html{font-size:150%}}@media only screen and (max-width:59.9375em){body[data-md-state=lock]{overflow:hidden}.ios body[data-md-state=lock] .md-container{display:none}html .md-nav__link[for=__toc]{display:block;padding-right:2.4rem}html .md-nav__link[for=__toc]:after{color:inherit;content:"\E8DE"}html .md-nav__link[for=__toc]+.md-nav__link{display:none}html .md-nav__link[for=__toc]~.md-nav{display:flex}html [dir=rtl] .md-nav__link{padding-right:.8rem;padding-left:2.4rem}.md-nav__source{display:block;padding:0 .2rem;background-color:rgba(69,0,203,.9675);color:#fff}.md-search__overlay{position:absolute;top:.2rem;left:.2rem;width:1.8rem;height:1.8rem;-webkit-transform-origin:center;transform-origin:center;transition:opacity .2s .2s,-webkit-transform .3s .1s;transition:transform .3s .1s,opacity .2s .2s;transition:transform .3s .1s,opacity .2s .2s,-webkit-transform .3s .1s;border-radius:1rem;background-color:#fff;overflow:hidden;pointer-events:none}[dir=rtl] .md-search__overlay{right:.2rem;left:auto}[data-md-toggle=search]:checked~.md-header .md-search__overlay{transition:opacity .1s,-webkit-transform .4s;transition:transform .4s,opacity .1s;transition:transform .4s,opacity .1s,-webkit-transform .4s;opacity:1}.md-search__inner{position:fixed;top:0;left:100%;width:100%;height:100%;-webkit-transform:translateX(5%);transform:translateX(5%);transition:right 0s .3s,left 0s .3s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.4,0,.2,1) .15s;transition:right 0s .3s,left 0s .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;transition:right 0s .3s,left 0s .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.4,0,.2,1) .15s;opacity:0;z-index:2}[data-md-toggle=search]:checked~.md-header .md-search__inner{left:0;-webkit-transform:translateX(0);transform:translateX(0);transition:right 0s 0s,left 0s 0s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1) .15s;transition:right 0s 0s,left 0s 0s,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;transition:right 0s 0s,left 0s 0s,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1) .15s;opacity:1}[dir=rtl] [data-md-toggle=search]:checked~.md-header .md-search__inner{right:0;left:auto}html [dir=rtl] .md-search__inner{right:100%;left:auto;-webkit-transform:translateX(-5%);transform:translateX(-5%)}.md-search__input{width:100%;height:2.4rem;font-size:.9rem}.md-search__icon[for=__search]{top:.6rem;left:.8rem}.md-search__icon[for=__search][for=__search]:before{content:"\E5C4"}[dir=rtl] .md-search__icon[for=__search][for=__search]:before{content:"\E5C8"}.md-search__icon[type=reset]{top:.6rem;right:.8rem}.md-search__output{top:2.4rem;bottom:0}.md-search-result__article--document:before{display:none}}@media only screen and (max-width:76.1875em){[data-md-toggle=drawer]:checked~.md-overlay{width:100%;height:100%;transition:width 0s,height 0s,opacity .25s;opacity:1}.md-header-nav__button.md-icon--home,.md-header-nav__button.md-logo{display:none}.md-hero__inner{margin-top:2.4rem;margin-bottom:1.2rem}.md-nav{background-color:#fff}.md-nav--primary,.md-nav--primary .md-nav{display:flex;position:absolute;top:0;right:0;left:0;flex-direction:column;height:100%;z-index:1}.md-nav--primary .md-nav__item,.md-nav--primary .md-nav__title{font-size:.8rem;line-height:1.5}html .md-nav--primary .md-nav__title{position:relative;height:5.6rem;padding:3rem .8rem .2rem;background-color:rgba(0,0,0,.07);color:rgba(0,0,0,.54);font-weight:400;line-height:2.4rem;white-space:nowrap;cursor:pointer}html .md-nav--primary .md-nav__title:before{display:block;position:absolute;top:.2rem;left:.2rem;width:2rem;height:2rem;color:rgba(0,0,0,.54)}html .md-nav--primary .md-nav__title~.md-nav__list{background-color:#fff;box-shadow:inset 0 .05rem 0 rgba(0,0,0,.07)}html .md-nav--primary .md-nav__title~.md-nav__list>.md-nav__item:first-child{border-top:0}html .md-nav--primary .md-nav__title--site{position:relative;background-color:#5700ff;color:#fff}html .md-nav--primary .md-nav__title--site .md-nav__button{display:block;position:absolute;top:.2rem;left:.2rem;width:3.2rem;height:3.2rem;font-size:2.4rem}html .md-nav--primary .md-nav__title--site:before{display:none}html [dir=rtl] .md-nav--primary .md-nav__title--site .md-nav__button,html [dir=rtl] .md-nav--primary .md-nav__title:before{right:.2rem;left:auto}.md-nav--primary .md-nav__list{flex:1;overflow-y:auto}.md-nav--primary .md-nav__item{padding:0;border-top:.05rem solid rgba(0,0,0,.07)}[dir=rtl] .md-nav--primary .md-nav__item{padding:0}.md-nav--primary .md-nav__item--nested>.md-nav__link{padding-right:2.4rem}[dir=rtl] .md-nav--primary .md-nav__item--nested>.md-nav__link{padding-right:.8rem;padding-left:2.4rem}.md-nav--primary .md-nav__item--nested>.md-nav__link:after{content:"\E315"}[dir=rtl] .md-nav--primary .md-nav__item--nested>.md-nav__link:after{content:"\E314"}.md-nav--primary .md-nav__link{position:relative;margin-top:0;padding:.6rem .8rem}.md-nav--primary .md-nav__link:after{position:absolute;top:50%;right:.6rem;margin-top:-.6rem;color:inherit;font-size:1.2rem}[dir=rtl] .md-nav--primary .md-nav__link:after{right:auto;left:.6rem}.md-nav--primary .md-nav--secondary .md-nav__link{position:static}.md-nav--primary .md-nav--secondary .md-nav{position:static;background-color:transparent}.md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem;padding-left:0}.md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem;padding-left:0}.md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem;padding-left:0}.md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem;padding-left:0}.md-nav__toggle~.md-nav{display:flex;-webkit-transform:translateX(100%);transform:translateX(100%);transition:opacity .125s .05s,-webkit-transform .25s cubic-bezier(.8,0,.6,1);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity .125s .05s;transition:transform .25s cubic-bezier(.8,0,.6,1),opacity .125s .05s,-webkit-transform .25s cubic-bezier(.8,0,.6,1);opacity:0}[dir=rtl] .md-nav__toggle~.md-nav{-webkit-transform:translateX(-100%);transform:translateX(-100%)}.no-csstransforms3d .md-nav__toggle~.md-nav{display:none}.md-nav__toggle:checked~.md-nav{-webkit-transform:translateX(0);transform:translateX(0);transition:opacity .125s .125s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .125s .125s;transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .125s .125s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);opacity:1}.no-csstransforms3d .md-nav__toggle:checked~.md-nav{display:flex}.md-sidebar--primary{position:fixed;top:0;left:-12.1rem;width:12.1rem;height:100%;-webkit-transform:translateX(0);transform:translateX(0);transition:box-shadow .25s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);background-color:#fff;z-index:3}[dir=rtl] .md-sidebar--primary{right:-12.1rem;left:auto}.no-csstransforms3d .md-sidebar--primary{display:none}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.4);-webkit-transform:translateX(12.1rem);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{-webkit-transform:translateX(-12.1rem);transform:translateX(-12.1rem)}.no-csstransforms3d [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{display:block}.md-sidebar--primary .md-sidebar__scrollwrap{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;margin:0}.md-tabs{display:none}}@media only screen and (min-width:60em){.md-content{margin-right:12.1rem}[dir=rtl] .md-content{margin-right:0;margin-left:12.1rem}.md-header-nav__button.md-icon--search{display:none}.md-header-nav__source{display:block;width:11.5rem;max-width:11.5rem;padding-right:.6rem}[dir=rtl] .md-header-nav__source{padding-right:0;padding-left:.6rem}.md-search{padding:.2rem}.md-search__overlay{position:fixed;top:0;left:0;width:0;height:0;transition:width 0s .25s,height 0s .25s,opacity .25s;background-color:rgba(0,0,0,.54);cursor:pointer}[dir=rtl] .md-search__overlay{right:0;left:auto}[data-md-toggle=search]:checked~.md-header .md-search__overlay{width:100%;height:100%;transition:width 0s,height 0s,opacity .25s;opacity:1}.md-search__inner{position:relative;width:11.5rem;margin-right:1rem;padding:.1rem 0;float:right;transition:width .25s cubic-bezier(.1,.7,.1,1)}[dir=rtl] .md-search__inner{margin-right:0;margin-left:1rem;float:left}.md-search__form,.md-search__input{border-radius:.1rem}.md-search__input{width:100%;height:1.8rem;padding-left:2.2rem;transition:background-color .25s cubic-bezier(.1,.7,.1,1),color .25s cubic-bezier(.1,.7,.1,1);background-color:rgba(0,0,0,.26);color:inherit;font-size:.8rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input+.md-search__icon{color:inherit}.md-search__input::-webkit-input-placeholder{color:hsla(0,0%,100%,.7)}.md-search__input:-ms-input-placeholder{color:hsla(0,0%,100%,.7)}.md-search__input::-ms-input-placeholder{color:hsla(0,0%,100%,.7)}.md-search__input::placeholder{color:hsla(0,0%,100%,.7)}.md-search__input:hover{background-color:hsla(0,0%,100%,.12)}[data-md-toggle=search]:checked~.md-header .md-search__input{border-radius:.1rem .1rem 0 0;background-color:#fff;color:rgba(0,0,0,.87);text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::-webkit-input-placeholder{color:rgba(0,0,0,.54)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input:-ms-input-placeholder{color:rgba(0,0,0,.54)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::-ms-input-placeholder{color:rgba(0,0,0,.54)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:rgba(0,0,0,.54)}.md-search__output{top:1.9rem;transition:opacity .4s;opacity:0}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.4);opacity:1}.md-search__scrollwrap{max-height:0}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap::-webkit-scrollbar{width:.2rem;height:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:#00e290}.md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem;padding-left:0}.md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem;padding-left:.8rem}.md-sidebar--secondary{display:block;margin-left:100%;-webkit-transform:translate(-100%);transform:translate(-100%)}[dir=rtl] .md-sidebar--secondary{margin-right:100%;margin-left:0;-webkit-transform:translate(100%);transform:translate(100%)}}@media only screen and (min-width:76.25em){.md-content{margin-left:12.1rem}[dir=rtl] .md-content{margin-right:12.1rem}.md-content__inner{margin-right:1.2rem;margin-left:1.2rem}.md-header-nav__button.md-icon--menu{display:none}.md-nav[data-md-state=animate]{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav__toggle~.md-nav{max-height:0;overflow:hidden}.no-js .md-nav__toggle~.md-nav{display:none}.md-nav[data-md-state=expand],.md-nav__toggle:checked~.md-nav{max-height:100%}.no-js .md-nav[data-md-state=expand],.no-js .md-nav__toggle:checked~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--nested>.md-nav__link:after{display:inline-block;-webkit-transform-origin:.45em .45em;transform-origin:.45em .45em;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;vertical-align:-.125em}.js .md-nav__item--nested>.md-nav__link:after{transition:-webkit-transform .4s;transition:transform .4s;transition:transform .4s,-webkit-transform .4s}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link:after{-webkit-transform:rotateX(180deg);transform:rotateX(180deg)}.md-search__inner{margin-right:1.4rem}[dir=rtl] .md-search__inner{margin-left:1.4rem}.md-search__scrollwrap,[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}.md-sidebar--secondary{margin-left:61rem}[dir=rtl] .md-sidebar--secondary{margin-right:61rem;margin-left:0}.md-tabs~.md-main .md-nav--primary>.md-nav__list>.md-nav__item--nested{font-size:0;visibility:hidden}.md-tabs--active~.md-main .md-nav--primary .md-nav__title{display:block;padding:0}.md-tabs--active~.md-main .md-nav--primary .md-nav__title--site{display:none}.no-js .md-tabs--active~.md-main .md-nav--primary .md-nav{display:block}.md-tabs--active~.md-main .md-nav--primary>.md-nav__list>.md-nav__item{font-size:0;visibility:hidden}.md-tabs--active~.md-main .md-nav--primary>.md-nav__list>.md-nav__item--nested{display:none;font-size:.7rem;overflow:auto;visibility:visible}.md-tabs--active~.md-main .md-nav--primary>.md-nav__list>.md-nav__item--nested>.md-nav__link{display:none}.md-tabs--active~.md-main .md-nav--primary>.md-nav__list>.md-nav__item--active{display:block}.md-tabs--active~.md-main .md-nav[data-md-level="1"]{max-height:none;overflow:visible}.md-tabs--active~.md-main .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:0}.md-tabs--active~.md-main .md-nav[data-md-level="1"] .md-nav .md-nav__title{display:none}}@media only screen and (min-width:45em){.md-footer-nav__link{width:50%}.md-footer-copyright{max-width:75%;float:left}[dir=rtl] .md-footer-copyright{float:right}.md-footer-social{padding:.6rem 0;float:right}[dir=rtl] .md-footer-social{float:left}}@media only screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transform:scale(45);transform:scale(45)}}@media only screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transform:scale(60);transform:scale(60)}}@media only screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transform:scale(75);transform:scale(75)}}@media only screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap,[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}.md-search-result__teaser{max-height:2.5rem;-webkit-line-clamp:3}} \ No newline at end of file diff --git a/docs/theme/assets/stylesheets/extra.css b/docs/theme/assets/stylesheets/extra.css new file mode 100644 index 0000000000..788114b345 --- /dev/null +++ b/docs/theme/assets/stylesheets/extra.css @@ -0,0 +1,15 @@ +.help-sidetab { + position: fixed; + top: 70%; + right: -71px; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + color: white; + background-color: #00e290; + transform: rotate(270deg); + padding: 5px 20px 5px 20px; + border-radius : 10px 10px 0px 0px; + cursor: pointer; + font-size: medium; +} \ No newline at end of file diff --git a/docs/theme/base.html b/docs/theme/base.html new file mode 100644 index 0000000000..8dc736895b --- /dev/null +++ b/docs/theme/base.html @@ -0,0 +1,220 @@ +{% import "partials/language.html" as lang with context %} +{% set feature = config.theme.feature %} +{% set palette = config.theme.palette %} +{% set font = config.theme.font %} + + + + {% block site_meta %} + + + + {% if page and page.meta and page.meta.description %} + + {% elif config.site_description %} + + {% endif %} + {% if page and page.meta and page.meta.redirect %} + + + + + {% elif page.canonical_url %} + + {% endif %} + {% if page and page.meta and page.meta.author %} + + {% elif config.site_author %} + + {% endif %} + {% for key in [ + "clipboard.copy", + "clipboard.copied", + "search.language", + "search.pipeline.stopwords", + "search.pipeline.trimmer", + "search.result.none", + "search.result.one", + "search.result.other", + "search.tokenizer" + ] %} + + {% endfor %} + + + {% endblock %} + {% block htmltitle %} + {% if page and page.meta and page.meta.title %} + {{ page.meta.title }} + {% elif page and page.title and not page.is_homepage %} + {{ page.title }} - {{ config.site_name }} + {% else %} + {{ config.site_name }} + {% endif %} + {% endblock %} + {% block styles %} + + {% if palette.primary or palette.accent %} + + {% endif %} + {% if palette.primary %} + {% import "partials/palette.html" as map %} + {% set primary = map.primary( + palette.primary | replace(" ", "-") | lower + ) %} + + {% endif %} + {% endblock %} + {% block libs %} + + {% endblock %} + {% block fonts %} + {% if font != false %} + + + + {% endif %} + {% endblock %} + + {% if config.extra.manifest %} + + {% endif %} + {% for path in config["extra_css"] %} + + {% endfor %} + {% block analytics %} + {% if config.google_analytics %} + {% include "partials/integrations/analytics.html" %} + {% endif %} + {% endblock %} + {% block extrahead %}{% endblock %} + + {% if palette.primary or palette.accent %} + {% set primary = palette.primary | replace(" ", "-") | lower %} + {% set accent = palette.accent | replace(" ", "-") | lower %} + + {% else %} + + {% endif %} + + + {% set platform = config.extra.repo_icon or config.repo_url %} + {% if "github" in platform %} + {% include "assets/images/icons/github.f0b8504a.svg" %} + {% elif "gitlab" in platform %} + {% include "assets/images/icons/gitlab.6dd19c00.svg" %} + {% elif "bitbucket" in platform %} + {% include "assets/images/icons/bitbucket.1b09e088.svg" %} + {% endif %} + + + + + + {% if page.toc | first is defined %} + + {{ lang.t('skip.link.title') }} + + {% endif %} + {% block header %} + {% include "partials/header.html" %} + {% endblock %} +
+ {% block hero %} + {% if page and page.meta and page.meta.hero %} + {% include "partials/hero.html" with context %} + {% endif %} + {% endblock %} + {% if feature.tabs %} + {% include "partials/tabs.html" %} + {% endif %} +
+
+ {% block site_nav %} + {% if nav %} +
+
+
+ {% include "partials/nav.html" %} +
+
+
+ {% endif %} + {% if page.toc %} +
+
+
+ {% include "partials/toc.html" %} +
+
+
+ {% endif %} + {% endblock %} +
+
+ {% block content %} + {% if page.edit_url %} + + {% endif %} + {% if not "\x3ch1" in page.content %} +

{{ page.title | default(config.site_name, true)}}

+ {% endif %} + {{ page.content }} + {% block source %} + {% if page and page.meta and page.meta.source %} +

{{ lang.t("meta.source") }}

+ {% set repo = config.repo_url %} + {% if repo | last == "/" %} + {% set repo = repo[:-1] %} + {% endif %} + {% set path = page.meta.path | default([""]) %} + {% set file = page.meta.source %} + + {{ file }} + + {% endif %} + {% endblock %} + {% endblock %} + {% block disqus %} + {% include "partials/integrations/disqus.html" %} + {% endblock %} +
+
+
+
+ {% block footer %} + {% include "partials/footer.html" %} + {% endblock %} +
+ {% block scripts %} + + {% if lang.t("search.language") != "en" %} + {% set languages = lang.t("search.language").split(",") %} + {% if languages | length and languages[0] != "" %} + {% set path = "assets/javascripts/lunr/" %} + + {% for language in languages | map("trim") %} + {% if language != "en" %} + {% if language == "ja" %} + + {% endif %} + {% if language in ("da", "de", "es", "fi", "fr", "hu", "it", "ja", "nl", "no", "pt", "ro", "ru", "sv", "th", "tr") %} + + {% endif %} + {% endif %} + {% endfor %} + {% if languages | length > 1 %} + + {% endif %} + {% endif %} + {% endif %} + + {% for path in config["extra_javascript"] %} + + {% endfor %} + {% endblock %} + + diff --git a/docs/theme/partials/footer.html b/docs/theme/partials/footer.html new file mode 100644 index 0000000000..35f12f0117 --- /dev/null +++ b/docs/theme/partials/footer.html @@ -0,0 +1,80 @@ +{% import "partials/language.html" as lang with context %} + +
+ +
diff --git a/docs/theme/partials/header.html b/docs/theme/partials/header.html new file mode 100644 index 0000000000..a063f3ad9c --- /dev/null +++ b/docs/theme/partials/header.html @@ -0,0 +1,87 @@ + + + +
+ + + +
diff --git a/docs/theme/partials/nav.html b/docs/theme/partials/nav.html new file mode 100644 index 0000000000..d68eb9d524 --- /dev/null +++ b/docs/theme/partials/nav.html @@ -0,0 +1,46 @@ + + + + diff --git a/eth/api.go b/eth/api.go index 76118e2d7f..2f4db404a2 100644 --- a/eth/api.go +++ b/eth/api.go @@ -61,6 +61,39 @@ func (api *PublicEthereumAPI) Coinbase() (common.Address, error) { return api.Etherbase() } +// Quorum +// StorageRoot returns the storage root of an account on the the given (optional) block height. +// If block number is not given the latest block is used. +func (s *PublicEthereumAPI) StorageRoot(ctx context.Context, addr common.Address, blockNr *rpc.BlockNumber) (common.Hash, error) { + var ( + pub, priv *state.StateDB + err error + ) + + psm, err := s.e.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return common.Hash{}, err + } + if blockNr == nil || blockNr.Int64() == rpc.LatestBlockNumber.Int64() { + pub, priv, err = s.e.blockchain.StatePSI(psm.ID) + } else { + if ch := s.e.blockchain.GetHeaderByNumber(uint64(blockNr.Int64())); ch != nil { + pub, priv, err = s.e.blockchain.StateAtPSI(ch.Root, psm.ID) + } else { + return common.Hash{}, fmt.Errorf("invalid block number") + } + } + + if err != nil { + return common.Hash{}, err + } + + if priv.Exist(addr) { + return priv.GetStorageRoot(addr) + } + return pub.GetStorageRoot(addr) +} + // Hashrate returns the POW hashrate func (api *PublicEthereumAPI) Hashrate() hexutil.Uint64 { return hexutil.Uint64(api.e.Miner().HashRate()) @@ -277,14 +310,61 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { } // DumpBlock retrieves the entire state of the database at a given block. -func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) { +// Quorum adds an additional parameter to support private state dump +func (api *PublicDebugAPI) DumpBlock(ctx context.Context, blockNr rpc.BlockNumber, typ *string) (state.Dump, error) { + publicState, privateState, err := api.getStateDbsFromBlockNumber(ctx, blockNr) + if err != nil { + return state.Dump{}, err + } + + if typ != nil && *typ == "private" { + return privateState.RawDump(false, false, true), nil + } + return publicState.RawDump(false, false, true), nil +} + +func (api *PublicDebugAPI) PrivateStateRoot(ctx context.Context, blockNr rpc.BlockNumber) (common.Hash, error) { + _, privateState, err := api.getStateDbsFromBlockNumber(ctx, blockNr) + if err != nil { + return common.Hash{}, err + } + return privateState.IntermediateRoot(true), nil +} + +// Quorum +// DumpAddress retrieves the state of an address at a given block. +// Quorum adds an additional parameter to support private state dump +func (api *PublicDebugAPI) DumpAddress(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (state.DumpAccount, error) { + publicState, privateState, err := api.getStateDbsFromBlockNumber(ctx, blockNr) + if err != nil { + return state.DumpAccount{}, err + } + + if accountDump, ok := privateState.DumpAddress(address); ok { + return accountDump, nil + } + if accountDump, ok := publicState.DumpAddress(address); ok { + return accountDump, nil + } + return state.DumpAccount{}, errors.New("error retrieving state") +} + +//Quorum +//Taken from DumpBlock, as it was reused in DumpAddress. +//Contains modifications from the original to return the private state db, as well as public. +func (api *PublicDebugAPI) getStateDbsFromBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *state.StateDB, error) { + psm, err := api.eth.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return nil, nil, err + } if blockNr == rpc.PendingBlockNumber { // If we're dumping the pending state, we need to request // both the pending block as well as the pending state from // the miner and operate on those - _, stateDb := api.eth.miner.Pending() - return stateDb.RawDump(false, false, true), nil + _, publicState, privateState := api.eth.miner.Pending(psm.ID) + return publicState, privateState, nil } + var block *types.Block if blockNr == rpc.LatestBlockNumber { block = api.eth.blockchain.CurrentBlock() @@ -292,13 +372,9 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) } if block == nil { - return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) - } - stateDb, err := api.eth.BlockChain().StateAt(block.Root()) - if err != nil { - return state.Dump{}, err + return nil, nil, fmt.Errorf("block #%d not found", blockNr) } - return stateDb.RawDump(false, false, true), nil + return api.eth.BlockChain().StateAtPSI(block.Root(), psm.ID) } // PrivateDebugAPI is the collection of Ethereum full node APIs exposed over @@ -355,16 +431,19 @@ func (api *PrivateDebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, const AccountRangeMaxResults = 256 // AccountRange enumerates all accounts in the given block and start point in paging request -func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start []byte, maxResults int, nocode, nostorage, incompletes bool) (state.IteratorDump, error) { +func (api *PublicDebugAPI) AccountRange(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, start []byte, maxResults int, nocode, nostorage, incompletes bool) (state.IteratorDump, error) { + psm, err := api.eth.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return state.IteratorDump{}, err + } var stateDb *state.StateDB - var err error if number, ok := blockNrOrHash.Number(); ok { if number == rpc.PendingBlockNumber { // If we're dumping the pending state, we need to request // both the pending block as well as the pending state from // the miner and operate on those - _, stateDb = api.eth.miner.Pending() + _, stateDb, _ = api.eth.miner.Pending(psm.ID) } else { var block *types.Block if number == rpc.LatestBlockNumber { @@ -375,7 +454,7 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta if block == nil { return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) } - stateDb, err = api.eth.BlockChain().StateAt(block.Root()) + stateDb, _, err = api.eth.BlockChain().StateAtPSI(block.Root(), psm.ID) if err != nil { return state.IteratorDump{}, err } @@ -385,7 +464,7 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta if block == nil { return state.IteratorDump{}, fmt.Errorf("block %s not found", hash.Hex()) } - stateDb, err = api.eth.BlockChain().StateAt(block.Root()) + stateDb, _, err = api.eth.BlockChain().StateAtPSI(block.Root(), psm.ID) if err != nil { return state.IteratorDump{}, err } @@ -411,13 +490,13 @@ type storageEntry struct { } // StorageRangeAt returns the storage at the given block height and transaction index. -func (api *PrivateDebugAPI) StorageRangeAt(blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) { +func (api *PrivateDebugAPI) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) { // Retrieve the block block := api.eth.blockchain.GetBlockByHash(blockHash) if block == nil { return StorageRangeResult{}, fmt.Errorf("block %#x not found", blockHash) } - _, _, statedb, err := api.computeTxEnv(block, txIndex, 0) + _, _, statedb, _, err := api.computeTxEnv(ctx, block, txIndex, 0) if err != nil { return StorageRangeResult{}, err } diff --git a/eth/api_backend.go b/eth/api_backend.go index 0e91691d8f..29e54aede7 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,13 +19,16 @@ package eth import ( "context" "errors" + "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -36,7 +39,9 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/params" + pcore "github.com/ethereum/go-ethereum/permission/core" "github.com/ethereum/go-ethereum/rpc" + "github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto" ) // EthAPIBackend implements ethapi.Backend for full nodes @@ -44,6 +49,14 @@ type EthAPIBackend struct { extRPCEnabled bool eth *Ethereum gpo *gasprice.Oracle + + // Quorum + // + // hex node id from node public key + hexNodeId string + + // timeout value for call + evmCallTimeOut time.Duration } // ChainConfig returns the active chain configuration. @@ -51,6 +64,11 @@ func (b *EthAPIBackend) ChainConfig() *params.ChainConfig { return b.eth.blockchain.Config() } +// PSMR returns the private state metadata resolver. +func (b *EthAPIBackend) PSMR() mps.PrivateStateMetadataResolver { + return b.eth.blockchain.PrivateStateManager() +} + func (b *EthAPIBackend) CurrentBlock() *types.Block { return b.eth.blockchain.CurrentBlock() } @@ -97,6 +115,10 @@ func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*ty func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { // Pending block is only known by the miner if number == rpc.PendingBlockNumber { + if b.eth.protocolManager.raftMode { + // Use latest instead. + return b.eth.blockchain.CurrentBlock(), nil + } block := b.eth.miner.PendingBlock() return block, nil } @@ -132,11 +154,25 @@ func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash r return nil, errors.New("invalid arguments; neither block nor hash specified") } -func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { +func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (vm.MinimalApiState, *types.Header, error) { + psm, err := b.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, nil, err + } // Pending state is only known by the miner if number == rpc.PendingBlockNumber { - block, state := b.eth.miner.Pending() - return state, block.Header(), nil + // Quorum + if b.eth.protocolManager.raftMode { + // Use latest instead. + header, err := b.HeaderByNumber(ctx, rpc.LatestBlockNumber) + if header == nil || err != nil { + return nil, nil, err + } + publicState, privateState, err := b.eth.BlockChain().StateAtPSI(header.Root, psm.ID) + return EthAPIState{publicState, privateState}, header, err + } + block, publicState, privateState := b.eth.miner.Pending(psm.ID) + return EthAPIState{publicState, privateState}, block.Header(), nil } // Otherwise resolve the block number and return its state header, err := b.HeaderByNumber(ctx, number) @@ -146,11 +182,12 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.B if header == nil { return nil, nil, errors.New("header not found") } - stateDb, err := b.eth.BlockChain().StateAt(header.Root) - return stateDb, header, err + stateDb, privateState, err := b.eth.BlockChain().StateAtPSI(header.Root, psm.ID) + return EthAPIState{stateDb, privateState}, header, err + } -func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { +func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.MinimalApiState, *types.Header, error) { if blockNr, ok := blockNrOrHash.Number(); ok { return b.StateAndHeaderByNumber(ctx, blockNr) } @@ -165,18 +202,43 @@ func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockN if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash { return nil, nil, errors.New("hash is not currently canonical") } - stateDb, err := b.eth.BlockChain().StateAt(header.Root) - return stateDb, header, err + psm, err := b.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, nil, err + } + stateDb, privateState, err := b.eth.BlockChain().StateAtPSI(header.Root, psm.ID) + return EthAPIState{stateDb, privateState}, header, err + } return nil, nil, errors.New("invalid arguments; neither block nor hash specified") } func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { - return b.eth.blockchain.GetReceiptsByHash(hash), nil + receipts := b.eth.blockchain.GetReceiptsByHash(hash) + psm, err := b.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } + + psiReceipts := make([]*types.Receipt, len(receipts)) + for i := 0; i < len(receipts); i++ { + psiReceipts[i] = receipts[i] + if receipts[i].PSReceipts != nil { + psReceipt, found := receipts[i].PSReceipts[psm.ID] + if found { + psiReceipts[i] = psReceipt + } + } + } + + return psiReceipts, nil } func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - receipts := b.eth.blockchain.GetReceiptsByHash(hash) + receipts, err := b.GetReceipts(ctx, hash) + if err != nil { + return nil, err + } if receipts == nil { return nil, nil } @@ -191,11 +253,24 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int { return b.eth.blockchain.GetTdByHash(hash) } -func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) { +func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state vm.MinimalApiState, header *types.Header) (*vm.EVM, func() error, error) { + statedb := state.(EthAPIState) vmError := func() error { return nil } - context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil) - return vm.NewEVM(context, state, b.eth.blockchain.Config(), *b.eth.blockchain.GetVMConfig()), vmError, nil + evmCtx := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil) + + // Set the private state to public state if contract address is not present in the private state + to := common.Address{} + if msg.To() != nil { + to = *msg.To() + } + + privateState := statedb.privateState + if !privateState.Exist(to) { + privateState = statedb.state + } + + return vm.NewEVM(evmCtx, statedb.state, privateState, b.eth.blockchain.Config(), *b.eth.blockchain.GetVMConfig()), vmError, nil } func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { @@ -203,7 +278,7 @@ func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEven } func (b *EthAPIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { - return b.eth.miner.SubscribePendingLogs(ch) + return b.eth.SubscribePendingLogs(ch) // Quorum } func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { @@ -223,6 +298,11 @@ func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri } func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + // validation for node need to happen here and cannot be done as a part of + // validateTx in tx_pool.go as tx_pool validation will happen in every node + if b.hexNodeId != "" && !pcore.ValidateNodeForTxn(b.hexNodeId, signedTx.From()) { + return errors.New("cannot send transaction from this node") + } return b.eth.txPool.AddLocal(signedTx) } @@ -276,7 +356,11 @@ func (b *EthAPIBackend) ProtocolVersion() int { } func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { - return b.gpo.SuggestPrice(ctx) + if b.ChainConfig().IsQuorum { + return big.NewInt(0), nil + } else { + return b.gpo.SuggestPrice(ctx) + } } func (b *EthAPIBackend) ChainDb() ethdb.Database { @@ -295,6 +379,10 @@ func (b *EthAPIBackend) ExtRPCEnabled() bool { return b.extRPCEnabled } +func (b *EthAPIBackend) CallTimeOut() time.Duration { + return b.evmCallTimeOut +} + func (b *EthAPIBackend) RPCGasCap() uint64 { return b.eth.config.RPCGasCap } @@ -329,3 +417,150 @@ func (b *EthAPIBackend) Miner() *miner.Miner { func (b *EthAPIBackend) StartMining(threads int) error { return b.eth.StartMining(threads) } + +// The validation of pre-requisite for multitenancy is done when EthService +// is being created. So it's safe to use the config value here. +func (b *EthAPIBackend) SupportsMultitenancy(rpcCtx context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) { + authToken := rpc.PreauthenticatedTokenFromContext(rpcCtx) + if authToken != nil && b.eth.config.EnableMultitenancy { + return authToken, true + } + return nil, false +} + +func (b *EthAPIBackend) AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { + s, _, err := b.StateAndHeaderByNumber(ctx, number) + return s, err +} + +// used by Quorum +type EthAPIState struct { + state, privateState *state.StateDB +} + +func (s EthAPIState) GetBalance(addr common.Address) *big.Int { + if s.privateState.Exist(addr) { + return s.privateState.GetBalance(addr) + } + return s.state.GetBalance(addr) +} + +func (s EthAPIState) GetCode(addr common.Address) []byte { + if s.privateState.Exist(addr) { + return s.privateState.GetCode(addr) + } + return s.state.GetCode(addr) +} + +func (s EthAPIState) SetNonce(addr common.Address, nonce uint64) { + if s.privateState.Exist(addr) { + s.privateState.SetNonce(addr, nonce) + } else { + s.state.SetNonce(addr, nonce) + } +} + +func (s EthAPIState) SetCode(addr common.Address, code []byte) { + if s.privateState.Exist(addr) { + s.privateState.SetCode(addr, code) + } else { + s.state.SetCode(addr, code) + } +} + +func (s EthAPIState) SetBalance(addr common.Address, balance *big.Int) { + if s.privateState.Exist(addr) { + s.privateState.SetBalance(addr, balance) + } else { + s.state.SetBalance(addr, balance) + } +} + +func (s EthAPIState) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { + if s.privateState.Exist(addr) { + s.privateState.SetStorage(addr, storage) + } else { + s.state.SetStorage(addr, storage) + } +} + +func (s EthAPIState) SetState(a common.Address, key common.Hash, value common.Hash) { + if s.privateState.Exist(a) { + s.privateState.SetState(a, key, value) + } else { + s.state.SetState(a, key, value) + } +} + +func (s EthAPIState) GetState(a common.Address, b common.Hash) common.Hash { + if s.privateState.Exist(a) { + return s.privateState.GetState(a, b) + } + return s.state.GetState(a, b) +} + +func (s EthAPIState) GetNonce(addr common.Address) uint64 { + if s.privateState.Exist(addr) { + return s.privateState.GetNonce(addr) + } + return s.state.GetNonce(addr) +} + +func (s EthAPIState) GetPrivacyMetadata(addr common.Address) (*state.PrivacyMetadata, error) { + if s.privateState.Exist(addr) { + return s.privateState.GetPrivacyMetadata(addr) + } + return nil, fmt.Errorf("%x: %w", addr, common.ErrNotPrivateContract) +} + +func (s EthAPIState) GetManagedParties(addr common.Address) ([]string, error) { + if s.privateState.Exist(addr) { + return s.privateState.GetManagedParties(addr) + } + return nil, fmt.Errorf("%x: %w", addr, common.ErrNotPrivateContract) +} + +func (s EthAPIState) GetRLPEncodedStateObject(addr common.Address) ([]byte, error) { + getFunc := s.state.GetRLPEncodedStateObject + if s.privateState.Exist(addr) { + getFunc = s.privateState.GetRLPEncodedStateObject + } + return getFunc(addr) +} + +func (s EthAPIState) GetProof(addr common.Address) ([][]byte, error) { + if s.privateState.Exist(addr) { + return s.privateState.GetProof(addr) + } + return s.state.GetProof(addr) +} + +func (s EthAPIState) GetStorageProof(addr common.Address, h common.Hash) ([][]byte, error) { + if s.privateState.Exist(addr) { + return s.privateState.GetStorageProof(addr, h) + } + return s.state.GetStorageProof(addr, h) +} + +func (s EthAPIState) StorageTrie(addr common.Address) state.Trie { + if s.privateState.Exist(addr) { + return s.privateState.StorageTrie(addr) + } + return s.state.StorageTrie(addr) +} + +func (s EthAPIState) Error() error { + if s.privateState.Error() != nil { + return s.privateState.Error() + } + return s.state.Error() +} + +func (s EthAPIState) GetCodeHash(addr common.Address) common.Hash { + if s.privateState.Exist(addr) { + return s.privateState.GetCodeHash(addr) + } + return s.state.GetCodeHash(addr) +} + +//func (s MinimalApiState) Error diff --git a/eth/api_backend_test.go b/eth/api_backend_test.go new file mode 100644 index 0000000000..8a48390bc4 --- /dev/null +++ b/eth/api_backend_test.go @@ -0,0 +1,63 @@ +package eth + +import ( + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/node" + "github.com/stretchr/testify/require" +) + +func TestEthAPIBackend_SubscribePendingLogsEvent(t *testing.T) { + conf := &Config{ + RaftMode: false, + } + stack, err := node.New(&node.Config{}) + if err != nil { + t.Fatalf("failed to create node, err = %v", err) + } + eth, err := New(stack, conf) + if err != nil { + t.Fatalf("failed to create eth service, err = %v", err) + } + + b := &EthAPIBackend{ + eth: eth, + } + + ch := make(chan []*types.Log, 1) + + _ = b.SubscribePendingLogsEvent(ch) + + recipientCount := eth.ConsensusServicePendingLogsFeed().Send([]*types.Log{}) + + require.Zero(t, recipientCount, "not using consensus service so its event feed should not have subscribers") + require.Zero(t, len(ch), "not using consensus service so subscribed channel should not have received event") +} + +func TestEthAPIBackend_SubscribePendingLogsEvent_SubscribesToConsensusServiceFeed(t *testing.T) { + conf := &Config{ + RaftMode: true, + } + stack, err := node.New(&node.Config{}) + if err != nil { + t.Fatalf("failed to create node, err = %v", err) + } + eth, err := New(stack, conf) + if err != nil { + t.Fatalf("failed to create eth service, err = %v ", err) + } + + b := &EthAPIBackend{ + eth: eth, + } + + ch := make(chan []*types.Log, 1) + + _ = b.SubscribePendingLogsEvent(ch) + + recipientCount := eth.ConsensusServicePendingLogsFeed().Send([]*types.Log{}) + + require.NotZero(t, recipientCount, "consensus service in use so its event feed should have subscribers") + require.Equal(t, 1, len(ch), "consensus service in use so subscribed channel should have received event") +} diff --git a/eth/api_tracer.go b/eth/api_tracer.go index 748280951c..988d64ff09 100644 --- a/eth/api_tracer.go +++ b/eth/api_tracer.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -38,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" @@ -78,10 +80,11 @@ type txTraceResult struct { // blockTraceTask represents a single block trace task when an entire chain is // being traced. type blockTraceTask struct { - statedb *state.StateDB // Intermediate state prepped for tracing - block *types.Block // Block to trace the transactions from - rootref common.Hash // Trie root reference held for this task - results []*txTraceResult // Trace results procudes by the task + statedb *state.StateDB // Intermediate state prepped for tracing + privateStateDb *state.StateDB // Quorum + block *types.Block // Block to trace the transactions from + rootref common.Hash // Trie root reference held for this task + results []*txTraceResult // Trace results procudes by the task } // blockTraceResult represets the results of tracing a single block when an entire @@ -95,8 +98,9 @@ type blockTraceResult struct { // txTraceTask represents a single transaction trace task when an entire block // is being traced. type txTraceTask struct { - statedb *state.StateDB // Intermediate state prepped for tracing - index int // Transaction offset in the block + statedb *state.StateDB // Intermediate state prepped for tracing + privateStateDb *state.StateDB + index int // Transaction offset in the block } // TraceChain returns the structured logs created during the execution of EVM @@ -155,7 +159,11 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl return nil, fmt.Errorf("parent block #%d not found", number-1) } } - statedb, err := state.New(start.Root(), database, nil) + psm, err := api.eth.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } + statedb, privateStateRepo, err := api.eth.blockchain.StateAt(start.Root()) if err != nil { // If the starting state is missing, allow some number of blocks to be reexecuted reexec := defaultTraceReexec @@ -168,7 +176,8 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl if start == nil { break } - if statedb, err = state.New(start.Root(), database, nil); err == nil { + statedb, privateStateRepo, err = api.eth.blockchain.StateAt(start.Root()) + if err == nil { break } } @@ -206,9 +215,10 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl // Trace all the transactions contained within for i, tx := range task.block.Transactions() { msg, _ := tx.AsMessage(signer) + msg = api.clearMessageDataIfNonParty(msg, psm) vmctx := core.NewEVMContext(msg, task.block.Header(), api.eth.blockchain, nil) - res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config) + res, err := api.traceTx(ctx, msg, tx, vmctx, task.statedb, task.privateStateDb, config) if err != nil { task.results[i] = &txTraceResult{Error: err.Error()} log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err) @@ -216,6 +226,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl } // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect task.statedb.Finalise(api.eth.blockchain.Config().IsEIP158(task.block.Number())) + task.privateStateDb.Finalise(api.eth.blockchain.Config().IsEIP158(task.block.Number())) task.results[i] = &txTraceResult{Result: res} } // Stream the result back to the user or abort on teardown @@ -280,16 +291,20 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl // Send the block over to the concurrent tracers (if not in the fast-forward phase) if number > origin { txs := block.Transactions() - + privateState, err := privateStateRepo.StatePSI(psm.ID) + if err != nil { + failed = err + break + } select { - case tasks <- &blockTraceTask{statedb: statedb.Copy(), block: block, rootref: proot, results: make([]*txTraceResult, len(txs))}: + case tasks <- &blockTraceTask{statedb: statedb.Copy(), privateStateDb: privateState.Copy(), block: block, rootref: proot, results: make([]*txTraceResult, len(txs))}: case <-notifier.Closed(): return } traced += uint64(len(txs)) } // Generate the next state snapshot fast without tracing - _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, vm.Config{}) + _, _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, privateStateRepo, vm.Config{}) if err != nil { failed = err break @@ -304,6 +319,17 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl failed = err break } + + err = privateStateRepo.Commit(api.eth.blockchain.Config().IsEIP158(block.Number()), block) + if err != nil { + failed = err + break + } + if err := privateStateRepo.Reset(); err != nil { + failed = err + break + } + // Reference the trie twice, once for us, once for the tracer database.TrieDB().Reference(root, common.Hash{}) if number >= origin { @@ -454,7 +480,15 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, if config != nil && config.Reexec != nil { reexec = *config.Reexec } - statedb, err := api.computeStateDB(parent, reexec) + statedb, privateStateRepo, err := api.computeStateDB(parent, reexec) + if err != nil { + return nil, err + } + psm, err := api.eth.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } + privateStateDb, err := privateStateRepo.StatePSI(psm.ID) if err != nil { return nil, err } @@ -479,10 +513,12 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, // Fetch and execute the next transaction trace tasks for task := range jobs { - msg, _ := txs[task.index].AsMessage(signer) + txn := txs[task.index] + msg, _ := txn.AsMessage(signer) + msg = api.clearMessageDataIfNonParty(msg, psm) vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil) - res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config) + res, err := api.traceTx(ctx, msg, txn, vmctx, task.statedb, task.privateStateDb, config) if err != nil { results[task.index] = &txTraceResult{Error: err.Error()} continue @@ -495,13 +531,23 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, var failed error for i, tx := range txs { // Send the trace task over for execution - jobs <- &txTraceTask{statedb: statedb.Copy(), index: i} + jobs <- &txTraceTask{ + statedb: statedb.Copy(), + privateStateDb: privateStateDb.Copy(), + index: i, + } // Generate the next state snapshot fast without tracing msg, _ := tx.AsMessage(signer) vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil) - vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vm.Config{}) + // Quorum + privateStateDbToUse := core.PrivateStateDBForTxn(api.eth.blockchain.Config().IsQuorum, tx.IsPrivate(), statedb, privateStateDb) + vmenv := vm.NewEVM(vmctx, statedb, privateStateDbToUse, api.eth.blockchain.Config(), vm.Config{}) + vmenv.SetCurrentTX(tx) + msg = api.clearMessageDataIfNonParty(msg, psm) + // /Quorum + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil { failed = err break @@ -509,6 +555,8 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, // Finalize the state so any modifications are written to the trie // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number())) + privateStateDb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number())) + } close(jobs) pend.Wait() @@ -542,7 +590,15 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block if config != nil && config.Reexec != nil { reexec = *config.Reexec } - statedb, err := api.computeStateDB(parent, reexec) + statedb, privateStateRepo, err := api.computeStateDB(parent, reexec) + if err != nil { + return nil, err + } + psm, err := api.eth.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } + privateStateDb, err := privateStateRepo.StatePSI(psm.ID) if err != nil { return nil, err } @@ -595,7 +651,13 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block } } // Execute the transaction and flush any traces to disk - vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vmConf) + // Quorum + privateStateDbToUse := core.PrivateStateDBForTxn(api.eth.blockchain.Config().IsQuorum, tx.IsPrivate(), statedb, privateStateDb) + vmenv := vm.NewEVM(vmctx, statedb, privateStateDbToUse, api.eth.blockchain.Config(), vmConf) + vmenv.SetCurrentTX(tx) + msg = api.clearMessageDataIfNonParty(msg, psm) + // /Quorum + _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())) if writer != nil { writer.Flush() @@ -633,11 +695,11 @@ func containsTx(block *types.Block, hash common.Hash) bool { // computeStateDB retrieves the state database associated with a certain block. // If no state is locally available for the given block, a number of blocks are // attempted to be reexecuted to generate the desired state. -func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*state.StateDB, error) { +func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*state.StateDB, mps.PrivateStateRepository, error) { // If we have the state fully available, use that - statedb, err := api.eth.blockchain.StateAt(block.Root()) + statedb, privateStateRepo, err := api.eth.blockchain.StateAt(block.Root()) if err == nil { - return statedb, nil + return statedb, privateStateRepo, nil } // Otherwise try to reexec blocks until we find a state or reach our limit origin := block.NumberU64() @@ -648,16 +710,17 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (* if block == nil { break } - if statedb, err = state.New(block.Root(), database, nil); err == nil { + statedb, privateStateRepo, err = api.eth.blockchain.StateAt(block.Root()) + if err == nil { break } } if err != nil { switch err.(type) { case *trie.MissingNodeError: - return nil, fmt.Errorf("required historical state unavailable (reexec=%d)", reexec) + return nil, nil, fmt.Errorf("required historical state unavailable (reexec=%d)", reexec) default: - return nil, err + return nil, nil, err } } // State was available at historical point, regenerate @@ -674,19 +737,26 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (* } // Retrieve the next block to regenerate and process it if block = api.eth.blockchain.GetBlockByNumber(block.NumberU64() + 1); block == nil { - return nil, fmt.Errorf("block #%d not found", block.NumberU64()+1) + return nil, nil, fmt.Errorf("block #%d not found", block.NumberU64()+1) } - _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, vm.Config{}) + _, _, _, _, err := api.eth.blockchain.Processor().Process(block, statedb, privateStateRepo, vm.Config{}) if err != nil { - return nil, fmt.Errorf("processing block %d failed: %v", block.NumberU64(), err) + return nil, nil, fmt.Errorf("processing block %d failed: %v", block.NumberU64(), err) } // Finalize the state so any modifications are written to the trie root, err := statedb.Commit(api.eth.blockchain.Config().IsEIP158(block.Number())) if err != nil { - return nil, err + return nil, nil, err } if err := statedb.Reset(root); err != nil { - return nil, fmt.Errorf("state reset after block %d failed: %v", block.NumberU64(), err) + return nil, nil, fmt.Errorf("state reset after block %d failed: %v", block.NumberU64(), err) + } + err = privateStateRepo.Commit(api.eth.blockchain.Config().IsEIP158(block.Number()), block) + if err != nil { + return nil, nil, err + } + if err := privateStateRepo.Reset(); err != nil { + return nil, nil, fmt.Errorf("state reset after block %d failed: %v", block.NumberU64(), err) } database.TrieDB().Reference(root, common.Hash{}) if proot != (common.Hash{}) { @@ -696,7 +766,7 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (* } nodes, imgs := database.TrieDB().Size() log.Info("Historical state regenerated", "block", block.NumberU64(), "elapsed", time.Since(start), "nodes", nodes, "preimages", imgs) - return statedb, nil + return statedb, privateStateRepo, nil } // TraceTransaction returns the structured logs created during the execution of EVM @@ -716,12 +786,12 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha if block == nil { return nil, fmt.Errorf("block %#x not found", blockHash) } - msg, vmctx, statedb, err := api.computeTxEnv(block, int(index), reexec) + msg, vmctx, statedb, privateState, err := api.computeTxEnv(ctx, block, int(index), reexec) if err != nil { return nil, err } // Trace the transaction and return - return api.traceTx(ctx, msg, vmctx, statedb, config) + return api.traceTx(ctx, msg, tx, vmctx, statedb, privateState, config) } // TraceCall lets you trace a given eth_call. It collects the structured logs created during the execution of EVM @@ -746,22 +816,27 @@ func (api *PrivateDebugAPI) TraceCall(ctx context.Context, args ethapi.CallArgs, if config != nil && config.Reexec != nil { reexec = *config.Reexec } - _, _, statedb, err = api.computeTxEnv(block, 0, reexec) + _, _, stateDB, privateState, err := api.computeTxEnv(ctx, block, 0, reexec) if err != nil { return nil, err } + statedb = EthAPIState{ + state: stateDB, + privateState: privateState, + } } // Execute the trace msg := args.ToMessage(api.eth.APIBackend.RPCGasCap()) vmctx := core.NewEVMContext(msg, header, api.eth.blockchain, nil) - return api.traceTx(ctx, msg, vmctx, statedb, config) + + return api.traceTx(ctx, msg, nil, vmctx, statedb.(EthAPIState).state, statedb.(EthAPIState).privateState, config) // public / standard run } // traceTx configures a new tracer according to the provided configuration, and // executes the given message in the provided environment. The return value will // be tracer dependent. -func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, vmctx vm.Context, statedb *state.StateDB, config *TraceConfig) (interface{}, error) { +func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, tx *types.Transaction, vmctx vm.Context, statedb *state.StateDB, privateStateDb *state.StateDB, config *TraceConfig) (interface{}, error) { // Assemble the structured logger or the JavaScript tracer var ( tracer vm.Tracer @@ -794,8 +869,19 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v default: tracer = vm.NewStructLogger(config.LogConfig) } + + // Quorum + // Set the private state to public state if it is not a private message + isPrivate := false + if msg, ok := message.(core.PrivateMessage); ok && msg.IsPrivate() { + isPrivate = true + } + privateStateDbToUse := core.PrivateStateDBForTxn(api.eth.blockchain.Config().IsQuorum, isPrivate, statedb, privateStateDb) + // Run the transaction with tracing enabled. - vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vm.Config{Debug: true, Tracer: tracer}) + vmenv := vm.NewEVM(vmctx, statedb, privateStateDbToUse, api.eth.blockchain.Config(), vm.Config{Debug: true, Tracer: tracer}) + vmenv.SetCurrentTX(tx) + // /Quorum result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas())) if err != nil { @@ -824,40 +910,67 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v } } +// clearMessageDataIfNonParty sets the message data to empty hash in case the private state is not party to the +// transaction. The effect is that when the private tx payload is resolved using the privacy manager the private part of +// the transaction is not retrieved and the transaction is being executed as if the node/private state is not party to +// the transaction. +func (api *PrivateDebugAPI) clearMessageDataIfNonParty(msg types.Message, psm *mps.PrivateStateMetadata) types.Message { + if msg.IsPrivate() { + _, managedParties, _, _, _ := private.P.Receive(common.BytesToEncryptedPayloadHash(msg.Data())) + if api.eth.blockchain.PrivateStateManager().NotIncludeAny(psm, managedParties...) { + return msg.WithEmptyPrivateData(true) + } + } + return msg +} + // computeTxEnv returns the execution environment of a certain transaction. -func (api *PrivateDebugAPI) computeTxEnv(block *types.Block, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, error) { +func (api *PrivateDebugAPI) computeTxEnv(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.Context, *state.StateDB, *state.StateDB, error) { // Create the parent state database parent := api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { - return nil, vm.Context{}, nil, fmt.Errorf("parent %#x not found", block.ParentHash()) + return nil, vm.Context{}, nil, nil, fmt.Errorf("parent %#x not found", block.ParentHash()) + } + statedb, privateStateRepo, err := api.computeStateDB(parent, reexec) + if err != nil { + return nil, vm.Context{}, nil, nil, err + } + psm, err := api.eth.blockchain.PrivateStateManager().ResolveForUserContext(ctx) + if err != nil { + return nil, vm.Context{}, nil, nil, err } - statedb, err := api.computeStateDB(parent, reexec) + privateStateDb, err := privateStateRepo.StatePSI(psm.ID) if err != nil { - return nil, vm.Context{}, nil, err + return nil, vm.Context{}, nil, nil, err } if txIndex == 0 && len(block.Transactions()) == 0 { - return nil, vm.Context{}, statedb, nil + return nil, vm.Context{}, statedb, privateStateDb, nil } // Recompute transactions up to the target index. signer := types.MakeSigner(api.eth.blockchain.Config(), block.Number()) for idx, tx := range block.Transactions() { + // Quorum + privateStateDbToUse := core.PrivateStateDBForTxn(api.eth.blockchain.Config().IsQuorum, tx.IsPrivate(), statedb, privateStateDb) + // /Quorum // Assemble the transaction call message and return if the requested offset msg, _ := tx.AsMessage(signer) + msg = api.clearMessageDataIfNonParty(msg, psm) context := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil) if idx == txIndex { - return msg, context, statedb, nil + return msg, context, statedb, privateStateDb, nil } // Not yet the searched for transaction, execute on top of the current state - vmenv := vm.NewEVM(context, statedb, api.eth.blockchain.Config(), vm.Config{}) + vmenv := vm.NewEVM(context, statedb, privateStateDbToUse, api.eth.blockchain.Config(), vm.Config{}) + vmenv.SetCurrentTX(tx) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { - return nil, vm.Context{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) + return nil, vm.Context{}, nil, nil, fmt.Errorf("tx %#x failed: %v", tx.Hash(), err) } // Ensure any modifications are committed to the state // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number())) } - return nil, vm.Context{}, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash()) + return nil, vm.Context{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash()) } diff --git a/eth/backend.go b/eth/backend.go index 3fd027137c..2fdfe2dc38 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -31,11 +31,14 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/istanbul" + istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -86,6 +89,9 @@ type Ethereum struct { p2pServer *p2p.Server lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) + + // Quorum - consensus as eth-service (e.g. raft) + consensusServicePendingLogsFeed *event.Feed } // New creates a new Ethereum object (including the @@ -124,27 +130,64 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { } log.Info("Initialised chain configuration", "config", chainConfig) - eth := &Ethereum{ - config: config, - chainDb: chainDb, - eventMux: stack.EventMux(), - accountManager: stack.AccountManager(), - engine: CreateConsensusEngine(stack, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb), - closeBloomHandler: make(chan struct{}), - networkID: config.NetworkId, - gasPrice: config.Miner.GasPrice, - etherbase: config.Miner.Etherbase, - bloomRequests: make(chan chan *bloombits.Retrieval), - bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), - p2pServer: stack.Server(), + // changes to manipulate the chain id for migration from 2.0.2 and below version to 2.0.3 + // version of Quorum - this is applicable for v2.0.3 onwards + if chainConfig.IsQuorum { + if (chainConfig.ChainID != nil && chainConfig.ChainID.Int64() == 1) || config.NetworkId == 1 { + return nil, errors.New("Cannot have chain id or network id as 1.") + } } + if !rawdb.GetIsQuorumEIP155Activated(chainDb) && chainConfig.ChainID != nil { + //Upon starting the node, write the flag to disallow changing ChainID/EIP155 block after HF + rawdb.WriteQuorumEIP155Activation(chainDb) + } + + eth := &Ethereum{ + config: config, + chainDb: chainDb, + eventMux: stack.EventMux(), + accountManager: stack.AccountManager(), + engine: CreateConsensusEngine(stack, chainConfig, config, config.Miner.Notify, config.Miner.Noverify, chainDb), + closeBloomHandler: make(chan struct{}), + networkID: config.NetworkId, + gasPrice: config.Miner.GasPrice, + etherbase: config.Miner.Etherbase, + bloomRequests: make(chan chan *bloombits.Retrieval), + bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), + p2pServer: stack.Server(), + consensusServicePendingLogsFeed: new(event.Feed), + } + + // Quorum: Set protocol Name/Version + // keep `var protocolName = "eth"` as is, and only update the quorum consensus specific protocol + // This is used to enable the eth service to return multiple devp2p subprotocols. + // Previously, for istanbul/64 istnbul/99 and clique (v2.6) `protocolName` would be overridden and + // set to the consensus subprotocol name instead of "eth", meaning the node would no longer + // communicate over the "eth" subprotocol, e.g. "eth" or "istanbul/99" but not eth" and "istanbul/99". + // With this change, support is added so that the "eth" subprotocol remains and optionally a consensus subprotocol + // can be added allowing the node to communicate over "eth" and an optional consensus subprotocol, e.g. "eth" and "istanbul/100" + if chainConfig.IsQuorum { + quorumProtocol := eth.engine.Protocol() + // set the quorum specific consensus devp2p subprotocol, eth subprotocol remains set to protocolName as in upstream geth. + quorumConsensusProtocolName = quorumProtocol.Name + quorumConsensusProtocolVersions = quorumProtocol.Versions + quorumConsensusProtocolLengths = quorumProtocol.Lengths + } + + // force to set the istanbul etherbase to node key address + if chainConfig.Istanbul != nil { + eth.etherbase = crypto.PubkeyToAddress(stack.GetNodeKey().PublicKey) + } bcVersion := rawdb.ReadDatabaseVersion(chainDb) var dbVer = "" if bcVersion != nil { dbVer = fmt.Sprintf("%d", *bcVersion) } - log.Info("Initialising Ethereum protocol", "versions", ProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) + log.Info("Initialising Ethereum protocol", "name", protocolName, "versions", ProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) + if chainConfig.IsQuorum { + log.Info("Initialising Quorum consensus protocol", "name", quorumConsensusProtocolName, "versions", quorumConsensusProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) + } if !config.SkipBcVersionCheck { if bcVersion != nil && *bcVersion > core.BlockChainVersion { @@ -171,7 +214,11 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { SnapshotLimit: config.SnapshotCache, } ) - eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit) + newBlockChainFunc := core.NewBlockChain + if config.EnableMultitenancy { + newBlockChainFunc = core.NewMultitenantBlockChain + } + eth.blockchain, err = newBlockChainFunc(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit) if err != nil { return nil, err } @@ -194,13 +241,14 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { if checkpoint == nil { checkpoint = params.TrustedCheckpoints[genesisHash] } - if eth.protocolManager, err = NewProtocolManager(chainConfig, checkpoint, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist); err != nil { + if eth.protocolManager, err = NewProtocolManager(chainConfig, checkpoint, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist, config.RaftMode); err != nil { return nil, err } eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) - eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) + eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData, eth.blockchain.Config().IsQuorum)) - eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), eth, nil} + hexNodeId := fmt.Sprintf("%x", crypto.FromECDSAPub(&stack.GetNodeKey().PublicKey)[1:]) // Quorum + eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), eth, nil, hexNodeId, config.EVMCallTimeOut} gpoParams := config.GPO if gpoParams.Default == nil { gpoParams.Default = config.Miner.GasPrice @@ -222,7 +270,7 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { return eth, nil } -func makeExtraData(extra []byte) []byte { +func makeExtraData(extra []byte, isQuorum bool) []byte { if len(extra) == 0 { // create default extradata extra, _ = rlp.EncodeToBytes([]interface{}{ @@ -232,21 +280,34 @@ func makeExtraData(extra []byte) []byte { runtime.GOOS, }) } - if uint64(len(extra)) > params.MaximumExtraDataSize { - log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.MaximumExtraDataSize) + if uint64(len(extra)) > params.GetMaximumExtraDataSize(isQuorum) { + log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.GetMaximumExtraDataSize(isQuorum)) extra = nil } return extra } // CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service -func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { +func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { // If proof-of-authority is requested, set it up if chainConfig.Clique != nil { + chainConfig.Clique.AllowedFutureBlockTime = config.Miner.AllowedFutureBlockTime //Quorum return clique.New(chainConfig.Clique, db) } + // If Istanbul is requested, set it up + if chainConfig.Istanbul != nil { + if chainConfig.Istanbul.Epoch != 0 { + config.Istanbul.Epoch = chainConfig.Istanbul.Epoch + } + config.Istanbul.ProposerPolicy = istanbul.ProposerPolicy(chainConfig.Istanbul.ProposerPolicy) + config.Istanbul.Ceil2Nby3Block = chainConfig.Istanbul.Ceil2Nby3Block + config.Istanbul.AllowedFutureBlockTime = config.Miner.AllowedFutureBlockTime //Quorum + + return istanbulBackend.New(&config.Istanbul, stack.GetNodeKey(), db) + } + // Otherwise assume proof-of-work - switch config.PowMode { + switch config.Ethash.PowMode { case ethash.ModeFake: log.Warn("Ethash used in fake mode") return ethash.NewFaker() @@ -257,18 +318,11 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, co log.Warn("Ethash used in shared mode") return ethash.NewShared() default: - engine := ethash.New(ethash.Config{ - CacheDir: stack.ResolvePath(config.CacheDir), - CachesInMem: config.CachesInMem, - CachesOnDisk: config.CachesOnDisk, - CachesLockMmap: config.CachesLockMmap, - DatasetDir: config.DatasetDir, - DatasetsInMem: config.DatasetsInMem, - DatasetsOnDisk: config.DatasetsOnDisk, - DatasetsLockMmap: config.DatasetsLockMmap, - }, notify, noverify) - engine.SetThreads(-1) // Disable CPU mining - return engine + // For Quorum, Raft run as a separate service, so + // the Ethereum service still needs a consensus engine, + // use the consensus with the lightest overhead + log.Warn("Ethash used in full fake mode") + return ethash.NewFullFaker() } } @@ -281,7 +335,7 @@ func (s *Ethereum) APIs() []rpc.API { apis = append(apis, s.engine.APIs(s.BlockChain())...) // Append all the local APIs and return - return append(apis, []rpc.API{ + apis = append(apis, []rpc.API{ { Namespace: "eth", Version: "1.0", @@ -327,6 +381,7 @@ func (s *Ethereum) APIs() []rpc.API { Public: true, }, }...) + return apis } func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { @@ -413,8 +468,12 @@ func (s *Ethereum) shouldPreserve(block *types.Block) bool { // SetEtherbase sets the mining reward address. func (s *Ethereum) SetEtherbase(etherbase common.Address) { s.lock.Lock() + defer s.lock.Unlock() + if _, ok := s.engine.(consensus.Istanbul); ok { + log.Error("Cannot set etherbase in Istanbul consensus") + return + } s.etherbase = etherbase - s.lock.Unlock() s.miner.SetEtherbase(etherbase) } @@ -496,6 +555,17 @@ func (s *Ethereum) Synced() bool { return atomic.LoadUint3 func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning } func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer } +// Quorum +// adds quorum specific protocols to the Protocols() function which in the associated upstream geth version returns +// only one subprotocol, "eth", and the supported versions of the "eth" protocol. +// Quorum uses the eth service to run configurable consensus protocols, e.g. istanbul. Thru release v20.10.0 +// the "eth" subprotocol would be replaced with a modified subprotocol, e.g. "istanbul/99" which would contain all the "eth" +// messages + the istanbul message and be communicated over the consensus specific subprotocol ("istanbul"), and +// not over "eth". +// Now the eth service supports multiple protocols, e.g. "eth" and an optional consensus +// protocol, e.g. "istanbul/100". +// /Quorum + // Protocols returns all the currently configured // network protocols to start. func (s *Ethereum) Protocols() []p2p.Protocol { @@ -505,6 +575,15 @@ func (s *Ethereum) Protocols() []p2p.Protocol { protos[i].Attributes = []enr.Entry{s.currentEthEntry()} protos[i].DialCandidates = s.dialCandidates } + + // /Quorum + // add additional quorum consensus protocol if set and if not set to "eth", e.g. istanbul + if quorumConsensusProtocolName != "" && quorumConsensusProtocolName != protocolName { + quorumProtos := s.quorumConsensusProtocols() + protos = append(protos, quorumProtos...) + } + // /end Quorum + return protos } @@ -546,3 +625,22 @@ func (s *Ethereum) Stop() error { s.eventMux.Stop() return nil } + +func (s *Ethereum) CalcGasLimit(block *types.Block) uint64 { + return core.CalcGasLimit(block, s.config.Miner.GasFloor, s.config.Miner.GasCeil) +} + +// (Quorum) +// ConsensusServicePendingLogsFeed returns an event.Feed. When the consensus protocol does not use eth.worker (e.g. raft), the event.Feed should be used to send logs from transactions included in the pending block +func (s *Ethereum) ConsensusServicePendingLogsFeed() *event.Feed { + return s.consensusServicePendingLogsFeed +} + +// (Quorum) +// SubscribePendingLogs starts delivering logs from transactions included in the consensus engine's pending block to the given channel. +func (s *Ethereum) SubscribePendingLogs(ch chan<- []*types.Log) event.Subscription { + if s.config.RaftMode { + return s.consensusServicePendingLogsFeed.Subscribe(ch) + } + return s.miner.SubscribePendingLogs(ch) +} diff --git a/eth/bloombits.go b/eth/bloombits.go index bd34bd7b69..c82b7686f1 100644 --- a/eth/bloombits.go +++ b/eth/bloombits.go @@ -115,10 +115,14 @@ func (b *BloomIndexer) Reset(ctx context.Context, section uint64, lastSectionHea return err } -// Process implements core.ChainIndexerBackend, adding a new header's bloom into -// the index. +// Process implements core.ChainIndexerBackend, executes an Or operation on header.bloom and private bloom +// (header.bloom | private bloom) and adds to index func (b *BloomIndexer) Process(ctx context.Context, header *types.Header) error { - b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom) + publicBloom := header.Bloom + privateBloom := rawdb.GetPrivateBlockBloom(b.db, header.Number.Uint64()) + publicBloom.OrBloom(privateBloom.Bytes()) + + b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), publicBloom) b.head = header.Hash() return nil } diff --git a/eth/config.go b/eth/config.go index 1074e5a371..4796ce3044 100644 --- a/eth/config.go +++ b/eth/config.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/istanbul" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -57,10 +58,10 @@ var DefaultConfig = Config{ DatasetsOnDisk: 2, DatasetsLockMmap: false, }, - NetworkId: 1, + NetworkId: 1337, LightPeers: 100, UltraLightFraction: 75, - DatabaseCache: 512, + DatabaseCache: 768, TrieCleanCache: 154, TrieCleanCacheJournal: "triecache", TrieCleanCacheRejournal: 60 * time.Minute, @@ -68,8 +69,8 @@ var DefaultConfig = Config{ TrieTimeout: 60 * time.Minute, SnapshotCache: 102, Miner: miner.Config{ - GasFloor: 8000000, - GasCeil: 8000000, + GasFloor: params.MinGasLimit, + GasCeil: params.GenesisGasLimit, GasPrice: big.NewInt(params.GWei), Recommit: 3 * time.Second, }, @@ -77,6 +78,8 @@ var DefaultConfig = Config{ RPCGasCap: 25000000, GPO: DefaultFullGPOConfig, RPCTxFeeCap: 1, // 1 ether + + Istanbul: *istanbul.DefaultConfig, // Quorum } func init() { @@ -163,6 +166,11 @@ type Config struct { // Enables tracking of SHA3 preimages in the VM EnablePreimageRecording bool + RaftMode bool + EnableNodePermission bool + // Istanbul options + Istanbul istanbul.Config + // Miscellaneous options DocRoot string `toml:"-"` @@ -184,4 +192,11 @@ type Config struct { // CheckpointOracle is the configuration for checkpoint oracle. CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` + + // Quorum + // timeout value for call + EVMCallTimeOut time.Duration + + // Quorum + EnableMultitenancy bool `toml:"-"` } diff --git a/eth/config_test.go b/eth/config_test.go new file mode 100644 index 0000000000..b50ae1b25c --- /dev/null +++ b/eth/config_test.go @@ -0,0 +1,21 @@ +package eth + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestQuorumDefautConfig(t *testing.T) { + type data struct { + actual uint64 + expected uint64 + } + var testData = map[string]data{ + "eth.DefaultConfig.Miner.GasFloor": {DefaultConfig.Miner.GasFloor, 700000000}, + "eth.DefaultConfig.Miner.GasCeil": {DefaultConfig.Miner.GasCeil, 800000000}, + } + for k, v := range testData { + assert.Equal(t, v.expected, v.actual, k+" value mismatch") + } +} diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 9c19543a46..98a457d173 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/permission/core" "github.com/ethereum/go-ethereum/trie" ) @@ -86,6 +87,8 @@ var ( errInvalidBody = errors.New("retrieved block body is invalid") errInvalidReceipt = errors.New("retrieved receipt is invalid") errCancelStateFetch = errors.New("state data download canceled (requested)") + errCancelHeaderFetch = errors.New("block header download canceled (requested)") + errCancelBlockFetch = errors.New("block download canceled (requested)") errCancelContentProcessing = errors.New("content processing canceled (requested)") errCanceled = errors.New("syncing canceled (requested)") errNoSyncActive = errors.New("no sync active") @@ -211,6 +214,11 @@ type BlockChain interface { // New creates a new downloader to fetch hashes and blocks from remote peers. func New(checkpoint uint64, stateDb ethdb.Database, stateBloom *trie.SyncBloom, mux *event.TypeMux, chain BlockChain, lightchain LightChain, dropPeer peerDropFn) *Downloader { + // Quorum + // reset the value of maxForkAncenstry for Quorum based + fullMaxForkAncestry = uint64(params.GetImmutabilityThreshold()) + // End Quorum + if lightchain == nil { lightchain = chain } @@ -366,6 +374,11 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode if !atomic.CompareAndSwapInt32(&d.synchronising, 0, 1) { return errBusy } + + // Quorum + // changes for permissions. added set sync status to indicate permissions that node sync has started + core.SetSyncStatus() + defer atomic.StoreInt32(&d.synchronising, 0) // Post a user notification of the sync (only once per session) @@ -420,6 +433,9 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode if p == nil { return errUnknownPeer } + if mode == BoundedFullSync { + return d.syncWithPeerUntil(p, hash, td) + } return d.syncWithPeer(p, hash, td) } @@ -1516,7 +1532,7 @@ func (d *Downloader) processHeaders(origin uint64, pivot uint64, td *big.Int) er } } // Unless we're doing light chains, schedule the headers for associated content retrieval - if mode == FullSync || mode == FastSync { + if mode == FullSync || mode == FastSync || mode == BoundedFullSync { // If we've reached the allowed number of pending headers, stall a bit for d.queue.PendingBlocks() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders { select { @@ -1907,3 +1923,229 @@ func (d *Downloader) requestTTL() time.Duration { } return ttl } + +// Extra downloader functionality for non-proof-of-work consensus + +// Synchronizes with a peer, but only up to the provided Hash +func (d *Downloader) syncWithPeerUntil(p *peerConnection, hash common.Hash, td *big.Int) (err error) { + d.mux.Post(StartEvent{}) + defer func() { + // reset on error + if err != nil { + d.mux.Post(FailedEvent{err}) + } else { + // Raft syncWithPeerUntil never use the latest field in DoneEvent + // therefore post empty DoneEvent only + d.mux.Post(DoneEvent{}) + } + }() + if p.version < 62 { + return errTooOld + } + + log.Info("Synchronising with the network", "id", p.id, "version", p.version) + defer func(start time.Time) { + log.Info("Synchronisation terminated", "duration", time.Since(start)) + }(time.Now()) + + frozen, _ := d.stateDB.Ancients() + localHeight := d.blockchain.CurrentBlock().NumberU64() + + // check if recovering state db and only ancient db is present + // in this case its possible that local hash is not the latest + // as per raft wal. change header to remote header + var remoteHeader *types.Header + if localHeight == 0 && frozen > 0 { + // statedb was removed and is being recovered now + // we trust the peer height and sync upto that + remoteHeader, err = d.fetchHeight(p) + } else { + remoteHeader, err = d.fetchHeader(p, hash) + } + if err != nil { + return err + } + + remoteHeight := remoteHeader.Number.Uint64() + + d.syncStatsLock.Lock() + if d.syncStatsChainHeight <= localHeight || d.syncStatsChainOrigin > localHeight { + d.syncStatsChainOrigin = localHeight + } + d.syncStatsChainHeight = remoteHeight + d.syncStatsLock.Unlock() + + d.queue.Prepare(localHeight+1, d.getMode()) + if d.syncInitHook != nil { + d.syncInitHook(localHeight, remoteHeight) + } + + pivot := uint64(0) + + fetchers := []func() error{ + func() error { return d.fetchBoundedHeaders(p, localHeight+1, remoteHeight) }, + func() error { return d.fetchBodies(localHeight + 1) }, + func() error { return d.fetchReceipts(localHeight + 1) }, // Receipts are only retrieved during fast sync + func() error { return d.processHeaders(localHeight+1, pivot, td) }, + d.processFullSyncContent, //This must be added to clear the buffer of downloaded content as it's being filled + } + return d.spawnSync(fetchers) +} + +// Fetches a single header from a peer +func (d *Downloader) fetchHeader(p *peerConnection, hash common.Hash) (*types.Header, error) { + log.Info("retrieving remote chain height", "peer", p) + + go p.peer.RequestHeadersByHash(hash, 1, 0, false) + + timeout := time.After(d.requestTTL()) + for { + select { + case <-d.cancelCh: + return nil, errCancelBlockFetch + + case packet := <-d.headerCh: + // Discard anything not from the origin peer + if packet.PeerId() != p.id { + log.Info("Received headers from incorrect peer", "peer id", packet.PeerId()) + break + } + // Make sure the peer actually gave something valid + headers := packet.(*headerPack).headers + if len(headers) != 1 { + log.Info("invalid number of head headers (!= 1)", "peer", p, "len(headers)", len(headers)) + return nil, errBadPeer + } + return headers[0], nil + + case <-timeout: + log.Info("head header timeout", "peer", p) + return nil, errTimeout + + case <-d.bodyCh: + case <-d.stateCh: + case <-d.receiptCh: + // Out of bounds delivery, ignore + } + } +} + +// Not defined in go's stdlib: +func minInt(a, b int) int { + if a < b { + return a + } + return b +} + +// Fetches headers between `from` and `to`, inclusive. +// Assumes invariant: from <= to. +func (d *Downloader) fetchBoundedHeaders(p *peerConnection, from uint64, to uint64) error { + log.Info("directing header downloads", "peer", p, "from", from, "to", to) + defer log.Info("header download terminated", "peer", p) + + // Create a timeout timer, and the associated header fetcher + skeleton := true // Skeleton assembly phase or finishing up + request := time.Now() // time of the last skeleton fetch request + timeout := time.NewTimer(0) // timer to dump a non-responsive active peer + <-timeout.C // timeout channel should be initially empty + defer timeout.Stop() + + getHeaders := func(from uint64) { + request = time.Now() + timeout.Reset(d.requestTTL()) + + skeletonStart := from + uint64(MaxHeaderFetch) - 1 + + if skeleton { + if skeletonStart > to { + skeleton = false + } + } + + if skeleton { + numSkeletonHeaders := minInt(MaxSkeletonSize, (int(to-from)+1)/MaxHeaderFetch) + log.Trace("fetching skeleton headers", "peer", p, "num skeleton headers", numSkeletonHeaders, "from", from) + go p.peer.RequestHeadersByNumber(skeletonStart, numSkeletonHeaders, MaxHeaderFetch-1, false) + } else { + // There are not enough headers remaining to warrant a skeleton fetch. + // Grab all of the remaining headers. + + numHeaders := int(to-from) + 1 + log.Trace("fetching full headers", "peer", p, "num headers", numHeaders, "from", from) + go p.peer.RequestHeadersByNumber(from, numHeaders, 0, false) + } + } + // Start pulling the header chain skeleton until all is done + getHeaders(from) + + for { + select { + case <-d.cancelCh: + return errCancelHeaderFetch + + case packet := <-d.headerCh: + // Make sure the active peer is giving us the skeleton headers + if packet.PeerId() != p.id { + log.Info("Received headers from incorrect peer", "peer id", packet.PeerId()) + break + } + headerReqTimer.UpdateSince(request) + timeout.Stop() + + headers := packet.(*headerPack).headers + + // If we received a skeleton batch, resolve internals concurrently + if skeleton { + filled, proced, err := d.fillHeaderSkeleton(from, headers) + if err != nil { + log.Debug("skeleton chain invalid", "peer", p, "err", err) + return errInvalidChain + } + headers = filled[proced:] + from += uint64(proced) + } + // Insert all the new headers and fetch the next batch + if len(headers) > 0 { + log.Trace("schedule headers", "peer", p, "num headers", len(headers), "from", from) + select { + case d.headerProcCh <- headers: + case <-d.cancelCh: + return errCancelHeaderFetch + } + from += uint64(len(headers)) + } + + if from <= to { + getHeaders(from) + } else { + // Notify the content fetchers that no more headers are inbound and return. + select { + case d.headerProcCh <- nil: + return nil + case <-d.cancelCh: + return errCancelHeaderFetch + } + } + + case <-timeout.C: + // Header retrieval timed out, consider the peer bad and drop + log.Info("header request timed out", "peer", p) + headerTimeoutMeter.Mark(1) + d.dropPeer(p.id) + + // Finish the sync gracefully instead of dumping the gathered data though + for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh} { + select { + case ch <- false: + case <-d.cancelCh: + } + } + select { + case d.headerProcCh <- nil: + case <-d.cancelCh: + } + return errBadPeer + } + } +} diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 51d485761b..59325339ae 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" ) @@ -41,6 +42,9 @@ func init() { lightMaxForkAncestry = 10000 blockCacheMaxItems = 1024 fsHeaderContCheck = 500 * time.Millisecond + + // set immutability threshold to 10000 as well + params.SetQuorumImmutabilityThreshold(10000) } // downloadTester is a test simulator for mocking out local block chain. diff --git a/eth/downloader/modes.go b/eth/downloader/modes.go index d866ceabce..3f5749ac99 100644 --- a/eth/downloader/modes.go +++ b/eth/downloader/modes.go @@ -26,6 +26,8 @@ const ( FullSync SyncMode = iota // Synchronise the entire blockchain history from full blocks FastSync // Quickly download the headers, full sync only at the chain head LightSync // Download only the headers and terminate afterwards + // Used by raft: + BoundedFullSync SyncMode = 100 // Perform a full sync until the requested hash, and no further ) func (mode SyncMode) IsValid() bool { diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go index c6671436f9..5ad499d6cd 100644 --- a/eth/downloader/peer.go +++ b/eth/downloader/peer.go @@ -29,6 +29,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" ) @@ -512,7 +513,7 @@ func (ps *peerSet) idlePeers(minProtocol, maxProtocol int, idleCheck func(*peerC idle, total := make([]*peerConnection, 0, len(ps.peers)), 0 tps := make([]float64, 0, len(ps.peers)) for _, p := range ps.peers { - if p.version >= minProtocol && p.version <= maxProtocol { + if p.version >= minProtocol && p.version <= maxProtocol || p.version == consensus.Istanbul99 { if idleCheck(p) { idle = append(idle, p) tps = append(tps, throughput(p)) diff --git a/eth/filters/api.go b/eth/filters/api.go index 30d7b71c31..922a65adbf 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -244,6 +244,11 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc rpcSub = notifier.CreateSubscription() matchedLogs = make(chan []*types.Log) ) + psm, err := api.backend.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } + crit.PSI = psm.ID logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), matchedLogs) if err != nil { @@ -288,8 +293,13 @@ type FilterCriteria ethereum.FilterQuery // In case "fromBlock" > "toBlock" an error is returned. // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter -func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { +func (api *PublicFilterAPI) NewFilter(ctx context.Context, crit FilterCriteria) (rpc.ID, error) { logs := make(chan []*types.Log) + psm, err := api.backend.PSMR().ResolveForUserContext(ctx) + if err != nil { + return rpc.ID(""), err + } + crit.PSI = psm.ID logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), logs) if err != nil { return rpc.ID(""), err @@ -324,10 +334,14 @@ func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) { + psm, err := api.backend.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } var filter *Filter if crit.BlockHash != nil { // Block filter requested, construct a single-shot filter - filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics) + filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics, psm.ID) } else { // Convert the RPC block numbers into internal representations begin := rpc.LatestBlockNumber.Int64() @@ -339,7 +353,7 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([ end = crit.ToBlock.Int64() } // Construct the range filter - filter = NewRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics) + filter = NewRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics, psm.ID) } // Run the filter and return all the logs logs, err := filter.Logs(ctx) @@ -371,6 +385,10 @@ func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool { // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Log, error) { + psm, err := api.backend.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } api.filtersMu.Lock() f, found := api.filters[id] api.filtersMu.Unlock() @@ -378,11 +396,18 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty if !found || f.typ != LogsSubscription { return nil, fmt.Errorf("filter not found") } - + // Quorum: + // - Make sure the tenant has access to the filter + // - Even when MPS or Multitenancy is not enabled, the DefaultPrivateStateIdentifier values + // will be populated in both context and filter criteria. So this check is safe without + // the need of checking for multitenancy enablement + if psm.ID != f.crit.PSI { + return nil, fmt.Errorf("filter not found for %v", psm.ID) + } var filter *Filter if f.crit.BlockHash != nil { // Block filter requested, construct a single-shot filter - filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics) + filter = NewBlockFilter(api.backend, *f.crit.BlockHash, f.crit.Addresses, f.crit.Topics, psm.ID) } else { // Convert the RPC block numbers into internal representations begin := rpc.LatestBlockNumber.Int64() @@ -394,7 +419,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty end = f.crit.ToBlock.Int64() } // Construct the range filter - filter = NewRangeFilter(api.backend, begin, end, f.crit.Addresses, f.crit.Topics) + filter = NewRangeFilter(api.backend, begin, end, f.crit.Addresses, f.crit.Topics, psm.ID) } // Run the filter and return all the logs logs, err := filter.Logs(ctx) @@ -411,7 +436,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty // (pending)Log filters return []Log. // // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterchanges -func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { +func (api *PublicFilterAPI) GetFilterChanges(ctx context.Context, id rpc.ID) (interface{}, error) { api.filtersMu.Lock() defer api.filtersMu.Unlock() diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go index 4f70d6d04a..42c1245117 100644 --- a/eth/filters/bench_test.go +++ b/eth/filters/bench_test.go @@ -132,7 +132,7 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) { var addr common.Address addr[0] = byte(i) addr[1] = byte(i / 256) - filter := NewRangeFilter(backend, 0, int64(cnt*sectionSize-1), []common.Address{addr}, nil) + filter := NewRangeFilter(backend, 0, int64(cnt*sectionSize-1), []common.Address{addr}, nil, "") if _, err := filter.Logs(context.Background()); err != nil { b.Error("filter.Find error:", err) } @@ -172,7 +172,7 @@ func BenchmarkNoBloomBits(b *testing.B) { b.Log("Running filter benchmarks...") start := time.Now() backend := &testBackend{db: db} - filter := NewRangeFilter(backend, 0, int64(*headNum), []common.Address{{}}, nil) + filter := NewRangeFilter(backend, 0, int64(*headNum), []common.Address{{}}, nil, "") filter.Logs(context.Background()) d := time.Since(start) b.Log("Finished running filter benchmarks") diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 17635837af..60e21f4522 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -24,7 +24,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" @@ -45,6 +48,10 @@ type Backend interface { BloomStatus() (uint64, uint64) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) + + // AccountExtraDataStateGetterByNumber returns state getter at a given block height + AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) + PSMR() mps.PrivateStateMetadataResolver } // Filter can be used to retrieve and filter logs. @@ -54,6 +61,7 @@ type Filter struct { db ethdb.Database addresses []common.Address topics [][]common.Hash + psi types.PrivateStateIdentifier block common.Hash // Block hash if filtering a single block begin, end int64 // Range interval if filtering multiple blocks @@ -63,7 +71,7 @@ type Filter struct { // NewRangeFilter creates a new filter which uses a bloom filter on blocks to // figure out whether a particular block is interesting or not. -func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { +func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Address, topics [][]common.Hash, psi types.PrivateStateIdentifier) *Filter { // Flatten the address and topic filter clauses into a single bloombits filter // system. Since the bloombits are not positional, nil topics are permitted, // which get flattened into a nil byte slice. @@ -85,7 +93,7 @@ func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Addres size, _ := backend.BloomStatus() // Create a generic filter and convert it into a range filter - filter := newFilter(backend, addresses, topics) + filter := newFilter(backend, addresses, topics, psi) filter.matcher = bloombits.NewMatcher(size, filters) filter.begin = begin @@ -96,20 +104,21 @@ func NewRangeFilter(backend Backend, begin, end int64, addresses []common.Addres // NewBlockFilter creates a new filter which directly inspects the contents of // a block to figure out whether it is interesting or not. -func NewBlockFilter(backend Backend, block common.Hash, addresses []common.Address, topics [][]common.Hash) *Filter { +func NewBlockFilter(backend Backend, block common.Hash, addresses []common.Address, topics [][]common.Hash, psi types.PrivateStateIdentifier) *Filter { // Create a generic filter and convert it into a block filter - filter := newFilter(backend, addresses, topics) + filter := newFilter(backend, addresses, topics, psi) filter.block = block return filter } // newFilter creates a generic filter that can either filter based on a block hash, // or based on range queries. The search criteria needs to be explicitly set. -func newFilter(backend Backend, addresses []common.Address, topics [][]common.Hash) *Filter { +func newFilter(backend Backend, addresses []common.Address, topics [][]common.Hash, psi types.PrivateStateIdentifier) *Filter { return &Filter{ backend: backend, addresses: addresses, topics: topics, + psi: psi, db: backend.ChainDb(), } } @@ -231,7 +240,11 @@ func (f *Filter) unindexedLogs(ctx context.Context, end uint64) ([]*types.Log, e // blockLogs returns the logs matching the filter criteria within a single block. func (f *Filter) blockLogs(ctx context.Context, header *types.Header) (logs []*types.Log, err error) { - if bloomFilter(header.Bloom, f.addresses, f.topics) { + // Quorum + // Apply bloom filter for both public bloom and private bloom + bloomMatches := bloomFilter(header.Bloom, f.addresses, f.topics) || + bloomFilter(rawdb.GetPrivateBlockBloom(f.db, header.Number.Uint64()), f.addresses, f.topics) + if bloomMatches { found, err := f.checkMatches(ctx, header) if err != nil { return logs, err @@ -253,7 +266,7 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs [ for _, logs := range logsList { unfiltered = append(unfiltered, logs...) } - logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics) + logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics, f.psi) if len(logs) > 0 { // We have matching logs, check if we need to resolve full logs via the light client if logs[0].TxHash == (common.Hash{}) { @@ -265,7 +278,7 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs [ for _, receipt := range receipts { unfiltered = append(unfiltered, receipt.Logs...) } - logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics) + logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics, f.psi) } return logs, nil } @@ -283,7 +296,7 @@ func includes(addresses []common.Address, a common.Address) bool { } // filterLogs creates a slice of logs matching the given criteria. -func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log { +func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash, psi types.PrivateStateIdentifier) []*types.Log { var ret []*types.Log Logs: for _, log := range logs { @@ -297,6 +310,10 @@ Logs: if len(addresses) > 0 && !includes(addresses, log.Address) { continue } + + if len(log.PSI) > 0 && log.PSI != psi { + continue + } // If the to filtered topics is greater than the amount of topics in logs, skip. if len(topics) > len(log.Topics) { continue Logs diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index a105ec51c3..77487ff835 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -313,7 +313,7 @@ func (es *EventSystem) handleLogs(filters filterIndex, ev []*types.Log) { return } for _, f := range filters[LogsSubscription] { - matchedLogs := filterLogs(ev, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics) + matchedLogs := filterLogs(ev, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics, f.logsCrit.PSI) if len(matchedLogs) > 0 { f.logs <- matchedLogs } @@ -325,7 +325,7 @@ func (es *EventSystem) handlePendingLogs(filters filterIndex, ev []*types.Log) { return } for _, f := range filters[PendingLogsSubscription] { - matchedLogs := filterLogs(ev, nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics) + matchedLogs := filterLogs(ev, nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics, f.logsCrit.PSI) if len(matchedLogs) > 0 { f.logs <- matchedLogs } @@ -334,7 +334,7 @@ func (es *EventSystem) handlePendingLogs(filters filterIndex, ev []*types.Log) { func (es *EventSystem) handleRemovedLogs(filters filterIndex, ev core.RemovedLogsEvent) { for _, f := range filters[LogsSubscription] { - matchedLogs := filterLogs(ev.Logs, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics) + matchedLogs := filterLogs(ev.Logs, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics, f.logsCrit.PSI) if len(matchedLogs) > 0 { f.logs <- matchedLogs } @@ -417,7 +417,7 @@ func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common. unfiltered = append(unfiltered, &logcopy) } } - logs := filterLogs(unfiltered, nil, nil, addresses, topics) + logs := filterLogs(unfiltered, nil, nil, addresses, topics, "") if len(logs) > 0 && logs[0].TxHash == (common.Hash{}) { // We have matching but non-derived logs receipts, err := es.backend.GetReceipts(ctx, header.Hash()) @@ -432,7 +432,7 @@ func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common. unfiltered = append(unfiltered, &logcopy) } } - logs = filterLogs(unfiltered, nil, nil, addresses, topics) + logs = filterLogs(unfiltered, nil, nil, addresses, topics, "") } return logs } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index c8d1d43abb..acf1997a14 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -25,13 +25,15 @@ import ( "testing" "time" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" @@ -82,18 +84,36 @@ func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*type func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil { - return rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig), nil + receipts := rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig) + + psm, err := b.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil, err + } + + psiReceipts := make([]*types.Receipt, len(receipts)) + for i := 0; i < len(receipts); i++ { + psiReceipts[i] = receipts[i] + if receipts[i].PSReceipts != nil { + psReceipt, found := receipts[i].PSReceipts[psm.ID] + if found { + psiReceipts[i] = psReceipt + } + } + } + return psiReceipts, nil } return nil, nil } func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - number := rawdb.ReadHeaderNumber(b.db, hash) - if number == nil { + receipts, err := b.GetReceipts(ctx, hash) + if err != nil { + return nil, err + } + if receipts == nil { return nil, nil } - receipts := rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig) - logs := make([][]*types.Log, len(receipts)) for i, receipt := range receipts { logs[i] = receipt.Logs @@ -152,6 +172,14 @@ func (b *testBackend) ServiceFilter(ctx context.Context, session *bloombits.Matc }() } +func (b *testBackend) AccountExtraDataStateGetterByNumber(context.Context, rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) { + return nil, nil +} + +func (b *testBackend) PSMR() mps.PrivateStateMetadataResolver { + return &core.DefaultPrivateStateManager{} +} + // TestBlockSubscription tests if a block subscription returns block hashes for posted chain events. // It creates multiple subscriptions: // - one at the start and should receive all posted chain events and a second (blockHashes) @@ -235,7 +263,7 @@ func TestPendingTxFilter(t *testing.T) { timeout := time.Now().Add(1 * time.Second) for { - results, err := api.GetFilterChanges(fid0) + results, err := api.GetFilterChanges(context.Background(), fid0) if err != nil { t.Fatalf("Unable to retrieve logs: %v", err) } @@ -296,7 +324,7 @@ func TestLogFilterCreation(t *testing.T) { ) for i, test := range testCases { - _, err := api.NewFilter(test.crit) + _, err := api.NewFilter(context.Background(), test.crit) if test.success && err != nil { t.Errorf("expected filter creation for case %d to success, got %v", i, err) } @@ -326,7 +354,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { } for i, test := range testCases { - if _, err := api.NewFilter(test); err == nil { + if _, err := api.NewFilter(context.Background(), test); err == nil { t.Errorf("Expected NewFilter for case #%d to fail", i) } } @@ -419,7 +447,7 @@ func TestLogFilter(t *testing.T) { // create all filters for i := range testCases { - testCases[i].id, _ = api.NewFilter(testCases[i].crit) + testCases[i].id, _ = api.NewFilter(context.Background(), testCases[i].crit) } // raise events @@ -435,7 +463,7 @@ func TestLogFilter(t *testing.T) { var fetched []*types.Log timeout := time.Now().Add(1 * time.Second) for { // fetch all expected logs - results, err := api.GetFilterChanges(tt.id) + results, err := api.GetFilterChanges(context.Background(), tt.id) if err != nil { t.Fatalf("Unable to fetch logs: %v", err) } diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index f45720d5a9..f1ea7b472e 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" ) func makeReceipt(addr common.Address) *types.Receipt { @@ -85,7 +86,7 @@ func BenchmarkFilters(b *testing.B) { } b.ResetTimer() - filter := NewRangeFilter(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil) + filter := NewRangeFilter(backend, 0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil, "") for i := 0; i < b.N; i++ { logs, _ := filter.Logs(context.Background()) @@ -112,6 +113,7 @@ func TestFilters(t *testing.T) { hash2 = common.BytesToHash([]byte("topic2")) hash3 = common.BytesToHash([]byte("topic3")) hash4 = common.BytesToHash([]byte("topic4")) + hash5 = common.BytesToHash([]byte("privateTopic")) ) defer db.Close() @@ -149,6 +151,19 @@ func TestFilters(t *testing.T) { } gen.AddUncheckedReceipt(receipt) gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil)) + // Add pseudo Quorum private transaction + privateReceipt := types.NewReceipt(nil, false, 0) + privateReceipt.Logs = []*types.Log{ + { + Address: addr, + Topics: []common.Hash{hash5}, + }, + } + if err := rawdb.WritePrivateBlockBloom(db, 999, []*types.Receipt{privateReceipt}); err != nil { + t.Fatal(err) + } + gen.AddUncheckedReceipt(privateReceipt) + gen.AddUncheckedTx(types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil)) case 999: receipt := types.NewReceipt(nil, false, 0) receipt.Logs = []*types.Log{ @@ -168,14 +183,14 @@ func TestFilters(t *testing.T) { rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i]) } - filter := NewRangeFilter(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}) + filter := NewRangeFilter(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}}, "") logs, _ := filter.Logs(context.Background()) if len(logs) != 4 { t.Error("expected 4 log, got", len(logs)) } - filter = NewRangeFilter(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}) + filter = NewRangeFilter(backend, 900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}, "") logs, _ = filter.Logs(context.Background()) if len(logs) != 1 { t.Error("expected 1 log, got", len(logs)) @@ -184,7 +199,7 @@ func TestFilters(t *testing.T) { t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) } - filter = NewRangeFilter(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}) + filter = NewRangeFilter(backend, 990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}, "") logs, _ = filter.Logs(context.Background()) if len(logs) != 1 { t.Error("expected 1 log, got", len(logs)) @@ -193,7 +208,7 @@ func TestFilters(t *testing.T) { t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash3, logs[0].Topics[0]) } - filter = NewRangeFilter(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}}) + filter = NewRangeFilter(backend, 1, 10, nil, [][]common.Hash{{hash1, hash2}}, "") logs, _ = filter.Logs(context.Background()) if len(logs) != 2 { @@ -201,7 +216,7 @@ func TestFilters(t *testing.T) { } failHash := common.BytesToHash([]byte("fail")) - filter = NewRangeFilter(backend, 0, -1, nil, [][]common.Hash{{failHash}}) + filter = NewRangeFilter(backend, 0, -1, nil, [][]common.Hash{{failHash}}, "") logs, _ = filter.Logs(context.Background()) if len(logs) != 0 { @@ -209,17 +224,171 @@ func TestFilters(t *testing.T) { } failAddr := common.BytesToAddress([]byte("failmenow")) - filter = NewRangeFilter(backend, 0, -1, []common.Address{failAddr}, nil) + filter = NewRangeFilter(backend, 0, -1, []common.Address{failAddr}, nil, "") logs, _ = filter.Logs(context.Background()) if len(logs) != 0 { t.Error("expected 0 log, got", len(logs)) } - filter = NewRangeFilter(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}}) + filter = NewRangeFilter(backend, 0, -1, nil, [][]common.Hash{{failHash}, {hash1}}, "") logs, _ = filter.Logs(context.Background()) if len(logs) != 0 { t.Error("expected 0 log, got", len(logs)) } + + // Quorum + + // Test individual private log with NewBlockFilter (query filter with block hash) + filter = NewBlockFilter(backend, chain[998].Hash(), nil, [][]common.Hash{{hash5}}, "") + + logs, _ = filter.Logs(context.Background()) + if len(logs) != 1 { + t.Error("expected 1 log, got", len(logs)) + } + if len(logs) > 0 && logs[0].Topics[0] != hash5 { + t.Errorf("expected log[0].Topics[0] to be %x, got %x", hash5, logs[0].Topics[0]) + } + + // Test a mix of public and private logs with NewBlockFilter (query filter with block hash) + filter = NewBlockFilter(backend, chain[998].Hash(), nil, [][]common.Hash{{hash3, hash5}}, "") + + logs, _ = filter.Logs(context.Background()) + if len(logs) != 2 { + t.Error("expected 2 log, got", len(logs)) + } + +} + +func TestMPSFilters(t *testing.T) { + dir, err := ioutil.TempDir("", "filtermpstest") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + var ( + db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "") + backend = &testBackend{db: db} + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr = crypto.PubkeyToAddress(key1.PublicKey) + hash1 = common.BytesToHash([]byte("topic1")) + ) + defer db.Close() + + noPSILog := []*types.Log{ + { + Address: addr, + Topics: []common.Hash{hash1}, + }, + } + + psi2PSILog := []*types.Log{ + { + Address: addr, + Topics: []common.Hash{hash1}, + PSI: types.PrivateStateIdentifier("psi2"), + }, + } + psi1PSILog := []*types.Log{ + { + Address: addr, + Topics: []common.Hash{hash1}, + PSI: types.PrivateStateIdentifier("psi1"), + }, + } + + genesis := core.GenesisBlockForTesting(db, addr, big.NewInt(1000000)) + chain, receipts := core.GenerateChain(params.QuorumMPSTestChainConfig, genesis, ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) { + switch i { + case 1: + //log on private transaction + //has "private" psi receipt + tx := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil) + tx.SetPrivate() + privateReceipt := types.NewReceipt(nil, false, 0) + privateReceipt.Logs = noPSILog + privateReceipt.PSReceipts = make(map[types.PrivateStateIdentifier]*types.Receipt) + psiReceipt := types.NewReceipt(nil, false, 0) + psiReceipt.Logs = psi2PSILog + privateReceipt.PSReceipts[types.PrivateStateIdentifier("psi2")] = psiReceipt + if err := rawdb.WritePrivateBlockBloom(db, 2, []*types.Receipt{privateReceipt}); err != nil { + t.Fatal(err) + } + gen.AddUncheckedReceipt(privateReceipt) + gen.AddUncheckedTx(tx) + case 2: + //no log on private transaction + //has "psi1" receipt + tx := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil) + tx.SetPrivate() + privateReceipt := types.NewReceipt(nil, false, 0) + privateReceipt.PSReceipts = make(map[types.PrivateStateIdentifier]*types.Receipt) + psiReceipt := types.NewReceipt(nil, false, 0) + psiReceipt.Logs = psi1PSILog + privateReceipt.PSReceipts[types.PrivateStateIdentifier("psi1")] = psiReceipt + if err := rawdb.WritePrivateBlockBloom(db, 3, []*types.Receipt{privateReceipt}); err != nil { + t.Fatal(err) + } + gen.AddUncheckedReceipt(privateReceipt) + gen.AddUncheckedTx(tx) + case 998: + //no log on private transaction + //has "psi2" psi receipt + tx := types.NewTransaction(998, common.HexToAddress("0x998"), big.NewInt(998), 998, big.NewInt(998), nil) + tx.SetPrivate() + privateReceipt := types.NewReceipt(nil, false, 0) + privateReceipt.PSReceipts = make(map[types.PrivateStateIdentifier]*types.Receipt) + psiReceipt := types.NewReceipt(nil, false, 0) + psiReceipt.Logs = psi2PSILog + privateReceipt.PSReceipts[types.PrivateStateIdentifier("psi2")] = psiReceipt + if err := rawdb.WritePrivateBlockBloom(db, 999, []*types.Receipt{privateReceipt}); err != nil { + t.Fatal(err) + } + gen.AddUncheckedReceipt(privateReceipt) + gen.AddUncheckedTx(tx) + case 999: + //log on private transaction + //no psi receipt + tx := types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, big.NewInt(999), nil) + tx.SetPrivate() + privateReceipt := types.NewReceipt(nil, false, 0) + privateReceipt.Logs = noPSILog + if err := rawdb.WritePrivateBlockBloom(db, 1000, []*types.Receipt{privateReceipt}); err != nil { + t.Fatal(err) + } + gen.AddUncheckedReceipt(privateReceipt) + gen.AddUncheckedTx(tx) + } + }) + for i, block := range chain { + rawdb.WriteBlock(db, block) + rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) + rawdb.WriteHeadBlockHash(db, block.Hash()) + rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i]) + } + + //no psi filter: but only gets top level private receipt logs(no psi) + filter := NewRangeFilter(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1}}, "") + logs, _ := filter.Logs(context.Background()) + if len(logs) != 2 { + t.Error("expected 2 logs, got", len(logs)) + } + + //test filtering "psi2" logs: gets psi2 logs and top level private receipt logs(no psi) + filter = NewRangeFilter(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1}}, types.ToPrivateStateIdentifier("psi2")) + ctx := rpc.WithPrivateStateIdentifier(context.Background(), types.ToPrivateStateIdentifier("psi2")) + logs, _ = filter.Logs(ctx) + if len(logs) != 3 { + t.Error("expected 3 logs, got", len(logs)) + } + + //test filtering "psi1" logs: gets psi1 logs and top level private receipt logs(no psi) + filter = NewRangeFilter(backend, 0, -1, []common.Address{addr}, [][]common.Hash{{hash1}}, types.PrivateStateIdentifier("psi1")) + ctx = rpc.WithPrivateStateIdentifier(context.Background(), types.ToPrivateStateIdentifier("psi1")) + logs, _ = filter.Logs(ctx) + if len(logs) != 3 { + t.Error("expected 3 logs, got", len(logs)) + } } diff --git a/eth/gen_config.go b/eth/gen_config.go index 0093439d14..b9d75ddcc9 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/consensus/istanbul" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -48,6 +49,7 @@ func (c Config) MarshalTOML() (interface{}, error) { TxPool core.TxPoolConfig GPO gasprice.Config EnablePreimageRecording bool + Istanbul istanbul.Config DocRoot string `toml:"-"` EWASMInterpreter string EVMInterpreter string @@ -88,6 +90,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.TxPool = c.TxPool enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording + enc.Istanbul = c.Istanbul enc.DocRoot = c.DocRoot enc.EWASMInterpreter = c.EWASMInterpreter enc.EVMInterpreter = c.EVMInterpreter @@ -132,6 +135,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { TxPool *core.TxPoolConfig GPO *gasprice.Config EnablePreimageRecording *bool + Istanbul *istanbul.Config DocRoot *string `toml:"-"` EWASMInterpreter *string EVMInterpreter *string @@ -237,6 +241,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.EnablePreimageRecording != nil { c.EnablePreimageRecording = *dec.EnablePreimageRecording } + if dec.Istanbul != nil { + c.Istanbul = *dec.Istanbul + } if dec.DocRoot != nil { c.DocRoot = *dec.DocRoot } diff --git a/eth/handler.go b/eth/handler.go index 7482a2f96e..552e80d3ae 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -28,9 +28,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/fetcher" "github.com/ethereum/go-ethereum/ethdb" @@ -95,13 +98,17 @@ type ProtocolManager struct { wg sync.WaitGroup peerWG sync.WaitGroup + // Quorum + raftMode bool + engine consensus.Engine + // Test fields or hooks broadcastTxAnnouncesOnly bool // Testing field, disable transaction propagation } // NewProtocolManager returns a new Ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // with the Ethereum network. -func NewProtocolManager(config *params.ChainConfig, checkpoint *params.TrustedCheckpoint, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database, cacheLimit int, whitelist map[uint64]common.Hash) (*ProtocolManager, error) { +func NewProtocolManager(config *params.ChainConfig, checkpoint *params.TrustedCheckpoint, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database, cacheLimit int, whitelist map[uint64]common.Hash, raftMode bool) (*ProtocolManager, error) { // Create the protocol manager with the base fields manager := &ProtocolManager{ networkID: networkID, @@ -114,7 +121,15 @@ func NewProtocolManager(config *params.ChainConfig, checkpoint *params.TrustedCh whitelist: whitelist, txsyncCh: make(chan *txsync), quitSync: make(chan struct{}), + raftMode: raftMode, + engine: engine, + } + + // Quorum + if handler, ok := manager.engine.(consensus.Handler); ok { + handler.SetBroadcaster(manager) } + // /Quorum if mode == downloader.FullSync { // The database seems empty as the current block is the genesis. Yet the fast @@ -205,6 +220,7 @@ func NewProtocolManager(config *params.ChainConfig, checkpoint *params.TrustedCh } func (pm *ProtocolManager) makeProtocol(version uint) p2p.Protocol { + // Quorum: Set p2p.Protocol info from engine.Protocol() length, ok := protocolLengths[version] if !ok { panic("makeProtocol for unknown version") @@ -215,7 +231,7 @@ func (pm *ProtocolManager) makeProtocol(version uint) p2p.Protocol { Version: version, Length: length, Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { - return pm.runPeer(pm.newPeer(int(version), p, rw, pm.txpool.Get)) + return pm.runPeer(pm.newPeer(int(version), p, rw, pm.txpool.Get), protocolName) }, NodeInfo: func() interface{} { return pm.NodeInfo() @@ -259,10 +275,19 @@ func (pm *ProtocolManager) Start(maxPeers int) { pm.txsSub = pm.txpool.SubscribeNewTxsEvent(pm.txsCh) go pm.txBroadcastLoop() - // broadcast mined blocks - pm.wg.Add(1) - pm.minedBlockSub = pm.eventMux.Subscribe(core.NewMinedBlockEvent{}) - go pm.minedBroadcastLoop() + // Quorum + if !pm.raftMode { + // broadcast mined blocks + pm.wg.Add(1) + pm.minedBlockSub = pm.eventMux.Subscribe(core.NewMinedBlockEvent{}) + go pm.minedBroadcastLoop() + } else { + // We set this immediately in raft mode to make sure the miner never drops + // incoming txes. Raft mode doesn't use the fetcher or downloader, and so + // this would never be set otherwise. + atomic.StoreUint32(&pm.acceptTxs, 1) + } + // /Quorum // start sync handlers pm.wg.Add(2) @@ -271,8 +296,10 @@ func (pm *ProtocolManager) Start(maxPeers int) { } func (pm *ProtocolManager) Stop() { - pm.txsSub.Unsubscribe() // quits txBroadcastLoop - pm.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop + pm.txsSub.Unsubscribe() // quits txBroadcastLoop + if !pm.raftMode { + pm.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop + } // Quit chainSync and txsync64. // After this is done, no new peers will be accepted. @@ -293,18 +320,20 @@ func (pm *ProtocolManager) newPeer(pv int, p *p2p.Peer, rw p2p.MsgReadWriter, ge return newPeer(pv, p, rw, getPooledTx) } -func (pm *ProtocolManager) runPeer(p *peer) error { +// Quorum - added protoName argument +func (pm *ProtocolManager) runPeer(p *peer, protoName string) error { if !pm.chainSync.handlePeerEvent(p) { return p2p.DiscQuitting } pm.peerWG.Add(1) defer pm.peerWG.Done() - return pm.handle(p) + return pm.handle(p, protoName) } +// quorum: protoname is either "eth" or a subprotocol that overrides "eth", e.g. legacy "istanbul/99" // handle is the callback invoked to manage the life cycle of an eth peer. When // this function terminates, the peer is disconnected. -func (pm *ProtocolManager) handle(p *peer) error { +func (pm *ProtocolManager) handle(p *peer, protoName string) error { // Ignore maxPeers if this is a trusted peer if pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted { return p2p.DiscTooManyPeers @@ -319,14 +348,26 @@ func (pm *ProtocolManager) handle(p *peer) error { number = head.Number.Uint64() td = pm.blockchain.GetTd(hash, number) ) - if err := p.Handshake(pm.networkID, td, hash, genesis.Hash(), forkid.NewID(pm.blockchain), pm.forkFilter); err != nil { - p.Log().Debug("Ethereum handshake failed", "err", err) + if err := p.Handshake(pm.networkID, td, hash, genesis.Hash(), forkid.NewID(pm.blockchain), pm.forkFilter, protoName); err != nil { + p.Log().Debug("Ethereum handshake failed", "protoName", protoName, "err", err) + + // Quorum + // When the Handshake() returns an error, the Run method corresponding to `eth` protocol returns with the error, causing the peer to drop, signal subprotocol as well to exit the `Run` method + p.EthPeerDisconnected <- struct{}{} + // End Quorum + return err } // Register the peer locally - if err := pm.peers.Register(p, pm.removePeer); err != nil { + if err := pm.peers.Register(p, pm.removePeer, protoName); err != nil { p.Log().Error("Ethereum peer registration failed", "err", err) + + // Quorum + // When the Register() returns an error, the Run method corresponding to `eth` protocol returns with the error, causing the peer to drop, signal subprotocol as well to exit the `Run` method + p.EthPeerDisconnected <- struct{}{} + // End Quorum + return err } defer pm.removePeer(p.id) @@ -366,6 +407,11 @@ func (pm *ProtocolManager) handle(p *peer) error { return err } } + + // Quorum notify other subprotocols that the eth peer is ready, and has been added to the peerset. + p.EthPeerRegistered <- struct{}{} + // Quorum + // Handle incoming messages until the connection is torn down for { if err := pm.handleMsg(p); err != nil { @@ -388,6 +434,28 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } defer msg.Discard() + // Quorum + if pm.raftMode { + switch msg.Code { + case TransactionMsg, PooledTransactionsMsg, + GetPooledTransactionsMsg, NewPooledTransactionHashesMsg, + GetBlockHeadersMsg, BlockHeadersMsg, + GetBlockBodiesMsg, BlockBodiesMsg: + // supported by Raft + default: + log.Info("raft: ignoring message", "code", msg.Code) + return nil + } + } else if handler, ok := pm.engine.(consensus.Handler); ok { // quorum: NewBlock required for consensus, e.g. "istanbul" + pubKey := p.Node().Pubkey() + addr := crypto.PubkeyToAddress(*pubKey) + handled, err := handler.HandleMsg(addr, msg) + if handled { + return err + } + } + // End Quorum + // Handle the message depending on its contents switch { case msg.Code == StatusMsg: @@ -817,6 +885,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { return nil } +// Quorum +func (pm *ProtocolManager) Enqueue(id string, block *types.Block) { + pm.blockFetcher.Enqueue(id, block) +} + // BroadcastBlock will either propagate a block to a subset of its peers, or // will only announce its availability (depending what's requested). func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) { @@ -858,6 +931,12 @@ func (pm *ProtocolManager) BroadcastTransactions(txs types.Transactions, propaga annos = make(map[*peer][]common.Hash) ) // Broadcast transactions to a batch of peers not knowing about it + // NOTE: Raft-based consensus currently assumes that geth broadcasts + // transactions to all peers in the network. A previous comment here + // indicated that this logic might change in the future to only send to a + // subset of peers. If this change occurs upstream, a merge conflict should + // arise here, and we should add logic to send to *all* peers in raft mode. + if propagate { for _, tx := range txs { peers := pm.peers.PeersWithoutTx(tx.Hash()) @@ -931,16 +1010,60 @@ type NodeInfo struct { Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules Head common.Hash `json:"head"` // SHA3 hash of the host's best owned block + Consensus string `json:"consensus"` // Consensus mechanism in use } // NodeInfo retrieves some protocol metadata about the running host node. func (pm *ProtocolManager) NodeInfo() *NodeInfo { currentBlock := pm.blockchain.CurrentBlock() + // //Quorum + // + // changes done to fetch maxCodeSize dynamically based on the + // maxCodeSizeConfig changes + // /Quorum + chainConfig := pm.blockchain.Config() + chainConfig.MaxCodeSize = uint64(chainConfig.GetMaxCodeSize(pm.blockchain.CurrentBlock().Number()) / 1024) + return &NodeInfo{ Network: pm.networkID, Difficulty: pm.blockchain.GetTd(currentBlock.Hash(), currentBlock.NumberU64()), Genesis: pm.blockchain.Genesis().Hash(), - Config: pm.blockchain.Config(), + Config: chainConfig, Head: currentBlock.Hash(), + Consensus: pm.getConsensusAlgorithm(), + } +} + +// Quorum +func (pm *ProtocolManager) getConsensusAlgorithm() string { + var consensusAlgo string + if pm.raftMode { // raft does not use consensus interface + consensusAlgo = "raft" + } else { + switch pm.engine.(type) { + case consensus.Istanbul: + consensusAlgo = "istanbul" + case *clique.Clique: + consensusAlgo = "clique" + case *ethash.Ethash: + consensusAlgo = "ethash" + default: + consensusAlgo = "unknown" + } + } + return consensusAlgo +} + +func (self *ProtocolManager) FindPeers(targets map[common.Address]bool) map[common.Address]consensus.Peer { + m := make(map[common.Address]consensus.Peer) + for _, p := range self.peers.Peers() { + pubKey := p.Node().Pubkey() + addr := crypto.PubkeyToAddress(*pubKey) + if targets[addr] { + m[addr] = p + } } + return m } + +// End Quorum diff --git a/eth/handler_test.go b/eth/handler_test.go index fc6c6f2745..aaae6036b0 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -25,6 +25,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" @@ -38,6 +39,45 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// Tests that correct consensus mechanism details are returned in NodeInfo. +func TestNodeInfo(t *testing.T) { + + // Define the tests to be run + tests := []struct { + consensus string + cliqueConfig *params.CliqueConfig + istanbulConfig *params.IstanbulConfig + raftMode bool + }{ + {"ethash", nil, nil, false}, + {"raft", nil, nil, true}, + {"istanbul", nil, ¶ms.IstanbulConfig{Epoch: 1, ProposerPolicy: 1, Ceil2Nby3Block: big.NewInt(0)}, false}, + {"clique", ¶ms.CliqueConfig{Period: 1, Epoch: 1}, nil, false}, + } + + // Make sure anything we screw up is restored + backup := consensus.EthProtocol.Versions + defer func() { consensus.EthProtocol.Versions = backup }() + + // Try all available consensus mechanisms and check for errors + for i, tt := range tests { + + pm, _, err := newTestProtocolManagerConsensus(tt.consensus, tt.cliqueConfig, tt.istanbulConfig, tt.raftMode) + + if pm != nil { + defer pm.Stop() + } + if err == nil { + pmConsensus := pm.getConsensusAlgorithm() + if tt.consensus != pmConsensus { + t.Errorf("test %d: consensus type error, wanted %v but got %v", i, tt.consensus, pmConsensus) + } + } else { + t.Errorf("test %d: consensus type error %v", i, err) + } + } +} + // Tests that block headers can be retrieved from a remote chain based on user queries. func TestGetBlockHeaders63(t *testing.T) { testGetBlockHeaders(t, 63) } func TestGetBlockHeaders64(t *testing.T) { testGetBlockHeaders(t, 64) } @@ -352,7 +392,7 @@ func testGetNodeData(t *testing.T, protocol int) { trie, _ := state.New(pm.blockchain.GetBlockByNumber(i).Root(), state.NewDatabase(statedb), nil) for j, acc := range accounts { - state, _ := pm.blockchain.State() + state, _, _ := pm.blockchain.State() bw := state.GetBalance(acc) bh := trie.GetBalance(acc) @@ -495,7 +535,7 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo if err != nil { t.Fatalf("failed to create new blockchain: %v", err) } - pm, err := NewProtocolManager(config, cht, syncmode, DefaultConfig.NetworkId, new(event.TypeMux), &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, ethash.NewFaker(), blockchain, db, 1, nil) + pm, err := NewProtocolManager(config, cht, syncmode, DefaultConfig.NetworkId, new(event.TypeMux), &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, ethash.NewFaker(), blockchain, db, 1, nil, false) if err != nil { t.Fatalf("failed to start test protocol manager: %v", err) } @@ -582,7 +622,7 @@ func testBroadcastBlock(t *testing.T, totalPeers, broadcastExpected int) { if err != nil { t.Fatalf("failed to create new blockchain: %v", err) } - pm, err := NewProtocolManager(config, nil, downloader.FullSync, DefaultConfig.NetworkId, evmux, &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, pow, blockchain, db, 1, nil) + pm, err := NewProtocolManager(config, nil, downloader.FullSync, DefaultConfig.NetworkId, evmux, &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, pow, blockchain, db, 1, nil, false) if err != nil { t.Fatalf("failed to start test protocol manager: %v", err) } @@ -646,7 +686,7 @@ func TestBroadcastMalformedBlock(t *testing.T) { if err != nil { t.Fatalf("failed to create new blockchain: %v", err) } - pm, err := NewProtocolManager(config, nil, downloader.FullSync, DefaultConfig.NetworkId, new(event.TypeMux), new(testTxPool), engine, blockchain, db, 1, nil) + pm, err := NewProtocolManager(config, nil, downloader.FullSync, DefaultConfig.NetworkId, new(event.TypeMux), new(testTxPool), engine, blockchain, db, 1, nil, false) if err != nil { t.Fatalf("failed to start test protocol manager: %v", err) } diff --git a/eth/helper_test.go b/eth/helper_test.go index 65effcc165..5c0c206134 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -28,6 +28,11 @@ import ( "sync" "testing" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/clique" + "github.com/ethereum/go-ethereum/consensus/istanbul" + istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -68,7 +73,59 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func if _, err := blockchain.InsertChain(chain); err != nil { panic(err) } - pm, err := NewProtocolManager(gspec.Config, nil, mode, DefaultConfig.NetworkId, evmux, &testTxPool{added: newtx, pool: make(map[common.Hash]*types.Transaction)}, engine, blockchain, db, 1, nil) + pm, err := NewProtocolManager(gspec.Config, nil, mode, DefaultConfig.NetworkId, evmux, &testTxPool{added: newtx, pool: make(map[common.Hash]*types.Transaction)}, engine, blockchain, db, 1, nil, false) + if err != nil { + return nil, nil, err + } + pm.Start(1000) + return pm, db, nil +} + +// newTestProtocolManagerConsensus creates a new protocol manager for testing purposes, +// that uses the specified consensus mechanism. +func newTestProtocolManagerConsensus(consensusAlgo string, cliqueConfig *params.CliqueConfig, istanbulConfig *params.IstanbulConfig, raftMode bool) (*ProtocolManager, ethdb.Database, error) { + + config := params.QuorumTestChainConfig + config.Clique = cliqueConfig + config.Istanbul = istanbulConfig + + var ( + blocks = 0 + evmux = new(event.TypeMux) + engine consensus.Engine = ethash.NewFaker() + db = rawdb.NewMemoryDatabase() + gspec = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}}, + } + genesis = gspec.MustCommit(db) + blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil) + ) + chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, nil) + if _, err := blockchain.InsertChain(chain); err != nil { + panic(err) + } + + switch consensusAlgo { + case "raft": + engine = ethash.NewFaker() //raft doesn't use engine, but just mirroring what runtime code does + + case "istanbul": + var istanbul istanbul.Config + config.Istanbul.Epoch = istanbulConfig.Epoch + config.Istanbul.ProposerPolicy = istanbulConfig.ProposerPolicy + + nodeKey, _ := crypto.GenerateKey() + engine = istanbulBackend.New(&istanbul, nodeKey, db) + + case "clique": + engine = clique.New(config.Clique, db) + + default: + engine = ethash.NewFaker() + } + + pm, err := NewProtocolManager(config, nil, downloader.FullSync, DefaultConfig.NetworkId, evmux, &testTxPool{added: nil}, engine, blockchain, db, 1, nil, raftMode) if err != nil { return nil, nil, err } @@ -175,7 +232,7 @@ func newTestPeer(name string, version int, pm *ProtocolManager, shake bool) (*te rand.Read(id[:]) peer := pm.newPeer(version, p2p.NewPeer(id, name, nil), net, pm.txpool.Get) errc := make(chan error, 1) - go func() { errc <- pm.runPeer(peer) }() + go func() { errc <- pm.runPeer(peer, protocolName) }() tp := &testPeer{app: app, net: net, peer: peer} // Execute any implicitly requested handshakes and return diff --git a/eth/peer.go b/eth/peer.go index 21b82a19c5..baa47a767f 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -25,6 +25,7 @@ import ( mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/p2p" @@ -107,6 +108,8 @@ type peer struct { getPooledTx func(common.Hash) *types.Transaction // Callback used to retrieve transaction from txpool term chan struct{} // Termination channel to stop the broadcaster + + consensusRw p2p.MsgReadWriter // Quorum: this is the RW for the consensus devp2p protocol, e.g. "istanbul/100" } func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter, getPooledTx func(hash common.Hash) *types.Transaction) *peer { @@ -333,6 +336,16 @@ func (p *peer) MarkTransaction(hash common.Hash) { p.knownTxs.Add(hash) } +// Quorum +// Quorum: this was added with the origin "istanbul" implementation. +// Send writes an RLP-encoded message with the given code. +// data should encode as an RLP list. +func (p *peer) Send(msgcode uint64, data interface{}) error { + return p2p.Send(p.rw, msgcode, data) +} + +// End Quorum + // SendTransactions64 sends transactions to the peer and includes the hashes // in its transaction hash set for future reference. // @@ -564,17 +577,19 @@ func (p *peer) RequestTxs(hashes []common.Hash) error { // Handshake executes the eth protocol handshake, negotiating version number, // network IDs, difficulties, head and genesis blocks. -func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter) error { +func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter, protocolName string) error { // Send out own handshake in a new thread errc := make(chan error, 2) var ( - status63 statusData63 // safe to read after two values have been received from errc - status statusData // safe to read after two values have been received from errc + status63 statusData63 // safe to read after two values have been received from errc + status statusData // safe to read after two values have been received from errc + istanbulOld = protocolName == "istanbul" && p.version == consensus.Istanbul64 + istanbulNew = protocolName == "istanbul" && p.version == consensus.Istanbul99 ) go func() { switch { - case p.version == eth63: + case p.version == eth63 || istanbulOld: errc <- p2p.Send(p.rw, StatusMsg, &statusData63{ ProtocolVersion: uint32(p.version), NetworkId: network, @@ -582,7 +597,7 @@ func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis CurrentBlock: head, GenesisBlock: genesis, }) - case p.version >= eth64: + case p.version >= eth64 || istanbulNew: errc <- p2p.Send(p.rw, StatusMsg, &statusData{ ProtocolVersion: uint32(p.version), NetworkID: network, @@ -597,9 +612,9 @@ func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis }() go func() { switch { - case p.version == eth63: + case p.version == eth63 || istanbulOld: errc <- p.readStatusLegacy(network, &status63, genesis) - case p.version >= eth64: + case p.version >= eth64 || istanbulNew: errc <- p.readStatus(network, &status, genesis, forkFilter) default: panic(fmt.Sprintf("unsupported eth protocol version: %d", p.version)) @@ -618,9 +633,9 @@ func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis } } switch { - case p.version == eth63: + case p.version == eth63 || istanbulOld: p.td, p.head = status63.TD, status63.CurrentBlock - case p.version >= eth64: + case p.version >= eth64 || istanbulNew: p.td, p.head = status.TD, status.Head default: panic(fmt.Sprintf("unsupported eth protocol version: %d", p.version)) @@ -707,10 +722,14 @@ func newPeerSet() *peerSet { } } +// Quorum protoName is needed to check if the peer is running eth protocol or a legacy quorum +// consensus protocol, e.g. istanbul/99 which would not support p.announceTransactions() / NewPooledTransactionHashesMsg +// Quorum + // Register injects a new peer into the working set, or returns an error if the // peer is already known. If a new peer it registered, its broadcast loop is also // started. -func (ps *peerSet) Register(p *peer, removePeer func(string)) error { +func (ps *peerSet) Register(p *peer, removePeer func(string), protoName string) error { ps.lock.Lock() defer ps.lock.Unlock() @@ -724,7 +743,9 @@ func (ps *peerSet) Register(p *peer, removePeer func(string)) error { go p.broadcastBlocks(removePeer) go p.broadcastTransactions(removePeer) - if p.version >= eth65 { + // Quorum passes in and checks the protoName to see if it is "eth" + // as it could also be a legacy protocol, e.g. "istanbul/99", protocolName is always set to "eth" for the eth service. + if p.version >= eth65 && protoName == protocolName { go p.announceTransactions(removePeer) } return nil @@ -746,6 +767,21 @@ func (ps *peerSet) Unregister(id string) error { return nil } +// Quorum +// Peers returns all registered peers +func (ps *peerSet) Peers() map[string]*peer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + set := make(map[string]*peer) + for id, p := range ps.peers { + set[id] = p + } + return set +} + +// End Quorum + // Peer retrieves the registered peer with the given id. func (ps *peerSet) Peer(id string) *peer { ps.lock.RLock() diff --git a/eth/protocol.go b/eth/protocol.go index dc75d6b31a..cd536c9755 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -37,7 +37,7 @@ const ( ) // protocolName is the official short name of the protocol used during capability negotiation. -const protocolName = "eth" +var protocolName = "eth" // ProtocolVersions are the supported versions of the eth protocol (first is primary). var ProtocolVersions = []uint{eth65, eth64, eth63} diff --git a/eth/protocol_test.go b/eth/protocol_test.go index fc916a2263..31d8a28763 100644 --- a/eth/protocol_test.go +++ b/eth/protocol_test.go @@ -181,8 +181,8 @@ func TestForkIDSplit(t *testing.T) { blocksNoFork, _ = core.GenerateChain(configNoFork, genesisNoFork, engine, dbNoFork, 2, nil) blocksProFork, _ = core.GenerateChain(configProFork, genesisProFork, engine, dbProFork, 2, nil) - ethNoFork, _ = NewProtocolManager(configNoFork, nil, downloader.FullSync, 1, new(event.TypeMux), &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, engine, chainNoFork, dbNoFork, 1, nil) - ethProFork, _ = NewProtocolManager(configProFork, nil, downloader.FullSync, 1, new(event.TypeMux), &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, engine, chainProFork, dbProFork, 1, nil) + ethNoFork, _ = NewProtocolManager(configNoFork, nil, downloader.FullSync, 1, new(event.TypeMux), &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, engine, chainNoFork, dbNoFork, 1, nil, false) + ethProFork, _ = NewProtocolManager(configProFork, nil, downloader.FullSync, 1, new(event.TypeMux), &testTxPool{pool: make(map[common.Hash]*types.Transaction)}, engine, chainProFork, dbProFork, 1, nil, false) ) ethNoFork.Start(1000) ethProFork.Start(1000) @@ -193,8 +193,8 @@ func TestForkIDSplit(t *testing.T) { peerProFork := newPeer(64, p2p.NewPeer(enode.ID{2}, "", nil), p2pProFork, nil) errc := make(chan error, 2) - go func() { errc <- ethNoFork.handle(peerProFork) }() - go func() { errc <- ethProFork.handle(peerNoFork) }() + go func() { errc <- ethNoFork.handle(peerProFork, protocolName) }() + go func() { errc <- ethProFork.handle(peerNoFork, protocolName) }() select { case err := <-errc: @@ -212,8 +212,8 @@ func TestForkIDSplit(t *testing.T) { peerProFork = newPeer(64, p2p.NewPeer(enode.ID{2}, "", nil), p2pProFork, nil) errc = make(chan error, 2) - go func() { errc <- ethNoFork.handle(peerProFork) }() - go func() { errc <- ethProFork.handle(peerNoFork) }() + go func() { errc <- ethNoFork.handle(peerProFork, protocolName) }() + go func() { errc <- ethProFork.handle(peerNoFork, protocolName) }() select { case err := <-errc: @@ -231,8 +231,8 @@ func TestForkIDSplit(t *testing.T) { peerProFork = newPeer(64, p2p.NewPeer(enode.ID{2}, "", nil), p2pProFork, nil) errc = make(chan error, 2) - go func() { errc <- ethNoFork.handle(peerProFork) }() - go func() { errc <- ethProFork.handle(peerNoFork) }() + go func() { errc <- ethNoFork.handle(peerProFork, protocolName) }() + go func() { errc <- ethProFork.handle(peerNoFork, protocolName) }() select { case err := <-errc: @@ -381,8 +381,8 @@ func testSyncTransaction(t *testing.T, propagtion bool) { // Sync up the two peers io1, io2 := p2p.MsgPipe() - go pmSender.handle(pmSender.newPeer(65, p2p.NewPeer(enode.ID{}, "sender", nil), io2, pmSender.txpool.Get)) - go pmFetcher.handle(pmFetcher.newPeer(65, p2p.NewPeer(enode.ID{}, "fetcher", nil), io1, pmFetcher.txpool.Get)) + go pmSender.handle(pmSender.newPeer(65, p2p.NewPeer(enode.ID{}, "sender", nil), io2, pmSender.txpool.Get), protocolName) + go pmFetcher.handle(pmFetcher.newPeer(65, p2p.NewPeer(enode.ID{}, "fetcher", nil), io1, pmFetcher.txpool.Get), protocolName) time.Sleep(250 * time.Millisecond) pmFetcher.doSync(peerToSyncOp(downloader.FullSync, pmFetcher.peers.BestPeer())) diff --git a/eth/quorum_protocol.go b/eth/quorum_protocol.go new file mode 100644 index 0000000000..c5202b7769 --- /dev/null +++ b/eth/quorum_protocol.go @@ -0,0 +1,209 @@ +package eth + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +// Quorum: quorum_protocol enables the eth service to return two different protocols, one for the eth mainnet "eth" service, +// and one for the quorum specific consensus algo, obtained from engine.consensus +// 2021 Jan in the future consensus (istanbul) may run from its own service and use a single subprotocol there, +// instead of overloading the eth service. + +var ( + // errEthPeerNil is returned when no eth peer is found to be associated with a p2p peer. + errEthPeerNil = errors.New("eth peer was nil") + errEthPeerNotRegistered = errors.New("eth peer was not registered") +) + +// quorum consensus Protocol variables are optionally set in addition to the "eth" protocol variables (eth/protocol.go). +var quorumConsensusProtocolName = "" + +// ProtocolVersions are the supported versions of the quorum consensus protocol (first is primary), e.g. []uint{Istanbul64, Istanbul99, Istanbul100}. +var quorumConsensusProtocolVersions []uint + +// protocol Length describe the number of messages support by the protocol/version map[uint]uint64{Istanbul64: 18, Istanbul99: 18, Istanbul100: 18} +var quorumConsensusProtocolLengths map[uint]uint64 + +// makeQuorumConsensusProtocol is similar to eth/handler.go -> makeProtocol. Called from eth/handler.go -> Protocols. +// returns the supported subprotocol to the p2p server. +// The Run method starts the protocol and is called by the p2p server. The quorum consensus subprotocol, +// leverages the peer created and managed by the "eth" subprotocol. +// The quorum consensus protocol requires that the "eth" protocol is running as well. +func (pm *ProtocolManager) makeQuorumConsensusProtocol(ProtoName string, version uint, length uint64) p2p.Protocol { + + return p2p.Protocol{ + Name: ProtoName, + Version: version, + Length: length, + // no new peer created, uses the "eth" peer, so no peer management needed. + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + /* + * 1. wait for the eth protocol to create and register an eth peer. + * 2. get the associate eth peer that was registered by he "eth" protocol. + * 2. add the rw protocol for the quorum subprotocol to the eth peer. + * 3. start listening for incoming messages. + * 4. the incoming message will be sent on the quorum specific subprotocol, e.g. "istanbul/100". + * 5. send messages to the consensus engine handler. + * 7. messages to other to other peers listening to the subprotocol can be sent using the + * (eth)peer.ConsensusSend() which will write to the protoRW. + */ + // wait for the "eth" protocol to create and register the peer (added to peerset) + select { + case <-p.EthPeerRegistered: + // the ethpeer should be registered, try to retrieve it and start the consensus handler. + p2pPeerId := fmt.Sprintf("%x", p.ID().Bytes()[:8]) + ethPeer := pm.peers.Peer(p2pPeerId) + if ethPeer != nil { + p.Log().Debug("consensus subprotocol retrieved eth peer from peerset", "ethPeer.id", ethPeer.id, "ProtoName", ProtoName) + // add the rw protocol for the quorum subprotocol to the eth peer. + ethPeer.addConsensusProtoRW(rw) + return pm.handleConsensusLoop(p, rw) + } + p.Log().Error("consensus subprotocol retrieved nil eth peer from peerset", "ethPeer.id", ethPeer) + return errEthPeerNil + case <-p.EthPeerDisconnected: + return errEthPeerNotRegistered + } + }, + NodeInfo: func() interface{} { + return pm.NodeInfo() + }, + PeerInfo: func(id enode.ID) interface{} { + if p := pm.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil { + return p.Info() + } + return nil + }, + } +} + +func (pm *ProtocolManager) handleConsensusLoop(p *p2p.Peer, protoRW p2p.MsgReadWriter) error { + // Handle incoming messages until the connection is torn down + for { + if err := pm.handleConsensus(p, protoRW); err != nil { + p.Log().Debug("Ethereum quorum message handling failed", "err", err) + return err + } + } +} + +// This is a no-op because the eth handleMsg main loop handle ibf message as well. +func (pm *ProtocolManager) handleConsensus(p *p2p.Peer, protoRW p2p.MsgReadWriter) error { + // Read the next message from the remote peer (in protoRW), and ensure it's fully consumed + msg, err := protoRW.ReadMsg() + if err != nil { + return err + } + if msg.Size > protocolMaxMsgSize { + return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, protocolMaxMsgSize) + } + defer msg.Discard() + + // See if the consensus engine protocol can handle this message, e.g. istanbul will check for message is + // istanbulMsg = 0x11, and NewBlockMsg = 0x07. + handled, err := pm.handleConsensusMsg(p, msg) + if handled { + p.Log().Debug("consensus message was handled by consensus engine", "handled", handled, + "quorumConsensusProtocolName", quorumConsensusProtocolName, "err", err) + return err + } + + return nil +} + +func (pm *ProtocolManager) handleConsensusMsg(p *p2p.Peer, msg p2p.Msg) (bool, error) { + if handler, ok := pm.engine.(consensus.Handler); ok { + pubKey := p.Node().Pubkey() + addr := crypto.PubkeyToAddress(*pubKey) + handled, err := handler.HandleMsg(addr, msg) + return handled, err + } + return false, nil +} + +// makeLegacyProtocol is basically a copy of the eth makeProtocol, but for legacy subprotocols, e.g. "istanbul/99" "istabnul/64" +// If support legacy subprotocols is removed, remove this and associated code as well. +// If quorum is using a legacy protocol then the "eth" subprotocol should not be available. +func (pm *ProtocolManager) makeLegacyProtocol(protoName string, version uint, length uint64) p2p.Protocol { + log.Debug("registering a legacy protocol ", "protoName", protoName) + return p2p.Protocol{ + Name: protoName, + Version: version, + Length: length, + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + peer := pm.newPeer(int(version), p, rw, pm.txpool.Get) + peer.addConsensusProtoRW(rw) + return pm.runPeer(peer, protoName) + }, + NodeInfo: func() interface{} { + return pm.NodeInfo() + }, + PeerInfo: func(id enode.ID) interface{} { + if p := pm.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil { + return p.Info() + } + return nil + }, + } +} + +func (s *Ethereum) quorumConsensusProtocols() []p2p.Protocol { + protos := make([]p2p.Protocol, len(quorumConsensusProtocolVersions)) + for i, vsn := range quorumConsensusProtocolVersions { + // if we have a legacy protocol, e.g. istanbul/99, istanbul/64 then the protocol handler is will be the "eth" + // protocol handler, and the subprotocol "eth" will not be used, but rather the legacy subprotocol will handle + // both eth messages and consensus messages. + if isLegacyProtocol(quorumConsensusProtocolName, vsn) { + length, ok := quorumConsensusProtocolLengths[vsn] + if !ok { + panic("makeProtocol for unknown version") + } + lp := s.protocolManager.makeLegacyProtocol(quorumConsensusProtocolName, vsn, length) + protos[i] = lp + } else { + length, ok := quorumConsensusProtocolLengths[vsn] + if !ok { + panic("makeQuorumConsensusProtocol for unknown version") + } + protos[i] = s.protocolManager.makeQuorumConsensusProtocol(quorumConsensusProtocolName, vsn, length) + } + } + return protos +} + +// istanbul/64, istanbul/99, clique/63, clique/64 all override the "eth" subprotocol. +func isLegacyProtocol(name string, version uint) bool { + // protocols that override "eth" subprotocol and run only the quorum subprotocol. + quorumLegacyProtocols := map[string][]uint{"istanbul": {64, 99}, "clique": {63, 64}} + for lpName, lpVersions := range quorumLegacyProtocols { + if lpName == name { + for _, v := range lpVersions { + if v == version { + return true + } + } + } + } + return false +} + +// Used to send consensus subprotocol messages from an "eth" peer, e.g. "istanbul/100" subprotocol messages. +func (p *peer) SendConsensus(msgcode uint64, data interface{}) error { + if p.consensusRw == nil { + return nil + } + return p2p.Send(p.consensusRw, msgcode, data) +} + +func (p *peer) addConsensusProtoRW(rw p2p.MsgReadWriter) *peer { + p.consensusRw = rw + return p +} diff --git a/eth/sync.go b/eth/sync.go index 26badd1e21..dcda127334 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/permission/core" ) const ( @@ -207,7 +208,9 @@ func (cs *chainSyncer) loop() { for { if op := cs.nextSyncOp(); op != nil { - cs.startSync(op) + if !cs.pm.raftMode { + cs.startSync(op) + } } select { @@ -260,8 +263,19 @@ func (cs *chainSyncer) nextSyncOp() *chainSyncOp { mode, ourTD := cs.modeAndLocalHead() op := peerToSyncOp(mode, peer) if op.td.Cmp(ourTD) <= 0 { + // Quorum + // added for permissions changes to indicate node sync up has started + // if peer's TD is smaller than ours, no sync will happen + core.SetSyncStatus() return nil // We're in sync. } + if mode == downloader.FastSync { + // Make sure the peer's total difficulty we are synchronizing is higher. + if cs.pm.blockchain.GetTdByHash(cs.pm.blockchain.CurrentFastBlock().Hash()).Cmp(ourTD) >= 0 { + // Quorum never use FastSync, no need to execute SetSyncStatus + return nil + } + } return op } diff --git a/eth/sync_test.go b/eth/sync_test.go index ac1e5fad1b..70d6490479 100644 --- a/eth/sync_test.go +++ b/eth/sync_test.go @@ -48,8 +48,8 @@ func testFastSyncDisabling(t *testing.T, protocol int) { // Sync up the two peers io1, io2 := p2p.MsgPipe() - go pmFull.handle(pmFull.newPeer(protocol, p2p.NewPeer(enode.ID{}, "empty", nil), io2, pmFull.txpool.Get)) - go pmEmpty.handle(pmEmpty.newPeer(protocol, p2p.NewPeer(enode.ID{}, "full", nil), io1, pmEmpty.txpool.Get)) + go pmFull.handle(pmFull.newPeer(protocol, p2p.NewPeer(enode.ID{}, "empty", nil), io2, pmFull.txpool.Get), protocolName) + go pmEmpty.handle(pmEmpty.newPeer(protocol, p2p.NewPeer(enode.ID{}, "full", nil), io1, pmEmpty.txpool.Get), protocolName) time.Sleep(250 * time.Millisecond) op := peerToSyncOp(downloader.FastSync, pmEmpty.peers.BestPeer()) diff --git a/eth/tracers/tracer_test.go b/eth/tracers/tracer_test.go index b4de998651..8af6139625 100644 --- a/eth/tracers/tracer_test.go +++ b/eth/tracers/tracer_test.go @@ -51,7 +51,8 @@ type dummyStatedb struct { func (*dummyStatedb) GetRefund() uint64 { return 1337 } func runTrace(tracer *Tracer) (json.RawMessage, error) { - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + db := &dummyStatedb{} + env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, db, db, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} @@ -165,8 +166,8 @@ func TestHaltBetweenSteps(t *testing.T) { if err != nil { t.Fatal(err) } - - env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) + db := &dummyStatedb{} + env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, db, db, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, nil, nil, contract, 0, nil) diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 18f8eb12aa..50edb2ee0d 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -175,7 +175,7 @@ func TestPrestateTracerCreate2(t *testing.T) { if err != nil { t.Fatalf("failed to create call tracer: %v", err) } - evm := vm.NewEVM(context, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer}) + evm := vm.NewEVM(context, statedb, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer}) msg, err := tx.AsMessage(signer) if err != nil { @@ -249,7 +249,7 @@ func TestCallTracer(t *testing.T) { if err != nil { t.Fatalf("failed to create call tracer: %v", err) } - evm := vm.NewEVM(context, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) + evm := vm.NewEVM(context, statedb, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) msg, err := tx.AsMessage(signer) if err != nil { diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index bc0305fc22..eba1151ac6 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -25,6 +25,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -34,7 +35,8 @@ import ( // Client defines typed wrappers for the Ethereum RPC API. type Client struct { - c *rpc.Client + c *rpc.Client + pc privateTransactionManagerClient // Tessera/Constellation client } // Dial connects a client to the given URL. @@ -52,9 +54,28 @@ func DialContext(ctx context.Context, rawurl string) (*Client, error) { // NewClient creates a client that uses the given RPC client. func NewClient(c *rpc.Client) *Client { - return &Client{c} + return &Client{c, nil} } +// Quorum +// +// NewClientWithPTM creates a client that uses the given RPC client and the privateTransactionManager client +func NewClientWithPTM(c *rpc.Client, ptm privateTransactionManagerClient) *Client { + return &Client{c, ptm} +} + +// provides support for private transactions +func (ec *Client) WithPrivateTransactionManager(rawurl string) (*Client, error) { + var err error + ec.pc, err = newPrivateTransactionManagerClient(rawurl) + if err != nil { + return nil, err + } + return ec, nil +} + +// /Quorum + func (ec *Client) Close() { ec.c.Close() } @@ -513,12 +534,27 @@ func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64 // // If the transaction was a contract creation use the TransactionReceipt method to get the // contract address after the transaction has been mined. -func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error { +func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction, args bind.PrivateTxArgs) error { data, err := rlp.EncodeToBytes(tx) if err != nil { return err } - return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)) + if args.PrivateFor != nil { + return ec.c.CallContext(ctx, nil, "eth_sendRawPrivateTransaction", common.ToHex(data), bind.PrivateTxArgs{PrivateFor: args.PrivateFor}) + } else { + return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) + } +} + +// Quorum +// +// Retrieve encrypted payload hash from the private transaction manager if configured +func (ec *Client) PreparePrivateTransaction(data []byte, privateFrom string) (common.EncryptedPayloadHash, error) { + if ec.pc == nil { + return common.EncryptedPayloadHash{}, errors.New("missing private transaction manager client configuration") + } + payLoadHash, err := ec.pc.StoreRaw(data, privateFrom) + return payLoadHash, err } func toCallArg(msg ethereum.CallMsg) interface{} { diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 16cf5ce61c..eccbf5fb0b 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/assert" ) // Verify that Client implements the ethereum interfaces. @@ -352,3 +353,31 @@ func TestChainID(t *testing.T) { t.Fatalf("ChainID returned wrong number: %+v", id) } } + +func TestClient_PreparePrivateTransaction_whenTypical(t *testing.T) { + testObject := NewClient(nil) + + _, err := testObject.PreparePrivateTransaction([]byte("arbitrary payload"), "arbitrary private from") + + assert.Error(t, err) +} + +func TestClient_PreparePrivateTransaction_whenClientIsConfigured(t *testing.T) { + expectedData := []byte("arbitrary payload") + expectedDataEPH := common.BytesToEncryptedPayloadHash(expectedData) + testObject := NewClient(nil) + testObject.pc = &privateTransactionManagerStubClient{expectedData} + + actualData, err := testObject.PreparePrivateTransaction([]byte("arbitrary payload"), "arbitrary private from") + + assert.NoError(t, err) + assert.Equal(t, expectedDataEPH, actualData) +} + +type privateTransactionManagerStubClient struct { + expectedData []byte +} + +func (s *privateTransactionManagerStubClient) StoreRaw(data []byte, from string) (common.EncryptedPayloadHash, error) { + return common.BytesToEncryptedPayloadHash(data), nil +} diff --git a/ethclient/privateTransactionManagerClient.go b/ethclient/privateTransactionManagerClient.go new file mode 100644 index 0000000000..07530abbc9 --- /dev/null +++ b/ethclient/privateTransactionManagerClient.go @@ -0,0 +1,73 @@ +package ethclient + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/ethereum/go-ethereum/common" +) + +type privateTransactionManagerClient interface { + StoreRaw(data []byte, privateFrom string) (common.EncryptedPayloadHash, error) +} + +type privateTransactionManagerDefaultClient struct { + rawurl string + httpClient *http.Client +} + +// Create a new client to interact with private transaction manager via a HTTP endpoint +func newPrivateTransactionManagerClient(endpoint string) (privateTransactionManagerClient, error) { + _, err := url.Parse(endpoint) + if err != nil { + return nil, err + } + return &privateTransactionManagerDefaultClient{ + rawurl: endpoint, + httpClient: &http.Client{}, + }, nil +} + +type storeRawReq struct { + Payload string `json:"payload"` + From string `json:"from,omitempty"` +} + +type storeRawResp struct { + Key string `json:"key"` +} + +func (pc *privateTransactionManagerDefaultClient) StoreRaw(data []byte, privateFrom string) (common.EncryptedPayloadHash, error) { + storeRawReq := &storeRawReq{ + Payload: base64.StdEncoding.EncodeToString(data), + From: privateFrom, + } + reqBodyBuf := new(bytes.Buffer) + if err := json.NewEncoder(reqBodyBuf).Encode(storeRawReq); err != nil { + return common.EncryptedPayloadHash{}, err + } + resp, err := pc.httpClient.Post(pc.rawurl+"/storeraw", "application/json", reqBodyBuf) + if err != nil { + return common.EncryptedPayloadHash{}, fmt.Errorf("unable to invoke /storeraw due to %s", err) + } + defer func() { + _ = resp.Body.Close() + }() + if resp.StatusCode != http.StatusOK { + return common.EncryptedPayloadHash{}, fmt.Errorf("server returns %s", resp.Status) + } + // parse response + var storeRawResp storeRawResp + if err := json.NewDecoder(resp.Body).Decode(&storeRawResp); err != nil { + return common.EncryptedPayloadHash{}, err + } + encryptedPayloadHash, err := common.Base64ToEncryptedPayloadHash(storeRawResp.Key) + if err != nil { + return common.EncryptedPayloadHash{}, err + } + return encryptedPayloadHash, nil +} diff --git a/ethclient/privateTransactionManagerClient_test.go b/ethclient/privateTransactionManagerClient_test.go new file mode 100644 index 0000000000..b1b6d53f5d --- /dev/null +++ b/ethclient/privateTransactionManagerClient_test.go @@ -0,0 +1,56 @@ +package ethclient + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" +) + +const ( + arbitraryBase64Data = "YXJiaXRyYXJ5IGRhdGE=" // = "arbitrary data" +) + +func TestPrivateTransactionManagerClient_storeRaw(t *testing.T) { + // mock tessera client + expectedData := []byte("arbitrary data") + expectedDataEPH := common.BytesToEncryptedPayloadHash(expectedData) + arbitraryServer := newStoreRawServer() + defer arbitraryServer.Close() + testObject, err := newPrivateTransactionManagerClient(arbitraryServer.URL) + assert.NoError(t, err) + + key, err := testObject.StoreRaw([]byte("arbitrary payload"), "arbitrary private from") + + assert.NoError(t, err) + assert.Equal(t, expectedDataEPH, key) +} + +func newStoreRawServer() *httptest.Server { + arbitraryResponse := fmt.Sprintf(` +{ + "key": "%s" +} +`, arbitraryBase64Data) + mux := http.NewServeMux() + mux.HandleFunc("/storeraw", func(w http.ResponseWriter, req *http.Request) { + if req.Method == "POST" { + // parse request + var storeRawReq storeRawReq + if err := json.NewDecoder(req.Body).Decode(&storeRawReq); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + // send response + _, _ = fmt.Fprintf(w, "%s", arbitraryResponse) + } else { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + } + + }) + return httptest.NewServer(mux) +} diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index 1828ad70fb..c8227698a3 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -445,7 +445,9 @@ func (s *Service) login(conn *connWrapper) error { infos := s.server.NodeInfo() var network, protocol string - if info := infos.Protocols["eth"]; info != nil { + //must pass engine protocol name for quorum + p := s.engine.Protocol() + if info := infos.Protocols[p.Name]; info != nil { network = fmt.Sprintf("%d", info.(*eth.NodeInfo).Network) protocol = fmt.Sprintf("eth/%d", eth.ProtocolVersions[0]) } else { diff --git a/extension/api.go b/extension/api.go new file mode 100644 index 0000000000..45b6b84c13 --- /dev/null +++ b/extension/api.go @@ -0,0 +1,395 @@ +package extension + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/multitenancy" + "github.com/ethereum/go-ethereum/permission/core" +) + +var ( + errNotAcceptor = errors.New("account is not acceptor of this extension request") + errNotCreator = errors.New("account is not the creator of this extension request") +) + +const extensionCompleted = "DONE" +const extensionInProgress = "ACTIVE" + +type PrivateExtensionAPI struct { + privacyService *PrivacyService +} + +func NewPrivateExtensionAPI(privacyService *PrivacyService) *PrivateExtensionAPI { + return &PrivateExtensionAPI{ + privacyService: privacyService, + } +} + +// ActiveExtensionContracts returns the list of all currently outstanding extension contracts +func (api *PrivateExtensionAPI) ActiveExtensionContracts(ctx context.Context) []ExtensionContract { + api.privacyService.mu.Lock() + defer api.privacyService.mu.Unlock() + + psi, err := api.privacyService.apiBackendHelper.PSMR().ResolveForUserContext(ctx) + if err != nil { + return nil + } + + extracted := make([]ExtensionContract, 0) + for _, contract := range api.privacyService.psiContracts[psi.ID] { + extracted = append(extracted, *contract) + } + + return extracted +} + +// checks of the passed contract address is under extension process +func (api *PrivateExtensionAPI) checkIfContractUnderExtension(ctx context.Context, toExtend common.Address) bool { + for _, v := range api.ActiveExtensionContracts(ctx) { + if v.ContractExtended == toExtend { + return true + } + } + return false +} + +// checks if the voter has already voted on the contract. +func (api *PrivateExtensionAPI) checkAlreadyVoted(addressToVoteOn, from common.Address, psi types.PrivateStateIdentifier) bool { + psiManagementContractClient := api.privacyService.managementContract(psi) + defer psiManagementContractClient.Close() + caller, _ := psiManagementContractClient.Caller(addressToVoteOn) + opts := bind.CallOpts{Pending: true, From: from} + + voted, _ := caller.CheckIfVoted(&opts) + return voted +} + +// checks if the contract extension is completed +func (api *PrivateExtensionAPI) checkIfExtensionComplete(addressToVoteOn, from common.Address, psi types.PrivateStateIdentifier) (bool, error) { + psiManagementContractClient := api.privacyService.managementContract(psi) + defer psiManagementContractClient.Close() + caller, _ := psiManagementContractClient.Caller(addressToVoteOn) + opts := bind.CallOpts{Pending: true, From: from} + + status, err := caller.CheckIfExtensionFinished(&opts) + if err != nil { + return true, err + } + return status, nil +} + +// returns the contract being extended for the given management contract +func (api *PrivateExtensionAPI) getContractExtended(addressToVoteOn, from common.Address, psi types.PrivateStateIdentifier) (common.Address, error) { + psiManagementContractClient := api.privacyService.managementContract(psi) + defer psiManagementContractClient.Close() + caller, _ := psiManagementContractClient.Caller(addressToVoteOn) + opts := bind.CallOpts{Pending: true, From: from} + + return caller.ContractToExtend(&opts) +} + +// checks if the contract being extended is a public contract +func (api *PrivateExtensionAPI) checkIfPublicContract(toExtend common.Address) (bool, error) { + // check if the passed contract is public contract + chain := api.privacyService.stateFetcher.chainAccessor + publicStateDb, _, err := chain.StateAtPSI(chain.CurrentBlock().Root(), types.DefaultPrivateStateIdentifier) + if err != nil { + return false, err + } + return publicStateDb != nil && publicStateDb.Exist(toExtend), nil +} + +// checks if the contract being extended is available on the node +func (api *PrivateExtensionAPI) checkIfPrivateStateExists(psi types.PrivateStateIdentifier, toExtend common.Address) (bool, error) { + // check if the private contract exists on the node extending the contract + chain := api.privacyService.stateFetcher.chainAccessor + _, privateStateDb, err := chain.StateAtPSI(chain.CurrentBlock().Root(), psi) + if err != nil { + return false, err + } + return privateStateDb != nil && privateStateDb.GetCode(toExtend) != nil, nil +} + +func (api *PrivateExtensionAPI) doMultiTenantChecks(ctx context.Context, address common.Address, txa ethapi.SendTxArgs) error { + backendHelper := api.privacyService.apiBackendHelper + if token, ok := backendHelper.SupportsMultitenancy(ctx); ok { + psm, err := backendHelper.PSMR().ResolveForUserContext(ctx) + if err != nil { + return err + } + eoaSecAttr := (&multitenancy.PrivateStateSecurityAttribute{}).WithPSI(psm.ID).WithNodeEOA(address) + psm, err = backendHelper.PSMR().ResolveForManagedParty(txa.PrivateFrom) + if err != nil { + return err + } + privateFromSecAttr := (&multitenancy.PrivateStateSecurityAttribute{}).WithPSI(psm.ID).WithNodeEOA(address) + if isAuthorized, _ := multitenancy.IsAuthorized(token, eoaSecAttr, privateFromSecAttr); !isAuthorized { + return multitenancy.ErrNotAuthorized + } + } + return nil +} + +// ApproveContractExtension submits the vote to the specified extension management contract. The vote indicates whether to extend +// a given contract to a new participant or not +func (api *PrivateExtensionAPI) ApproveExtension(ctx context.Context, addressToVoteOn common.Address, vote bool, txa ethapi.SendTxArgs) (string, error) { + err := api.doMultiTenantChecks(ctx, txa.From, txa) + if err != nil { + return "", err + } + + psm, err := api.privacyService.apiBackendHelper.PSMR().ResolveForUserContext(ctx) + if err != nil { + return "", err + } + psi := psm.ID + + // check if the extension has been completed. if yes + // no acceptance required + status, err := api.checkIfExtensionComplete(addressToVoteOn, txa.From, psi) + if err != nil { + return "", err + } + + if status { + return "", errors.New("contract extension process complete. nothing to accept") + } + + if !core.CheckIfAdminAccount(txa.From) { + return "", errors.New("account cannot accept extension") + } + + // get all participants for the contract being extended + participants, err := api.privacyService.GetAllParticipants(api.privacyService.stateFetcher.getCurrentBlockHash(), addressToVoteOn, psi) + if err == nil { + txa.PrivateFor = append(txa.PrivateFor, participants...) + } + + txArgs, err := api.privacyService.GenerateTransactOptions(txa) + if err != nil { + return "", err + } + + psiManagementContractClient := api.privacyService.managementContract(psi) + defer psiManagementContractClient.Close() + voterList, err := psiManagementContractClient.GetAllVoters(addressToVoteOn) + if err != nil { + return "", err + } + if isVoter := checkAddressInList(txArgs.From, voterList); !isVoter { + return "", errNotAcceptor + } + + if api.checkAlreadyVoted(addressToVoteOn, txArgs.From, psi) { + return "", errors.New("already voted") + } + uuid, err := generateUuid(addressToVoteOn, txArgs.PrivateFrom, txArgs.PrivateFor, api.privacyService.ptm) + if err != nil { + return "", err + } + + //Find the extension contract in order to interact with it + extender, err := psiManagementContractClient.Transactor(addressToVoteOn) + if err != nil { + return "", err + } + + //Perform the vote transaction. + tx, err := extender.DoVote(txArgs, vote, uuid) + if err != nil { + return "", err + } + msg := fmt.Sprintf("0x%x", tx.Hash()) + return msg, nil +} + +// ExtendContract deploys a new extension management contract to the blockchain to start the process of extending +// a contract to a new participant +//Create a new extension contract that signifies that we want to add a new participant to an existing contract +//This should contain: +// - arguments for sending a new transaction (the same as sendTransaction) +// - the contract address we want to extend +// - the new PTM public key +// - the Ethereum addresses of who can vote to extend the contract +func (api *PrivateExtensionAPI) ExtendContract(ctx context.Context, toExtend common.Address, newRecipientPtmPublicKey string, recipientAddr common.Address, txa ethapi.SendTxArgs) (string, error) { + // check if the contract to be extended is already under extension + // if yes throw an error + if api.checkIfContractUnderExtension(ctx, toExtend) { + return "", errors.New("contract extension in progress for the given contract address") + } + + // check if a public contract is being extended + isPublic, err := api.checkIfPublicContract(toExtend) + if err != nil { + return "", err + } + if isPublic { + return "", errors.New("extending a public contract!!! not allowed") + } + + err = api.doMultiTenantChecks(ctx, txa.From, txa) + if err != nil { + return "", err + } + + // check if recipient address is 0x0 + if recipientAddr == (common.Address{0}) { + return "", errors.New("invalid recipient address") + } + + psm, err := api.privacyService.apiBackendHelper.PSMR().ResolveForUserContext(ctx) + if err != nil { + return "", err + } + + // check if a private contract exists + privateContractExists, err := api.checkIfPrivateStateExists(psm.ID, toExtend) + if err != nil { + return "", err + } + if !privateContractExists { + return "", errors.New("extending a non-existent private contract!!! not allowed") + } + + // check if contract creator + if !api.privacyService.CheckIfContractCreator(api.privacyService.stateFetcher.getCurrentBlockHash(), toExtend, psm.ID) { + return "", errors.New("operation not allowed") + } + + // if running in permissioned mode with new permissions model + // ensure that the account extending the contract is an admin + // account and recipient account is an admin account as well + if txa.From == recipientAddr { + return "", errors.New("account accepting the extension cannot be the account initiating extension") + } + if !core.CheckIfAdminAccount(txa.From) { + return "", errors.New("account not an org admin account, cannot initiate extension") + } + if !core.CheckIfAdminAccount(recipientAddr) { + return "", errors.New("recipient account address is not an org admin account. cannot accept extension") + } + + // check the new key is valid + if _, err := base64.StdEncoding.DecodeString(newRecipientPtmPublicKey); err != nil { + return "", errors.New("invalid new recipient transaction manager key provided") + } + + // check the the intended new recipient will actually receive the extension request + switch len(txa.PrivateFor) { + case 0: + txa.PrivateFor = append(txa.PrivateFor, newRecipientPtmPublicKey) + case 1: + if txa.PrivateFor[0] != newRecipientPtmPublicKey { + return "", errors.New("mismatch between recipient transaction manager key and privateFor argument") + } + default: + return "", errors.New("invalid transaction manager keys given in privateFor argument") + } + + // get all participants for the contract being extended + participants, err := api.privacyService.GetAllParticipants(api.privacyService.stateFetcher.getCurrentBlockHash(), toExtend, psm.ID) + if err == nil { + txa.PrivateFor = append(txa.PrivateFor, participants...) + } + + //generate some valid transaction options for sending in the transaction + txArgs, err := api.privacyService.GenerateTransactOptions(txa) + if err != nil { + return "", err + } + + psiManagementContractClient := api.privacyService.managementContract(psm.ID) + defer psiManagementContractClient.Close() + //Deploy the contract + tx, err := psiManagementContractClient.Deploy(txArgs, toExtend, recipientAddr, newRecipientPtmPublicKey) + if err != nil { + return "", err + } + + //Return the transaction hash for later lookup + msg := fmt.Sprintf("0x%x", tx.Hash()) + return msg, nil +} + +// CancelExtension allows the creator to cancel the given extension contract, ensuring +// that no more calls for votes or accepting can be made +func (api *PrivateExtensionAPI) CancelExtension(ctx context.Context, extensionContract common.Address, txa ethapi.SendTxArgs) (string, error) { + err := api.doMultiTenantChecks(ctx, txa.From, txa) + if err != nil { + return "", err + } + + psm, err := api.privacyService.apiBackendHelper.PSMR().ResolveForUserContext(ctx) + if err != nil { + return "", err + } + // get all participants for the contract being extended + status, err := api.checkIfExtensionComplete(extensionContract, txa.From, psm.ID) + if err != nil { + return "", err + } + if status { + return "", errors.New("contract extension process complete. nothing to cancel") + } + + participants, err := api.privacyService.GetAllParticipants(api.privacyService.stateFetcher.getCurrentBlockHash(), extensionContract, psm.ID) + if err == nil { + txa.PrivateFor = append(txa.PrivateFor, participants...) + } + + txArgs, err := api.privacyService.GenerateTransactOptions(txa) + if err != nil { + return "", err + } + + psiManagementContractClient := api.privacyService.managementContract(psm.ID) + defer psiManagementContractClient.Close() + caller, err := psiManagementContractClient.Caller(extensionContract) + if err != nil { + return "", err + } + creatorAddress, err := caller.Creator(nil) + if err != nil { + return "", err + } + if isCreator := checkAddressInList(txArgs.From, []common.Address{creatorAddress}); !isCreator { + return "", errNotCreator + } + + extender, err := psiManagementContractClient.Transactor(extensionContract) + if err != nil { + return "", err + } + + tx, err := extender.Finish(txArgs) + if err != nil { + return "", err + } + msg := fmt.Sprintf("0x%x", tx.Hash()) + return msg, nil +} + +// Returns the extension status from management contract +func (api *PrivateExtensionAPI) GetExtensionStatus(ctx context.Context, extensionContract common.Address) (string, error) { + psm, err := api.privacyService.apiBackendHelper.PSMR().ResolveForUserContext(ctx) + if err != nil { + return "", err + } + status, err := api.checkIfExtensionComplete(extensionContract, common.Address{}, psm.ID) + if err != nil { + return "", err + } + + if status { + return extensionCompleted, nil + } + + return extensionInProgress, nil +} diff --git a/extension/backend.go b/extension/backend.go new file mode 100644 index 0000000000..a948fe87f3 --- /dev/null +++ b/extension/backend.go @@ -0,0 +1,429 @@ +package extension + +import ( + "context" + "encoding/hex" + "errors" + "fmt" + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/extension/extensionContracts" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" + "github.com/ethereum/go-ethereum/rpc" +) + +type PrivacyService struct { + ptm private.PrivateTransactionManager + stateFetcher *StateFetcher + accountManager *accounts.Manager + dataHandler DataHandler + stopFeed event.Feed + apiBackendHelper APIBackendHelper + + mu sync.Mutex + psiContracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract + + node *node.Node +} + +var ( + //default gas limit to use if not passed in sendTxArgs + defaultGasLimit = uint64(4712384) + //default gas price to use if not passed in sendTxArgs + defaultGasPrice = big.NewInt(0) + + //Private participants must be specified for contract extension related transactions + errNotPrivate = errors.New("must specify private participants") +) + +// to signal all watches when service is stopped +type stopEvent struct { +} + +func (service *PrivacyService) newEthClient(psi types.PrivateStateIdentifier) *ethclient.Client { + rpcClient, err := service.node.AttachWithPSI(psi) + if err != nil { + // AttachWithPSI does not return non-nil error. This is just a defensive check + panic("this should not happen: " + err.Error()) + } + return ethclient.NewClientWithPTM(rpcClient, service.ptm) +} + +func (service *PrivacyService) client(psi types.PrivateStateIdentifier) Client { + return NewInProcessClient(service.newEthClient(psi)) +} + +func (service *PrivacyService) managementContract(psi types.PrivateStateIdentifier) ManagementContractFacade { + return NewManagementContractFacade(service.newEthClient(psi)) +} + +func (service *PrivacyService) subscribeStopEvent() (chan stopEvent, event.Subscription) { + c := make(chan stopEvent) + s := service.stopFeed.Subscribe(c) + return c, s +} + +func New(stack *node.Node, ptm private.PrivateTransactionManager, manager *accounts.Manager, handler DataHandler, fetcher *StateFetcher, apiBackendHelper APIBackendHelper) (*PrivacyService, error) { + service := &PrivacyService{ + psiContracts: make(map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract), + ptm: ptm, + dataHandler: handler, + stateFetcher: fetcher, + accountManager: manager, + apiBackendHelper: apiBackendHelper, + node: stack, + } + + var err error + service.psiContracts, err = service.dataHandler.Load() + if err != nil { + return nil, errors.New("could not load existing extension contracts: " + err.Error()) + } + + // Register service to node + stack.RegisterAPIs(service.apis()) + stack.RegisterLifecycle(service) + + return service, nil +} + +func (service *PrivacyService) watchForNewContracts(psi types.PrivateStateIdentifier) error { + handler := NewSubscriptionHandler(service.node, psi, service.ptm, service) + + cb := func(foundLog types.Log) { + service.mu.Lock() + psiClient := service.client(psi) + defer psiClient.Close() + tx, _ := service.client(psi).TransactionByHash(foundLog.TxHash) + from, _ := types.QuorumPrivateTxSigner{}.Sender(tx) + + newExtensionEvent, err := extensionContracts.UnpackNewExtensionCreatedLog(foundLog.Data) + if err != nil { + log.Error("Error unpacking extension creation log", "error", err) + log.Debug("Errored log", foundLog) + service.mu.Unlock() + return + } + + newContractExtension := ExtensionContract{ + ContractExtended: newExtensionEvent.ToExtend, + Initiator: from, + Recipient: newExtensionEvent.RecipientAddress, + RecipientPtmKey: newExtensionEvent.RecipientPTMKey, + ManagementContractAddress: foundLog.Address, + CreationData: tx.Data(), + } + + enclaveKey := common.BytesToEncryptedPayloadHash(tx.Data()) + privateFrom, _, _, _, err := service.ptm.Receive(enclaveKey) + if err != nil { + log.Error("Error receiving private payload", "error", err) + service.mu.Unlock() + return + } + + if service.psiContracts[psi] == nil { + service.psiContracts[psi] = make(map[common.Address]*ExtensionContract) + } + service.psiContracts[psi][foundLog.Address] = &newContractExtension + + if err := service.dataHandler.Save(service.psiContracts); err != nil { + log.Error("Error writing extension data to file", "error", err) + service.mu.Unlock() + return + } + service.mu.Unlock() + + // if party is sender then complete self voting + + isSender, _ := service.ptm.IsSender(enclaveKey) + + if isSender { + fetchedParties, err := service.ptm.GetParticipants(enclaveKey) + if err != nil || len(fetchedParties) == 0 { + log.Error("Extension: unable to fetch all parties for extension management contract", "error", err) + return + } + + psm, _ := service.apiBackendHelper.PSMR().ResolveForManagedParty(privateFrom) + if psm.ID != psi { + return + } + + psiManagementContractClient := service.managementContract(psi) + defer psiManagementContractClient.Close() + //Find the extension contract in order to interact with it + caller, _ := psiManagementContractClient.Caller(newContractExtension.ManagementContractAddress) + contractCreator, _ := caller.Creator(nil) + + txArgs := ethapi.SendTxArgs{From: contractCreator, PrivateTxArgs: ethapi.PrivateTxArgs{PrivateFor: fetchedParties, PrivateFrom: privateFrom}} + + extensionAPI := NewPrivateExtensionAPI(service) + ctx := rpc.WithPrivateStateIdentifier(context.Background(), psm.ID) + _, err = extensionAPI.ApproveExtension(ctx, newContractExtension.ManagementContractAddress, true, txArgs) + + if err != nil { + log.Error("Extension: initiator vote on management contract failed", "error", err) + } + } + } + + return handler.createSub(newExtensionQuery, cb) +} + +func (service *PrivacyService) watchForCancelledContracts(psi types.PrivateStateIdentifier) error { + handler := NewSubscriptionHandler(service.node, psi, service.ptm, service) + + cb := func(l types.Log) { + service.mu.Lock() + if _, ok := service.psiContracts[psi][l.Address]; ok { + delete(service.psiContracts[psi], l.Address) + if err := service.dataHandler.Save(service.psiContracts); err != nil { + log.Error("Failed to store list of contracts being extended", "error", err) + } + } + service.mu.Unlock() + } + + return handler.createSub(finishedExtensionQuery, cb) +} + +func (service *PrivacyService) watchForCompletionEvents(psi types.PrivateStateIdentifier) error { + handler := NewSubscriptionHandler(service.node, psi, service.ptm, service) + + cb := func(l types.Log) { + log.Debug("Extension: Received a completion event", "address", l.Address.Hex(), "blockNumber", l.BlockNumber) + service.mu.Lock() + defer func() { + service.mu.Unlock() + }() + extensionEntry, ok := service.psiContracts[psi][l.Address] + if !ok { + // we didn't have this management contract, so ignore it + log.Debug("Extension: this node doesn't participate in the contract extender", "address", l.Address.Hex()) + return + } + + psiManagementContractClient := service.managementContract(psi) + defer psiManagementContractClient.Close() + //Find the extension contract in order to interact with it + caller, err := psiManagementContractClient.Caller(l.Address) + if err != nil { + log.Error("service.managementContractFacade.Caller", "address", l.Address.Hex(), "error", err) + return + } + contractCreator, err := caller.Creator(nil) + if err != nil { + log.Error("[contract] caller.Creator", "error", err) + return + } + log.Debug("Extension: check if this node has the account that created the contract extender", "account", contractCreator) + if _, err := service.accountManager.Find(accounts.Account{Address: contractCreator}); err != nil { + log.Warn("Account used to sign extension contract no longer available", "account", contractCreator.Hex()) + return + } + + // fetch all the participants and send + payload := common.BytesToEncryptedPayloadHash(extensionEntry.CreationData) + fetchedParties, err := service.ptm.GetParticipants(payload) + if err != nil || len(fetchedParties) == 0 { + log.Error("Extension: Unable to fetch all parties for extension management contract", "error", err) + return + } + log.Debug("Extension: able to fetch all parties", "parties", fetchedParties) + + privateFrom, _, _, _, err := service.ptm.Receive(payload) + if err != nil || len(privateFrom) == 0 { + log.Error("Extension: unable to fetch privateFrom(sender) for extension management contract", "error", err) + return + } + log.Debug("Extension: able to fetch privateFrom(sender)", "privateFrom", privateFrom) + + txPsi, err := service.apiBackendHelper.PSMR().ResolveForManagedParty(privateFrom) + if err != nil { + log.Error("Extension: unable to resolve private state metadata for sender", "error", err) + return + } + if txPsi.ID != psi { + return + } + txArgs, err := service.GenerateTransactOptions(ethapi.SendTxArgs{From: contractCreator, PrivateTxArgs: ethapi.PrivateTxArgs{PrivateFor: fetchedParties, PrivateFrom: privateFrom}}) + if err != nil { + log.Error("service.accountManager.GenerateTransactOptions", "error", err, "contractCreator", contractCreator.Hex(), "privateFor", fetchedParties) + return + } + + //we found the account, so we can send + contractToExtend, err := caller.ContractToExtend(nil) + if err != nil { + log.Error("[contract] caller.ContractToExtend", "error", err) + return + } + log.Debug("Extension: dump current state", "block", l.BlockHash, "contract", contractToExtend.Hex(), "psi", txPsi.ID) + entireStateData, err := service.stateFetcher.GetAddressStateFromBlock(l.BlockHash, contractToExtend, txPsi.ID) + if err != nil { + log.Error("[state] service.stateFetcher.GetAddressStateFromBlock", "block", l.BlockHash.Hex(), "contract", contractToExtend.Hex(), "error", err) + return + } + + log.Debug("Extension: send the state dump to the new recipient", "recipients", fetchedParties) + + // PSV & PP changes + // send the new transaction with state dump to all participants + extraMetaData := engine.ExtraMetadata{PrivacyFlag: engine.PrivacyFlagStandardPrivate} + privacyMetaData, err := service.stateFetcher.GetPrivacyMetaData(l.BlockHash, contractToExtend, txPsi.ID) + if err != nil { + log.Error("[privacyMetaData] fetch err", "err", err) + } else { + extraMetaData.PrivacyFlag = privacyMetaData.PrivacyFlag + if privacyMetaData.PrivacyFlag == engine.PrivacyFlagStateValidation { + storageRoot, err := service.stateFetcher.GetStorageRoot(l.BlockHash, contractToExtend, txPsi.ID) + if err != nil { + log.Error("[storageRoot] fetch err", "err", err) + } + extraMetaData.ACMerkleRoot = storageRoot + } + } + _, _, hashOfStateData, err := service.ptm.Send(entireStateData, privateFrom, fetchedParties, &extraMetaData) + + if err != nil { + log.Error("[ptm] service.ptm.Send", "stateDataInHex", hex.EncodeToString(entireStateData[:]), "recipients", fetchedParties, "error", err) + return + } + hashofStateDataBase64 := hashOfStateData.ToBase64() + + transactor, err := psiManagementContractClient.Transactor(l.Address) + if err != nil { + log.Error("service.managementContractFacade.Transactor", "address", l.Address.Hex(), "error", err) + return + } + log.Debug("Extension: store the encrypted payload hash of dump state", "contract", l.Address.Hex()) + if tx, err := transactor.SetSharedStateHash(txArgs, hashofStateDataBase64); err != nil { + log.Error("[contract] transactor.SetSharedStateHash", "error", err, "hashOfStateInBase64", hashofStateDataBase64) + } else { + log.Debug("Extension: transaction carrying shared state", "txhash", tx.Hash(), "private", tx.IsPrivate()) + } + } + + return handler.createSub(canPerformStateShareQuery, cb) +} + +// utility methods +func (service *PrivacyService) apis() []rpc.API { + return []rpc.API{ + { + Namespace: "quorumExtension", + Version: "1.0", + Service: NewPrivateExtensionAPI(service), + Public: true, + }, + } +} + +// node.Lifecycle interface methods: + +func (service *PrivacyService) Start() error { + log.Debug("extension service: starting") + service.mu.Lock() + defer service.mu.Unlock() + + for _, psi := range service.apiBackendHelper.PSMR().PSIs() { + for _, f := range []func(identifier types.PrivateStateIdentifier) error{ + service.watchForNewContracts, // watch for new extension contract creation event + service.watchForCancelledContracts, // watch for extension contract cancellation event + service.watchForCompletionEvents, // watch for extension contract voting complete event + } { + if err := f(psi); err != nil { + return err + } + } + } + + return nil +} + +func (service *PrivacyService) Stop() error { + log.Info("extension service: stopping") + service.stopFeed.Send(stopEvent{}) + log.Info("extension service: stopped") + return nil +} + +func (service *PrivacyService) GenerateTransactOptions(txa ethapi.SendTxArgs) (*bind.TransactOpts, error) { + if txa.PrivateFor == nil { + return nil, errNotPrivate + } + from := accounts.Account{Address: txa.From} + wallet, err := service.accountManager.Find(from) + + if err != nil { + return nil, fmt.Errorf("no wallet found for account %s", txa.From.String()) + } + + //Find the account we plan to send the transaction from + + txArgs := bind.NewWalletTransactor(wallet, from) + txArgs.PrivateFrom = txa.PrivateFrom + txArgs.PrivateFor = txa.PrivateFor + txArgs.GasLimit = defaultGasLimit + txArgs.GasPrice = defaultGasPrice + if txa.GasPrice != nil { + txArgs.GasPrice = txa.GasPrice.ToInt() + } + if txa.Gas != nil { + txArgs.GasLimit = uint64(*txa.Gas) + } + return txArgs, nil +} + +// returns the participant list for a given private contract +func (service *PrivacyService) GetAllParticipants(blockHash common.Hash, address common.Address, psi types.PrivateStateIdentifier) ([]string, error) { + privacyMetaData, err := service.stateFetcher.GetPrivacyMetaData(blockHash, address, psi) + if err != nil { + return nil, err + } + if privacyMetaData.PrivacyFlag.IsStandardPrivate() { + return nil, nil + } + + participants, err := service.ptm.GetParticipants(privacyMetaData.CreationTxHash) + if err != nil { + return nil, err + } + return participants, nil +} + +// check if the node had created the contract +func (service *PrivacyService) CheckIfContractCreator(blockHash common.Hash, address common.Address, psi types.PrivateStateIdentifier) bool { + privacyMetaData, err := service.stateFetcher.GetPrivacyMetaData(blockHash, address, psi) + if err != nil { + return true + } + + isCreator, err := service.ptm.IsSender(privacyMetaData.CreationTxHash) + if err != nil { + return false + } + + if !isCreator { + return false + } + + privateFrom, _, _, _, err := service.ptm.Receive(privacyMetaData.CreationTxHash) + if err != nil || len(privateFrom) == 0 { + return false + } + psm, _ := service.apiBackendHelper.PSMR().ResolveForManagedParty(privateFrom) + return psm.ID == psi +} diff --git a/extension/backend_test.go b/extension/backend_test.go new file mode 100644 index 0000000000..0bd1c35b29 --- /dev/null +++ b/extension/backend_test.go @@ -0,0 +1,211 @@ +package extension + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" +) + +type MockBackend struct { + wallets []accounts.Wallet +} + +func (backend *MockBackend) Wallets() []accounts.Wallet { + return backend.wallets +} + +func (backend *MockBackend) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { + return nil +} + +type MockWallet struct { + isContained bool +} + +func (wallet *MockWallet) URL() accounts.URL { panic("not implemented") } + +func (wallet *MockWallet) Status() (string, error) { panic("not implemented") } + +func (wallet *MockWallet) Open(passphrase string) error { panic("not implemented") } + +func (wallet *MockWallet) Close() error { panic("not implemented") } + +func (wallet *MockWallet) Accounts() []accounts.Account { panic("not implemented") } + +func (wallet *MockWallet) Contains(account accounts.Account) bool { return wallet.isContained } + +func (wallet *MockWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { + panic("not implemented") +} + +func (wallet *MockWallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { + panic("not implemented") +} + +func (wallet *MockWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + panic("not implemented") +} + +func (wallet *MockWallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + panic("not implemented") +} + +func (wallet *MockWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + panic("not implemented") +} + +func (wallet *MockWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + panic("not implemented") +} + +func (wallet *MockWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + panic("not implemented") +} + +func (wallet *MockWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { + panic("not implemented") +} + +func TestGenerateTransactionOptionsErrorsWhenNoPrivateParticipants(t *testing.T) { + sendTxArgs := ethapi.SendTxArgs{ + From: common.Address{}, + } + + mockBackend := MockBackend{} + accountManager := accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true}, &mockBackend) + + service := &PrivacyService{ + accountManager: accountManager, + } + + _, err := service.GenerateTransactOptions(sendTxArgs) + if err == nil { + t.Errorf("expected err to not be nil") + return + } + + expectedErr := "must specify private participants" + if err.Error() != expectedErr { + t.Errorf("expected err to be '%s', but was '%s'", expectedErr, err.Error()) + } +} + +func TestGenerateTransactionOptionsErrorsWhenAccountNotFound(t *testing.T) { + privateTxArgs := ethapi.PrivateTxArgs{PrivateFor: []string{}} + sendTxArgs := ethapi.SendTxArgs{ + From: common.Address{}, + PrivateTxArgs: privateTxArgs, + } + + mockBackend := MockBackend{} + accountManager := accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true}, &mockBackend) + + service := &PrivacyService{ + accountManager: accountManager, + } + + _, err := service.GenerateTransactOptions(sendTxArgs) + if err == nil { + t.Errorf("expected err to not be nil") + return + } + + expectedErr := "no wallet found for account 0x0000000000000000000000000000000000000000" + if err.Error() != expectedErr { + t.Errorf("expected err to be '%s', but was '%s'", expectedErr, err.Error()) + } +} + +func TestGenerateTransactionOptionsGivesDefaults(t *testing.T) { + from := common.HexToAddress("0x2222222222222222222222222222222222222222") + + privateTxArgs := ethapi.PrivateTxArgs{PrivateFor: []string{"privateFor1", "privateFor2"}, PrivateFrom: "privateFrom"} + + sendTxArgs := ethapi.SendTxArgs{ + From: from, + PrivateTxArgs: privateTxArgs, + } + + mockWallet := &MockWallet{isContained: true} + mockBackend := MockBackend{wallets: []accounts.Wallet{mockWallet}} + accountManager := accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true}, &mockBackend) + service := &PrivacyService{ + accountManager: accountManager, + } + + generatedOptions, err := service.GenerateTransactOptions(sendTxArgs) + if err != nil { + t.Errorf("expected err to be '%s', but was '%s'", "nil", err.Error()) + return + } + + if generatedOptions.PrivateFrom != sendTxArgs.PrivateFrom { + t.Errorf("expected PrivateFrom to be '%s', but was '%s'", sendTxArgs.PrivateFrom, generatedOptions.PrivateFrom) + return + } + + if len(generatedOptions.PrivateFor) != 2 || generatedOptions.PrivateFor[0] != sendTxArgs.PrivateFor[0] || generatedOptions.PrivateFor[1] != sendTxArgs.PrivateFor[1] { + t.Errorf("expected PrivateFor to be '%s', but was '%s'", sendTxArgs.PrivateFor, generatedOptions.PrivateFor) + return + } + + if generatedOptions.GasLimit != 4712384 { + t.Errorf("expected GasLimit to be '%d', but was '%d'", 4712384, generatedOptions.GasLimit) + return + } + + if generatedOptions.GasPrice == nil || generatedOptions.GasPrice.Cmp(new(big.Int)) != 0 { + t.Errorf("expected GasLimit to be '%d', but was '%d'", new(big.Int), generatedOptions.GasPrice) + return + } + + if generatedOptions.From != from { + t.Errorf("expected From to be '%d', but was '%d'", from, generatedOptions.From) + return + } +} + +func TestGenerateTransactionOptionsGivesNonDefaultsWhenSpecified(t *testing.T) { + from := common.HexToAddress("0x2222222222222222222222222222222222222222") + gasLimit := hexutil.Uint64(5000) + gasPrice := hexutil.Big(*big.NewInt(50)) + + privateTxArgs := ethapi.PrivateTxArgs{PrivateFor: []string{}} + + sendTxArgs := ethapi.SendTxArgs{ + From: from, + Gas: &gasLimit, + GasPrice: &gasPrice, + PrivateTxArgs: privateTxArgs, + } + + mockWallet := &MockWallet{isContained: true} + mockBackend := MockBackend{wallets: []accounts.Wallet{mockWallet}} + accountManager := accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: true}, &mockBackend) + service := &PrivacyService{ + accountManager: accountManager, + } + + generatedOptions, err := service.GenerateTransactOptions(sendTxArgs) + if err != nil { + t.Errorf("expected err to be '%s', but was '%s'", "nil", err.Error()) + return + } + + if generatedOptions.GasLimit != 5000 { + t.Errorf("expected GasLimit to be '%d', but was '%d'", 5000, generatedOptions.GasLimit) + return + } + + if generatedOptions.GasPrice == nil || generatedOptions.GasPrice.Cmp(big.NewInt(50)) != 0 { + t.Errorf("expected GasLimit to be '%d', but was '%d'", big.NewInt(50), generatedOptions.GasPrice) + return + } +} diff --git a/extension/client.go b/extension/client.go new file mode 100644 index 0000000000..838dbecc62 --- /dev/null +++ b/extension/client.go @@ -0,0 +1,51 @@ +package extension + +import ( + "context" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" +) + +type Client interface { + SubscribeToLogs(query ethereum.FilterQuery) (<-chan types.Log, ethereum.Subscription, error) + NextNonce(from common.Address) (uint64, error) + TransactionByHash(hash common.Hash) (*types.Transaction, error) + TransactionInBlock(blockHash common.Hash, txIndex uint) (*types.Transaction, error) + Close() +} + +type InProcessClient struct { + client *ethclient.Client +} + +func NewInProcessClient(client *ethclient.Client) *InProcessClient { + return &InProcessClient{ + client: client, + } +} + +func (client *InProcessClient) SubscribeToLogs(query ethereum.FilterQuery) (<-chan types.Log, ethereum.Subscription, error) { + retrievedLogsChan := make(chan types.Log) + sub, err := client.client.SubscribeFilterLogs(context.Background(), query, retrievedLogsChan) + return retrievedLogsChan, sub, err +} + +func (client *InProcessClient) NextNonce(from common.Address) (uint64, error) { + return client.client.PendingNonceAt(context.Background(), from) +} + +func (client *InProcessClient) TransactionByHash(hash common.Hash) (*types.Transaction, error) { + tx, _, err := client.client.TransactionByHash(context.Background(), hash) + return tx, err +} + +func (client *InProcessClient) TransactionInBlock(blockHash common.Hash, txIndex uint) (*types.Transaction, error) { + return client.client.TransactionInBlock(context.Background(), blockHash, txIndex) +} + +func (client *InProcessClient) Close() { + client.client.Close() +} diff --git a/extension/contract_facade.go b/extension/contract_facade.go new file mode 100644 index 0000000000..32f3084936 --- /dev/null +++ b/extension/contract_facade.go @@ -0,0 +1,66 @@ +package extension + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/extension/extensionContracts" +) + +type ManagementContractFacade interface { + Transactor(managementAddress common.Address) (*extensionContracts.ContractExtenderTransactor, error) + Caller(managementAddress common.Address) (*extensionContracts.ContractExtenderCaller, error) + Deploy(args *bind.TransactOpts, toExtend common.Address, recipientAddress common.Address, recipientHash string) (*types.Transaction, error) + + GetAllVoters(addressToVoteOn common.Address) ([]common.Address, error) + Close() +} + +type EthclientManagementContractFacade struct { + client *ethclient.Client +} + +func NewManagementContractFacade(client *ethclient.Client) ManagementContractFacade { + return EthclientManagementContractFacade{client: client} +} + +func (facade EthclientManagementContractFacade) Transactor(managementAddress common.Address) (*extensionContracts.ContractExtenderTransactor, error) { + return extensionContracts.NewContractExtenderTransactor(managementAddress, facade.client) +} + +func (facade EthclientManagementContractFacade) Caller(managementAddress common.Address) (*extensionContracts.ContractExtenderCaller, error) { + return extensionContracts.NewContractExtenderCaller(managementAddress, facade.client) +} + +func (facade EthclientManagementContractFacade) Deploy(args *bind.TransactOpts, toExtend common.Address, recipientAddress common.Address, recipientHash string) (*types.Transaction, error) { + _, tx, _, err := extensionContracts.DeployContractExtender(args, facade.client, toExtend, recipientAddress, recipientHash) + return tx, err +} + +func (facade EthclientManagementContractFacade) GetAllVoters(addressToVoteOn common.Address) ([]common.Address, error) { + caller, err := facade.Caller(addressToVoteOn) + if err != nil { + return nil, err + } + numberOfVoters, err := caller.TotalNumberOfVoters(nil) + if err != nil { + return nil, err + } + var i int64 + var voters []common.Address + for i = 0; i < numberOfVoters.Int64(); i++ { + voter, err := caller.WalletAddressesToVote(nil, big.NewInt(i)) + if err != nil { + return nil, err + } + voters = append(voters, voter) + } + return voters, nil +} + +func (facade EthclientManagementContractFacade) Close() { + facade.client.Close() +} diff --git a/extension/data_handler.go b/extension/data_handler.go new file mode 100644 index 0000000000..5a4e638242 --- /dev/null +++ b/extension/data_handler.go @@ -0,0 +1,107 @@ +package extension + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +/* + The file can have two formats: + + 1. + { + "psiContracts": { + "psi1": { + "contract1address": ..., + "contract2address": ..., + }, + ... + } + } + + 2. + { + "contract1address": ..., + "contract2address": ..., + } + +*/ + +const extensionContractData = "activeExtensions.json" + +type DataHandler interface { + Load() (map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract, error) + + Save(extensionContracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract) error +} + +type JsonFileDataHandler struct { + saveFile string +} + +func NewJsonFileDataHandler(dataDirectory string) *JsonFileDataHandler { + return &JsonFileDataHandler{ + saveFile: filepath.Join(dataDirectory, extensionContractData), + } +} + +/* + The strategy when loading the save file is too check if the newer "psiContracts" field is present. + If so, then everything should exist under that key, and so we can unmarshal and return immediately. + + If not, then the save file was made from a previous version. Load up all the data as before and + put it under the "private" PSI. + + It should never be the case the file contains both types of data at once. +*/ +func (handler *JsonFileDataHandler) Load() (map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract, error) { + if _, err := os.Stat(handler.saveFile); !(err == nil || !os.IsNotExist(err)) { + return map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract{types.DefaultPrivateStateIdentifier: {}}, nil + } + + blob, err := ioutil.ReadFile(handler.saveFile) + if err != nil { + return nil, err + } + + var untyped map[string]json.RawMessage + if err := json.Unmarshal(blob, &untyped); err != nil { + return nil, err + } + + if psiContracts, ok := untyped["psiContracts"]; ok { + var contracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract + json.Unmarshal(psiContracts, &contracts) + return contracts, nil + } + + currentContracts := make(map[common.Address]*ExtensionContract) + for key, val := range untyped { + extAddress := common.HexToAddress(key) + var ext ExtensionContract + json.Unmarshal(val, &ext) + currentContracts[extAddress] = &ext + } + return map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract{types.DefaultPrivateStateIdentifier: currentContracts}, nil +} + +func (handler *JsonFileDataHandler) Save(extensionContracts map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract) error { + //we want to put the map under "psiContracts" key to distinguish from existing data + saveData := make(map[string]interface{}) + saveData["psiContracts"] = extensionContracts + + //no unmarshallable types, so can't error + output, _ := json.Marshal(&saveData) + + if errSaving := ioutil.WriteFile(handler.saveFile, output, 0644); errSaving != nil { + log.Error("Couldn't save outstanding extension contract details") + return errSaving + } + return nil +} diff --git a/extension/data_handler_test.go b/extension/data_handler_test.go new file mode 100644 index 0000000000..76e4179856 --- /dev/null +++ b/extension/data_handler_test.go @@ -0,0 +1,80 @@ +package extension + +import ( + "encoding/json" + "io/ioutil" + "os" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +func TestWriteContentsToFileWritesOkay(t *testing.T) { + extensionContracts := make(map[common.Address]*ExtensionContract) + extensionContracts[common.HexToAddress("0x2222222222222222222222222222222222222222")] = &ExtensionContract{ + ContractExtended: common.HexToAddress("0x1111111111111111111111111111111111111111"), + Initiator: common.HexToAddress("0x3333333333333333333333333333333333333333"), + Recipient: common.HexToAddress("0x4444444444444444444444444444444444444444"), + RecipientPtmKey: "1234567891234567891234567891234567891234567=", + ManagementContractAddress: common.HexToAddress("0x2222222222222222222222222222222222222222"), + CreationData: []byte("Sample Transaction Data"), + } + psiExtensions := map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract{ + types.DefaultPrivateStateIdentifier: extensionContracts, + "somekey": extensionContracts, + } + + datadir, err := ioutil.TempDir("", t.Name()) + defer os.RemoveAll(datadir) + assert.Nil(t, err, "could not create temp directory for test") + + dataHandler := NewJsonFileDataHandler(datadir) + + err = dataHandler.Save(psiExtensions) + assert.Nil(t, err, "error writing data from file") + + loadedData, err := dataHandler.Load() + assert.Nil(t, err, "error reading data from file") + + if !assert.ObjectsAreEqual(psiExtensions, loadedData) { + expected, _ := json.Marshal(extensionContracts) + actual, _ := json.Marshal(loadedData) + t.Errorf("expected data from file different to data written, expected %v, got %v", string(expected), string(actual)) + } +} + +func TestLoadOldContents(t *testing.T) { + extensionContracts := make(map[common.Address]*ExtensionContract) + extensionContracts[common.HexToAddress("0x2222222222222222222222222222222222222222")] = &ExtensionContract{ + ContractExtended: common.HexToAddress("0x1111111111111111111111111111111111111111"), + Initiator: common.HexToAddress("0x3333333333333333333333333333333333333333"), + Recipient: common.HexToAddress("0x4444444444444444444444444444444444444444"), + RecipientPtmKey: "1234567891234567891234567891234567891234567=", + ManagementContractAddress: common.HexToAddress("0x2222222222222222222222222222222222222222"), + CreationData: []byte("Sample Transaction Data"), + } + psiExtensions := map[types.PrivateStateIdentifier]map[common.Address]*ExtensionContract{ + types.DefaultPrivateStateIdentifier: extensionContracts, + "somekey": extensionContracts, + } + + datadir, err := ioutil.TempDir("", t.Name()) + defer os.RemoveAll(datadir) + assert.Nil(t, err, "could not create temp directory for test") + + dataHandler := NewJsonFileDataHandler(datadir) + + err = dataHandler.Save(psiExtensions) + assert.Nil(t, err, "error writing data from file") + + loadedData, err := dataHandler.Load() + assert.Nil(t, err, "error reading data from file") + + if !assert.ObjectsAreEqual(psiExtensions, loadedData) { + expected, _ := json.Marshal(extensionContracts) + actual, _ := json.Marshal(loadedData) + t.Errorf("expected data from file different to data written, expected %v, got %v", string(expected), string(actual)) + } +} diff --git a/extension/extensionContracts/contract_extender.go b/extension/extensionContracts/contract_extender.go new file mode 100644 index 0000000000..56e800b09c --- /dev/null +++ b/extension/extensionContracts/contract_extender.go @@ -0,0 +1,1559 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package extensionContracts + +import ( + "github.com/ethereum/go-ethereum/common/math" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = math.U256Bytes + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// ContractExtenderABI is the input ABI used to generate the binding from. +const ContractExtenderABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"creator\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"contractToExtend\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"checkIfExtensionFinished\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalNumberOfVoters\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"walletAddressesToVote\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"isFinished\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"nextuuid\",\"type\":\"string\"}],\"name\":\"setUuid\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"sharedDataHash\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"hash\",\"type\":\"string\"}],\"name\":\"setSharedStateHash\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"updatePartyMembers\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"voteOutcome\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"checkIfVoted\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"finish\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"votes\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"vote\",\"type\":\"bool\"},{\"name\":\"nextuuid\",\"type\":\"string\"}],\"name\":\"doVote\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"targetRecipientPTMKey\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"haveAllNodesVoted\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\"},{\"name\":\"recipientAddress\",\"type\":\"address\"},{\"name\":\"recipientPTMKey\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"toExtend\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"recipientPTMKey\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"recipientAddress\",\"type\":\"address\"}],\"name\":\"NewContractExtensionContractCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"outcome\",\"type\":\"bool\"}],\"name\":\"AllNodesHaveAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"CanPerformStateShare\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ExtensionFinished\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"vote\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"voter\",\"type\":\"address\"}],\"name\":\"NewVote\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"toExtend\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tesserahash\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"uuid\",\"type\":\"string\"}],\"name\":\"StateShared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"toExtend\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"uuid\",\"type\":\"string\"}],\"name\":\"UpdateMembers\",\"type\":\"event\"}]" + +var ContractExtenderParsedABI, _ = abi.JSON(strings.NewReader(ContractExtenderABI)) + +// ContractExtenderBin is the compiled bytecode used for deploying new contracts. +var ContractExtenderBin = "0x60806040523480156200001157600080fd5b506040516200135738038062001357833981018060405260608110156200003757600080fd5b81516020830151604084018051929491938201926401000000008111156200005e57600080fd5b820160208101848111156200007257600080fd5b81516401000000008111828201871017156200008d57600080fd5b5050600080546001600160a01b031916331790558051909350620000bb92506001915060208401906200028d565b50600280546001600160a01b038086166001600160a01b031992831617909255600380546001818101835560008381527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b92830180548616331790558354918201909355018054938616939092169290921790556040805160208101918290528290526200014d91600a91906200028d565b506009805460ff19166001179055600060068190555b600354811015620001c1576001600560006003848154811015156200018457fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff191691151591909117905560010162000163565b50600354600455604080516001600160a01b0380861682528416918101919091526060602080830182815284519284019290925283517f04576ede6057794ada68966eebc285c98a2726cbc4929ffd1ad9900336728d9393879386938893608084019186019080838360005b83811015620002475781810151838201526020016200022d565b50505050905090810190601f168015620002755780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a150505062000332565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002d057805160ff191683800117855562000300565b8280016001018555821562000300579182015b8281111562000300578251825591602001919060010190620002e3565b506200030e92915062000312565b5090565b6200032f91905b808211156200030e576000815560010162000319565b90565b61101580620003426000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c8063893971ba116100a2578063d56b288911610071578063d56b28891461037a578063d8bff5a514610382578063de5828cb146103a8578063e5af0f3014610457578063f57077d81461045f5761010b565b8063893971ba146102bc578063ac8b920514610362578063b5da45bb1461036a578063cb2805ec146103725761010b565b806379d41b8f116100de57806379d41b8f146101725780637b3529621461018f578063821e93da1461019757806388f520a01461023f5761010b565b806302d05d3f1461011057806315e56a6a146101345780631962cb9b1461013c5780633852772714610158575b600080fd5b610118610467565b604080516001600160a01b039092168252519081900360200190f35b610118610476565b610144610485565b604080519115158252519081900360200190f35b61016061048f565b60408051918252519081900360200190f35b6101186004803603602081101561018857600080fd5b5035610495565b6101446104bd565b61023d600480360360208110156101ad57600080fd5b8101906020810181356401000000008111156101c857600080fd5b8201836020820111156101da57600080fd5b803590602001918460018302840111640100000000831117156101fc57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506104c6945050505050565b005b610247610554565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610281578181015183820152602001610269565b50505050905090810190601f1680156102ae5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61023d600480360360208110156102d257600080fd5b8101906020810181356401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506105e2945050505050565b61023d61094c565b610144610a47565b610144610a50565b61023d610a66565b6101446004803603602081101561039857600080fd5b50356001600160a01b0316610b01565b61023d600480360360408110156103be57600080fd5b8135151591908101906040810160208201356401000000008111156103e257600080fd5b8201836020820111156103f457600080fd5b8035906020019184600183028401116401000000008311171561041657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610b16945050505050565b610247610bbb565b610144610c15565b6000546001600160a01b031681565b6002546001600160a01b031681565b600c5460ff165b90565b60045481565b60038054829081106104a357fe5b6000918252602090912001546001600160a01b0316905081565b600c5460ff1681565b600c5460ff161561050b57604051600160e51b62461bcd028152600401808060200182810382526025815260200180610fc56025913960400191505060405180910390fd5b600b805460018101808355600092909252825161054f917f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db901906020850190610ee1565b505050565b600a805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156105da5780601f106105af576101008083540402835291602001916105da565b820191906000526020600020905b8154815290600101906020018083116105bd57829003601f168201915b505050505081565b6000546001600160a01b0316331461062e57604051600160e51b62461bcd028152600401808060200182810382526023815260200180610fa26023913960400191505060405180910390fd5b600c5460ff161561067357604051600160e51b62461bcd028152600401808060200182810382526025815260200180610fc56025913960400191505060405180910390fd5b600a8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106ff5780601f106106d4576101008083540402835291602001916106ff565b820191906000526020600020905b8154815290600101906020018083116106e257829003601f168201915b505085519394508593151592506107639150505760408051600160e51b62461bcd02815260206004820152601860248201527f6e657720686173682063616e6e6f7420626520656d7074790000000000000000604482015290519081900360640190fd5b8151156107ba5760408051600160e51b62461bcd02815260206004820152601660248201527f7374617465206861736820616c72656164792073657400000000000000000000604482015290519081900360640190fd5b82516107cd90600a906020860190610ee1565b5060005b600b5481101561094357600254600b80547f67a92539f3cbd7c5a9b36c23c0e2beceb27d2e1b3cd8eda02c623689267ae71e926001600160a01b031691600a918590811061081b57fe5b6000918252602091829020604080516001600160a01b038716815260609481018581528654600260001961010060018416150201909116049582018690529290930193908301906080840190869080156108b65780601f1061088b576101008083540402835291602001916108b6565b820191906000526020600020905b81548152906001019060200180831161089957829003601f168201915b505083810382528454600260001961010060018416150201909116048082526020909101908590801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b50509550505050505060405180910390a16001016107d1565b5061054f610a66565b60005b600b54811015610a4457600254600b80547f8adc4573f947f9930560525736f61b116be55049125cb63a36887a40f92f3b44926001600160a01b031691908490811061099757fe5b6000918252602091829020604080516001600160a01b0386168152938401818152919092018054600260001961010060018416150201909116049284018390529291606083019084908015610a2d5780601f10610a0257610100808354040283529160200191610a2d565b820191906000526020600020905b815481529060010190602001808311610a1057829003601f168201915b5050935050505060405180910390a160010161094f565b50565b60095460ff1681565b3360009081526007602052604090205460ff1690565b600c5460ff1615610aab57604051600160e51b62461bcd028152600401808060200182810382526025815260200180610fc56025913960400191505060405180910390fd5b6000546001600160a01b03163314610af757604051600160e51b62461bcd028152600401808060200182810382526023815260200180610fa26023913960400191505060405180910390fd5b610aff610c1f565b565b60086020526000908152604090205460ff1681565b600c5460ff1615610b5b57604051600160e51b62461bcd028152600401808060200182810382526025815260200180610fc56025913960400191505060405180910390fd5b610b6482610c57565b8115610b7357610b73816104c6565b610b7b610e28565b60408051831515815233602082015281517f225708d30006b0cc86d855ab91047edb5fe9c2e416412f36c18c6e90fe4e461f929181900390910190a15050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156105da5780601f106105af576101008083540402835291602001916105da565b6006546003541490565b600c805460ff191660011790556040517f79c47b570b18a8a814b785800e5fcbf104e067663589cef1bba07756e3c6ede990600090a1565b600c5460ff1615610c9c57604051600160e51b62461bcd028152600401808060200182810382526028815260200180610f7a6028913960400191505060405180910390fd5b3360009081526005602052604090205460ff161515610d055760408051600160e51b62461bcd02815260206004820152601360248201527f6e6f7420616c6c6f77656420746f20766f746500000000000000000000000000604482015290519081900360640190fd5b3360009081526007602052604090205460ff1615610d6d5760408051600160e51b62461bcd02815260206004820152600d60248201527f616c726561647920766f74656400000000000000000000000000000000000000604482015290519081900360640190fd5b60095460ff161515610dc95760408051600160e51b62461bcd02815260206004820152601760248201527f766f74696e6720616c7265616479206465636c696e6564000000000000000000604482015290519081900360640190fd5b3360009081526007602090815260408083208054600160ff19918216811790925560089093529220805490911683151517905560068054909101905560095460ff168015610e145750805b6009805460ff191691151591909117905550565b60095460ff161515610e7557604080516000815290517ff20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd369181900360200190a1610e70610c1f565b610aff565b610e7d610c15565b15610aff57604080516001815290517ff20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd369181900360200190a16040517ffd46cafaa71d87561071b8095703a7f081265fad232945049f5cf2d2c39b3d2890600090a1565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610f2257805160ff1916838001178555610f4f565b82800160010185558215610f4f579182015b82811115610f4f578251825591602001919060010190610f34565b50610f5b929150610f5f565b5090565b61048c91905b80821115610f5b5760008155600101610f6556fe657874656e73696f6e2070726f6365737320636f6d706c657465642e2063616e6e6f7420766f74656f6e6c79206c6561646572206d617920706572666f726d207468697320616374696f6e657874656e73696f6e20686173206265656e206d61726b65642061732066696e6973686564a165627a7a723058201430571f2ddc1fc4db18fbe992d5cb9955a993fb01a34d163aebb1b5d891a6f00029" + +// DeployContractExtender deploys a new Ethereum contract, binding an instance of ContractExtender to it. +func DeployContractExtender(auth *bind.TransactOpts, backend bind.ContractBackend, contractAddress common.Address, recipientAddress common.Address, recipientPTMKey string) (common.Address, *types.Transaction, *ContractExtender, error) { + parsed, err := abi.JSON(strings.NewReader(ContractExtenderABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ContractExtenderBin), backend, contractAddress, recipientAddress, recipientPTMKey) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ContractExtender{ContractExtenderCaller: ContractExtenderCaller{contract: contract}, ContractExtenderTransactor: ContractExtenderTransactor{contract: contract}, ContractExtenderFilterer: ContractExtenderFilterer{contract: contract}}, nil +} + +// ContractExtender is an auto generated Go binding around an Ethereum contract. +type ContractExtender struct { + ContractExtenderCaller // Read-only binding to the contract + ContractExtenderTransactor // Write-only binding to the contract + ContractExtenderFilterer // Log filterer for contract events +} + +// ContractExtenderCaller is an auto generated read-only Go binding around an Ethereum contract. +type ContractExtenderCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractExtenderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ContractExtenderTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractExtenderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ContractExtenderFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ContractExtenderSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ContractExtenderSession struct { + Contract *ContractExtender // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractExtenderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ContractExtenderCallerSession struct { + Contract *ContractExtenderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ContractExtenderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ContractExtenderTransactorSession struct { + Contract *ContractExtenderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ContractExtenderRaw is an auto generated low-level Go binding around an Ethereum contract. +type ContractExtenderRaw struct { + Contract *ContractExtender // Generic contract binding to access the raw methods on +} + +// ContractExtenderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ContractExtenderCallerRaw struct { + Contract *ContractExtenderCaller // Generic read-only contract binding to access the raw methods on +} + +// ContractExtenderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ContractExtenderTransactorRaw struct { + Contract *ContractExtenderTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewContractExtender creates a new instance of ContractExtender, bound to a specific deployed contract. +func NewContractExtender(address common.Address, backend bind.ContractBackend) (*ContractExtender, error) { + contract, err := bindContractExtender(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ContractExtender{ContractExtenderCaller: ContractExtenderCaller{contract: contract}, ContractExtenderTransactor: ContractExtenderTransactor{contract: contract}, ContractExtenderFilterer: ContractExtenderFilterer{contract: contract}}, nil +} + +// NewContractExtenderCaller creates a new read-only instance of ContractExtender, bound to a specific deployed contract. +func NewContractExtenderCaller(address common.Address, caller bind.ContractCaller) (*ContractExtenderCaller, error) { + contract, err := bindContractExtender(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ContractExtenderCaller{contract: contract}, nil +} + +// NewContractExtenderTransactor creates a new write-only instance of ContractExtender, bound to a specific deployed contract. +func NewContractExtenderTransactor(address common.Address, transactor bind.ContractTransactor) (*ContractExtenderTransactor, error) { + contract, err := bindContractExtender(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ContractExtenderTransactor{contract: contract}, nil +} + +// NewContractExtenderFilterer creates a new log filterer instance of ContractExtender, bound to a specific deployed contract. +func NewContractExtenderFilterer(address common.Address, filterer bind.ContractFilterer) (*ContractExtenderFilterer, error) { + contract, err := bindContractExtender(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ContractExtenderFilterer{contract: contract}, nil +} + +// bindContractExtender binds a generic wrapper to an already deployed contract. +func bindContractExtender(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ContractExtenderABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ContractExtender *ContractExtenderRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _ContractExtender.Contract.ContractExtenderCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ContractExtender *ContractExtenderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractExtender.Contract.ContractExtenderTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractExtender *ContractExtenderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractExtender.Contract.ContractExtenderTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ContractExtender *ContractExtenderCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + return _ContractExtender.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ContractExtender *ContractExtenderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractExtender.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ContractExtender *ContractExtenderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ContractExtender.Contract.contract.Transact(opts, method, params...) +} + +// CheckIfExtensionFinished is a free data retrieval call binding the contract method 0x1962cb9b. +// +// Solidity: function checkIfExtensionFinished() constant returns(bool) +func (_ContractExtender *ContractExtenderCaller) CheckIfExtensionFinished(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "checkIfExtensionFinished") + return *ret0, err +} + +// CheckIfExtensionFinished is a free data retrieval call binding the contract method 0x1962cb9b. +// +// Solidity: function checkIfExtensionFinished() constant returns(bool) +func (_ContractExtender *ContractExtenderSession) CheckIfExtensionFinished() (bool, error) { + return _ContractExtender.Contract.CheckIfExtensionFinished(&_ContractExtender.CallOpts) +} + +// CheckIfExtensionFinished is a free data retrieval call binding the contract method 0x1962cb9b. +// +// Solidity: function checkIfExtensionFinished() constant returns(bool) +func (_ContractExtender *ContractExtenderCallerSession) CheckIfExtensionFinished() (bool, error) { + return _ContractExtender.Contract.CheckIfExtensionFinished(&_ContractExtender.CallOpts) +} + +// CheckIfVoted is a free data retrieval call binding the contract method 0xcb2805ec. +// +// Solidity: function checkIfVoted() constant returns(bool) +func (_ContractExtender *ContractExtenderCaller) CheckIfVoted(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "checkIfVoted") + return *ret0, err +} + +// CheckIfVoted is a free data retrieval call binding the contract method 0xcb2805ec. +// +// Solidity: function checkIfVoted() constant returns(bool) +func (_ContractExtender *ContractExtenderSession) CheckIfVoted() (bool, error) { + return _ContractExtender.Contract.CheckIfVoted(&_ContractExtender.CallOpts) +} + +// CheckIfVoted is a free data retrieval call binding the contract method 0xcb2805ec. +// +// Solidity: function checkIfVoted() constant returns(bool) +func (_ContractExtender *ContractExtenderCallerSession) CheckIfVoted() (bool, error) { + return _ContractExtender.Contract.CheckIfVoted(&_ContractExtender.CallOpts) +} + +// ContractToExtend is a free data retrieval call binding the contract method 0x15e56a6a. +// +// Solidity: function contractToExtend() constant returns(address) +func (_ContractExtender *ContractExtenderCaller) ContractToExtend(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "contractToExtend") + return *ret0, err +} + +// ContractToExtend is a free data retrieval call binding the contract method 0x15e56a6a. +// +// Solidity: function contractToExtend() constant returns(address) +func (_ContractExtender *ContractExtenderSession) ContractToExtend() (common.Address, error) { + return _ContractExtender.Contract.ContractToExtend(&_ContractExtender.CallOpts) +} + +// ContractToExtend is a free data retrieval call binding the contract method 0x15e56a6a. +// +// Solidity: function contractToExtend() constant returns(address) +func (_ContractExtender *ContractExtenderCallerSession) ContractToExtend() (common.Address, error) { + return _ContractExtender.Contract.ContractToExtend(&_ContractExtender.CallOpts) +} + +// Creator is a free data retrieval call binding the contract method 0x02d05d3f. +// +// Solidity: function creator() constant returns(address) +func (_ContractExtender *ContractExtenderCaller) Creator(opts *bind.CallOpts) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "creator") + return *ret0, err +} + +// Creator is a free data retrieval call binding the contract method 0x02d05d3f. +// +// Solidity: function creator() constant returns(address) +func (_ContractExtender *ContractExtenderSession) Creator() (common.Address, error) { + return _ContractExtender.Contract.Creator(&_ContractExtender.CallOpts) +} + +// Creator is a free data retrieval call binding the contract method 0x02d05d3f. +// +// Solidity: function creator() constant returns(address) +func (_ContractExtender *ContractExtenderCallerSession) Creator() (common.Address, error) { + return _ContractExtender.Contract.Creator(&_ContractExtender.CallOpts) +} + +// HaveAllNodesVoted is a free data retrieval call binding the contract method 0xf57077d8. +// +// Solidity: function haveAllNodesVoted() constant returns(bool) +func (_ContractExtender *ContractExtenderCaller) HaveAllNodesVoted(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "haveAllNodesVoted") + return *ret0, err +} + +// HaveAllNodesVoted is a free data retrieval call binding the contract method 0xf57077d8. +// +// Solidity: function haveAllNodesVoted() constant returns(bool) +func (_ContractExtender *ContractExtenderSession) HaveAllNodesVoted() (bool, error) { + return _ContractExtender.Contract.HaveAllNodesVoted(&_ContractExtender.CallOpts) +} + +// HaveAllNodesVoted is a free data retrieval call binding the contract method 0xf57077d8. +// +// Solidity: function haveAllNodesVoted() constant returns(bool) +func (_ContractExtender *ContractExtenderCallerSession) HaveAllNodesVoted() (bool, error) { + return _ContractExtender.Contract.HaveAllNodesVoted(&_ContractExtender.CallOpts) +} + +// IsFinished is a free data retrieval call binding the contract method 0x7b352962. +// +// Solidity: function isFinished() constant returns(bool) +func (_ContractExtender *ContractExtenderCaller) IsFinished(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "isFinished") + return *ret0, err +} + +// IsFinished is a free data retrieval call binding the contract method 0x7b352962. +// +// Solidity: function isFinished() constant returns(bool) +func (_ContractExtender *ContractExtenderSession) IsFinished() (bool, error) { + return _ContractExtender.Contract.IsFinished(&_ContractExtender.CallOpts) +} + +// IsFinished is a free data retrieval call binding the contract method 0x7b352962. +// +// Solidity: function isFinished() constant returns(bool) +func (_ContractExtender *ContractExtenderCallerSession) IsFinished() (bool, error) { + return _ContractExtender.Contract.IsFinished(&_ContractExtender.CallOpts) +} + +// SharedDataHash is a free data retrieval call binding the contract method 0x88f520a0. +// +// Solidity: function sharedDataHash() constant returns(string) +func (_ContractExtender *ContractExtenderCaller) SharedDataHash(opts *bind.CallOpts) (string, error) { + var ( + ret0 = new(string) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "sharedDataHash") + return *ret0, err +} + +// SharedDataHash is a free data retrieval call binding the contract method 0x88f520a0. +// +// Solidity: function sharedDataHash() constant returns(string) +func (_ContractExtender *ContractExtenderSession) SharedDataHash() (string, error) { + return _ContractExtender.Contract.SharedDataHash(&_ContractExtender.CallOpts) +} + +// SharedDataHash is a free data retrieval call binding the contract method 0x88f520a0. +// +// Solidity: function sharedDataHash() constant returns(string) +func (_ContractExtender *ContractExtenderCallerSession) SharedDataHash() (string, error) { + return _ContractExtender.Contract.SharedDataHash(&_ContractExtender.CallOpts) +} + +// TargetRecipientPTMKey is a free data retrieval call binding the contract method 0xe5af0f30. +// +// Solidity: function targetRecipientPTMKey() constant returns(string) +func (_ContractExtender *ContractExtenderCaller) TargetRecipientPTMKey(opts *bind.CallOpts) (string, error) { + var ( + ret0 = new(string) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "targetRecipientPTMKey") + return *ret0, err +} + +// TargetRecipientPTMKey is a free data retrieval call binding the contract method 0xe5af0f30. +// +// Solidity: function targetRecipientPTMKey() constant returns(string) +func (_ContractExtender *ContractExtenderSession) TargetRecipientPTMKey() (string, error) { + return _ContractExtender.Contract.TargetRecipientPTMKey(&_ContractExtender.CallOpts) +} + +// TargetRecipientPTMKey is a free data retrieval call binding the contract method 0xe5af0f30. +// +// Solidity: function targetRecipientPTMKey() constant returns(string) +func (_ContractExtender *ContractExtenderCallerSession) TargetRecipientPTMKey() (string, error) { + return _ContractExtender.Contract.TargetRecipientPTMKey(&_ContractExtender.CallOpts) +} + +// TotalNumberOfVoters is a free data retrieval call binding the contract method 0x38527727. +// +// Solidity: function totalNumberOfVoters() constant returns(uint256) +func (_ContractExtender *ContractExtenderCaller) TotalNumberOfVoters(opts *bind.CallOpts) (*big.Int, error) { + var ( + ret0 = new(*big.Int) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "totalNumberOfVoters") + return *ret0, err +} + +// TotalNumberOfVoters is a free data retrieval call binding the contract method 0x38527727. +// +// Solidity: function totalNumberOfVoters() constant returns(uint256) +func (_ContractExtender *ContractExtenderSession) TotalNumberOfVoters() (*big.Int, error) { + return _ContractExtender.Contract.TotalNumberOfVoters(&_ContractExtender.CallOpts) +} + +// TotalNumberOfVoters is a free data retrieval call binding the contract method 0x38527727. +// +// Solidity: function totalNumberOfVoters() constant returns(uint256) +func (_ContractExtender *ContractExtenderCallerSession) TotalNumberOfVoters() (*big.Int, error) { + return _ContractExtender.Contract.TotalNumberOfVoters(&_ContractExtender.CallOpts) +} + +// VoteOutcome is a free data retrieval call binding the contract method 0xb5da45bb. +// +// Solidity: function voteOutcome() constant returns(bool) +func (_ContractExtender *ContractExtenderCaller) VoteOutcome(opts *bind.CallOpts) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "voteOutcome") + return *ret0, err +} + +// VoteOutcome is a free data retrieval call binding the contract method 0xb5da45bb. +// +// Solidity: function voteOutcome() constant returns(bool) +func (_ContractExtender *ContractExtenderSession) VoteOutcome() (bool, error) { + return _ContractExtender.Contract.VoteOutcome(&_ContractExtender.CallOpts) +} + +// VoteOutcome is a free data retrieval call binding the contract method 0xb5da45bb. +// +// Solidity: function voteOutcome() constant returns(bool) +func (_ContractExtender *ContractExtenderCallerSession) VoteOutcome() (bool, error) { + return _ContractExtender.Contract.VoteOutcome(&_ContractExtender.CallOpts) +} + +// Votes is a free data retrieval call binding the contract method 0xd8bff5a5. +// +// Solidity: function votes(address ) constant returns(bool) +func (_ContractExtender *ContractExtenderCaller) Votes(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var ( + ret0 = new(bool) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "votes", arg0) + return *ret0, err +} + +// Votes is a free data retrieval call binding the contract method 0xd8bff5a5. +// +// Solidity: function votes(address ) constant returns(bool) +func (_ContractExtender *ContractExtenderSession) Votes(arg0 common.Address) (bool, error) { + return _ContractExtender.Contract.Votes(&_ContractExtender.CallOpts, arg0) +} + +// Votes is a free data retrieval call binding the contract method 0xd8bff5a5. +// +// Solidity: function votes(address ) constant returns(bool) +func (_ContractExtender *ContractExtenderCallerSession) Votes(arg0 common.Address) (bool, error) { + return _ContractExtender.Contract.Votes(&_ContractExtender.CallOpts, arg0) +} + +// WalletAddressesToVote is a free data retrieval call binding the contract method 0x79d41b8f. +// +// Solidity: function walletAddressesToVote(uint256 ) constant returns(address) +func (_ContractExtender *ContractExtenderCaller) WalletAddressesToVote(opts *bind.CallOpts, arg0 *big.Int) (common.Address, error) { + var ( + ret0 = new(common.Address) + ) + out := ret0 + err := _ContractExtender.contract.Call(opts, out, "walletAddressesToVote", arg0) + return *ret0, err +} + +// WalletAddressesToVote is a free data retrieval call binding the contract method 0x79d41b8f. +// +// Solidity: function walletAddressesToVote(uint256 ) constant returns(address) +func (_ContractExtender *ContractExtenderSession) WalletAddressesToVote(arg0 *big.Int) (common.Address, error) { + return _ContractExtender.Contract.WalletAddressesToVote(&_ContractExtender.CallOpts, arg0) +} + +// WalletAddressesToVote is a free data retrieval call binding the contract method 0x79d41b8f. +// +// Solidity: function walletAddressesToVote(uint256 ) constant returns(address) +func (_ContractExtender *ContractExtenderCallerSession) WalletAddressesToVote(arg0 *big.Int) (common.Address, error) { + return _ContractExtender.Contract.WalletAddressesToVote(&_ContractExtender.CallOpts, arg0) +} + +// DoVote is a paid mutator transaction binding the contract method 0xde5828cb. +// +// Solidity: function doVote(bool vote, string nextuuid) returns() +func (_ContractExtender *ContractExtenderTransactor) DoVote(opts *bind.TransactOpts, vote bool, nextuuid string) (*types.Transaction, error) { + return _ContractExtender.contract.Transact(opts, "doVote", vote, nextuuid) +} + +// DoVote is a paid mutator transaction binding the contract method 0xde5828cb. +// +// Solidity: function doVote(bool vote, string nextuuid) returns() +func (_ContractExtender *ContractExtenderSession) DoVote(vote bool, nextuuid string) (*types.Transaction, error) { + return _ContractExtender.Contract.DoVote(&_ContractExtender.TransactOpts, vote, nextuuid) +} + +// DoVote is a paid mutator transaction binding the contract method 0xde5828cb. +// +// Solidity: function doVote(bool vote, string nextuuid) returns() +func (_ContractExtender *ContractExtenderTransactorSession) DoVote(vote bool, nextuuid string) (*types.Transaction, error) { + return _ContractExtender.Contract.DoVote(&_ContractExtender.TransactOpts, vote, nextuuid) +} + +// Finish is a paid mutator transaction binding the contract method 0xd56b2889. +// +// Solidity: function finish() returns() +func (_ContractExtender *ContractExtenderTransactor) Finish(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractExtender.contract.Transact(opts, "finish") +} + +// Finish is a paid mutator transaction binding the contract method 0xd56b2889. +// +// Solidity: function finish() returns() +func (_ContractExtender *ContractExtenderSession) Finish() (*types.Transaction, error) { + return _ContractExtender.Contract.Finish(&_ContractExtender.TransactOpts) +} + +// Finish is a paid mutator transaction binding the contract method 0xd56b2889. +// +// Solidity: function finish() returns() +func (_ContractExtender *ContractExtenderTransactorSession) Finish() (*types.Transaction, error) { + return _ContractExtender.Contract.Finish(&_ContractExtender.TransactOpts) +} + +// SetSharedStateHash is a paid mutator transaction binding the contract method 0x893971ba. +// +// Solidity: function setSharedStateHash(string hash) returns() +func (_ContractExtender *ContractExtenderTransactor) SetSharedStateHash(opts *bind.TransactOpts, hash string) (*types.Transaction, error) { + return _ContractExtender.contract.Transact(opts, "setSharedStateHash", hash) +} + +// SetSharedStateHash is a paid mutator transaction binding the contract method 0x893971ba. +// +// Solidity: function setSharedStateHash(string hash) returns() +func (_ContractExtender *ContractExtenderSession) SetSharedStateHash(hash string) (*types.Transaction, error) { + return _ContractExtender.Contract.SetSharedStateHash(&_ContractExtender.TransactOpts, hash) +} + +// SetSharedStateHash is a paid mutator transaction binding the contract method 0x893971ba. +// +// Solidity: function setSharedStateHash(string hash) returns() +func (_ContractExtender *ContractExtenderTransactorSession) SetSharedStateHash(hash string) (*types.Transaction, error) { + return _ContractExtender.Contract.SetSharedStateHash(&_ContractExtender.TransactOpts, hash) +} + +// SetUuid is a paid mutator transaction binding the contract method 0x821e93da. +// +// Solidity: function setUuid(string nextuuid) returns() +func (_ContractExtender *ContractExtenderTransactor) SetUuid(opts *bind.TransactOpts, nextuuid string) (*types.Transaction, error) { + return _ContractExtender.contract.Transact(opts, "setUuid", nextuuid) +} + +// SetUuid is a paid mutator transaction binding the contract method 0x821e93da. +// +// Solidity: function setUuid(string nextuuid) returns() +func (_ContractExtender *ContractExtenderSession) SetUuid(nextuuid string) (*types.Transaction, error) { + return _ContractExtender.Contract.SetUuid(&_ContractExtender.TransactOpts, nextuuid) +} + +// SetUuid is a paid mutator transaction binding the contract method 0x821e93da. +// +// Solidity: function setUuid(string nextuuid) returns() +func (_ContractExtender *ContractExtenderTransactorSession) SetUuid(nextuuid string) (*types.Transaction, error) { + return _ContractExtender.Contract.SetUuid(&_ContractExtender.TransactOpts, nextuuid) +} + +// UpdatePartyMembers is a paid mutator transaction binding the contract method 0xac8b9205. +// +// Solidity: function updatePartyMembers() returns() +func (_ContractExtender *ContractExtenderTransactor) UpdatePartyMembers(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ContractExtender.contract.Transact(opts, "updatePartyMembers") +} + +// UpdatePartyMembers is a paid mutator transaction binding the contract method 0xac8b9205. +// +// Solidity: function updatePartyMembers() returns() +func (_ContractExtender *ContractExtenderSession) UpdatePartyMembers() (*types.Transaction, error) { + return _ContractExtender.Contract.UpdatePartyMembers(&_ContractExtender.TransactOpts) +} + +// UpdatePartyMembers is a paid mutator transaction binding the contract method 0xac8b9205. +// +// Solidity: function updatePartyMembers() returns() +func (_ContractExtender *ContractExtenderTransactorSession) UpdatePartyMembers() (*types.Transaction, error) { + return _ContractExtender.Contract.UpdatePartyMembers(&_ContractExtender.TransactOpts) +} + +// ContractExtenderAllNodesHaveAcceptedIterator is returned from FilterAllNodesHaveAccepted and is used to iterate over the raw logs and unpacked data for AllNodesHaveAccepted events raised by the ContractExtender contract. +type ContractExtenderAllNodesHaveAcceptedIterator struct { + Event *ContractExtenderAllNodesHaveAccepted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderAllNodesHaveAcceptedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderAllNodesHaveAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderAllNodesHaveAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderAllNodesHaveAcceptedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderAllNodesHaveAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderAllNodesHaveAccepted represents a AllNodesHaveAccepted event raised by the ContractExtender contract. +type ContractExtenderAllNodesHaveAccepted struct { + Outcome bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAllNodesHaveAccepted is a free log retrieval operation binding the contract event 0xf20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd36. +// +// Solidity: event AllNodesHaveAccepted(bool outcome) +func (_ContractExtender *ContractExtenderFilterer) FilterAllNodesHaveAccepted(opts *bind.FilterOpts) (*ContractExtenderAllNodesHaveAcceptedIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "AllNodesHaveAccepted") + if err != nil { + return nil, err + } + return &ContractExtenderAllNodesHaveAcceptedIterator{contract: _ContractExtender.contract, event: "AllNodesHaveAccepted", logs: logs, sub: sub}, nil +} + +var AllNodesHaveAcceptedTopicHash = "0xf20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd36" + +// WatchAllNodesHaveAccepted is a free log subscription operation binding the contract event 0xf20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd36. +// +// Solidity: event AllNodesHaveAccepted(bool outcome) +func (_ContractExtender *ContractExtenderFilterer) WatchAllNodesHaveAccepted(opts *bind.WatchOpts, sink chan<- *ContractExtenderAllNodesHaveAccepted) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "AllNodesHaveAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderAllNodesHaveAccepted) + if err := _ContractExtender.contract.UnpackLog(event, "AllNodesHaveAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAllNodesHaveAccepted is a log parse operation binding the contract event 0xf20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd36. +// +// Solidity: event AllNodesHaveAccepted(bool outcome) +func (_ContractExtender *ContractExtenderFilterer) ParseAllNodesHaveAccepted(log types.Log) (*ContractExtenderAllNodesHaveAccepted, error) { + event := new(ContractExtenderAllNodesHaveAccepted) + if err := _ContractExtender.contract.UnpackLog(event, "AllNodesHaveAccepted", log); err != nil { + return nil, err + } + return event, nil +} + +// ContractExtenderCanPerformStateShareIterator is returned from FilterCanPerformStateShare and is used to iterate over the raw logs and unpacked data for CanPerformStateShare events raised by the ContractExtender contract. +type ContractExtenderCanPerformStateShareIterator struct { + Event *ContractExtenderCanPerformStateShare // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderCanPerformStateShareIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderCanPerformStateShare) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderCanPerformStateShare) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderCanPerformStateShareIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderCanPerformStateShareIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderCanPerformStateShare represents a CanPerformStateShare event raised by the ContractExtender contract. +type ContractExtenderCanPerformStateShare struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCanPerformStateShare is a free log retrieval operation binding the contract event 0xfd46cafaa71d87561071b8095703a7f081265fad232945049f5cf2d2c39b3d28. +// +// Solidity: event CanPerformStateShare() +func (_ContractExtender *ContractExtenderFilterer) FilterCanPerformStateShare(opts *bind.FilterOpts) (*ContractExtenderCanPerformStateShareIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "CanPerformStateShare") + if err != nil { + return nil, err + } + return &ContractExtenderCanPerformStateShareIterator{contract: _ContractExtender.contract, event: "CanPerformStateShare", logs: logs, sub: sub}, nil +} + +var CanPerformStateShareTopicHash = "0xfd46cafaa71d87561071b8095703a7f081265fad232945049f5cf2d2c39b3d28" + +// WatchCanPerformStateShare is a free log subscription operation binding the contract event 0xfd46cafaa71d87561071b8095703a7f081265fad232945049f5cf2d2c39b3d28. +// +// Solidity: event CanPerformStateShare() +func (_ContractExtender *ContractExtenderFilterer) WatchCanPerformStateShare(opts *bind.WatchOpts, sink chan<- *ContractExtenderCanPerformStateShare) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "CanPerformStateShare") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderCanPerformStateShare) + if err := _ContractExtender.contract.UnpackLog(event, "CanPerformStateShare", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCanPerformStateShare is a log parse operation binding the contract event 0xfd46cafaa71d87561071b8095703a7f081265fad232945049f5cf2d2c39b3d28. +// +// Solidity: event CanPerformStateShare() +func (_ContractExtender *ContractExtenderFilterer) ParseCanPerformStateShare(log types.Log) (*ContractExtenderCanPerformStateShare, error) { + event := new(ContractExtenderCanPerformStateShare) + if err := _ContractExtender.contract.UnpackLog(event, "CanPerformStateShare", log); err != nil { + return nil, err + } + return event, nil +} + +// ContractExtenderExtensionFinishedIterator is returned from FilterExtensionFinished and is used to iterate over the raw logs and unpacked data for ExtensionFinished events raised by the ContractExtender contract. +type ContractExtenderExtensionFinishedIterator struct { + Event *ContractExtenderExtensionFinished // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderExtensionFinishedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderExtensionFinished) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderExtensionFinished) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderExtensionFinishedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderExtensionFinishedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderExtensionFinished represents a ExtensionFinished event raised by the ContractExtender contract. +type ContractExtenderExtensionFinished struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExtensionFinished is a free log retrieval operation binding the contract event 0x79c47b570b18a8a814b785800e5fcbf104e067663589cef1bba07756e3c6ede9. +// +// Solidity: event ExtensionFinished() +func (_ContractExtender *ContractExtenderFilterer) FilterExtensionFinished(opts *bind.FilterOpts) (*ContractExtenderExtensionFinishedIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "ExtensionFinished") + if err != nil { + return nil, err + } + return &ContractExtenderExtensionFinishedIterator{contract: _ContractExtender.contract, event: "ExtensionFinished", logs: logs, sub: sub}, nil +} + +var ExtensionFinishedTopicHash = "0x79c47b570b18a8a814b785800e5fcbf104e067663589cef1bba07756e3c6ede9" + +// WatchExtensionFinished is a free log subscription operation binding the contract event 0x79c47b570b18a8a814b785800e5fcbf104e067663589cef1bba07756e3c6ede9. +// +// Solidity: event ExtensionFinished() +func (_ContractExtender *ContractExtenderFilterer) WatchExtensionFinished(opts *bind.WatchOpts, sink chan<- *ContractExtenderExtensionFinished) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "ExtensionFinished") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderExtensionFinished) + if err := _ContractExtender.contract.UnpackLog(event, "ExtensionFinished", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseExtensionFinished is a log parse operation binding the contract event 0x79c47b570b18a8a814b785800e5fcbf104e067663589cef1bba07756e3c6ede9. +// +// Solidity: event ExtensionFinished() +func (_ContractExtender *ContractExtenderFilterer) ParseExtensionFinished(log types.Log) (*ContractExtenderExtensionFinished, error) { + event := new(ContractExtenderExtensionFinished) + if err := _ContractExtender.contract.UnpackLog(event, "ExtensionFinished", log); err != nil { + return nil, err + } + return event, nil +} + +// ContractExtenderNewContractExtensionContractCreatedIterator is returned from FilterNewContractExtensionContractCreated and is used to iterate over the raw logs and unpacked data for NewContractExtensionContractCreated events raised by the ContractExtender contract. +type ContractExtenderNewContractExtensionContractCreatedIterator struct { + Event *ContractExtenderNewContractExtensionContractCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderNewContractExtensionContractCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderNewContractExtensionContractCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderNewContractExtensionContractCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderNewContractExtensionContractCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderNewContractExtensionContractCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderNewContractExtensionContractCreated represents a NewContractExtensionContractCreated event raised by the ContractExtender contract. +type ContractExtenderNewContractExtensionContractCreated struct { + ToExtend common.Address + RecipientPTMKey string + RecipientAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewContractExtensionContractCreated is a free log retrieval operation binding the contract event 0x04576ede6057794ada68966eebc285c98a2726cbc4929ffd1ad9900336728d93. +// +// Solidity: event NewContractExtensionContractCreated(address toExtend, string recipientPTMKey, address recipientAddress) +func (_ContractExtender *ContractExtenderFilterer) FilterNewContractExtensionContractCreated(opts *bind.FilterOpts) (*ContractExtenderNewContractExtensionContractCreatedIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "NewContractExtensionContractCreated") + if err != nil { + return nil, err + } + return &ContractExtenderNewContractExtensionContractCreatedIterator{contract: _ContractExtender.contract, event: "NewContractExtensionContractCreated", logs: logs, sub: sub}, nil +} + +var NewContractExtensionContractCreatedTopicHash = "0x04576ede6057794ada68966eebc285c98a2726cbc4929ffd1ad9900336728d93" + +// WatchNewContractExtensionContractCreated is a free log subscription operation binding the contract event 0x04576ede6057794ada68966eebc285c98a2726cbc4929ffd1ad9900336728d93. +// +// Solidity: event NewContractExtensionContractCreated(address toExtend, string recipientPTMKey, address recipientAddress) +func (_ContractExtender *ContractExtenderFilterer) WatchNewContractExtensionContractCreated(opts *bind.WatchOpts, sink chan<- *ContractExtenderNewContractExtensionContractCreated) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "NewContractExtensionContractCreated") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderNewContractExtensionContractCreated) + if err := _ContractExtender.contract.UnpackLog(event, "NewContractExtensionContractCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNewContractExtensionContractCreated is a log parse operation binding the contract event 0x04576ede6057794ada68966eebc285c98a2726cbc4929ffd1ad9900336728d93. +// +// Solidity: event NewContractExtensionContractCreated(address toExtend, string recipientPTMKey, address recipientAddress) +func (_ContractExtender *ContractExtenderFilterer) ParseNewContractExtensionContractCreated(log types.Log) (*ContractExtenderNewContractExtensionContractCreated, error) { + event := new(ContractExtenderNewContractExtensionContractCreated) + if err := _ContractExtender.contract.UnpackLog(event, "NewContractExtensionContractCreated", log); err != nil { + return nil, err + } + return event, nil +} + +// ContractExtenderNewVoteIterator is returned from FilterNewVote and is used to iterate over the raw logs and unpacked data for NewVote events raised by the ContractExtender contract. +type ContractExtenderNewVoteIterator struct { + Event *ContractExtenderNewVote // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderNewVoteIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderNewVote) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderNewVote) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderNewVoteIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderNewVoteIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderNewVote represents a NewVote event raised by the ContractExtender contract. +type ContractExtenderNewVote struct { + Vote bool + Voter common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewVote is a free log retrieval operation binding the contract event 0x225708d30006b0cc86d855ab91047edb5fe9c2e416412f36c18c6e90fe4e461f. +// +// Solidity: event NewVote(bool vote, address voter) +func (_ContractExtender *ContractExtenderFilterer) FilterNewVote(opts *bind.FilterOpts) (*ContractExtenderNewVoteIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "NewVote") + if err != nil { + return nil, err + } + return &ContractExtenderNewVoteIterator{contract: _ContractExtender.contract, event: "NewVote", logs: logs, sub: sub}, nil +} + +var NewVoteTopicHash = "0x225708d30006b0cc86d855ab91047edb5fe9c2e416412f36c18c6e90fe4e461f" + +// WatchNewVote is a free log subscription operation binding the contract event 0x225708d30006b0cc86d855ab91047edb5fe9c2e416412f36c18c6e90fe4e461f. +// +// Solidity: event NewVote(bool vote, address voter) +func (_ContractExtender *ContractExtenderFilterer) WatchNewVote(opts *bind.WatchOpts, sink chan<- *ContractExtenderNewVote) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "NewVote") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderNewVote) + if err := _ContractExtender.contract.UnpackLog(event, "NewVote", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNewVote is a log parse operation binding the contract event 0x225708d30006b0cc86d855ab91047edb5fe9c2e416412f36c18c6e90fe4e461f. +// +// Solidity: event NewVote(bool vote, address voter) +func (_ContractExtender *ContractExtenderFilterer) ParseNewVote(log types.Log) (*ContractExtenderNewVote, error) { + event := new(ContractExtenderNewVote) + if err := _ContractExtender.contract.UnpackLog(event, "NewVote", log); err != nil { + return nil, err + } + return event, nil +} + +// ContractExtenderStateSharedIterator is returned from FilterStateShared and is used to iterate over the raw logs and unpacked data for StateShared events raised by the ContractExtender contract. +type ContractExtenderStateSharedIterator struct { + Event *ContractExtenderStateShared // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderStateSharedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderStateShared) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderStateShared) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderStateSharedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderStateSharedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderStateShared represents a StateShared event raised by the ContractExtender contract. +type ContractExtenderStateShared struct { + ToExtend common.Address + Tesserahash string + Uuid string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStateShared is a free log retrieval operation binding the contract event 0x67a92539f3cbd7c5a9b36c23c0e2beceb27d2e1b3cd8eda02c623689267ae71e. +// +// Solidity: event StateShared(address toExtend, string tesserahash, string uuid) +func (_ContractExtender *ContractExtenderFilterer) FilterStateShared(opts *bind.FilterOpts) (*ContractExtenderStateSharedIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "StateShared") + if err != nil { + return nil, err + } + return &ContractExtenderStateSharedIterator{contract: _ContractExtender.contract, event: "StateShared", logs: logs, sub: sub}, nil +} + +var StateSharedTopicHash = "0x67a92539f3cbd7c5a9b36c23c0e2beceb27d2e1b3cd8eda02c623689267ae71e" + +// WatchStateShared is a free log subscription operation binding the contract event 0x67a92539f3cbd7c5a9b36c23c0e2beceb27d2e1b3cd8eda02c623689267ae71e. +// +// Solidity: event StateShared(address toExtend, string tesserahash, string uuid) +func (_ContractExtender *ContractExtenderFilterer) WatchStateShared(opts *bind.WatchOpts, sink chan<- *ContractExtenderStateShared) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "StateShared") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderStateShared) + if err := _ContractExtender.contract.UnpackLog(event, "StateShared", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseStateShared is a log parse operation binding the contract event 0x67a92539f3cbd7c5a9b36c23c0e2beceb27d2e1b3cd8eda02c623689267ae71e. +// +// Solidity: event StateShared(address toExtend, string tesserahash, string uuid) +func (_ContractExtender *ContractExtenderFilterer) ParseStateShared(log types.Log) (*ContractExtenderStateShared, error) { + event := new(ContractExtenderStateShared) + if err := _ContractExtender.contract.UnpackLog(event, "StateShared", log); err != nil { + return nil, err + } + return event, nil +} + +// ContractExtenderUpdateMembersIterator is returned from FilterUpdateMembers and is used to iterate over the raw logs and unpacked data for UpdateMembers events raised by the ContractExtender contract. +type ContractExtenderUpdateMembersIterator struct { + Event *ContractExtenderUpdateMembers // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ContractExtenderUpdateMembersIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ContractExtenderUpdateMembers) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ContractExtenderUpdateMembers) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ContractExtenderUpdateMembersIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ContractExtenderUpdateMembersIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ContractExtenderUpdateMembers represents a UpdateMembers event raised by the ContractExtender contract. +type ContractExtenderUpdateMembers struct { + ToExtend common.Address + Uuid string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdateMembers is a free log retrieval operation binding the contract event 0x8adc4573f947f9930560525736f61b116be55049125cb63a36887a40f92f3b44. +// +// Solidity: event UpdateMembers(address toExtend, string uuid) +func (_ContractExtender *ContractExtenderFilterer) FilterUpdateMembers(opts *bind.FilterOpts) (*ContractExtenderUpdateMembersIterator, error) { + + logs, sub, err := _ContractExtender.contract.FilterLogs(opts, "UpdateMembers") + if err != nil { + return nil, err + } + return &ContractExtenderUpdateMembersIterator{contract: _ContractExtender.contract, event: "UpdateMembers", logs: logs, sub: sub}, nil +} + +var UpdateMembersTopicHash = "0x8adc4573f947f9930560525736f61b116be55049125cb63a36887a40f92f3b44" + +// WatchUpdateMembers is a free log subscription operation binding the contract event 0x8adc4573f947f9930560525736f61b116be55049125cb63a36887a40f92f3b44. +// +// Solidity: event UpdateMembers(address toExtend, string uuid) +func (_ContractExtender *ContractExtenderFilterer) WatchUpdateMembers(opts *bind.WatchOpts, sink chan<- *ContractExtenderUpdateMembers) (event.Subscription, error) { + + logs, sub, err := _ContractExtender.contract.WatchLogs(opts, "UpdateMembers") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ContractExtenderUpdateMembers) + if err := _ContractExtender.contract.UnpackLog(event, "UpdateMembers", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdateMembers is a log parse operation binding the contract event 0x8adc4573f947f9930560525736f61b116be55049125cb63a36887a40f92f3b44. +// +// Solidity: event UpdateMembers(address toExtend, string uuid) +func (_ContractExtender *ContractExtenderFilterer) ParseUpdateMembers(log types.Log) (*ContractExtenderUpdateMembers, error) { + event := new(ContractExtenderUpdateMembers) + if err := _ContractExtender.contract.UnpackLog(event, "UpdateMembers", log); err != nil { + return nil, err + } + return event, nil +} diff --git a/extension/extensionContracts/contract_extender.sol b/extension/extensionContracts/contract_extender.sol new file mode 100644 index 0000000000..47f8ecbe9d --- /dev/null +++ b/extension/extensionContracts/contract_extender.sol @@ -0,0 +1,168 @@ +pragma solidity ^0.5.3; + +contract ContractExtender { + + //target details - what, who and when to extend + address public creator; + string public targetRecipientPTMKey; + address public contractToExtend; + + //list of wallet addresses that can cast votes + address[] public walletAddressesToVote; + uint256 public totalNumberOfVoters; + mapping(address => bool) walletAddressesToVoteMap; + uint256 numberOfVotesSoFar; + mapping(address => bool) hasVotedMapping; + mapping(address => bool) public votes; + + //contains the total outcome of voting + //true if ALL nodes vote true, false if ANY node votes false + bool public voteOutcome; + + //the hash of the shared payload + string public sharedDataHash; + string[] uuids; + + //if creator cancelled this extension + bool public isFinished; + + // General housekeeping + event NewContractExtensionContractCreated(address toExtend, string recipientPTMKey, address recipientAddress); //to tell nodes a new extension is happening + event AllNodesHaveAccepted(bool outcome); //when all nodes have voted + event CanPerformStateShare(); //when all nodes have voted & the recipient has accepted + event ExtensionFinished(); //if the extension is cancelled or completed + event NewVote(bool vote, address voter); // when someone voted (either true or false) + event StateShared(address toExtend, string tesserahash, string uuid); //when the state is shared and can be replayed into the database + event UpdateMembers(address toExtend, string uuid); //to update the original transaction hash for the new party member + + constructor(address contractAddress, address recipientAddress, string memory recipientPTMKey) public { + creator = msg.sender; + + targetRecipientPTMKey = recipientPTMKey; + + contractToExtend = contractAddress; + walletAddressesToVote.push(msg.sender); + walletAddressesToVote.push(recipientAddress); + + sharedDataHash = ""; + + voteOutcome = true; + numberOfVotesSoFar = 0; + + for (uint256 i = 0; i < walletAddressesToVote.length; i++) { + walletAddressesToVoteMap[walletAddressesToVote[i]] = true; + } + totalNumberOfVoters = walletAddressesToVote.length; + emit NewContractExtensionContractCreated(contractAddress, recipientPTMKey, recipientAddress); + } + + ///////////////////////////////////////////////////////////////////////////////////// + //modifiers + ///////////////////////////////////////////////////////////////////////////////////// + modifier notFinished() { + require(!isFinished, "extension has been marked as finished"); + _; + } + + modifier onlyCreator() { + require(msg.sender == creator, "only leader may perform this action"); + _; + } + + ///////////////////////////////////////////////////////////////////////////////////// + //main + ///////////////////////////////////////////////////////////////////////////////////// + function haveAllNodesVoted() public view returns (bool) { + return walletAddressesToVote.length == numberOfVotesSoFar; + } + + // returns true if the sender address has already voted on the + // extension contracts + function checkIfVoted() public view returns (bool) { + return hasVotedMapping[msg.sender]; + } + + // returns true if the contract extension is finished + function checkIfExtensionFinished() public view returns (bool) { + return isFinished; + } + + // single node vote to either extend or not + // can't have voted before + function doVote(bool vote, string memory nextuuid) public notFinished() { + cast(vote); + if (vote) { + setUuid(nextuuid); + } + // check if voting has finished + checkVotes(); + emit NewVote(vote, msg.sender); + } + + // this event is emitted to tell each node to use this tx as the original tx + // only if they voted for it + function updatePartyMembers() public { + for(uint256 i = 0; i < uuids.length; i++) { + emit UpdateMembers(contractToExtend, uuids[i]); + } + } + + //state has been shared off chain via a private transaction, the hash the PTM generated is set here + function setSharedStateHash(string memory hash) public onlyCreator() notFinished() { + bytes memory hashAsBytes = bytes(sharedDataHash); + bytes memory incomingAsBytes = bytes(hash); + + require(incomingAsBytes.length != 0, "new hash cannot be empty"); + require(hashAsBytes.length == 0, "state hash already set"); + sharedDataHash = hash; + + for(uint256 i = 0; i < uuids.length; i++) { + emit StateShared(contractToExtend, sharedDataHash, uuids[i]); + } + + finish(); + } + + //close the contract to further modifications + function finish() public notFinished() onlyCreator() { + setFinished(); + } + + //this sets a unique code that only the sending node has access to, that can be referred to later + function setUuid(string memory nextuuid) public notFinished() { + uuids.push(nextuuid); + } + + // Internal methods + function setFinished() internal { + isFinished = true; + emit ExtensionFinished(); + } + + // checks if all the conditions for voting have been met + // either all voted true and target accepted, or someone voted false + function checkVotes() internal { + if (!voteOutcome) { + emit AllNodesHaveAccepted(false); + setFinished(); + return; + } + + if (haveAllNodesVoted()) { + emit AllNodesHaveAccepted(true); + emit CanPerformStateShare(); + } + } + + function cast(bool vote) internal { + require(!isFinished, "extension process completed. cannot vote"); + require(walletAddressesToVoteMap[msg.sender], "not allowed to vote"); + require(!hasVotedMapping[msg.sender], "already voted"); + require(voteOutcome, "voting already declined"); + + hasVotedMapping[msg.sender] = true; + votes[msg.sender] = vote; + numberOfVotesSoFar++; + voteOutcome = voteOutcome && vote; + } +} \ No newline at end of file diff --git a/extension/extensionContracts/extensionHandler.go b/extension/extensionContracts/extensionHandler.go new file mode 100644 index 0000000000..39f43aaf8b --- /dev/null +++ b/extension/extensionContracts/extensionHandler.go @@ -0,0 +1,18 @@ +package extensionContracts + +import "github.com/ethereum/go-ethereum/common" + +func UnpackStateSharedLog(logData []byte) (common.Address, string, string, error) { + decodedLog := new(ContractExtenderStateShared) + if err := ContractExtenderParsedABI.Unpack(decodedLog, "StateShared", logData); err != nil { + return common.Address{}, "", "", err + } + return decodedLog.ToExtend, decodedLog.Tesserahash, decodedLog.Uuid, nil +} + +func UnpackNewExtensionCreatedLog(data []byte) (*ContractExtenderNewContractExtensionContractCreated, error) { + newExtensionEvent := new(ContractExtenderNewContractExtensionContractCreated) + err := ContractExtenderParsedABI.Unpack(newExtensionEvent, "NewContractExtensionContractCreated", data) + + return newExtensionEvent, err +} diff --git a/extension/extensionContracts/types.go b/extension/extensionContracts/types.go new file mode 100644 index 0000000000..60f75e7242 --- /dev/null +++ b/extension/extensionContracts/types.go @@ -0,0 +1,9 @@ +package extensionContracts + +import ( + "github.com/ethereum/go-ethereum/core/state" +) + +type AccountWithMetadata struct { + State state.DumpAccount `json:"state"` +} diff --git a/extension/extension_utilities.go b/extension/extension_utilities.go new file mode 100644 index 0000000000..ff0a89a37c --- /dev/null +++ b/extension/extension_utilities.go @@ -0,0 +1,38 @@ +package extension + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" +) + +// generateUuid sends some data to the linked Private Transaction Manager which +// uses a randomly generated key to encrypt the data and then hash it this +// means we get a effectively random hash, whilst also having a reference +// transaction inside the PTM +func generateUuid(contractAddress common.Address, privateFrom string, privateFor []string, ptm private.PrivateTransactionManager) (string, error) { + + // to ensure recoverability , the UUID generation logic is as below: + // 1. Call Tessera to encrypt the management contract address + // 2. Send the encrypted payload to all participants on the contract extension + // 3. Use the received hash as the UUID + payloadHash, err := ptm.EncryptPayload(contractAddress.Bytes(), privateFrom, []string{}, &engine.ExtraMetadata{}) + if err != nil { + return "", err + } + + _, _, hash, err := ptm.Send(payloadHash, privateFrom, privateFor, &engine.ExtraMetadata{}) + if err != nil { + return "", err + } + return hash.String(), nil +} + +func checkAddressInList(addressToFind common.Address, addressList []common.Address) bool { + for _, addr := range addressList { + if addressToFind == addr { + return true + } + } + return false +} diff --git a/extension/privacyExtension/state_set_utilities.go b/extension/privacyExtension/state_set_utilities.go new file mode 100644 index 0000000000..e2aa7468f4 --- /dev/null +++ b/extension/privacyExtension/state_set_utilities.go @@ -0,0 +1,98 @@ +package privacyExtension + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + extension "github.com/ethereum/go-ethereum/extension/extensionContracts" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private" + "github.com/ethereum/go-ethereum/private/engine" +) + +func setState(privateState *state.StateDB, accounts map[string]extension.AccountWithMetadata, privacyMetaData *state.PrivacyMetadata, managedParties []string) bool { + log.Debug("Extension: set private state explicitly from state dump") + for key, value := range accounts { + stateDump := value.State + + contractAddress := common.HexToAddress(key) + + privateState.CreateAccount(contractAddress) + newBalance, errBalanceSet := new(big.Int).SetString(stateDump.Balance, 10) + if !errBalanceSet { + log.Error("could not set address balance", "address", key, "balance", stateDump.Balance) + return false + } + privateState.SetBalance(contractAddress, newBalance) + privateState.SetNonce(contractAddress, stateDump.Nonce) + privateState.SetCode(contractAddress, common.Hex2Bytes(stateDump.Code)) + for keyStore, valueStore := range stateDump.Storage { + privateState.SetState(contractAddress, keyStore, common.HexToHash(valueStore)) + } + if privacyMetaData.PrivacyFlag != engine.PrivacyFlagStandardPrivate { + privateState.SetPrivacyMetadata(contractAddress, privacyMetaData) + } + if managedParties != nil { + privateState.SetManagedParties(contractAddress, managedParties) + } + } + return true +} + +// updates the privacy metadata +func setPrivacyMetadata(privateState *state.StateDB, address common.Address, hash string) { + privacyMetaData, err := privateState.GetPrivacyMetadata(address) + if err != nil || privacyMetaData.PrivacyFlag.IsStandardPrivate() { + return + } + + ptmHash, err := common.Base64ToEncryptedPayloadHash(hash) + if err != nil { + log.Error("setting privacy metadata failed", "err", err) + return + } + pm := state.NewStatePrivacyMetadata(ptmHash, privacyMetaData.PrivacyFlag) + privateState.SetPrivacyMetadata(address, pm) +} + +func setManagedParties(ptm private.PrivateTransactionManager, privateState *state.StateDB, address common.Address, hash string) { + existingManagedParties, err := privateState.GetManagedParties(address) + if err != nil { + return + } + + ptmHash, err := common.Base64ToEncryptedPayloadHash(hash) + if err != nil { + log.Error("setting privacy metadata failed", "err", err) + return + } + + _, managedParties, _, _, _ := ptm.Receive(ptmHash) + newManagedParties := common.AppendSkipDuplicates(existingManagedParties, managedParties...) + privateState.SetManagedParties(address, newManagedParties) +} + +func logContainsExtensionTopic(receivedLog *types.Log) bool { + if len(receivedLog.Topics) != 1 { + return false + } + return receivedLog.Topics[0].String() == extension.StateSharedTopicHash +} + +// validateAccountsExist checks that all the accounts in the expected list are +// present in the state map, and that no other accounts exist in the state map +// that are unexpected +func validateAccountsExist(expectedAccounts []common.Address, actualAccounts map[string]extension.AccountWithMetadata) bool { + if len(expectedAccounts) != len(actualAccounts) { + return false + } + for _, account := range expectedAccounts { + _, exists := actualAccounts[account.String()] + if !exists { + return false + } + } + return true +} diff --git a/extension/privacyExtension/state_set_utilities_test.go b/extension/privacyExtension/state_set_utilities_test.go new file mode 100644 index 0000000000..e7a3886f2d --- /dev/null +++ b/extension/privacyExtension/state_set_utilities_test.go @@ -0,0 +1,368 @@ +package privacyExtension + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + extension "github.com/ethereum/go-ethereum/extension/extensionContracts" + "github.com/ethereum/go-ethereum/private/engine" + "github.com/ethereum/go-ethereum/private/engine/notinuse" + "github.com/stretchr/testify/assert" +) + +var input = `{"0x2222222222222222222222222222222222222222": + {"state": + {"balance":"22", + "nonce":5, + "root":"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash":"87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", + "code":"03030303030303", + "storage":{ + "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421": "2a" + } + }}}` + +func TestLogContainsExtensionTopicWithWrongLengthReturnsFalse(t *testing.T) { + testLog := &types.Log{ + Topics: []common.Hash{{}, {}}, + } + + contained := logContainsExtensionTopic(testLog) + + if contained { + t.Errorf("expected value '%t', but got '%t'", false, contained) + } +} + +func TestLogContainsExtensionTopicWithWrongHashReturnsFalse(t *testing.T) { + testLog := &types.Log{ + Topics: []common.Hash{common.HexToHash("0xf20540914db019dd7c8d05ed165316a58d1583642772ac46f3d0c29b8644bd36")}, + } + + contained := logContainsExtensionTopic(testLog) + + if contained { + t.Errorf("expected value '%t', but got '%t'", false, contained) + } +} + +func TestLogContainsExtensionTopicWithCorrectHashReturnsTrue(t *testing.T) { + testLog := &types.Log{ + Topics: []common.Hash{common.HexToHash("0x67a92539f3cbd7c5a9b36c23c0e2beceb27d2e1b3cd8eda02c623689267ae71e")}, + } + + contained := logContainsExtensionTopic(testLog) + + if !contained { + t.Errorf("expected value '%t', but got '%t'", true, contained) + } +} + +func createStateDb(t *testing.T, metadata *state.PrivacyMetadata) *state.StateDB { + statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + + var accounts map[string]extension.AccountWithMetadata + if err := json.Unmarshal([]byte(input), &accounts); err != nil { + t.Errorf("error when unmarshalling static data: %s", err.Error()) + } + + success := setState(statedb, accounts, metadata, nil) + if !success { + t.Errorf("unexpected error when setting state") + } + + return statedb +} + +func TestStateSetWithListedAccounts(t *testing.T) { + statedb := createStateDb(t, &state.PrivacyMetadata{}) + + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + balance := statedb.GetBalance(address) + code := statedb.GetCode(address) + nonce := statedb.GetNonce(address) + storage, _ := statedb.GetStorageRoot(address) + + // we don't save PrivacyMetadata if it's standardprivate + privacyMetaData, err := statedb.GetPrivacyMetadata(address) + assert.Error(t, err, common.ErrNoAccountExtraData) + assert.Nil(t, privacyMetaData) + + if balance.Uint64() != 22 { + t.Errorf("expect Balance value of '%d', but got '%d'", 22, balance.Uint64()) + return + } + + expectedCode := []byte{3, 3, 3, 3, 3, 3, 3} + if !bytes.Equal(code, expectedCode) { + t.Errorf("expect Code value of '%d', but got '%d'", expectedCode, code) + return + } + + if nonce != 5 { + t.Errorf("expect Nonce value of '%d', but got '%d'", 5, nonce) + return + } + + expectedStorageHash := common.FromHex("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + if !bytes.Equal(storage.Bytes(), expectedStorageHash) { + t.Errorf("expect Storage value of '%d', but got '%s'", expectedStorageHash, storage) + return + } + + stateVal := statedb.GetState(address, common.BytesToHash(expectedStorageHash)) + assert.Equal(t, common.HexToHash("0x2a"), stateVal) +} + +func TestStateSetWithListedAccountsFailsOnInvalidBalance(t *testing.T) { + input := `{"0x2222222222222222222222222222222222222222":{"state":{"balance":"invalid","nonce":5,"root":"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3","code":"03030303030303","storage":{}}}}` + statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + + var accounts map[string]extension.AccountWithMetadata + if err := json.Unmarshal([]byte(input), &accounts); err != nil { + t.Errorf("error when unmarshalling static data: %s", err.Error()) + } + + success := setState(statedb, accounts, &state.PrivacyMetadata{}, nil) + if success { + t.Errorf("error expected when setting state") + } +} + +func Test_setPrivacyMetadata(t *testing.T) { + privacyMetaData := &state.PrivacyMetadata{} + + statedb := createStateDb(t, privacyMetaData) + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + // call setPrivacyMetaData + arbitraryBytes1 := []byte{10} + hash := common.BytesToEncryptedPayloadHash(arbitraryBytes1) + setPrivacyMetadata(statedb, address, base64.StdEncoding.EncodeToString(arbitraryBytes1)) + + // we don't save PrivacyMetadata if it's standardprivate + _, err := statedb.GetPrivacyMetadata(address) + assert.Error(t, err, common.ErrNoAccountExtraData) + + privacyMetaData = &state.PrivacyMetadata{CreationTxHash: hash, PrivacyFlag: engine.PrivacyFlagPartyProtection} + statedb.SetPrivacyMetadata(address, privacyMetaData) + + privacyMetaData, err = statedb.GetPrivacyMetadata(address) + if err != nil { + t.Errorf("expected error to be nil, got err %s", err) + } + assert.Equal(t, engine.PrivacyFlagPartyProtection, privacyMetaData.PrivacyFlag) + assert.Equal(t, hash, privacyMetaData.CreationTxHash) + + arbitraryBytes2 := []byte{20} + newHash := common.BytesToEncryptedPayloadHash(arbitraryBytes2) + setPrivacyMetadata(statedb, address, base64.StdEncoding.EncodeToString(arbitraryBytes2)) + + privacyMetaData, err = statedb.GetPrivacyMetadata(address) + if err != nil { + t.Errorf("expected error to be nil, got err %s", err) + } + assert.Equal(t, engine.PrivacyFlagPartyProtection, privacyMetaData.PrivacyFlag) + assert.Equal(t, newHash, privacyMetaData.CreationTxHash) +} + +func Test_setState_WithManagedParties(t *testing.T) { + statedb := createStateDb(t, &state.PrivacyMetadata{}) + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + presetManagedParties := []string{"mp1", "mp2"} + statedb.SetManagedParties(address, presetManagedParties) + + mp, err := statedb.GetManagedParties(address) + assert.Nil(t, err) + assert.EqualValues(t, presetManagedParties, mp) + + extraManagedParties := []string{"mp1", "mp2", "mp3"} + var accounts map[string]extension.AccountWithMetadata + json.Unmarshal([]byte(input), &accounts) + success := setState(statedb, accounts, &state.PrivacyMetadata{}, extraManagedParties) + assert.True(t, success) + + mp, err = statedb.GetManagedParties(address) + assert.Nil(t, err) + assert.EqualValues(t, []string{"mp1", "mp2", "mp3"}, mp) +} + +func Test_validateAccountsExist_AllPresent(t *testing.T) { + expected := []common.Address{ + common.HexToAddress("0x2222222222222222222222222222222222222222"), + common.HexToAddress("0x3333333333333333333333333333333333333333"), + } + actual := map[string]extension.AccountWithMetadata{ + "0x2222222222222222222222222222222222222222": {}, + "0x3333333333333333333333333333333333333333": {}, + } + + equal := validateAccountsExist(expected, actual) + + assert.True(t, equal) +} + +func Test_validateAccountsExist_NotAllPresent(t *testing.T) { + expected := []common.Address{ + common.HexToAddress("0x2222222222222222222222222222222222222222"), + common.HexToAddress("0x3333333333333333333333333333333333333333"), + } + actual := map[string]extension.AccountWithMetadata{ + "0x2222222222222222222222222222222222222222": {}, + "0x4444444444444444444444444444444444444444": {}, + } + + equal := validateAccountsExist(expected, actual) + + assert.False(t, equal) +} + +func Test_setManagedParties(t *testing.T) { + statedb := createStateDb(t, &state.PrivacyMetadata{}) + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + presetManagedParties := []string{"mp1", "mp2"} + statedb.SetManagedParties(address, presetManagedParties) + + mp, err := statedb.GetManagedParties(address) + assert.Nil(t, err) + assert.EqualValues(t, presetManagedParties, mp) + + extraManagedParties := []string{"mp1", "mp3"} + mpm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{"Receive": {"", extraManagedParties, nil, nil, nil}}, + } + + ptmHash := common.EncryptedPayloadHash{86}.ToBase64() + setManagedParties(mpm, statedb, address, ptmHash) + + mp, err = statedb.GetManagedParties(address) + assert.Nil(t, err) + assert.Len(t, mp, 3) + assert.Contains(t, mp, "mp1") + assert.Contains(t, mp, "mp2") + assert.Contains(t, mp, "mp3") +} + +func Test_setManagedPartiesInvalidHash(t *testing.T) { + statedb := createStateDb(t, &state.PrivacyMetadata{}) + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + presetManagedParties := []string{"mp1", "mp2"} + statedb.SetManagedParties(address, presetManagedParties) + + mp, err := statedb.GetManagedParties(address) + assert.Nil(t, err) + assert.EqualValues(t, presetManagedParties, mp) + + extraManagedParties := []string{"mp1", "mp3"} + mpm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{"Receive": {"", extraManagedParties, nil, nil, nil}}, + } + + ptmHash := common.EncryptedPayloadHash{86}.Hex() //should be base64, so hex will fail + setManagedParties(mpm, statedb, address, ptmHash) + + mp, err = statedb.GetManagedParties(address) + assert.Nil(t, err) + assert.EqualValues(t, presetManagedParties, mp) +} + +type mockPSMR struct { + core.DefaultPrivateStateManager + returns map[string][]interface{} +} + +type mockPrivateTransactionManager struct { + notinuse.PrivateTransactionManager + returns map[string][]interface{} +} + +func (mpsmr *mockPSMR) ResolveForManagedParty(managedParty string) (*mps.PrivateStateMetadata, error) { + values := mpsmr.returns["ResolveForManagedParty"] + var ( + r1 *mps.PrivateStateMetadata + r2 error + ) + if values[0] != nil { + r1 = values[0].(*mps.PrivateStateMetadata) + } + if values[1] != nil { + r2 = values[1].(error) + } + return r1, r2 +} + +func (mpm *mockPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) { + values := mpm.returns["Receive"] + var ( + r1 string + r2 []string + r3 []byte + r4 *engine.ExtraMetadata + r5 error + ) + if values[0] != nil { + r1 = values[0].(string) + } + if values[1] != nil { + r2 = values[1].([]string) + } + if values[2] != nil { + r3 = values[2].([]byte) + } + if values[3] != nil { + r4 = values[3].(*engine.ExtraMetadata) + } + if values[4] != nil { + r5 = values[4].(error) + } + return r1, r2, r3, r4, r5 +} + +func (mpm *mockPrivateTransactionManager) IsSender(txHash common.EncryptedPayloadHash) (bool, error) { + values := mpm.returns["IsSender"] + var ( + r1 bool + r2 error + ) + if values[0] != nil { + r1 = values[0].(bool) + } + if values[1] != nil { + r2 = values[1].(error) + } + return r1, r2 +} + +func (mpm *mockPrivateTransactionManager) DecryptPayload(payload common.DecryptRequest) ([]byte, *engine.ExtraMetadata, error) { + values := mpm.returns["DecryptPayload"] + var ( + r3 []byte + r4 *engine.ExtraMetadata + r5 error + ) + if values[0] != nil { + r3 = values[0].([]byte) + } + if values[1] != nil { + r4 = values[1].(*engine.ExtraMetadata) + } + if values[2] != nil { + r5 = values[2].(error) + } + return r3, r4, r5 +} + +func (mpm *mockPrivateTransactionManager) GetCache() state.Database { + return nil +} diff --git a/extension/privacyExtension/state_setter.go b/extension/privacyExtension/state_setter.go new file mode 100644 index 0000000000..ede5ca03a5 --- /dev/null +++ b/extension/privacyExtension/state_setter.go @@ -0,0 +1,178 @@ +package privacyExtension + +import ( + "bytes" + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + extension "github.com/ethereum/go-ethereum/extension/extensionContracts" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/private" +) + +var DefaultExtensionHandler *ExtensionHandler + +type ExtensionHandler struct { + ptm private.PrivateTransactionManager + psmr mps.PrivateStateMetadataResolver + isMultitenant bool +} + +func Init() { + DefaultExtensionHandler = NewExtensionHandler(private.P) +} + +func NewExtensionHandler(transactionManager private.PrivateTransactionManager) *ExtensionHandler { + return &ExtensionHandler{ptm: transactionManager} +} + +func (handler *ExtensionHandler) SupportMultitenancy(b bool) { + handler.isMultitenant = b +} + +func (handler *ExtensionHandler) SetPSMR(psmr mps.PrivateStateMetadataResolver) { + handler.psmr = psmr +} + +func (handler *ExtensionHandler) CheckExtensionAndSetPrivateState(txLogs []*types.Log, privateState *state.StateDB, psi types.PrivateStateIdentifier) { + extraMetaDataUpdated := false + for _, txLog := range txLogs { + if !logContainsExtensionTopic(txLog) { + continue + } + //this is a direct state share + address, hash, uuid, err := extension.UnpackStateSharedLog(txLog.Data) + if err != nil { + continue + } + + // check if state exists for the extension address. If yes then skip + // processing + if privateState.GetCode(address) != nil { + if extraMetaDataUpdated { + continue + } + // check the privacy flag of the contract. if its other than + // 0 then need to update the privacy metadata for the contract + //TODO: validate the old and new parties to ensure that all old parties are there + setPrivacyMetadata(privateState, address, hash) + if handler.isMultitenant { + setManagedParties(handler.ptm, privateState, address, hash) + } + extraMetaDataUpdated = true + } else { + managedParties, accounts, privacyMetaData, found := handler.FetchStateData(txLog.Address, hash, uuid, psi) + if !found { + continue + } + if !handler.isMultitenant { + managedParties = nil + } + if !validateAccountsExist([]common.Address{address}, accounts) { + log.Error("Account mismatch", "expected", address, "found", accounts) + continue + } + snapshotId := privateState.Snapshot() + + if success := setState(privateState, accounts, privacyMetaData, managedParties); !success { + privateState.RevertToSnapshot(snapshotId) + } + } + } +} + +func (handler *ExtensionHandler) FetchStateData(address common.Address, hash string, uuid string, psi types.PrivateStateIdentifier) ([]string, map[string]extension.AccountWithMetadata, *state.PrivacyMetadata, bool) { + if uuidIsSentByUs := handler.UuidIsOwn(address, uuid, psi); !uuidIsSentByUs { + return nil, nil, nil, false + } + + managedParties, stateData, privacyMetaData, ok := handler.FetchDataFromPTM(hash) + if !ok { + //there is nothing to do here, the state wasn't shared with us + log.Error("Extension: No state shared with us") + return nil, nil, nil, false + } + + var accounts map[string]extension.AccountWithMetadata + if err := json.Unmarshal(stateData, &accounts); err != nil { + log.Error("Extension: Could not unmarshal data") + return nil, nil, nil, false + } + + return managedParties, accounts, privacyMetaData, true +} + +// Checks + +func (handler *ExtensionHandler) FetchDataFromPTM(hash string) ([]string, []byte, *state.PrivacyMetadata, bool) { + ptmHash, _ := common.Base64ToEncryptedPayloadHash(hash) + _, managedParties, stateData, extraMetaData, err := handler.ptm.Receive(ptmHash) + + if stateData == nil { + log.Error("No state data found in PTM", "ptm hash", hash) + return nil, nil, nil, false + } + if err != nil { + log.Error("Error receiving state data from PTM", "ptm hash", hash, "err", err.Error()) + return nil, nil, nil, false + } + + privacyMetaData := state.NewStatePrivacyMetadata(ptmHash, extraMetaData.PrivacyFlag) + return managedParties, stateData, privacyMetaData, true +} + +func (handler *ExtensionHandler) UuidIsOwn(address common.Address, uuid string, psi types.PrivateStateIdentifier) bool { + if uuid == "" { + //we never called accept + log.Warn("Extension: State shared by accept never called") + return false + } + encryptedTxHash := common.BytesToEncryptedPayloadHash(common.FromHex(uuid)) + isSender, err := handler.ptm.IsSender(encryptedTxHash) + if err != nil { + log.Debug("Extension: could not determine if we are sender", "err", err.Error()) + return false + } + + if !isSender { + return false + } + + senderPublicKey, _, encryptedPayload, _, err := handler.ptm.Receive(encryptedTxHash) + if err != nil { + log.Debug("Extension: payload not found", "err", err) + return false + } + + //check the given PSI is same as PSI of sender key + senderPsm, err := handler.psmr.ResolveForManagedParty(senderPublicKey) + if err != nil { + log.Debug("Extension: unable to determine sender public key PSI", "err", err) + return false + } + + if senderPsm.ID != psi { + // sender was another tenant on this node + //not an error case, so no need to log an error + return false + } + + var payload common.DecryptRequest + if err := json.Unmarshal(encryptedPayload, &payload); err != nil { + log.Debug("Extension: payload unmarshal failed", "err", err) + } + + contractDetails, _, err := handler.ptm.DecryptPayload(payload) + if err != nil { + log.Debug("Extension: payload decrypt failed", "err", err) + } + + if !bytes.Equal(contractDetails, address.Bytes()) { + log.Error("Extension: wrong address in retrieved UUID") + return false + } + return true +} diff --git a/extension/privacyExtension/state_setter_test.go b/extension/privacyExtension/state_setter_test.go new file mode 100644 index 0000000000..20aaf923d4 --- /dev/null +++ b/extension/privacyExtension/state_setter_test.go @@ -0,0 +1,218 @@ +package privacyExtension + +import ( + "errors" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +func TestExtensionHandler_CheckExtensionAndSetPrivateState_NoLogs(t *testing.T) { + ptm := &mockPrivateTransactionManager{} + handler := NewExtensionHandler(ptm) + statedb := createStateDb(t, &state.PrivacyMetadata{}) + + dbBefore := statedb.Copy() + rootBeforeExtension, _ := statedb.Commit(true) + + handler.CheckExtensionAndSetPrivateState(nil, statedb, types.DefaultPrivateStateIdentifier) + + rootAfterExtension, _ := statedb.Commit(true) + assert.Equal(t, rootBeforeExtension, rootAfterExtension) + + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + beforeManagedParties, _ := dbBefore.GetManagedParties(address) + afterManagedParties, _ := statedb.GetManagedParties(address) + assert.Equal(t, beforeManagedParties, afterManagedParties) + + beforePrivacyMetadata, _ := dbBefore.GetPrivacyMetadata(address) + afterPrivacyMetadata, _ := statedb.GetPrivacyMetadata(address) + assert.Equal(t, beforePrivacyMetadata, afterPrivacyMetadata) +} + +func TestExtensionHandler_CheckExtensionAndSetPrivateState_LogsAreNotExtensionLogs(t *testing.T) { + ptm := &mockPrivateTransactionManager{} + handler := NewExtensionHandler(ptm) + statedb := createStateDb(t, &state.PrivacyMetadata{}) + + dbBefore := statedb.Copy() + rootBeforeExtension, _ := statedb.Commit(true) + + notExtensionLogs := []*types.Log{ + { + Address: common.HexToAddress("0x9ccd1e1089c79fe1cca81601fc9ccfa24f77eb58"), + Topics: []common.Hash{common.HexToHash("0x24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b")}, + Data: []byte{}, + BlockNumber: 6, + TxHash: common.HexToHash("0x5faf9ffe6fedc1139bdc1af20b26a2e113d16d736be872571458f8d4bcc048c7"), + TxIndex: 0, + BlockHash: common.HexToHash("0x7e7fb6985ff7e1c7293b8e3202a2b101458acd0b93b5fbed18aab40e8cbeb587"), + Index: 0, + Removed: false, + PSI: types.DefaultPrivateStateIdentifier, + }, + } + handler.CheckExtensionAndSetPrivateState(notExtensionLogs, statedb, types.DefaultPrivateStateIdentifier) + + rootAfterExtension, _ := statedb.Commit(true) + assert.Equal(t, rootBeforeExtension, rootAfterExtension) + + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + beforeManagedParties, _ := dbBefore.GetManagedParties(address) + afterManagedParties, _ := statedb.GetManagedParties(address) + assert.Equal(t, beforeManagedParties, afterManagedParties) + + beforePrivacyMetadata, _ := dbBefore.GetPrivacyMetadata(address) + afterPrivacyMetadata, _ := statedb.GetPrivacyMetadata(address) + assert.Equal(t, beforePrivacyMetadata, afterPrivacyMetadata) +} + +func TestExtensionHandler_UuidIsOwn_EmptyUUID(t *testing.T) { + ptm := &mockPrivateTransactionManager{} + handler := NewExtensionHandler(ptm) + + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + isOwn := handler.UuidIsOwn(address, "", types.DefaultPrivateStateIdentifier) + + assert.False(t, isOwn) +} + +func TestExtensionHandler_UuidIsOwn_IsSenderIsFalse(t *testing.T) { + ptm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{"IsSender": {false, nil}}, + } + handler := NewExtensionHandler(ptm) + + const uuid = "0xabcd" + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + isOwn := handler.UuidIsOwn(address, uuid, types.DefaultPrivateStateIdentifier) + + assert.False(t, isOwn) +} + +func TestExtensionHandler_UuidIsOwn_WrongPSIFails(t *testing.T) { + ptm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{ + "IsSender": {true, nil}, + "Receive": {"psi1", nil, []byte{}, nil, nil}, + }, + } + handler := NewExtensionHandler(ptm) + psmr := &mockPSMR{ + returns: map[string][]interface{}{ + "ResolveForManagedParty": {&mps.PrivateStateMetadata{ID: "psi1", Type: mps.Resident}, nil}, + }, + } + handler.SetPSMR(psmr) + + uuid := "0xabcd" + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + isOwn := handler.UuidIsOwn(address, uuid, "other") + + assert.False(t, isOwn) +} + +func TestExtensionHandler_UuidIsOwn_DecryptPayloadFails(t *testing.T) { + ptm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{ + "IsSender": {true, nil}, + "Receive": {"psi1", nil, []byte(`{"somedata": "val"}`), nil, nil}, + "DecryptPayload": {nil, nil, errors.New("test error")}, + }, + } + handler := NewExtensionHandler(ptm) + psmr := &mockPSMR{ + returns: map[string][]interface{}{ + "ResolveForManagedParty": {&mps.PrivateStateMetadata{ID: "psi1", Type: mps.Resident}, nil}, + }, + } + handler.SetPSMR(psmr) + + uuid := "0xabcd" + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + isOwn := handler.UuidIsOwn(address, uuid, "psi1") + + assert.False(t, isOwn) +} + +func TestExtensionHandler_UuidIsOwn_AddressDoesntMatch(t *testing.T) { + ptm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{ + "IsSender": {true, nil}, + "Receive": {"psi1", nil, []byte(`{"somedata": "val"}`), nil, nil}, + "DecryptPayload": {[]byte(`unknown`), nil, nil}, + }, + } + handler := NewExtensionHandler(ptm) + psmr := &mockPSMR{ + returns: map[string][]interface{}{ + "ResolveForManagedParty": {&mps.PrivateStateMetadata{ID: "psi1", Type: mps.Resident}, nil}, + }, + } + handler.SetPSMR(psmr) + + uuid := "0xabcd" + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + isOwn := handler.UuidIsOwn(address, uuid, "psi1") + + assert.False(t, isOwn) +} + +func TestExtensionHandler_UuidIsOwn_AddressMatches(t *testing.T) { + uuid := "0xabcd" + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + ptm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{ + "IsSender": {true, nil}, + "Receive": {"psi1", nil, []byte(`{"somedata": "val"}`), nil, nil}, + "DecryptPayload": {address.Bytes(), nil, nil}, + }, + } + handler := NewExtensionHandler(ptm) + psmr := &mockPSMR{ + returns: map[string][]interface{}{ + "ResolveForManagedParty": {&mps.PrivateStateMetadata{ID: "psi1", Type: mps.Resident}, nil}, + }, + } + handler.SetPSMR(psmr) + + isOwn := handler.UuidIsOwn(address, uuid, "psi1") + + assert.True(t, isOwn) +} + +func TestExtensionHandler_UuidIsOwn_PrivatePSMRSucceeds(t *testing.T) { + uuid := "0xabcd" + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + ptm := &mockPrivateTransactionManager{ + returns: map[string][]interface{}{ + "IsSender": {true, nil}, + "Receive": {"psi1, private", nil, []byte(`{"somedata": "val"}`), nil, nil}, + "DecryptPayload": {address.Bytes(), nil, nil}, + }, + } + handler := NewExtensionHandler(ptm) + psmr := &mockPSMR{ + returns: map[string][]interface{}{ + "ResolveForManagedParty": {&mps.PrivateStateMetadata{ID: "private", Type: mps.Resident}, nil}, + }, + } + handler.SetPSMR(psmr) + + isOwn := handler.UuidIsOwn(address, uuid, types.DefaultPrivateStateIdentifier) + + assert.True(t, isOwn) +} diff --git a/extension/services_factory.go b/extension/services_factory.go new file mode 100644 index 0000000000..0285bdd678 --- /dev/null +++ b/extension/services_factory.go @@ -0,0 +1,58 @@ +package extension + +import ( + "context" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/extension/privacyExtension" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/private" +) + +type ServicesFactory interface { + AccountManager() *accounts.Manager + DataHandler() DataHandler + StateFetcher() *StateFetcher +} + +type DefaultServicesFactory struct { + backendService *PrivacyService + accountManager *accounts.Manager + dataHandler *JsonFileDataHandler + stateFetcher *StateFetcher +} + +func NewServicesFactory(stack *node.Node, ptm private.PrivateTransactionManager, ethService *eth.Ethereum) (*DefaultServicesFactory, error) { + factory := &DefaultServicesFactory{} + + factory.accountManager = ethService.AccountManager() + factory.dataHandler = NewJsonFileDataHandler(stack.InstanceDir()) + factory.stateFetcher = NewStateFetcher(ethService.BlockChain()) + + backendService, err := New(stack, ptm, factory.AccountManager(), factory.DataHandler(), factory.StateFetcher(), ethService.APIBackend) + if err != nil { + return nil, err + } + factory.backendService = backendService + + _, isMultitenant := ethService.BlockChain().SupportsMultitenancy(context.Background()) + privacyExtension.DefaultExtensionHandler.SupportMultitenancy(isMultitenant) + privacyExtension.DefaultExtensionHandler.SetPSMR(ethService.BlockChain().PrivateStateManager()) + + ethService.BlockChain().PopulateSetPrivateState(privacyExtension.DefaultExtensionHandler.CheckExtensionAndSetPrivateState) + + return factory, nil +} + +func (factory *DefaultServicesFactory) AccountManager() *accounts.Manager { + return factory.accountManager +} + +func (factory *DefaultServicesFactory) DataHandler() DataHandler { + return factory.dataHandler +} + +func (factory *DefaultServicesFactory) StateFetcher() *StateFetcher { + return factory.stateFetcher +} diff --git a/extension/state_fetcher.go b/extension/state_fetcher.go new file mode 100644 index 0000000000..0a67e7f053 --- /dev/null +++ b/extension/state_fetcher.go @@ -0,0 +1,122 @@ +package extension + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/extension/extensionContracts" + "github.com/ethereum/go-ethereum/rpc" + "github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto" +) + +// ChainAccessor provides methods to fetch state and blocks from the local blockchain +type ChainAccessor interface { + // GetBlockByHash retrieves a block from the local chain. + GetBlockByHash(common.Hash) *types.Block + StateAt(root common.Hash) (*state.StateDB, mps.PrivateStateRepository, error) + StateAtPSI(root common.Hash, psi types.PrivateStateIdentifier) (*state.StateDB, *state.StateDB, error) + State() (*state.StateDB, mps.PrivateStateRepository, error) + CurrentBlock() *types.Block +} + +// Only extract required methods from EthAPIBackend +type APIBackendHelper interface { + AccountExtraDataStateGetterByNumber(ctx context.Context, number rpc.BlockNumber) (vm.AccountExtraDataStateGetter, error) + PSMR() mps.PrivateStateMetadataResolver + CurrentBlock() *types.Block + SupportsMultitenancy(rpcCtx context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) +} + +// StateFetcher manages retrieving state from the database and returning it in +// a usable form by the extension API. +type StateFetcher struct { + chainAccessor ChainAccessor +} + +// Creates a new StateFetcher from the ethereum service +func NewStateFetcher(chainAccessor ChainAccessor) *StateFetcher { + return &StateFetcher{ + chainAccessor: chainAccessor, + } +} + +// returns the current block hash +func (fetcher *StateFetcher) getCurrentBlockHash() common.Hash { + return fetcher.chainAccessor.CurrentBlock().Hash() +} + +// GetAddressStateFromBlock is a public method that combines the other +// functions of a StateFetcher, retrieving the state of an address at a given +// block, represented in JSON. +func (fetcher *StateFetcher) GetAddressStateFromBlock(blockHash common.Hash, addressToFetch common.Address, psi types.PrivateStateIdentifier) ([]byte, error) { + privateState, err := fetcher.privateState(blockHash, psi) + if err != nil { + return nil, err + } + stateData, err := fetcher.addressStateAsJson(privateState, addressToFetch) + if err != nil { + return nil, err + } + return stateData, nil +} + +// privateState returns the private state database for a given block hash. +func (fetcher *StateFetcher) privateState(blockHash common.Hash, psi types.PrivateStateIdentifier) (*state.StateDB, error) { + block := fetcher.chainAccessor.GetBlockByHash(blockHash) + _, privateState, err := fetcher.chainAccessor.StateAtPSI(block.Root(), psi) + + return privateState, err +} + +// addressStateAsJson returns the state of an address, including the balance, +// nonce, code and state data as a JSON map. +func (fetcher *StateFetcher) addressStateAsJson(privateState *state.StateDB, addressToShare common.Address) ([]byte, error) { + keepAddresses := make(map[string]extensionContracts.AccountWithMetadata) + + if account, found := privateState.DumpAddress(addressToShare); found { + keepAddresses[addressToShare.Hex()] = extensionContracts.AccountWithMetadata{ + State: account, + } + } else { + return nil, fmt.Errorf("error in contract state fetch") + } + //types can be marshalled, so errors can't occur + out, _ := json.Marshal(&keepAddresses) + return out, nil +} + +// returns the privacy metadata +func (fetcher *StateFetcher) GetPrivacyMetaData(blockHash common.Hash, address common.Address, psi types.PrivateStateIdentifier) (*state.PrivacyMetadata, error) { + privateState, err := fetcher.privateState(blockHash, psi) + if err != nil { + return nil, err + } + + privacyMetaData, err := privateState.GetPrivacyMetadata(address) + if err != nil { + return nil, err + } + + return privacyMetaData, nil +} + +// returns the privacy metadata +func (fetcher *StateFetcher) GetStorageRoot(blockHash common.Hash, address common.Address, psi types.PrivateStateIdentifier) (common.Hash, error) { + privateState, err := fetcher.privateState(blockHash, psi) + if err != nil { + return common.Hash{}, err + } + + storageRoot, err := privateState.GetStorageRoot(address) + if err != nil { + return common.Hash{}, err + } + + return storageRoot, nil +} diff --git a/extension/state_fetcher_test.go b/extension/state_fetcher_test.go new file mode 100644 index 0000000000..86e726b555 --- /dev/null +++ b/extension/state_fetcher_test.go @@ -0,0 +1,49 @@ +package extension + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" +) + +func TestDumpAddressWhenFound(t *testing.T) { + //db := ethdb.NewMemDatabase() + db := rawdb.NewMemoryDatabase() + + statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + + stateFetcher := NewStateFetcher(nil) + + // generate a few entries and write them out to the db + statedb.SetBalance(address, big.NewInt(22)) + statedb.SetCode(address, []byte{3, 3, 3, 3, 3, 3, 3}) + statedb.Commit(false) + + out, _ := stateFetcher.addressStateAsJson(statedb, address) + + want := `{"0x2222222222222222222222222222222222222222":{"state":{"balance":"22","nonce":0,"root":"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3","code":"03030303030303"}}}` + + if string(out) != want { + t.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", string(out), want) + } +} + +func TestDumpAddressWhenNotFound(t *testing.T) { + //db := ethdb.NewMemDatabase() + db := rawdb.NewMemoryDatabase() + statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + statedb.Commit(false) + + stateFetcher := NewStateFetcher(nil) + + address := common.HexToAddress("0x2222222222222222222222222222222222222222") + out, _ := stateFetcher.addressStateAsJson(statedb, address) + + if out != nil { + t.Errorf("dump mismatch:\ngot: %s\nwant: nil\n", string(out)) + } +} diff --git a/extension/subscriptions.go b/extension/subscriptions.go new file mode 100644 index 0000000000..55bff6bf6e --- /dev/null +++ b/extension/subscriptions.go @@ -0,0 +1,58 @@ +package extension + +import ( + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/private" +) + +type subscriptionHandler struct { + facade ManagementContractFacade + client Client + service *PrivacyService +} + +func NewSubscriptionHandler(node *node.Node, psi types.PrivateStateIdentifier, ptm private.PrivateTransactionManager, service *PrivacyService) *subscriptionHandler { + rpcClient, err := node.AttachWithPSI(psi) + if err != nil { + panic("extension: could not connect to ethereum client rpc") + } + + client := ethclient.NewClientWithPTM(rpcClient, ptm) + + return &subscriptionHandler{ + facade: NewManagementContractFacade(client), + client: NewInProcessClient(client), + service: service, + } +} + +func (handler *subscriptionHandler) createSub(query ethereum.FilterQuery, logHandlerCb func(types.Log)) error { + incomingLogs, subscription, err := handler.client.SubscribeToLogs(query) + + if err != nil { + return err + } + + go func() { + stopChan, stopSubscription := handler.service.subscribeStopEvent() + defer stopSubscription.Unsubscribe() + + for { + select { + case err := <-subscription.Err(): + log.Error("Contract extension watcher subscription error", "error", err) + break + case foundLog := <-incomingLogs: + logHandlerCb(foundLog) + case <-stopChan: + return + } + } + }() + + return nil +} diff --git a/extension/types.go b/extension/types.go new file mode 100644 index 0000000000..c68e3a3409 --- /dev/null +++ b/extension/types.go @@ -0,0 +1,40 @@ +package extension + +import ( + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/extension/extensionContracts" +) + +var ( + //Log queries + newExtensionQuery = ethereum.FilterQuery{ + FromBlock: nil, + ToBlock: nil, + Topics: [][]common.Hash{{common.HexToHash(extensionContracts.NewContractExtensionContractCreatedTopicHash)}}, + Addresses: []common.Address{}, + } + + finishedExtensionQuery = ethereum.FilterQuery{ + FromBlock: nil, + ToBlock: nil, + Topics: [][]common.Hash{{common.HexToHash(extensionContracts.ExtensionFinishedTopicHash)}}, + Addresses: []common.Address{}, + } + + canPerformStateShareQuery = ethereum.FilterQuery{ + FromBlock: nil, + ToBlock: nil, + Topics: [][]common.Hash{{common.HexToHash(extensionContracts.CanPerformStateShareTopicHash)}}, + Addresses: []common.Address{}, + } +) + +type ExtensionContract struct { + ContractExtended common.Address `json:"contractExtended"` + Initiator common.Address `json:"initiator"` + Recipient common.Address `json:"recipient"` + ManagementContractAddress common.Address `json:"managementContractAddress"` + RecipientPtmKey string `json:"recipientPtmKey"` + CreationData []byte `json:"creationData"` +} diff --git a/go.mod b/go.mod index 7e8d0d1b8c..e7547eaeaf 100755 --- a/go.mod +++ b/go.mod @@ -1,11 +1,20 @@ module github.com/ethereum/go-ethereum -go 1.13 +go 1.15 + +// Quorum - Replace Go modules that use modifications done by us +replace ( + github.com/coreos/etcd => github.com/Consensys/etcd v3.3.13-quorum197+incompatible + github.com/ethereum/go-ethereum/crypto/secp256k1 => ./crypto/secp256k1 +) + +// End Quorum require ( github.com/Azure/azure-pipeline-go v0.2.2 // indirect github.com/Azure/azure-storage-blob-go v0.7.0 github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect + github.com/BurntSushi/toml v0.3.1 github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/VictoriaMetrics/fastcache v1.5.7 github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 @@ -13,36 +22,50 @@ require ( github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 github.com/cespare/cp v0.1.0 github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9 + github.com/coreos/etcd v3.3.20+incompatible + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea github.com/dlclark/regexp2 v1.2.0 // indirect github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 + github.com/eapache/channels v1.1.0 + github.com/eapache/queue v1.1.0 // indirect github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c - github.com/fatih/color v1.3.0 + github.com/ethereum/go-ethereum/crypto/secp256k1 v0.0.0 + github.com/fatih/color v1.7.0 github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 + github.com/golang/mock v1.4.3 github.com/golang/protobuf v1.4.2 github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26 github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989 github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 + github.com/hashicorp/go-hclog v0.13.0 + github.com/hashicorp/go-plugin v1.2.2 github.com/hashicorp/golang-lru v0.5.4 github.com/holiman/uint256 v1.1.1 github.com/huin/goupnp v1.0.0 github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883 github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 + github.com/jpmorganchase/quorum-account-plugin-sdk-go v0.0.0-20200714175524-662195b38a5e + github.com/jpmorganchase/quorum-hello-world-plugin-sdk-go v0.0.0-20200210211148-57f99f69eeb3 + github.com/jpmorganchase/quorum-security-plugin-sdk-go v0.0.0-20200714173835-22a319bb78ce github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 github.com/kr/pretty v0.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mattn/go-colorable v0.1.0 - github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 + github.com/mattn/go-colorable v0.1.4 + github.com/mattn/go-isatty v0.0.10 github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c + github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150 @@ -55,16 +78,22 @@ require ( github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect github.com/stretchr/testify v1.4.0 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca + github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect - golang.org/x/sync v0.0.0-20181108010431-42b317875d0f + golang.org/x/sync v0.0.0-20190423024810-112230192c58 golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 golang.org/x/text v0.3.3 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 + google.golang.org/grpc v1.29.1 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 + gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce - gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 + gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772 + gopkg.in/oleiade/lane.v1 v1.0.0 gopkg.in/urfave/cli.v1 v1.20.0 gotest.tools v2.2.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index 31c2c48221..40c3bab97f 100755 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= @@ -19,7 +20,12 @@ github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1Gn github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/ConsenSys/quorum/crypto/secp256k1 v0.0.0-20210223160031-6e8585c2a9ad h1:04hKIfJWbJFYtNFeI77cRzfiEpNT9f44KNdHhB6sGOw= +github.com/ConsenSys/quorum/crypto/secp256k1 v0.0.0-20210223160031-6e8585c2a9ad/go.mod h1:mrsI3XgXEfdgdT37sIJiqEha0aOBGreMcc1fbu7aDEw= +github.com/Consensys/etcd v3.3.13-quorum197+incompatible h1:ZBM9sH4QEufgaShSyNNhffuZv6Zhl5kyD2b/NHViByM= +github.com/Consensys/etcd v3.3.13-quorum197+incompatible/go.mod h1:wz4o/jwsTgMkSZUY9DmwVEIL3b2JX3t+tCDdy/J5ilY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= @@ -33,17 +39,27 @@ github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4 github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aws/aws-sdk-go v1.25.48 h1:J82DYDGZHOKHdhx6hD24Tm30c2C3GchYGfN0mf9iKUk= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI= github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9 h1:J82+/8rub3qSy0HxEnoYD8cs+HDlHWYrqYXe2Vqxluk= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -59,10 +75,18 @@ github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmak github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= +github.com/eapache/channels v1.1.0 h1:F1taHcn7/F0i8DYqKXJnyhJcVpp2kgFcNePxXtnyu4k= +github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c h1:JHHhtb9XWJrGNMcrVP6vyzO4dusgi/HnceHTgxSejUM= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/fatih/color v1.3.0 h1:YehCCcyeQ6Km0D6+IapqPinWBK6y+0eB5umvZXK9WPs= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -81,8 +105,18 @@ github.com/go-sourcemap/sourcemap v2.1.2+incompatible h1:0b/xya7BKGhXuqFESKM4oIi github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -94,6 +128,7 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26 h1:lMm2hD9Fy0ynom5+85/pbdkiYcBqM1JWmhpAXLmy0fw= github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -103,8 +138,15 @@ github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989 h1:giknQ4mEuDF github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 h1:E0whKxgp2ojts0FDgUA8dl62bmH0LxKanMoBr6MDTDM= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.13.0 h1:Do32YnDMnq7v7FU50AgH+1ExKCOkl9HBxvSI1JWr+rA= +github.com/hashicorp/go-hclog v0.13.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-plugin v1.2.2 h1:mgDpq0PkoK5gck2w4ivaMpWRHv/matdOR4xmeScmf/w= +github.com/hashicorp/go-plugin v1.2.2/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/holiman/uint256 v1.1.1 h1:4JywC80b+/hSfljFlEBLHrrh+CIONLDz9NuFl0af4Mw= github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= @@ -116,12 +158,21 @@ github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883 h1:FSeK4fZCo github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jpmorganchase/quorum-account-plugin-sdk-go v0.0.0-20200714175524-662195b38a5e h1:aE+TcHdEop381e8gMBWw/7Nw5aOdXdVmVrVP7ZrKrq4= +github.com/jpmorganchase/quorum-account-plugin-sdk-go v0.0.0-20200714175524-662195b38a5e/go.mod h1:clocsx5vZHANnLM+SmcJJDKY6VVxxcdRUCKe5Y+roQ0= +github.com/jpmorganchase/quorum-hello-world-plugin-sdk-go v0.0.0-20200210211148-57f99f69eeb3 h1:vaXIQlaE9ELd0V5NjwMHD8hlAPeC2A1Zu1i2TxKdpVY= +github.com/jpmorganchase/quorum-hello-world-plugin-sdk-go v0.0.0-20200210211148-57f99f69eeb3/go.mod h1:xZOd/PmBeJkF1X+VLaIkCsQq1nqlr2DiekzGMpBDZq0= +github.com/jpmorganchase/quorum-security-plugin-sdk-go v0.0.0-20200714173835-22a319bb78ce h1:N0BFCITB+CS2fwTlnYuwr9KslnVWxpz7rs8xyyhS1xA= +github.com/jpmorganchase/quorum-security-plugin-sdk-go v0.0.0-20200714173835-22a319bb78ce/go.mod h1:Zq2sOjX+LZrNoV+cyvS/4Xsy69v8HOFKHtCLkiXQ3Kk= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21 h1:F/iKcka0K2LgnKy/fgSBf235AETtm1n1TvBzqu40LE0= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -131,23 +182,29 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 h1:USWjF42jDCSEeikX/G1g40ZWnsPXN5WkZ4jMHZWyBK4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c h1:1RHs3tNxjXGHeul8z2t6H2N2TlAqpKe5yryJztRx4Jk= @@ -161,6 +218,8 @@ github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 h1:goeTyGkArOZIVOMA0dQbyuPWGNQJZGPwPu/QS9GlpnA= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= @@ -170,9 +229,14 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1 h1:K47Rk0v/fkEfwfQet2KWhscE0cJzjgCCDBG2KHZoVno= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce h1:X0jFYGnHemYDIW6jlc+fSI8f9Cg+jqCnClYP2WgZT/A= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150 h1:ZeU+auZj1iNzN8iVhff6M38Mfu73FQiJve/GEXYJBjE= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -193,6 +257,7 @@ github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -200,30 +265,48 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= +github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -231,6 +314,7 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 h1:AvbQYmiaaaza3cW3QXRyPo5kYgpFIzOAfeAAN7m3qQ4= golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -238,11 +322,32 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -256,10 +361,14 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951 h1:DMTcQRFbEH62YPRWwOI647s2e5mHda3oBPMHfrLs2bw= +gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951/go.mod h1:owOxCRGGeAx1uugABik6K9oeNu1cgxP/R9ItzLDxNWA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772 h1:hhsSf/5z74Ck/DJYc+R8zpq8KGm7uJvpdLRQED/IedA= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/oleiade/lane.v1 v1.0.0 h1:Xs7/GTdnZNGuuXV7z8gTrHoHEeHdCnhuNXm4n0UpxjY= +gopkg.in/oleiade/lane.v1 v1.0.0/go.mod h1:e9mCiNjxfTGlkjxn/TPK3JUwhjKjby5cjXuGotH/QlE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= @@ -271,3 +380,8 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/graphql/graphiql.go b/graphql/graphiql.go index 864ebf57df..574fc851d0 100644 --- a/graphql/graphiql.go +++ b/graphql/graphiql.go @@ -24,15 +24,25 @@ package graphql import ( "bytes" + "context" "fmt" + "html/template" "net/http" + + "github.com/ethereum/go-ethereum/plugin/security" + "github.com/ethereum/go-ethereum/rpc" ) // GraphiQL is an in-browser IDE for exploring GraphiQL APIs. // This handler returns GraphiQL when requested. // // For more information, see https://github.com/graphql/graphiql. -type GraphiQL struct{} +// Quorum +// 1. Introduce 2 fields to support rendering additional HTML snippets +type GraphiQL struct { + authManagerFunc security.AuthenticationManagerDeferFunc + isMPS bool +} func respond(w http.ResponseWriter, body []byte, code int) { w.Header().Set("Content-Type", "application/json; charset=utf-8") @@ -53,7 +63,43 @@ func (h GraphiQL) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } w.Header().Set("Content-Type", "text/html") - w.Write(graphiql) + html, err := h.addQuorumHTML(graphiql) + if err != nil { + respond(w, errorJSON("unable to add Quorum-specific HTML"), http.StatusInternalServerError) + return + } + w.Write(html) +} + +func (h GraphiQL) addQuorumHTML(g []byte) ([]byte, error) { + tmpl, err := template.New("Quorum").Parse(string(g)) + if err != nil { + return nil, err + } + authManager, err := h.authManagerFunc() + if err != nil { + return nil, err + } + authManagerEnabled, err := authManager.IsEnabled(context.Background()) + if err != nil { + return nil, err + } + data := struct { + ShowPSI bool + ShowAccessToken bool + AuthHeader string + PSIHeader string + }{ + ShowPSI: h.isMPS, + ShowAccessToken: authManagerEnabled, + AuthHeader: rpc.HttpAuthorizationHeader, + PSIHeader: rpc.HttpPrivateStateIdentifierHeader, + } + var buf bytes.Buffer + if err := tmpl.Execute(&buf, data); err != nil { + return nil, err + } + return buf.Bytes(), nil } var graphiql = []byte(` @@ -91,12 +137,68 @@ var graphiql = []byte(` integrity="sha384-roSmzNmO4zJK9X4lwggDi4/oVy+9V4nlS1+MN8Taj7tftJy1GvMWyAhTNXdC/fFR" crossorigin="anonymous" > +{{- if or .ShowAccessToken .ShowPSI }} + +{{- end }} +{{- if or .ShowAccessToken .ShowPSI }} +
+ + +{{- if .ShowAccessToken }} + +{{- end }} +{{- if .ShowPSI }} + +{{- end }} + +
Access Token  ?  + Target PSI  ?  +
+
+{{- end }}
Loading...
+

dS0! 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%0D|XM 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 {d;n=$T`cdAK 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