From 180c827db3506ad8d2145a7a7e4dbf662c199b4b Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 18 Jul 2013 09:39:30 -0500 Subject: [PATCH 001/190] Initial commit. --- .gitignore | 28 ++++++++++++++++++++++++++++ README.md | 4 ++++ 2 files changed, 32 insertions(+) create mode 100644 .gitignore create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5b97dbba --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +# Temp files +*~ + +# Log files +*.log + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/README.md b/README.md new file mode 100644 index 00000000..37420b77 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +btcchain +======== + +Package btcchain implements bitcoin block handling and chain selection rules. From aa5847f3cc9e6f825ffa1772d8428160e4b637b6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 18 Jul 2013 09:49:28 -0500 Subject: [PATCH 002/190] Initial implementation. --- LICENSE | 13 + README.md | 140 ++++++ accept.go | 159 +++++++ chain.go | 716 +++++++++++++++++++++++++++++ checkpoints.go | 258 +++++++++++ cov_report.sh | 17 + difficulty.go | 285 ++++++++++++ doc.go | 124 +++++ internal_test.go | 28 ++ log.go | 65 +++ merkle.go | 114 +++++ merkle_test.go | 24 + notifications.go | 76 ++++ process.go | 175 +++++++ reorganization_test.go | 133 ++++++ scriptval.go | 136 ++++++ test_coverage.txt | 77 ++++ testdata/blk_0_to_4.dat.bz2 | Bin 0 -> 1684 bytes testdata/blk_3A.dat.bz2 | Bin 0 -> 801 bytes testdata/blk_4A.dat.bz2 | Bin 0 -> 271 bytes testdata/blk_5A.dat.bz2 | Bin 0 -> 480 bytes testdata/reorgtest.hex | 180 ++++++++ timesorter.go | 31 ++ txlookup.go | 248 ++++++++++ validate.go | 877 ++++++++++++++++++++++++++++++++++++ validate_test.go | 274 +++++++++++ 26 files changed, 4150 insertions(+) create mode 100644 LICENSE create mode 100644 accept.go create mode 100644 chain.go create mode 100644 checkpoints.go create mode 100644 cov_report.sh create mode 100644 difficulty.go create mode 100644 doc.go create mode 100644 internal_test.go create mode 100644 log.go create mode 100644 merkle.go create mode 100644 merkle_test.go create mode 100644 notifications.go create mode 100644 process.go create mode 100644 reorganization_test.go create mode 100644 scriptval.go create mode 100644 test_coverage.txt create mode 100644 testdata/blk_0_to_4.dat.bz2 create mode 100644 testdata/blk_3A.dat.bz2 create mode 100644 testdata/blk_4A.dat.bz2 create mode 100644 testdata/blk_5A.dat.bz2 create mode 100644 testdata/reorgtest.hex create mode 100644 timesorter.go create mode 100644 txlookup.go create mode 100644 validate.go create mode 100644 validate_test.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0d760cbb --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2013 Conformal Systems LLC. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 37420b77..2c9bf4d2 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,143 @@ btcchain ======== Package btcchain implements bitcoin block handling and chain selection rules. +The test coverage is currently only around 60%, but will be increasing over +time. See `test_coverage.txt` for the gocov coverage report. Alternatively, if +you are running a POSIX OS, you can run the `cov_report.sh` script for a +real-time report. Package btcchain is licensed under the liberal ISC license. + +There is an associated blog post about the release of this package +[here](https://blog.conformal.com/btcchain-the-bitcoin-chain-package-from-bctd/). + +This package is one of the core packages from btcd, an alternative full-node +implementation of bitcoin which is under active development by Conformal. +Although it was primarily written for btcd, this package has intentionally been +designed so it can be used as a standalone package for any projects needing to +handle processing of blocks into the bitcoin block chain. + +## Documentation + +Full `go doc` style documentation for the project can be viewed online without +installing this package by using the GoDoc site here: +http://godoc.org/github.com/conformal/btcchain + +You can also view the documentation locally once the package is installed with +the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to +http://localhost:6060/pkg/github.com/conformal/btcchain + +## Installation + +```bash +$ go get github.com/conformal/btcchain +``` + +## Bitcoin Chain Processing Overview + +Before a block is allowed into the block chain, it must go through an intensive +series of validation rules. The following list serves as a general outline of +those rules to provide some intuition into what is going on under the hood, but +is by no means exhaustive: + + - Reject duplicate blocks + - Perform a series of sanity checks on the block and its transactions such as + verifying proof of work, timestamps, number and character of transactions, + transaction amounts, script complexity, and merkle root calculations + - Compare the block against predetermined checkpoints for expected timestamps + and difficulty based on elapsed time since the checkpoint + - Save the most recent orphan blocks for a limited time in case their parent + blocks become available + - Stop processing if the block is an orphan as the rest of the processing + depends on the block's position within the block chain + - Perform a series of more thorough checks that depend on the block's position + within the block chain such as verifying block difficulties adhere to + difficulty retarget rules, timestamps are after the median of the last + several blocks, all transactions are finalized, checkpoint blocks match, and + block versions are in line with the previous blocks + - Determine how the block fits into the chain and perform different actions + accordingly in order to ensure any side chains which have higher difficulty + than the main chain become the new main chain + - When a block is being connected to the main chain (either through + reorganization of a side chain to the main chain or just extending the + main chain), perform further checks on the block's transactions such as + verifying transaction duplicates, script complexity for the combination of + connected scripts, coinbase maturity, double spends, and connected + transaction values + - Run the transaction scripts to verify the spender is allowed to spend the + coins + - Insert the block into the block database + +## Block Processing Example + +The following example program demonstrates processing a block. This example +intentionally causes an error by attempting to process a duplicate block. + +```Go + package main + + import ( + "fmt" + "github.com/conformal/btcchain" + "github.com/conformal/btcdb" + _ "github.com/conformal/btcdb/sqlite3" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + ) + + func main() { + // First, we create a new database to store the accepted blocks into. + // Typically this would be opening an existing database, but we create + // a new db here so this is a complete working example. + db, err := btcdb.CreateDB("sqlite", "example.db") + if err != nil { + fmt.Printf("Failed to create database: %v\n", err) + return + } + defer db.Close() + + // Create a new BlockChain instance using the underlying database for + // the main bitcoin network and ignore notifications. + chain := btcchain.New(db, btcwire.MainNet, nil) + + // Process a block. For this example, we are going to intentionally + // cause an error by trying to process the genesis block which already + // exists. + block := btcutil.NewBlock(&btcwire.GenesisBlock, btcwire.ProtocolVersion) + err = chain.ProcessBlock(block) + if err != nil { + fmt.Printf("Failed to process block: %v\n", err) + return + } + } +``` + +## TODO + +- Increase test coverage +- Add testnet specific rules +- Profile and optimize +- Expose some APIs for block verification (without actually inserting it) and + transaction input lookups + +## GPG Verification Key + +All official release tags are signed by Conformal so users can ensure the code +has not been tampered with and is coming from Conformal. To verify the +signature perform the following: + +- Download the public key from the Conformal website at + https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt + +- Import the public key into your GPG keyring: + ```bash + gpg --import GIT-GPG-KEY-conformal.txt + ``` + +- Verify the release tag with the following command where `TAG_NAME` is a + placeholder for the specific tag: + ```bash + git tag -v TAG_NAME + ``` + +## License + +Package btcchain is licensed under the liberal ISC License. diff --git a/accept.go b/accept.go new file mode 100644 index 00000000..e52dad09 --- /dev/null +++ b/accept.go @@ -0,0 +1,159 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" +) + +// maybeAcceptBlock potentially accepts a block into the memory block chain. +// It performs several validation checks which depend on its position within +// the block chain before adding it. The block is expected to have already gone +// through ProcessBlock before calling this function with it. +func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { + // Get a block node for the block previous to this one. Will be nil + // if this is the genesis block. + prevNode, err := b.getPrevNodeFromBlock(block) + if err != nil { + return err + } + + // The height of this block one more than the referenced previous block. + blockHeight := int64(0) + if prevNode != nil { + blockHeight = prevNode.height + 1 + } + + // Ensure the difficulty specified in the block header matches the + // calculated difficulty based on the previous block and difficulty + // retarget rules. + blockHeader := block.MsgBlock().Header + expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode) + if err != nil { + return err + } + blockDifficulty := blockHeader.Bits + if blockDifficulty != expectedDifficulty { + str := "block difficulty of %d is not the expected value of %d" + str = fmt.Sprintf(str, blockDifficulty, expectedDifficulty) + return RuleError(str) + } + + // Ensure the timestamp for the block header is after the median time of + // the last several blocks (medianTimeBlocks). + medianTime, err := b.calcPastMedianTime(prevNode) + if err != nil { + return err + } + if !blockHeader.Timestamp.After(medianTime) { + str := "block timestamp of %v is not after expected %v" + str = fmt.Sprintf(str, blockHeader.Timestamp, medianTime) + return RuleError(str) + } + + // Ensure all transactions in the block are finalized. + for i, tx := range block.MsgBlock().Transactions { + if !isFinalizedTransaction(tx, blockHeight, blockHeader.Timestamp) { + // Use the TxSha function from the block rather + // than the transaction itself since the block version + // is cached. Also, it's safe to ignore the error here + // since the only reason TxSha can fail is if the index + // is out of range which is impossible here. + txSha, _ := block.TxSha(i) + str := fmt.Sprintf("block contains unfinalized "+ + "transaction %v", txSha) + return RuleError(str) + } + } + + // Ensure chain matches up to predetermined checkpoints. + // It's safe to ignore the error on Sha since it's already cached. + blockHash, _ := block.Sha() + if !b.verifyCheckpoint(blockHeight, blockHash) { + // TODO(davec): This should probably be a distinct error type + // (maybe CheckpointError). Since this error shouldn't happen + // unless the peer is connected to a rogue network serving up an + // alternate chain, the caller would likely need to react by + // disconnecting peers and rolling back the chain to the last + // known good point. + str := fmt.Sprintf("block at height %d does not match "+ + "checkpoint hash", blockHeight) + return RuleError(str) + } + + // Reject version 1 blocks once a majority of the network has upgraded. + // Rules: + // 95% (950 / 1000) for main network + // 75% (75 / 100) for the test network + // This is part of BIP_0034. + if blockHeader.Version == 1 { + minRequired := uint64(950) + numToCheck := uint64(1000) + if b.btcnet == btcwire.TestNet3 || b.btcnet == btcwire.TestNet { + minRequired = 75 + numToCheck = 100 + } + if b.isMajorityVersion(2, prevNode, minRequired, numToCheck) { + str := "new blocks with version %d are no longer valid" + str = fmt.Sprintf(str, blockHeader.Version) + return RuleError(str) + } + } + + // Ensure coinbase starts with serialized block heights for blocks + // whose version is the serializedHeightVersion or newer once a majority + // of the network has upgraded. + // Rules: + // 75% (750 / 1000) for main network + // 51% (51 / 100) for the test network + // This is part of BIP_0034. + if blockHeader.Version >= serializedHeightVersion { + minRequired := uint64(750) + numToCheck := uint64(1000) + if b.btcnet == btcwire.TestNet3 || b.btcnet == btcwire.TestNet { + minRequired = 51 + numToCheck = 100 + } + if b.isMajorityVersion(serializedHeightVersion, prevNode, + minRequired, numToCheck) { + + expectedHeight := int64(0) + if prevNode != nil { + expectedHeight = prevNode.height + 1 + } + coinbaseTx := block.MsgBlock().Transactions[0] + err := checkSerializedHeight(coinbaseTx, expectedHeight) + if err != nil { + return err + } + } + } + + // Create a new block node for the block and add it to the in-memory + // block chain (could be either a side chain or the main chain). + newNode := newBlockNode(block) + if prevNode != nil { + newNode.parent = prevNode + newNode.height = blockHeight + newNode.workSum.Add(prevNode.workSum, newNode.workSum) + } + + // Connect the passed block to the chain while respecting proper chain + // selection according to the chain with the most proof of work. This + // also handles validation of the transaction scripts. + err = b.connectBestChain(newNode, block) + if err != nil { + return err + } + + // Notify the caller that the new block was accepted into the block + // chain. The caller would typically want to react by relaying the + // inventory to other peers. + b.sendNotification(NTBlockAccepted, block) + + return nil +} diff --git a/chain.go b/chain.go new file mode 100644 index 00000000..40e378ab --- /dev/null +++ b/chain.go @@ -0,0 +1,716 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "container/list" + "fmt" + "github.com/conformal/btcdb" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "math/big" + "sort" + "time" +) + +// maxOrphanBlocks is the maximum number of orphan blocks that can be queued. +const maxOrphanBlocks = 100 + +// blockNode represents a block within the block chain and is primarily used to +// aid in selecting the best chain to be the main chain. The main chain is +// stored into the block database. +type blockNode struct { + // parent is the parent block for this node. + parent *blockNode + + // children contains the child nodes for this node. Typically there + // will only be one, but sometimes there can be more than one and that + // is when the best chain selection algorithm is used. + children []*blockNode + + // hash is the double sha 256 of the block. + hash *btcwire.ShaHash + + // height is the position in the block chain. + height int64 + + // workSum is the total amount of work in the chain up to and including + // this node. + workSum *big.Rat + + // inMainChain denotes whether the block node is currently on the + // the main chain or not. This is used to help find the common + // ancestor when switching chains. + inMainChain bool + + // Some fields from block headers to aid in best chain selection. + version uint32 + bits uint32 + timestamp time.Time +} + +// newBlockNode returns a new block node for the given block. It is completely +// disconnected from the chain and the workSum value is just the work for the +// passed block. The work sum is updated accordingly when the node is inserted +// into a chain. +func newBlockNode(block *btcutil.Block) *blockNode { + // Get the block sha. It's ok to ignore the error here since + // sha has already been called and an error there would have caused + // an exit before this function is called. + blockSha, _ := block.Sha() + + blockHeader := block.MsgBlock().Header + node := blockNode{ + hash: blockSha, + workSum: calcWork(blockHeader.Bits), + height: block.Height(), + version: blockHeader.Version, + bits: blockHeader.Bits, + timestamp: blockHeader.Timestamp, + } + return &node +} + +// orphanBlock represents a block that we don't yet have the parent for. It +// is a normal block plus an expiration time to prevent caching the orphan +// forever. +type orphanBlock struct { + block *btcutil.Block + expiration time.Time +} + +// addChildrenWork adds the passed work amount to all children all the way +// down the chain. It is used primarily to allow a new node to be dynamically +// inserted from the database into the memory chain prior to nodes we already +// have and update their work values accordingly. +func addChildrenWork(node *blockNode, work *big.Rat) { + for _, childNode := range node.children { + childNode.workSum.Add(childNode.workSum, work) + addChildrenWork(childNode, work) + } +} + +// removeChildNode deletes node from the provided slice of child block +// nodes. It ensures the final pointer reference is set to nil to prevent +// potential memory leaks. The original slice is returned unmodified if node +// is invalid or not in the slice. +func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { + if node == nil { + return children + } + for i, n := range children { + if n.hash.IsEqual(node.hash) { + copy(children[i:], children[i+1:]) + children[len(children)-1] = nil + return children[:len(children)-1] + } + } + return children +} + +// BlockChain provides functions for working with the bitcoin block chain. +// It includes functionality such as rejecting duplicate blocks, ensuring blocks +// follow all rules, orphan handling, checkpoint handling, and best chain +// selection with reorganization. +type BlockChain struct { + db btcdb.Db + btcnet btcwire.BitcoinNet + notifications chan *Notification + root *blockNode + bestChain *blockNode + index map[btcwire.ShaHash]*blockNode + depNodes map[btcwire.ShaHash][]*blockNode + orphans map[btcwire.ShaHash]*orphanBlock + prevOrphans map[btcwire.ShaHash][]*orphanBlock + oldestOrphan *orphanBlock + blockCache map[btcwire.ShaHash]*btcutil.Block + noVerify bool + noCheckpoints bool +} + +// DisableVerify provides a mechanism to disable transaction script validation +// which you DO NOT want to do in production as it could allow double spends +// and othe undesirable things. It is provided only for debug purposes since +// script validation is extremely intensive and when debugging it is sometimes +// nice to quickly get the chain. +func (b *BlockChain) DisableVerify(disable bool) { + b.noVerify = disable +} + +// getOrphanRoot returns the head of the chain for the provided hash from the +// map of orphan blocks. +func (b *BlockChain) getOrphanRoot(sha *btcwire.ShaHash) *btcwire.ShaHash { + // Keep looping while the parent of each orphaned block is + // known and is an orphan itself. + prevHash := sha + for { + orphan, exists := b.orphans[*prevHash] + if !exists { + break + } + prevHash = &orphan.block.MsgBlock().Header.PrevBlock + } + + return prevHash +} + +// removeOrphanBlock removes the passed orphan block from the orphan pool and +// previous orphan index. +func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) { + // Remove the orphan block from the orphan pool. It's safe to ignore + // the error on Sha since it's cached. + orphanHash, _ := orphan.block.Sha() + delete(b.orphans, *orphanHash) + + // Remove the reference from the previous orphan index too. + prevHash := &orphan.block.MsgBlock().Header.PrevBlock + orphans := b.prevOrphans[*prevHash] + for i, ob := range orphans { + hash, _ := ob.block.Sha() + if hash.IsEqual(orphanHash) { + copy(orphans[i:], orphans[i+1:]) + orphans[len(orphans)-1] = nil + b.prevOrphans[*prevHash] = orphans[:len(orphans)-1] + } + } + + // Remove the map entry altogether if there are no longer any orphans + // which depend on the parent hash. + if len(b.prevOrphans[*prevHash]) == 0 { + delete(b.prevOrphans, *prevHash) + } +} + +// addOrphanBlock adds the passed block (which is already determined to be +// an orphan prior calling this function) to the orphan pool. It lazily cleans +// up any expired blocks so a separate cleanup poller doesn't need to be run. +// It also imposes a maximum limit on the number of outstanding orphan +// blocks and will remove the oldest received orphan block if the limit is +// exceeded. +func (b *BlockChain) addOrphanBlock(block *btcutil.Block) { + // Remove expired orphan blocks. + for _, oBlock := range b.orphans { + if time.Now().After(oBlock.expiration) { + b.removeOrphanBlock(oBlock) + continue + } + + // Update the oldest orphan block pointer so it can be discarded + // in case the orphan pool fills up. + if b.oldestOrphan == nil || oBlock.expiration.Before(b.oldestOrphan.expiration) { + b.oldestOrphan = oBlock + } + } + + // Limit orphan blocks to prevent memory exhaustion. + if len(b.orphans)+1 > maxOrphanBlocks { + // Remove the oldest orphan to make room for the new one. + b.removeOrphanBlock(b.oldestOrphan) + b.oldestOrphan = nil + } + + // Get the block sha. It is safe to ignore the error here since any + // errors would've been caught prior to calling this function. + blockSha, _ := block.Sha() + + // Insert the block into the orphan map with an expiration time + // 1 hour from now. + expiration := time.Now().Add(time.Hour) + oBlock := &orphanBlock{ + block: block, + expiration: expiration, + } + b.orphans[*blockSha] = oBlock + + // Add to previous hash lookup index for faster dependency lookups. + prevHash := &block.MsgBlock().Header.PrevBlock + b.prevOrphans[*prevHash] = append(b.prevOrphans[*prevHash], oBlock) + + return +} + +// loadBlockNode loads the block identified by hash from the block database, +// creates a block node from it, and updates the memory block chain accordingly. +// It is used mainly to dynamically load previous blocks from database as they +// are needed to avoid needing to put the entire block chain in memory. +func (b *BlockChain) loadBlockNode(hash *btcwire.ShaHash) (*blockNode, error) { + // Load the block from the db. + block, err := b.db.FetchBlockBySha(hash) + if err != nil { + return nil, err + } + + // Create the new block node for the block and set the work. + node := newBlockNode(block) + node.inMainChain = true + + // Add the node to the chain. + // There are several possibilities here: + // 1) This node is a child of an existing block node + // 2) This node is the parent of one or more nodes + // 3) Neither 1 or 2 is true, and this is not the first node being + // added to the tree which implies it's an orphan block and + // therefore is an error to insert into the chain + // 4) Neither 1 or 2 is true, but this is the first node being added + // to the tree, so it's the root. + prevHash := &block.MsgBlock().Header.PrevBlock + if parentNode, ok := b.index[*prevHash]; ok { + // Case 1 -- This node is a child of an existing block node. + // Update the node's work sum with the sum of the parent node's + // work sum and this node's work, append the node as a child of + // the parent node and set this node's parent to the parent + // node. + node.workSum = node.workSum.Add(parentNode.workSum, node.workSum) + parentNode.children = append(parentNode.children, node) + node.parent = parentNode + + } else if childNodes, ok := b.depNodes[*hash]; ok { + // Case 2 -- This node is the parent of one or more nodes. + // Connect this block node to all of its children and update + // all of the children (and their children) with the new work + // sums. + for _, childNode := range childNodes { + childNode.parent = node + node.children = append(node.children, childNode) + addChildrenWork(childNode, node.workSum) + b.root = node + } + + } else { + // Case 3 -- The node does't have a parent and is not the parent + // of another node. This is only acceptable for the first node + // inserted into the chain. Otherwise it means an arbitrary + // orphan block is trying to be loaded which is not allowed. + if b.root != nil { + str := "loadBlockNode: attempt to insert orphan block %v" + return nil, fmt.Errorf(str, hash) + } + + // Case 4 -- This is the root since it's the first and only node. + b.root = node + } + + // Add the new node to the indices for faster lookups. + b.index[*hash] = node + b.depNodes[*prevHash] = append(b.depNodes[*prevHash], node) + + return node, nil +} + +// getPrevNodeFromBlock returns a block node for the block previous to the +// passed block (the passed block's parent). When it is already in the memory +// block chain, it simply returns it. Otherwise, it loads the previous block +// from the block database, creates a new block node from it, and returns it. +// The returned node will be nil if the genesis block is passed. +func (b *BlockChain) getPrevNodeFromBlock(block *btcutil.Block) (*blockNode, error) { + // Genesis block. + prevHash := &block.MsgBlock().Header.PrevBlock + if prevHash.IsEqual(zeroHash) { + return nil, nil + } + + // Return the existing previous block node if it's already there. + if bn, ok := b.index[*prevHash]; ok { + return bn, nil + } + + // Dynamically load the previous block from the block database, create + // a new block node for it, and update the memory chain accordingly. + prevBlockNode, err := b.loadBlockNode(prevHash) + if err != nil { + return nil, err + } + return prevBlockNode, nil +} + +// getPrevNodeFromNode returns a block node for the block previous to the +// passed block node (the passed block node's parent). When the node is already +// connected to a parent, it simply returns it. Otherwise, it loads the +// associated block from the database to obtain the previous hash and uses that +// to dynamically create a new block node and return it. The memory block +// chain is updated accordingly. The returned node will be nil if the genesis +// block is passed. +func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { + // Return the existing previous block node if it's already there. + if node.parent != nil { + return node.parent, nil + } + + // Genesis block. + if node.hash.IsEqual(&btcwire.GenesisHash) { + return nil, nil + } + + // Load the actual block for this block node from the db to ascertain + // the previous hash. + block, err := b.db.FetchBlockBySha(node.hash) + if err != nil { + return nil, err + } + + // Dynamically load the previous block from the block database, create + // a new block node for it, and update the memory chain accordingly. + prevHash := &block.MsgBlock().Header.PrevBlock + prevBlockNode, err := b.loadBlockNode(prevHash) + if err != nil { + return nil, err + } + + return prevBlockNode, nil +} + +// isMajorityVersion determines if a previous number of blocks in the chain +// starting with startNode are at least the minimum passed version. +func (b *BlockChain) isMajorityVersion(minVer uint32, startNode *blockNode, numRequired, numToCheck uint64) bool { + numFound := uint64(0) + iterNode := startNode + for i := uint64(0); i < numToCheck && iterNode != nil; i++ { + // This node has a version that is at least the minimum version. + if iterNode.version >= minVer { + numFound++ + } + + // Get the previous block node. This function is used over + // simply accessing iterNode.parent directly as it will + // dynamically create previous block nodes as needed. This + // helps allow only the pieces of the chain that are needed + // to remain in memory. + var err error + iterNode, err = b.getPrevNodeFromNode(iterNode) + if err != nil { + break + } + } + + return numFound >= numRequired +} + +// calcPastMedianTime calculates the median time of the previous few blocks +// prior to, and including, the passed block node. It is primarily used to +// validate new blocks have sane timestamps. +func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) { + // Genesis block. + if startNode == nil { + return btcwire.GenesisBlock.Header.Timestamp, nil + } + + // Create a slice of the previous few block timestamps used to calculate + // the median per the number defined by the constant medianTimeBlocks. + timestamps := make([]time.Time, medianTimeBlocks) + numNodes := 0 + iterNode := startNode + for i := 0; i < medianTimeBlocks && iterNode != nil; i++ { + timestamps[i] = iterNode.timestamp + numNodes++ + + // Get the previous block node. This function is used over + // simply accessing iterNode.parent directly as it will + // dynamically create previous block nodes as needed. This + // helps allow only the pieces of the chain that are needed + // to remain in memory. + var err error + iterNode, err = b.getPrevNodeFromNode(iterNode) + if err != nil { + return time.Time{}, err + } + } + + // Prune the slice to the actual number of available timestamps which + // will be fewer than desired near the beginning of the block chain + // and sort them. + timestamps = timestamps[:numNodes] + sort.Sort(timeSorter(timestamps)) + + // NOTE: bitcoind incorrectly calculates the median for even numbers of + // blocks. A true median averages the middle two elements for a set + // with an even number of elements in it. Since the constant for the + // previous number of blocks to be used is odd, this is only an issue + // for a few blocks near the beginning of the chain. I suspect this is + // an optimization even though the result is slightly wrong for a few + // of the first blocks since after the first few blocks, there will + // always be an odd number of blocks in the set per the constant. + // + // This code follows suit to ensure the same rules are used as bitcoind + // however, be aware that should the medianTimeBlocks constant ever be + // changed to an even number, this code will be wrong. + medianTimestamp := timestamps[numNodes/2] + return medianTimestamp, nil +} + +// getReorganizeNodes finds the fork point between the main chain and the passed +// node and returns a list of block nodes that would need to be detached from +// the main chain and a list of block nodes that would need to be attached to +// the fork point (which will be the end of the main chain after detaching the +// returned list of block nodes) in order to reorganize the chain such that the +// passed node is the new end of the main chain. The lists will be empty if the +// passed node is not on a side chain. +func (b *BlockChain) getReorganizeNodes(node *blockNode) (*list.List, *list.List) { + // Nothing to detach or attach if there is no node. + attachNodes := list.New() + detachNodes := list.New() + if node == nil { + return detachNodes, attachNodes + } + + // Find the fork point (if any) adding each block to the list of nodes + // to attach to the main tree. Push them onto the list in reverse order + // so they are attached in the appropriate order when iterating the list + // later. + ancestor := node + for ; ancestor.parent != nil; ancestor = ancestor.parent { + if ancestor.inMainChain { + break + } + attachNodes.PushFront(ancestor) + } + + // TODO(davec): Use prevNodeFromNode function in case the requested + // node is further back than the what is in memory. This shouldn't + // happen in the normal course of operation, but the ability to fetch + // input transactions of arbitrary blocks will likely to be exposed at + // some point and that could lead to an issue here. + + // Start from the end of the main chain and work backwards until the + // common ancestor adding each block to the list of nodes to detach from + // the main chain. + for n := b.bestChain; n != nil && n.parent != nil; n = n.parent { + if n.hash.IsEqual(ancestor.hash) { + break + } + detachNodes.PushBack(n) + } + + return detachNodes, attachNodes +} + +// connectBlock handles connecting the passed node/block to the end of the main +// (best) chain. +func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block) error { + // Make sure it's extending the end of the best chain. + prevHash := &block.MsgBlock().Header.PrevBlock + if b.bestChain != nil && !prevHash.IsEqual(b.bestChain.hash) { + return fmt.Errorf("connectBlock must be called with a block " + + "that extends the main chain") + } + + // Insert the block into the database which houses the main chain. + _, err := b.db.InsertBlock(block) + if err != nil { + return err + } + + // TODO(davec): Remove transactions from memory transaction pool. + + // Add the new node to the memory main chain indices for faster + // lookups. + node.inMainChain = true + b.index[*node.hash] = node + b.depNodes[*prevHash] = append(b.depNodes[*prevHash], node) + + // This node is now the end of the best chain. + b.bestChain = node + + // Notify the caller that the block was connected to the main chain. + // The caller would typically want to react with actions such as + // updating wallets. + b.sendNotification(NTBlockConnected, block) + + return nil +} + +// disconnectBlock handles disconnecting the passed node/block from the end of +// the main (best) chain. +func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block) error { + // Make sure the node being disconnected is the end of the best chain. + if b.bestChain == nil || !node.hash.IsEqual(b.bestChain.hash) { + return fmt.Errorf("disconnectBlock must be called with the " + + "block at the end of the main chain") + } + + // Remove the block from the database which houses the main chain. + prevNode, err := b.getPrevNodeFromNode(node) + if err != nil { + return err + } + err = b.db.DropAfterBlockBySha(prevNode.hash) + if err != nil { + return err + } + + // TODO(davec): Put transactions back in memory transaction pool. + + // Put block in the side chain cache. + node.inMainChain = false + b.blockCache[*node.hash] = block + + // This node's parent is now the end of the best chain. + b.bestChain = node.parent + + // Notify the caller that the block was disconnect from the main chain. + // The caller would typically want to react with actions such as + // updating wallets. + b.sendNotification(NTBlockDisconnected, block) + + return nil +} + +// reorganizeChain reorganizes the block chain by disconnecting the nodes in the +// detachNodes list and connecting the nodes in the attach list. It expects +// that the lists are already in the correct order and are in sync with the +// end of the current best chain. Specifically, nodes that are being +// disconnected must be in reverse order (think of popping them off +// the end of the chain) and nodes the are being attached must be in forwards +// order (think pushing them onto the end of the chain). +func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error { + // Ensure all of the needed side chain blocks are in the cache. + for e := attachNodes.Front(); e != nil; e = e.Next() { + n := e.Value.(*blockNode) + if _, exists := b.blockCache[*n.hash]; !exists { + return fmt.Errorf("block %v is missing from the side "+ + "chain block cache", n.hash) + } + } + + // Perform several checks to verify each block that needs to be attached + // to the main chain can be connected without violating any rules and + // without actually connecting the block. + // + // NOTE: bitcoind does these checks directly when it connects a block. + // The downside to that approach is that if any of these checks fail + // after disconneting some blocks or attaching others, all of the + // operations have to be rolled back to get the chain back into the + // state it was before the rule violation (or other failure). There are + // at least a couple of ways accomplish that rollback, but both involve + // tweaking the chain. This approach catches these issues before ever + // modifying the chain. + for e := attachNodes.Front(); e != nil; e = e.Next() { + n := e.Value.(*blockNode) + block := b.blockCache[*n.hash] + err := b.checkConnectBlock(n, block) + if err != nil { + return err + } + + } + + // Disconnect blocks from the main chain. + for e := detachNodes.Front(); e != nil; e = e.Next() { + n := e.Value.(*blockNode) + block, err := b.db.FetchBlockBySha(n.hash) + if err != nil { + return err + } + err = b.disconnectBlock(n, block) + if err != nil { + return err + } + } + + // Connect the new best chain blocks. + for e := attachNodes.Front(); e != nil; e = e.Next() { + n := e.Value.(*blockNode) + block := b.blockCache[*n.hash] + err := b.connectBlock(n, block) + if err != nil { + return err + } + delete(b.blockCache, *n.hash) + } + + return nil +} + +// connectBestChain handles connecting the passed block to the chain while +// respecting proper chain selection according to the chain with the most +// proof of work. In the typical case, the new block simply extends the main +// chain. However, it may also be extending (or creating) a side chain (fork) +// which may or may not end up becoming the main chain depending on which fork +// cumulatively has the most proof of work. +func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) error { + // We haven't selected a best chain yet or we are extending the main + // (best) chain with a new block. This is the most common case. + if b.bestChain == nil || node.parent.hash.IsEqual(b.bestChain.hash) { + // Perform several checks to verify the block can be connected + // to the main chain (including whatever reorganization might + // be necessary to get this node to the main chain) without + // violating any rules and without actually connecting the + // block. + err := b.checkConnectBlock(node, block) + if err != nil { + return err + } + + // Connect the block to the main chain. + err = b.connectBlock(node, block) + if err != nil { + return err + } + + // Connect the parent node to this node. + if node.parent != nil { + node.parent.children = append(node.parent.children, node) + } + + return nil + } + + // We're extending (or creating) a side chain which may or may not + // become the main chain, but in either case we need the block stored + // for future processing, so add the block to the side chain holding + // cache. + log.Debugf("Adding block %v to side chain cache", node.hash) + b.blockCache[*node.hash] = block + b.index[*node.hash] = node + + // We're extending (or creating) a side chain, but the cumulative + // work for this new side chain is not enough to make it the new chain. + if node.workSum.Cmp(b.bestChain.workSum) <= 0 { + // Connect the parent node to this node. + node.inMainChain = false + if node.parent != nil { + node.parent.children = append(node.parent.children, node) + } + return nil + } + + // We're extending (or creating) a side chain and the cumulative work + // for this new side chain is more than the old best chain, so this side + // chain needs to become the main chain. In order to accomplish that, + // find the common ancestor of both sides of the fork, disconnect the + // blocks that form the (now) old fork from the main chain, and attach + // the blocks that form the new chain to the main chain starting at the + // common ancenstor (the point where the chain forked). + detachNodes, attachNodes := b.getReorganizeNodes(node) + + // Reorganize the chain. + err := b.reorganizeChain(detachNodes, attachNodes) + if err != nil { + return err + } + + return nil +} + +// New returns a BlockChain instance for the passed bitcoin network using the +// provided backing database. It accepts a channel on which asynchronous +// notifications will be sent when various events take place. See the +// documentation for Notification and NotificationType for details on the +// types and contents of notifications. The provided channel can be nil if the +// caller is not interested in receiving notifications. +func New(db btcdb.Db, btcnet btcwire.BitcoinNet, c chan *Notification) *BlockChain { + b := BlockChain{ + db: db, + btcnet: btcnet, + notifications: c, + root: nil, + bestChain: nil, + index: make(map[btcwire.ShaHash]*blockNode), + depNodes: make(map[btcwire.ShaHash][]*blockNode), + orphans: make(map[btcwire.ShaHash]*orphanBlock), + prevOrphans: make(map[btcwire.ShaHash][]*orphanBlock), + blockCache: make(map[btcwire.ShaHash]*btcutil.Block), + } + return &b +} diff --git a/checkpoints.go b/checkpoints.go new file mode 100644 index 00000000..ba3a4233 --- /dev/null +++ b/checkpoints.go @@ -0,0 +1,258 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" + "github.com/conformal/btcscript" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" +) + +const CheckpointConfirmations = 20 + +// A checkpoint is a known good point in the block chain. Using checkpoints +// allows a few optimizations for old blocks during initial download and also +// prevents forks from old blocks. +// +// Each checkpoint is selected by the core developers based upon several +// factors. See the documentation for IsCheckpointCandidate for details +// on the selection criteria. +// +// As alluded to above, this package provides an IsCheckpointCandidate function +// which programatically identifies a block as a checkpoint candidate. The idea +// is that candidates are reviewed by a developer to make the final decision and +// then manually added to the list of checkpoints. +type Checkpoint struct { + Height int64 + Hash *btcwire.ShaHash +} + +// checkpointData groups checkpoints and other pertinent checkpoint data into +// a single type. +type checkpointData struct { + // Checkpoints ordered from oldest to newest. + checkpoints []Checkpoint + + // A map that will be automatically generated with the heights from + // the checkpoints as keys. + checkpointsByHeight map[int64]*Checkpoint +} + +// checkpointDataMainNet contains checkpoint data for the main network. +var checkpointDataMainNet = checkpointData{ + checkpoints: []Checkpoint{ + {11111, newShaHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, + {33333, newShaHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, + {74000, newShaHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, + {105000, newShaHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, + {134444, newShaHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, + {168000, newShaHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, + {193000, newShaHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, + {210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, + {216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, + {225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, + }, + checkpointsByHeight: nil, // Automatically generated in init. +} + +// checkpointDataTestNet contains checkpoint data for the test network. +var checkpointDataTestNet = checkpointData{ + checkpoints: []Checkpoint{ + {546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, + }, + checkpointsByHeight: nil, // Automatically generated in init. +} + +// newShaHashFromStr converts the passed big-endian hex string into a +// btcwire.ShaHash. It only differs from the one available in btcwire in that +// it ignores the error since it will only (and must only) be called with +// hard-coded, and therefore known good, hashes. +func newShaHashFromStr(hexStr string) *btcwire.ShaHash { + sha, _ := btcwire.NewShaHashFromStr(hexStr) + return sha +} + +// DisableCheckpoints provides a mechanism to disable validation against +// checkpoints which you DO NOT want to do in production. It is provided only +// for debug purposes. +func (b *BlockChain) DisableCheckpoints(disable bool) { + b.noCheckpoints = disable +} + +// checkpointData returns the appropriate checkpoint data set depending on the +// network configured for the block chain. +func (b *BlockChain) checkpointData() *checkpointData { + switch b.btcnet { + case btcwire.TestNet3: + return &checkpointDataTestNet + case btcwire.MainNet: + fallthrough + default: + return &checkpointDataMainNet + } +} + +// LatestCheckpoint returns the most recent checkpoint (regardless of whether it +// is already known). When checkpoints are disabled it will return nil. +func (b *BlockChain) LatestCheckpoint() *Checkpoint { + if b.noCheckpoints { + return nil + } + + checkpoints := b.checkpointData().checkpoints + return &checkpoints[len(checkpoints)-1] +} + +// verifyCheckpoint returns whether the passed block height and hash combination +// match the hard-coded checkpoint data. It also returns true if there is no +// checkpoint data for the passed block height. +func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool { + if b.noCheckpoints { + return true + } + + // Nothing to check if there is no checkpoint data for the block height. + checkpoint, exists := b.checkpointData().checkpointsByHeight[height] + if !exists { + return true + } + + return checkpoint.Hash.IsEqual(hash) +} + +// findClosestKnownCheckpoint finds the most recent checkpoint that is already +// available in the downloaded portion of the block chain and returns the +// associated block. It returns nil if a checkpoint can't be found (this should +// really only happen for blocks before the first checkpoint). +func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) { + if b.noCheckpoints { + return nil, nil + } + + // Loop backwards through the available checkpoints to find one that + // we already have. + checkpoints := b.checkpointData().checkpoints + clen := len(checkpoints) + for i := clen - 1; i >= 0; i-- { + if b.db.ExistsSha(checkpoints[i].Hash) { + block, err := b.db.FetchBlockBySha(checkpoints[i].Hash) + if err != nil { + return nil, err + } + return block, nil + } + } + return nil, nil +} + +// isNonstandardTransaction determines whether a transaction contains any +// scripts which are not one of the standard types. +func isNonstandardTransaction(tx *btcwire.MsgTx) bool { + // TODO(davec): Should there be checks for the input signature scripts? + + // Check all of the output public key scripts for non-standard scripts. + for _, txOut := range tx.TxOut { + scriptClass := btcscript.GetScriptClass(txOut.PkScript) + if scriptClass == btcscript.NonStandardTy { + return true + } + } + return false +} + +// IsCheckpointCandidate returns whether or not the passed block is a good +// checkpoint candidate. +// +// The factors used to determine a good checkpoint are: +// - The block must be in the main chain +// - The block must be at least 'CheckpointConfirmations' blocks prior to the +// current end of the main chain +// - The timestamps for the blocks before and after the checkpoint must have +// timestamps which are also before and after the checkpoint, respectively +// (due to the median time allowance this is not always the case) +// - The block must not contain any strange transaction such as those with +// nonstandard scripts +func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { + // Checkpoints must be enabled. + if b.noCheckpoints { + return false, fmt.Errorf("checkpoints are disabled") + } + + blockHash, err := block.Sha() + if err != nil { + return false, err + } + + // A checkpoint must be in the main chain. + if !b.db.ExistsSha(blockHash) { + return false, nil + } + + // A checkpoint must be at least CheckpointConfirmations blocks before + // the end of the main chain. + blockHeight := block.Height() + _, mainChainHeight, err := b.db.NewestSha() + if err != nil { + return false, err + } + if blockHeight > (mainChainHeight - CheckpointConfirmations) { + return false, nil + } + + // Get the previous block. + prevHash := &block.MsgBlock().Header.PrevBlock + prevBlock, err := b.db.FetchBlockBySha(prevHash) + if err != nil { + return false, err + } + + // Get the next block. + nextHash, err := b.db.FetchBlockShaByHeight(blockHeight + 1) + if err != nil { + return false, err + } + nextBlock, err := b.db.FetchBlockBySha(nextHash) + if err != nil { + return false, err + } + + // A checkpoint must have timestamps for the block and the blocks on + // either side of it in order (due to the median time allowance this is + // not always the case). + prevTime := prevBlock.MsgBlock().Header.Timestamp + curTime := block.MsgBlock().Header.Timestamp + nextTime := nextBlock.MsgBlock().Header.Timestamp + if prevTime.After(curTime) || nextTime.Before(curTime) { + return false, nil + } + + // A checkpoint must have transactions that only contain standard + // scripts. + for _, tx := range block.MsgBlock().Transactions { + if isNonstandardTransaction(tx) { + return false, nil + } + } + + return true, nil +} + +// init is called on package load. +func init() { + // Generate the checkpoint by height maps from the checkpoint data + // when the package loads. + checkpointInitializeList := []*checkpointData{ + &checkpointDataMainNet, + &checkpointDataTestNet, + } + for _, data := range checkpointInitializeList { + data.checkpointsByHeight = make(map[int64]*Checkpoint) + for i := range data.checkpoints { + checkpoint := &data.checkpoints[i] + data.checkpointsByHeight[checkpoint.Height] = checkpoint + } + } +} diff --git a/cov_report.sh b/cov_report.sh new file mode 100644 index 00000000..307f05b7 --- /dev/null +++ b/cov_report.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# This script uses gocov to generate a test coverage report. +# The gocov tool my be obtained with the following command: +# go get github.com/axw/gocov/gocov +# +# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH. + +# Check for gocov. +type gocov >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo >&2 "This script requires the gocov tool." + echo >&2 "You may obtain it with the following command:" + echo >&2 "go get github.com/axw/gocov/gocov" + exit 1 +fi +gocov test | gocov report diff --git a/difficulty.go b/difficulty.go new file mode 100644 index 00000000..c30ad7ac --- /dev/null +++ b/difficulty.go @@ -0,0 +1,285 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" + "github.com/conformal/btcwire" + "math/big" + "time" +) + +const ( + // targetTimespan is the desired amount of time that should elapse + // before block difficulty requirement is examined to determine how + // it should be changed in order to maintain the desired block + // generation rate. + targetTimespan = time.Hour * 24 * 14 + + // targetSpacing is the desired amount of time to generate each block. + targetSpacing = time.Minute * 10 + + // blocksPerRetarget is the number of blocks between each difficulty + // retarget. It is calculated based on the desired block generation + // rate. + blocksPerRetarget = int64(targetTimespan / targetSpacing) + + // retargetAdjustmentFactor is the adjustment factor used to limit + // the minimum and maximum amount of adjustment that can occur between + // difficulty retargets. + retargetAdjustmentFactor = 4 + + // minRetargetTimespan is the minimum amount of adjustment that can + // occur between difficulty retargets. It equates to 25% of the + // previous difficulty. + minRetargetTimespan = int64(targetTimespan / retargetAdjustmentFactor) + + // maxRetargetTimespan is the maximum amount of adjustment that can + // occur between difficulty retargets. It equates to 400% of the + // previous difficulty. + maxRetargetTimespan = int64(targetTimespan * retargetAdjustmentFactor) +) + +var ( + // bigOne is 1 represented as a big.Int. It is defined here to avoid + // the overhead of creating it multiple times. + bigOne = big.NewInt(1) + + // oneLsh256 is 1 shifted left 256 bits. It is defined here to avoid + // the overhead of creating it multiple times. + oneLsh256 = new(big.Int).Lsh(bigOne, 256) + + // powLimit is the highest proof of work value a bitcoin block can have. + // It is the value 2^224 - 1. + powLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) +) + +// ShaHashToBig converts a btcwire.ShaHash into a big.Int that can be used to +// perform math comparisons. +func ShaHashToBig(hash *btcwire.ShaHash) *big.Int { + // A ShaHash is in little-endian, but the big package wants the bytes + // in big-endian. Reverse them. ShaHash.Bytes makes a copy, so it + // is safe to modify the returned buffer. + buf := hash.Bytes() + blen := len(buf) + for i := 0; i < blen/2; i++ { + buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i] + } + + return new(big.Int).SetBytes(buf) +} + +// CompactToBig converts a compact representation of a whole number N to an +// unsigned 32-bit number. The representation is similar to IEEE754 floating +// point numbers. +// +// Like IEEE754 floating point, there are three basic components: the sign, +// the exponent, and the mantissa. They are broken out as follows: +// +// * the most significant 8 bits represent the unsigned base 256 exponent +// * bit 23 (the 24th bit) represents the sign bit +// * the least significant 23 bits represent the mantissa +// +// ------------------------------------------------- +// | Exponent | Sign | Mantissa | +// ------------------------------------------------- +// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | +// ------------------------------------------------- +// +// The formula to calculate N is: +// N = (-1^sign) * mantissa * 256^(exponent-3) +// +// This compact form is only used in bitcoin to encode unsigned 256-bit numbers +// which represent difficulty targets, thus there really is not a need for a +// sign bit, but it is implemented here to stay consistent with bitcoind. +func CompactToBig(compact uint32) *big.Int { + // Extract the mantissa, sign bit, and exponent. + mantissa := compact & 0x007fffff + isNegative := compact&0x00800000 != 0 + exponent := uint(compact >> 24) + + // Since the base for the exponent is 256, the exponent can be treated + // as the number of bytes to represent the full 256-bit number. So, + // treat the exponent as the number of bytes and shift the mantissa + // right or left accordingly. This is equivalent to: + // N = mantissa * 256^(exponent-3) + var bn *big.Int + if exponent <= 3 { + mantissa >>= 8 * (3 - exponent) + bn = big.NewInt(int64(mantissa)) + } else { + bn = big.NewInt(int64(mantissa)) + bn.Lsh(bn, 8*(exponent-3)) + } + + // Make it negative if the sign bit is set. + if isNegative { + bn = bn.Neg(bn) + } + + return bn +} + +// BigToCompact converts a whole number N to a compact representation using +// an unsigned 32-bit number. The compact representation only provides 23 bits +// of precision, so values larger than (2^23 - 1) only encode the most +// significant digits of the number. See CompactToBig for details. +func BigToCompact(n *big.Int) uint32 { + // No need to do any work if it's zero. + if n.Sign() == 0 { + return 0 + } + + // Since the base for the exponent is 256, the exponent can be treated + // as the number of bytes. So, shift the number right or left + // accordingly. This is equivalent to: + // mantissa = mantissa / 256^(exponent-3) + var mantissa uint32 + exponent := uint(len(n.Bytes())) + if exponent <= 3 { + mantissa = uint32(n.Bits()[0]) + mantissa <<= 8 * (3 - exponent) + } else { + // Use a copy to avoid modifying the caller's original number. + tn := new(big.Int).Set(n) + mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0]) + } + + // When the mantissa already has the sign bit set, the number is too + // large to fit into the available 23-bits, so divide the number by 256 + // and increment the exponent accordingly. + if mantissa&0x00800000 != 0 { + mantissa >>= 8 + exponent++ + } + + // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit + // int and return it. + compact := uint32(exponent<<24) | mantissa + if n.Sign() < 0 { + compact |= 0x00800000 + } + return compact +} + +// calcWork calculates a work value from difficulty bits. Bitcoin increases +// the difficulty for generating a block by decreasing the value which the +// generated hash must be less than. This difficulty target is stored in each +// block header using a compact representation as described in the documenation +// for CompactToBig. The main chain is selected by choosing the chain that has +// the most proof of work (highest difficulty). Since a lower target difficulty +// value equates to higher actual difficulty, the work value which will be +// accumulated must be the inverse of the difficulty. Also, in order to avoid +// potential division by zero and really small floating point numbers, add 1 to +// the denominator and multiply the numerator by 2^256. +func calcWork(bits uint32) *big.Rat { + // (1 << 256) / (difficultyNum + 1) + difficultyNum := CompactToBig(bits) + denominator := new(big.Int).Add(difficultyNum, bigOne) + return new(big.Rat).SetFrac(oneLsh256, denominator) +} + +// calcEasiestDifficulty calculates the easiest possible difficulty that a block +// can have given starting difficulty bits and a duration. It is mainly used to +// verify that claimed proof of work by a block is sane as compared to a +// known good checkpoint. +func calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { + // Convert types used in the calculations below. + durationVal := int64(duration) + adjustmentFactor := big.NewInt(retargetAdjustmentFactor) + + // TODO(davec): Testnet has special rules. + + // Since easier difficulty equates to higher numbers, the easiest + // difficulty for a given duration is the largest value possible given + // the number of retargets for the duration and starting difficulty + // multiplied by the max adjustment factor. + newTarget := CompactToBig(bits) + for durationVal > 0 && newTarget.Cmp(powLimit) < 0 { + newTarget.Mul(newTarget, adjustmentFactor) + durationVal -= maxRetargetTimespan + } + + // Limit new value to the proof of work limit. + if newTarget.Cmp(powLimit) > 0 { + newTarget.Set(powLimit) + } + + return BigToCompact(newTarget) +} + +// calcNextRequiredDifficulty calculates the required difficulty for the block +// after the passed previous block node based on the difficulty retarget rules. +func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode) (uint32, error) { + // Genesis block. + if lastNode == nil { + return BigToCompact(powLimit), nil + } + + // Return the previous block's difficulty requirements if this block + // is not at a difficulty retarget interval. + if (lastNode.height+1)%blocksPerRetarget != 0 { + // TODO(davec): Testnet has special rules. + return lastNode.bits, nil + } + + // Get the block node at the previous retarget (targetTimespan days + // worth of blocks). + firstNode := lastNode + for i := int64(0); i < blocksPerRetarget-1 && firstNode != nil; i++ { + // Get the previous block node. This function is used over + // simply accessing firstNode.parent directly as it will + // dynamically create previous block nodes as needed. This + // helps allow only the pieces of the chain that are needed + // to remain in memory. + var err error + firstNode, err = b.getPrevNodeFromNode(firstNode) + if err != nil { + return 0, err + } + } + + if firstNode == nil { + return 0, fmt.Errorf("unable to obtain previous retarget block") + } + + // Limit the amount of adjustment that can occur to the previous + // difficulty. + actualTimespan := lastNode.timestamp.UnixNano() - firstNode.timestamp.UnixNano() + adjustedTimespan := actualTimespan + if actualTimespan < minRetargetTimespan { + adjustedTimespan = minRetargetTimespan + } else if actualTimespan > maxRetargetTimespan { + adjustedTimespan = maxRetargetTimespan + } + + // Calculate new target difficulty as: + // currentDifficulty * (adjustedTimespan / targetTimespan) + // The result uses integer division which means it will be slightly + // rounded down. Bitcoind also uses integer division to calculate this + // result. + oldTarget := CompactToBig(lastNode.bits) + newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan)) + newTarget.Div(newTarget, big.NewInt(int64(targetTimespan))) + + // Limit new value to the proof of work limit. + if newTarget.Cmp(powLimit) > 0 { + newTarget.Set(powLimit) + } + + // Log new target difficulty and return it. The new target logging is + // intentionally converting the bits back to a number instead of using + // newTarget since conversion to the compact representation loses + // precision. + newTargetBits := BigToCompact(newTarget) + log.Debugf("Difficulty retarget at block height %d", lastNode.height+1) + log.Debugf("Old target %08x (%064x)", lastNode.bits, oldTarget) + log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits)) + log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v", + time.Duration(actualTimespan), time.Duration(adjustedTimespan), + targetTimespan) + + return newTargetBits, nil +} diff --git a/doc.go b/doc.go new file mode 100644 index 00000000..a96b6ad8 --- /dev/null +++ b/doc.go @@ -0,0 +1,124 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package btcchain implements bitcoin block handling and chain selection rules. + +The bitcoin block handling and chain selection rules are an integral, and quite +likely the most important, part of bitcoin. Unfortunately, at the time of +this writing, these rules are also largely undocumented and had to be +ascertained from the bitcoind source code. At its core, bitcoin is a +distributed consensus of which blocks are valid and which ones will comprise the +main block chain (public ledger) that ultimately determines accepted +transactions, so it is extremely important that fully validating nodes agree on +all rules. + +At a high level, this package provides support for inserting new blocks into +the block chain according to the aforementioned rules. It includes +functionality such as rejecting duplicate blocks, ensuring blocks and +transactions follow all rules, orphan handling, and best chain selection along +with reorganization. + +Since this package does not deal with other bitcoin specifics such as network +communication or wallets, it provides a notification system which gives the +caller a high level of flexibility in how they want to react to certain events +such as orphan blocks which need their parents requested and newly connected +main chain blocks which might result in wallet updates. + +Bitcoin Chain Processing Overview + +Before a block is allowed into the block chain, it must go through an intensive +series of validation rules. The following list serves as a general outline of +those rules to provide some intuition into what is going on under the hood, but +is by no means exhaustive: + + - Reject duplicate blocks + - Perform a series of sanity checks on the block and its transactions such as + verifying proof of work, timestamps, number and character of transactions, + transaction amounts, script complexity, and merkle root calculations + - Compare the block against predetermined checkpoints for expected timestamps + and difficulty based on elapsed time since the checkpoint + - Save the most recent orphan blocks for a limited time in case their parent + blocks become available + - Stop processing if the block is an orphan as the rest of the processing + depends on the block's position within the block chain + - Perform a series of more thorough checks that depend on the block's position + within the block chain such as verifying block difficulties adhere to + difficulty retarget rules, timestamps are after the median of the last + several blocks, all transactions are finalized, checkpoint blocks match, and + block versions are in line with the previous blocks + - Determine how the block fits into the chain and perform different actions + accordingly in order to ensure any side chains which have higher difficulty + than the main chain become the new main chain + - When a block is being connected to the main chain (either through + reorganization of a side chain to the main chain or just extending the + main chain), perform further checks on the block's transactions such as + verifying transaction duplicates, script complexity for the combination of + connected scripts, coinbase maturity, double spends, and connected + transaction values + - Run the transaction scripts to verify the spender is allowed to spend the + coins + - Insert the block into the block database + +Block Processing Example + +The following example program demonstrates processing a block. This example +intentionally causes an error by attempting to process a duplicate block. + + package main + + import ( + "fmt" + "github.com/conformal/btcchain" + "github.com/conformal/btcdb" + _ "github.com/conformal/btcdb/sqlite3" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + ) + + func main() { + // First, we create a new database to store the accepted blocks into. + // Typically this would be opening an existing database, but we create + // a new db here so this is a complete working example. + db, err := btcdb.CreateDB("sqlite", "example.db") + if err != nil { + fmt.Printf("Failed to create database: %v\n", err) + return + } + defer db.Close() + + // Create a new BlockChain instance using the underlying database for + // the main bitcoin network and ignore notifications. + chain := btcchain.New(db, btcwire.MainNet, nil) + + // Process a block. For this example, we are going to intentionally + // cause an error by trying to process the genesis block which already + // exists. + block := btcutil.NewBlock(&btcwire.GenesisBlock, btcwire.ProtocolVersion) + err = chain.ProcessBlock(block) + if err != nil { + fmt.Printf("Failed to process block: %v\n", err) + return + } + } + +Errors + +Errors returned by this package are either the raw errors provided by underlying +calls or of type btcchain.RuleError. This allows the caller to differentiate +between unexpected errors, such as database errors, versus errors due to rule +violations through type assertions. + +Bitcoin Improvement Proposals + +This package includes spec changes outlined by the following BIPs: + + BIP0016 (https://en.bitcoin.it/wiki/BIP_0016) + BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) + +Other important information + +This package does not yet implement all of the unique rules for testnet. +*/ +package btcchain diff --git a/internal_test.go b/internal_test.go new file mode 100644 index 00000000..c5c9a404 --- /dev/null +++ b/internal_test.go @@ -0,0 +1,28 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +This test file is part of the btcchain package rather than than the +btcchain_test package so it can bridge access to the internals to properly test +cases which are either not possible or can't reliably be tested via the public +interface. The functions are only exported while the tests are being run. +*/ + +package btcchain + +import ( + "github.com/conformal/btcutil" +) + +// TstCheckBlockSanity makes the internal checkBlockSanity function available to +// the test package. +func TstCheckBlockSanity(block *btcutil.Block) error { + return checkBlockSanity(block) +} + +// TstSetCoinbaseMaturity makes the ability to set the coinbase maturity +// available to the test package. +func TstSetCoinbaseMaturity(maturity int64) { + coinbaseMaturity = maturity +} diff --git a/log.go b/log.go new file mode 100644 index 00000000..0c273bd3 --- /dev/null +++ b/log.go @@ -0,0 +1,65 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "errors" + "github.com/conformal/seelog" + "io" +) + +// log is a logger that is initialized with no output filters. This +// means the package will not perform any logging by default until the caller +// requests it. +var log seelog.LoggerInterface + +// The default amount of logging is none. +func init() { + DisableLog() +} + +// DisableLog disables all library log output. Logging output is disabled +// by default until either UseLogger or SetLogWriter are called. +func DisableLog() { + log = seelog.Disabled +} + +// UseLogger uses a specified Logger to output package logging info. +// This should be used in preference to SetLogWriter if the caller is also +// using seelog. +func UseLogger(logger seelog.LoggerInterface) { + log = logger +} + +// SetLogWriter uses a specified io.Writer to output package logging info. +// This allows a caller to direct package logging output without needing a +// dependency on seelog. If the caller is also using seelog, UseLogger should +// be used instead. +func SetLogWriter(w io.Writer) error { + if w == nil { + return errors.New("nil writer") + } + + l, err := seelog.LoggerFromWriterWithMinLevel(w, seelog.TraceLvl) + if err != nil { + return err + } + + UseLogger(l) + return nil +} + +// LogClosure is a closure that can be printed with %v to be used to +// generate expensive-to-create data for a detailed log level and avoid doing +// the work if the data isn't printed. +type logClosure func() string + +func (c logClosure) String() string { + return c() +} + +func newLogClosure(c func() string) logClosure { + return logClosure(c) +} diff --git a/merkle.go b/merkle.go new file mode 100644 index 00000000..e0aa0053 --- /dev/null +++ b/merkle.go @@ -0,0 +1,114 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "math" +) + +// nextPowerOfTwo returns the next highest power of two from a given number if +// it is not already a power of two. This is a helper function used during the +// calculation of a merkle tree. +func nextPowerOfTwo(n int) int { + // Return the number if it's already a power of 2. + if n&(n-1) == 0 { + return n + } + + // Figure out and return the next power of two. + exponent := uint(math.Log2(float64(n))) + 1 + return 1 << exponent // 2^exponent +} + +// hashMerkleBranches takes two hashes, treated as the left and right tree +// nodes, and returns the hash of their concatenation. This is a helper +// function used to during generatation of a merkle tree. +func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire.ShaHash { + // Concatenate the left and right nodes. + var sha [btcwire.HashSize * 2]byte + copy(sha[:btcwire.HashSize], left.Bytes()) + copy(sha[btcwire.HashSize:], right.Bytes()) + + // Create a new sha hash from the double sha 256. Ignore the error + // here since SetBytes can't fail here due to the fact DoubleSha256 + // always returns a []byte of the right size regardless of input. + newSha, _ := btcwire.NewShaHash(btcwire.DoubleSha256(sha[:])) + return newSha +} + +// BuildMerkleTreeStore creates a merkle tree from block, stores it using a +// linear array, and returns a slice of the backing array. A linear array was +// chosen as opposed to an actual tree structure since it uses about half as +// much memory. The following describes a merkle tree and how it is stored in +// a linear array. +// +// A merkle tree is a tree in which every non-leaf node is the hash of its +// children nodes. A diagram depicting how this works for bitcoin transactions +// where h(x) is a double sha256 follows: +// +// root = h1234 = h(h12 + h34) +// / \ +// h12 = h(h1 + h2) h34 = h(h3 + h4) +// / \ / \ +// h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4) +// +// The above stored as a linear array is as follows: +// +// [h1 h2 h3 h4 h12 h34 root] +// +// As the above shows, the merkle root is always the last element in the array. +// +// The number of inputs is not always a power of two which results in a +// balanced tree structure as above. In that case, parent nodes with no +// children are also zero and parent nodes with only a single left node +// are calculated by concatenating the left node with itself before hashing. +// Since this function uses nodes that are pointers to the hashes, empty nodes +// will be nil. +func BuildMerkleTreeStore(block *btcutil.Block) []*btcwire.ShaHash { + numTransactions := len(block.MsgBlock().Transactions) + + // Calculate how many entries are required to hold the binary merkle + // tree as a linear array and create an array of that size. + nextPoT := nextPowerOfTwo(numTransactions) + arraySize := nextPoT*2 - 1 + merkles := make([]*btcwire.ShaHash, arraySize) + + // Create the base transaction shas and populate the array with them. + for i := 0; i < numTransactions; i++ { + // Ignore the error since the only reason TxSha can fail is + // if the index is out of range which is impossible here due + // to using a loop over the existing transactions. + sha, _ := block.TxSha(i) + merkles[i] = sha + } + + // Start the array offset after the last transaction and adjusted to the + // next power of two. + offset := nextPoT + for i := 0; i < arraySize-1; i += 2 { + switch { + // When there is no left child node, the parent is nil too. + case merkles[i] == nil: + merkles[offset] = nil + + // When there is no right child, the parent is generated by + // hashing the concatenation of the left child with itself. + case merkles[i+1] == nil: + newSha := hashMerkleBranches(merkles[i], merkles[i]) + merkles[offset] = newSha + + // The normal case sets the parent node to the double sha256 + // of the concatentation of the left and right children. + default: + newSha := hashMerkleBranches(merkles[i], merkles[i+1]) + merkles[offset] = newSha + } + offset++ + } + + return merkles +} diff --git a/merkle_test.go b/merkle_test.go new file mode 100644 index 00000000..cd2d4532 --- /dev/null +++ b/merkle_test.go @@ -0,0 +1,24 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "github.com/conformal/btcchain" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "testing" +) + +// TestMerkle tests the BuildMerkleTreeStore API. +func TestMerkle(t *testing.T) { + block := btcutil.NewBlock(&Block100000, btcwire.ProtocolVersion) + merkles := btcchain.BuildMerkleTreeStore(block) + calculatedMerkleRoot := merkles[len(merkles)-1] + wantMerkle := &Block100000.Header.MerkleRoot + if !wantMerkle.IsEqual(calculatedMerkleRoot) { + t.Errorf("BuildMerkleTreeStore: merkle root mismatch - "+ + "got %v, want %v", calculatedMerkleRoot, wantMerkle) + } +} diff --git a/notifications.go b/notifications.go new file mode 100644 index 00000000..5cc544f2 --- /dev/null +++ b/notifications.go @@ -0,0 +1,76 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" +) + +// NotificationType represents the type of a notification message. +type NotificationType int + +// Constants for the type of a notification message. +const ( + // NTOrphanBlock indicates an orphan block was processed and the + // associated block hash is the root of all known orphans which should + // be used to request the missing blocks. + NTOrphanBlock NotificationType = iota + + // NTBlockAccepted indicates the associated block was accepted into + // the block chain. Note that this does not necessarily mean it was + // added to the main chain. For that, use NTBlockConnected. + NTBlockAccepted + + // NTBlockConnected indicates the associated block was connected to the + // main chain. + NTBlockConnected + + // NTBlockDisconnected indicates the associated block was disconnected + // from the main chain. + NTBlockDisconnected +) + +// notificationTypeStrings is a map of notification types back to their constant +// names for pretty printing. +var notificationTypeStrings = map[NotificationType]string{ + NTOrphanBlock: "NTOrphanBlock", + NTBlockAccepted: "NTBlockAccepted", + NTBlockConnected: "NTBlockConnected", + NTBlockDisconnected: "NTBlockDisconnected", +} + +// String returns the NotificationType in human-readable form. +func (n NotificationType) String() string { + if s, ok := notificationTypeStrings[n]; ok { + return s + } + return fmt.Sprintf("Unknown Notification Type (%d)", int(n)) +} + +// Notification defines an asynchronous notification that is sent to the caller +// over the notification channel provided during the call to New and consists +// of a notification type as well as associated data that depends on the type as +// follows: +// - NTOrphanBlock: *btcwire.ShaHash +// - NTBlockAccepted: *btcutil.Block +// - NTBlockConnected: *btcutil.Block +// - NTBlockDisconnected: *btcutil.Block +type Notification struct { + Type NotificationType + Data interface{} +} + +// sendNotification sends a notification with the passed type and data if the +// caller requested notifications by providing a channel in the call to New. +func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { + // Ignore it if the caller didn't request notifications. + if b.notifications == nil { + return + } + + // Generate and send the notification. + n := Notification{Type: typ, Data: data} + b.notifications <- &n +} diff --git a/process.go b/process.go new file mode 100644 index 00000000..5b9eef98 --- /dev/null +++ b/process.go @@ -0,0 +1,175 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" +) + +// RuleError identifies a rule violation. It is used to indicate that +// processing of a block or transaction failed due to one of the many validation +// rules. The caller can use type assertions to determine if a failure was +// specifically due to a rule violation. +type RuleError string + +// Error satisfies the error interface to print human-readable errors. +func (e RuleError) Error() string { + return string(e) +} + +// blockExists determines whether a block with the given hash exists either in +// the main chain or any side chains. +func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { + // Check memory chain first (could be main chain or side chain blocks). + if _, ok := b.index[*hash]; ok { + return true + } + + // Check in database (rest of main chain not in memory). + return b.db.ExistsSha(hash) +} + +// processOrphans determines if there are any orphans which depend on the passed +// block hash (they are no longer orphans if true) and potentially accepts them. +// It repeats the process for the newly accepted blocks (to detect further +// orphans which may no longer be orphans) until there are no more. +func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { + processHashes := []*btcwire.ShaHash{hash} + for len(processHashes) > 0 { + // Pop the first hash to process from the slice. + processHash := processHashes[0] + processHashes = processHashes[1:] + + // Look up all orphans that are parented by the block we just + // accepted. This will typically only be one, but it could + // be multiple if multiple blocks are mined and broadcast + // around the same time. The one with the most proof of work + // will eventually win out. + for _, orphan := range b.prevOrphans[*processHash] { + // Remove the orphan from the orphan pool. + // It's safe to ignore the error on Sha since the hash + // is already cached. + orphanHash, _ := orphan.block.Sha() + b.removeOrphanBlock(orphan) + + // Potentially accept the block into the block chain. + err := b.maybeAcceptBlock(orphan.block) + if err != nil { + return err + } + + // Add this block to the list of blocks to process so + // any orphan blocks that depend on this block are + // handled too. + processHashes = append(processHashes, orphanHash) + } + } + return nil +} + +// ProcessBlock is the main workhorse for handling insertion of new blocks into +// the block chain. It includes functionality such as rejecting duplicate +// blocks, ensuring blocks follow all rules, orphan handling, and insertion into +// the block chain along with best chain selection and reorganization. +func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { + blockHash, err := block.Sha() + if err != nil { + return err + } + log.Debugf("Processing block %v", blockHash) + + // The block must not already exist in the main chain or side chains. + if b.blockExists(blockHash) { + str := fmt.Sprintf("already have block %v", blockHash) + return RuleError(str) + } + + // The block must not already exist as an orphan. + if _, exists := b.orphans[*blockHash]; exists { + str := fmt.Sprintf("already have block (orphan) %v", blockHash) + return RuleError(str) + } + + // Perform preliminary sanity checks on the block and its transactions. + err = checkBlockSanity(block) + if err != nil { + return err + } + + // Find the latest known checkpoint and perform some additional checks + // based on the checkpoint. This provides a few nice properties such as + // preventing forks from blocks before the last checkpoint, rejecting + // easy to mine, but otherwise bogus, blocks that could be used to eat + // memory, and ensuring expected (versus claimed) proof of work + // requirements since the last checkpoint are met. + blockHeader := block.MsgBlock().Header + checkpointBlock, err := b.findLatestKnownCheckpoint() + if err != nil { + return err + } + if checkpointBlock != nil { + // Ensure the block timestamp is after the checkpoint timestamp. + checkpointHeader := checkpointBlock.MsgBlock().Header + checkpointTime := checkpointHeader.Timestamp + if blockHeader.Timestamp.Before(checkpointTime) { + str := fmt.Sprintf("block %v has timestamp %v before "+ + "last checkpoint timestamp %v", blockHash, + blockHeader.Timestamp, checkpointTime) + return RuleError(str) + } + + // Even though the checks prior to now have already ensured the + // proof of work exceeds the claimed amount, the claimed amount + // is a field in the block header which could be forged. This + // check ensures the proof of work is at least the minimum + // expected based on elapsed time since the last checkpoint and + // maximum adjustment allowed by the retarget rules. + duration := blockHeader.Timestamp.Sub(checkpointTime) + requiredTarget := CompactToBig(calcEasiestDifficulty( + checkpointHeader.Bits, duration)) + currentTarget := CompactToBig(blockHeader.Bits) + if currentTarget.Cmp(requiredTarget) > 0 { + str := fmt.Sprintf("block target difficulty of %064x "+ + "is too low when compared to the previous "+ + "checkpoint", currentTarget) + return RuleError(str) + } + } + + // Handle orphan blocks. + prevHash := &blockHeader.PrevBlock + if !prevHash.IsEqual(zeroHash) && !b.blockExists(prevHash) { + // Add the orphan block to the orphan pool. + log.Infof("Adding orphan block %v", blockHash) + b.addOrphanBlock(block) + + // Get the hash for the head of the orphaned block chain for + // this block and notify the caller so it can request missing + // blocks. + orphanRoot := b.getOrphanRoot(prevHash) + b.sendNotification(NTOrphanBlock, orphanRoot) + return nil + } + + // The block has passed all context independent checks and appears sane + // enough to potentially accept it into the block chain. + err = b.maybeAcceptBlock(block) + if err != nil { + return err + } + + // Accept any orphan blocks that depend on this block (they are no + // longer orphans) and repeat for those accepted blocks until there are + // no more. + err = b.processOrphans(blockHash) + if err != nil { + return err + } + + log.Debugf("Accepted block %v", blockHash) + return nil +} diff --git a/reorganization_test.go b/reorganization_test.go new file mode 100644 index 00000000..70fcf054 --- /dev/null +++ b/reorganization_test.go @@ -0,0 +1,133 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "compress/bzip2" + "encoding/binary" + "github.com/conformal/btcchain" + "github.com/conformal/btcdb" + _ "github.com/conformal/btcdb/sqlite3" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "io" + "os" + "path/filepath" + "strings" + "testing" +) + +// TestReorganization loads a set of test blocks which force a chain +// reorganization to test the block chain handling code. +// The test blocks were originally from a post on the bitcoin talk forums: +// https://bitcointalk.org/index.php?topic=46370.msg577556#msg577556 +func TestReorganization(t *testing.T) { + // Intentionally load the side chain blocks out of order to ensure + // orphans are handled properly along with chain reorganization. + testFiles := [...]string{ + "blk_0_to_4.dat.bz2", + "blk_4A.dat.bz2", + "blk_5A.dat.bz2", + "blk_3A.dat.bz2", + } + + var blocks []*btcutil.Block + for _, file := range testFiles { + blockTmp, err := loadBlocks(file) + if err != nil { + t.Errorf("Error loading file: %v\n", err) + } + for _, block := range blockTmp { + blocks = append(blocks, block) + } + } + + t.Logf("Number of blocks: %v\n", len(blocks)) + + dbname := "chaintest" + _ = os.Remove(dbname) + db, err := btcdb.CreateDB("sqlite", dbname) + if err != nil { + t.Errorf("Error creating db: %v\n", err) + } + // Clean up + defer os.Remove(dbname) + defer db.Close() + + // Since we're not dealing with the real block chain, disable + // checkpoints and set the coinbase maturity to 1. + blockChain := btcchain.New(db, btcwire.MainNet, nil) + blockChain.DisableCheckpoints(true) + btcchain.TstSetCoinbaseMaturity(1) + + for i := 1; i < len(blocks); i++ { + err = blockChain.ProcessBlock(blocks[i]) + if err != nil { + t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) + return + } + } + db.Sync() + + return +} + +// loadBlocks reads files containing bitcoin block data (gzipped but otherwise +// in the format bitcoind writes) from disk and returns them as an array of +// btcutil.Block. This is largely borrowed from the test code in btcdb. +func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { + filename = filepath.Join("testdata/", filename) + + var network = btcwire.MainNet + var dr io.Reader + var fi io.ReadCloser + + fi, err = os.Open(filename) + if err != nil { + return + } + + if strings.HasSuffix(filename, ".bz2") { + dr = bzip2.NewReader(fi) + } else { + dr = fi + } + defer fi.Close() + + var block *btcutil.Block + + err = nil + for height := int64(1); err == nil; height++ { + var rintbuf uint32 + err = binary.Read(dr, binary.LittleEndian, &rintbuf) + if err == io.EOF { + // hit end of file at expected offset: no warning + height-- + err = nil + break + } + if err != nil { + break + } + if rintbuf != uint32(network) { + break + } + err = binary.Read(dr, binary.LittleEndian, &rintbuf) + blocklen := rintbuf + + rbytes := make([]byte, blocklen) + + // read block + dr.Read(rbytes) + + block, err = btcutil.NewBlockFromBytes(rbytes, btcwire.ProtocolVersion) + if err != nil { + return + } + blocks = append(blocks, block) + } + + return +} diff --git a/scriptval.go b/scriptval.go new file mode 100644 index 00000000..37eec3b3 --- /dev/null +++ b/scriptval.go @@ -0,0 +1,136 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" + "github.com/conformal/btcscript" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "math" + "time" +) + +// txValidate is used to track results of validating scripts for each +// transaction input index. +type txValidate struct { + txIndex int + err error +} + +// txProcessList +type txProcessList struct { + txsha btcwire.ShaHash + tx *btcwire.MsgTx +} + +// validateTxIn validates a the script pair for the passed spending transaction +// (along with the specific input index) and origin transaction (with the +// specific output index). +func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, pver uint32, timestamp time.Time, originTx *btcwire.MsgTx) error { + // If the input transaction has no previous input, there is nothing + // to check. + originTxIdx := txin.PreviousOutpoint.Index + if originTxIdx == math.MaxUint32 { + return nil + } + + if originTxIdx >= uint32(len(originTx.TxOut)) { + originTxSha := &txin.PreviousOutpoint.Hash + log.Warnf("unable to locate source tx %v spending tx %v", originTxSha, &txSha) + return fmt.Errorf("invalid index %x", originTxIdx) + } + + sigScript := txin.SignatureScript + pkScript := originTx.TxOut[originTxIdx].PkScript + engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, tx, + pver, timestamp.After(btcscript.Bip16Activation)) + if err != nil { + return err + } + + err = engine.Execute() + if err != nil { + log.Warnf("validate of input %v failed: %v", txInIdx, err) + return err + } + + return nil +} + +// validateAllTxIn validates the scripts for all of the passed transaction +// inputs using multiple goroutines. +func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, pver uint32, timestamp time.Time, job []*btcwire.TxIn, txStore map[btcwire.ShaHash]*txData) (err error) { + c := make(chan txValidate) + resultErrors := make([]error, len(job)) + + var currentItem int + var completedItems int + + processFunc := func(txInIdx int) { + log.Tracef("validating tx %v input %v len %v", + &txsha, currentItem, len(job)) + txin := job[txInIdx] + originTxSha := &txin.PreviousOutpoint.Hash + origintxidx := txin.PreviousOutpoint.Index + + var originTx *btcwire.MsgTx + if origintxidx != math.MaxUint32 { + txInfo, ok := txStore[*originTxSha] + if !ok { + //wtf? + fmt.Printf("obj not found in txStore %v", + originTxSha) + } + originTx = txInfo.tx + } + err := validateTxIn(txInIdx, job[txInIdx], txsha, txValidator, + pver, timestamp, originTx) + r := txValidate{txInIdx, err} + c <- r + } + for currentItem = 0; currentItem < len(job) && currentItem < 16; currentItem++ { + go processFunc(currentItem) + } + for completedItems < len(job) { + select { + case result := <-c: + completedItems++ + resultErrors[result.txIndex] = result.err + // would be nice to determine if we could stop + // on early errors here instead of running more. + if err == nil { + err = result.err + } + + if currentItem < len(job) { + go processFunc(currentItem) + currentItem++ + } + } + } + for i := 0; i < len(job); i++ { + if resultErrors[i] != nil { + log.Warnf("tx %v failed input %v, err %v", &txsha, i, resultErrors[i]) + } + } + return +} + +// checkBlockScripts executes and validates the scripts for all transactions in +// the passed block. +func checkBlockScripts(block *btcutil.Block, txStore map[btcwire.ShaHash]*txData) error { + pver := block.ProtocolVersion() + timestamp := block.MsgBlock().Header.Timestamp + for i, tx := range block.MsgBlock().Transactions { + txHash, _ := block.TxSha(i) + err := validateAllTxIn(txHash, tx, pver, timestamp, tx.TxIn, txStore) + if err != nil { + return err + } + } + + return nil +} diff --git a/test_coverage.txt b/test_coverage.txt new file mode 100644 index 00000000..736687db --- /dev/null +++ b/test_coverage.txt @@ -0,0 +1,77 @@ + +github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (12/12) +github.com/conformal/btcchain/chain.go BlockChain.getOrphanRoot 100.00% (7/7) +github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) +github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) +github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) +github.com/conformal/btcchain/difficulty.go calcWork 100.00% (3/3) +github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) +github.com/conformal/btcchain/chain.go New 100.00% (2/2) +github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) +github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) +github.com/conformal/btcchain/process.go BlockChain.processOrphans 91.67% (11/12) +github.com/conformal/btcchain/txlookup.go disconnectTransactions 90.91% (10/11) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxList 88.57% (31/35) +github.com/conformal/btcchain/scriptval.go validateAllTxIn 87.88% (29/33) +github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 87.50% (14/16) +github.com/conformal/btcchain/scriptval.go checkBlockScripts 87.50% (7/8) +github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 86.96% (20/23) +github.com/conformal/btcchain/validate.go countSigOps 86.67% (13/15) +github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) +github.com/conformal/btcchain/validate.go isCoinBase 83.33% (5/6) +github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 80.77% (21/26) +github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 78.26% (18/23) +github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) +github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) +github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 75.00% (12/16) +github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) +github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 68.52% (37/54) +github.com/conformal/btcchain/validate.go checkBlockSanity 66.67% (30/45) +github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) +github.com/conformal/btcchain/scriptval.go validateTxIn 64.71% (11/17) +github.com/conformal/btcchain/validate.go checkTransactionInputs 63.64% (28/44) +github.com/conformal/btcchain/validate.go checkTransactionSanity 62.16% (23/37) +github.com/conformal/btcchain/txlookup.go connectTransactions 60.00% (9/15) +github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) +github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/14) +github.com/conformal/btcchain/validate.go checkProofOfWork 56.25% (9/16) +github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 54.55% (24/44) +github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) +github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) +github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 49.23% (32/65) +github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 33.33% (4/12) +github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 33.33% (2/6) +github.com/conformal/btcchain/validate.go isFinalizedTransaction 23.08% (3/13) +github.com/conformal/btcchain/checkpoints.go BlockChain.findLatestKnownCheckpoint 18.18% (2/11) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 10.71% (3/28) +github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) +github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/26) +github.com/conformal/btcchain/difficulty.go BigToCompact 0.00% (0/16) +github.com/conformal/btcchain/validate.go checkSerializedHeight 0.00% (0/12) +github.com/conformal/btcchain/difficulty.go calcEasiestDifficulty 0.00% (0/9) +github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) +github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) +github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) +github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) +github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) +github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) +github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 59.02% (569/964) + diff --git a/testdata/blk_0_to_4.dat.bz2 b/testdata/blk_0_to_4.dat.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..274c710d275f032791bcbd4b463be9c1901b85ed GIT binary patch literal 1684 zcmV;F25b33T4*^jL0KkKS>X=}n*alCfB*mg|NsB~|NsC0|NsC0|Ns2||NsC0|NsC0 z|NsC0|M$=Y9t(Fm>CWv=ZMtEpNSUHxp$!c(Z3M^-0D77zBWYbXck0U6}AU2aVH2qV`dLgwvPe^%9G-UM$sLAC$Pg80Q9*m>ZdY(kc z(@#dHpifBk4^vN5z?wA;JtwA7hND2p(1o z=yg{qttlfz;)yXscsGR(5C)TK6Hpv_Pk>L|Z$1FW7sl#J#f5^EFk?RGk}2}OQHWmt zCkrKivn*Y95NXEdtS9#2ha(9rE7%A7=&0QG&d&pIMBeyzspkuNJ(?qSQ*WlrMpak8 z*#&ikj*8fm%)b*GMLucZmne_XVc-mAw}&pfrK$R9bk-2m>Pl|WZ6ypg0U`aLL?yLB zaglMf!D^hc6$a?m!JU$?PbMk6A+rg{oNcusEjSN_3N#`iplPsy*!(=L!Ig^nmLMgg zr!s^Vyw#5Tx<+i~CyKFzqBszwrEO;|Ty+a(TrGL#4C`@%f0QMQqcPHXNFpQ3;`w2A zw3ryzNfMdP7{fMQHwb{!)D_XvWvP`m(xa?NW0zD~ym1E)UUA%x*lSR76U4I?b7@RE z+hXztqDF1tCtThrVK$+c+%}C0sSaZI7XFbr_u8<8J-VqX9hn>H58bpWzK_K7IM4b7 z2|niAf9pH6Mb?Z=(h;bWKLE5W6R=Dq^33r~jta*kM+b~nJ~RY=*B8}?+XsY^p+wU$D*u+(fl02==XNV5 zazgd?ICllOR_iyij-Vav$@XDvA;60lopJ5pB~QnGFM_tk4EV7(wud8sxU&{_{T2kJ zs>Mq{NE8LxZ8JyGPh9fm{pN-~B+W$F@|W17K413j9EX`=oFW^>@3Dksc>`tQ@S_kCRq9#_IJ-KV=AoS`veBIfAfB;Zn=C8aiK zKF(x>$`mYn_m6Z*d_m+vjD#?mJzkjrp#KV;U2*>WFu2Z+5~v_6A-<1*TvK&L2f2bq>1VIw2fElyv7wSUV2wi| eLqeg%m7b@}t+ANUN4}&X{}*yaI8cz`4+)z-{1!U^ literal 0 HcmV?d00001 diff --git a/testdata/blk_3A.dat.bz2 b/testdata/blk_3A.dat.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..01266565d573ca0f7e7601d011fb4f98e243445a GIT binary patch literal 801 zcmV++1K#{XT4*^jL0KkKSvvUkH~;}T|NsBz_5c0;|L_05_I~^R?|c2;-~aRc|NsC0 z|NsB{fBe7!yv*vg#8pi;rf2{F00hXxK`;O&1i>&(F`xh=00009hJX>80$>0DWGA3Z zdWM0tjUJ#8R2l#P000dD000008UO$Q00E!?XaEL)Gyu>5GyniJGyoa}R5qXnhJer- z00001paVbvG&Ilv0000000E!|hJXM70004@rkVs()dWqFU;rje005W(695T-009p| z3Jk%wT+;0O$0FY!ne@1J8)9k90GOeZGInoM1&UY41q8TUM5S9l{fm}~XuF$g0*D{bOg6L;u&U>AFG>g9|;M&U> z1w|OguMnW1sS^dz91cXDHw_xR;eW~XC=|3qoP{edVW5%|YD6QM5zK{VS=8ad7%;1d zU~4^Rhb-VQrZcE9Ps0!X7C(3F9(fyu+l&#w%G;BTbA{&QHx6`P!%=P%#gtH^OVA-I zU0=IB4bB*n=X-fliQ7?Y1%y@<0Nvt5A3~51XAKg~+yUbLM1Vp-)MEMbrqxHDyC1NH z7!W1`ED$8}380;NL$K-BvBN}`5tR59j9nL^$p5T@?qBpcyuwz>6O2K)mibZ!0&YD7 z_s4+p_+ab}Gy#5e(@dU@Z%D-ChuU~&14RA!fF!Dd`cgP=NT~SjahqqpIK}{;HC~TT z2(ILkeuBLc?gM2zZY*x^7$rC=;p80^7A^UV-7;G;LGs%_hy~6qb f_`c&%W+X@o@c@qy4iiSpcZ<0qoG3^ge0v-K)fQGt literal 0 HcmV?d00001 diff --git a/testdata/blk_4A.dat.bz2 b/testdata/blk_4A.dat.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..19b409e752f37840b271e4e9f0b90dcd06e1cad3 GIT binary patch literal 271 zcmV+q0r37pT4*^jL0KkKS)#5T-T(kw|Nr)=P(OnG%3!|lLXNzfU?7AN6cRr~MVBQ2 zA0t9myXT+)lo>RJ)HG?4qfADgrVz=aL&yZgWZ0T&8X6v^L)7&eZ8XCv>8MpdQ2+rL z00A_>00000BLX&n000cEjyQmUh5!K)7oh+EqJZEaPB5`2`g%`}NewXJA%&J^c!3*M z$>&bK9{A*x-#>_1L8fteTKC-0?Cz6_@US3)f1n@oih|ATh}}(4Jy`UR58d*`H|r@9 zn^e@jIT!g%N-p)E1~|{dn8BDHZ~gm547v*zyOjpf)Jn$MfHXv+%N;`K))-t6TsWFQ05 zP|5&g8fefoGyr4_o>LZzc~ zp`#N(0j7qTG-v>6p`g*AX^7K602wj>FouSJ0i#BNrj1;cQ3j$xfC2yjL;;2u@c;+{ zmmo%n6kwkqz!};kMF*mNWE62tG=RVH)POU#z~VBHgOiEVpItH$l30xDGRXF!C4(!F zm2p{67q;92;Dsoa7tNZKHpsy7arVhE-@{}&c0R9zbN=av#Q`5aLQlstV5M*uJm_9Y z86x2&VkO?P4`X!KirXud5$d4O57oTkVI{TPp^6!Lon|}lzctd=a|8u7D^ip4@NQJ~ z_nL9s#MxZGz5`XDg8QmCNR3Wap_q`;|3sOV5M=z}Mz6txyzLMvx&+SI{NZ!vu^oW_ zKcRFYm;`k@0xyy)8C6JtU?Ql;?N1QXCWw(aH32%xW1Ud@xYp{1wLJJx?+;2#Ip0x+ W5)=|hP-7M^@pmLsg$WN38`vQD7Tcl# literal 0 HcmV?d00001 diff --git a/testdata/reorgtest.hex b/testdata/reorgtest.hex new file mode 100644 index 00000000..5b9e75e7 --- /dev/null +++ b/testdata/reorgtest.hex @@ -0,0 +1,180 @@ +File path: reorgTest/blk_0_to_4.dat + +Block 0: + f9beb4d9 + 1d010000 + + 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 3ba3edfd 7a7b12b2 7ac72c3e 67768f61 7fc81bc3 888a5132 3a9fb8aa + 4b1e5e4a 29ab5f49 ffff001d 1dac2b7c + 01 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff4d04ff ff001d01 04455468 65205469 6d657320 30332f4a + 616e2f32 30303920 4368616e 63656c6c 6f72206f 6e206272 696e6b20 6f662073 + 65636f6e 64206261 696c6f75 7420666f 72206261 6e6b73ff ffffff01 00f2052a + 01000000 43410467 8afdb0fe 55482719 67f1a671 30b7105c d6a828e0 3909a679 + 62e0ea1f 61deb649 f6bc3f4c ef38c4f3 5504e51e c112de5c 384df7ba 0b8d578a + 4c702b6b f11d5fac 00000000 +Block 1: + f9beb4d9 + d4000000 + + 01000000 6fe28c0a b6f1b372 c1a6a246 ae63f74f 931e8365 e15a089c 68d61900 + 00000000 3bbd67ad e98fbbb7 0718cd80 f9e9acf9 3b5fae91 7bb2b41d 4c3bb82c + 77725ca5 81ad5f49 ffff001d 44e69904 + 01 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff04722f 2e2bffff ffff0100 f2052a01 00000043 41046868 + 0737c76d abb801cb 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 + b5ac9e8b 4c9f49be 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ac00 + 000000 +Block 2: + f9beb4d9 + 95010000 + + 01000000 13ca7940 4c11c63e ca906bbd f190b751 2872b857 1b5143ae e8cb5737 + 00000000 fc07c983 d7391736 0aeda657 29d0d4d3 2533eb84 76ee9d64 aa27538f + 9b4fc00a d9af5f49 ffff001d 630bea22 + 02 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff04eb96 14e5ffff ffff0100 f2052a01 00000043 41046868 + 0737c76d abb801cb 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 + b5ac9e8b 4c9f49be 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ac00 + 000000 + + 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 + 4fdcb8ee d2000000 004a4930 46022100 3dde52c6 5e339f45 7fe1015e 70eed208 + 872eb71e dd484c07 206b190e cb2ec3f8 02210011 c78dcfd0 3d43fa63 61242a33 + 6291ba2a 8c1ef5bc d5472126 2468f2bf 8dee4d01 ffffffff 0200ca9a 3b000000 + 001976a9 14cb2abd e8bccacc 32e893df 3a054b9e f7f227a4 ce88ac00 286bee00 + 00000019 76a914ee 26c56fc1 d942be8d 7a24b2a1 001dd894 69398088 ac000000 + 00 +Block 3: + f9beb4d9 + 96020000 + + 01000000 7d338254 0506faab 0d4cf179 45dda023 49db51f9 6233f24c 28002258 + 00000000 4806fe80 bf85931b 882ea645 77ca5a03 22bb8af2 3f277b20 55f160cd + 972c8e8b 31b25f49 ffff001d e8f0c653 + 03 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff044abd 8159ffff ffff0100 f2052a01 00000043 4104b95c + 249d84f4 17e3e395 a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c + a5e56c90 f340988d 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ac00 + 000000 + + 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb + bad253d3 77010000 008c4930 46022100 96ee0d02 b35fd61e 4960b44f f396f67e + 01fe17f9 de4e0c17 b6a963bd ab2b50a6 02210034 920d4daa 7e9f8abe 5675c931 + 495809f9 0b9c1189 d05fbaf1 dd6696a5 b0d8f301 41046868 0737c76d abb801cb + 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 b5ac9e8b 4c9f49be + 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ffff ffff0100 286bee00 + 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 + 00 + + 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb + bad253d3 77000000 008c4930 46022100 b08b922a c4bde411 1c229f92 9fe6eb6a + 50161f98 1f4cf47e a9214d35 bf74d380 022100d2 f6640327 e677a1e1 cc474991 + b9a48ba5 bd1e0c94 d1c8df49 f7b0193b 7ea4fa01 4104b95c 249d84f4 17e3e395 + a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c a5e56c90 f340988d + 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ffff ffff0100 ca9a3b00 + 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 + 00 + +Block 4: + f9beb4d9 + 73010000 + + 01000000 5da36499 06f35e09 9be42a1d 87b6dd42 11bc1400 6c220694 0807eaae + 00000000 48eeeaed 2d9d8522 e6201173 743823fd 4b87cd8a ca8e6408 ec75ca38 + 302c2ff0 89b45f49 ffff001d 00530839 + 02 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff04d41d 2213ffff ffff0100 f2052a01 00000043 4104678a + fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 + bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 + 000000 + + 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 + 4fdcb8ee d2000000 004a4930 46022100 8c8fd57b 48762135 8d8f3e69 19f33e08 + 804736ff 83db47aa 248512e2 6df9b8ba 022100b0 c59e5ee7 bfcbfcd1 a4d83da9 + 55fb260e fda7f42a 25522625 a3d6f2d9 1174a701 ffffffff 0100f205 2a010000 + 001976a9 14c52266 4fb0e55c dc5c0cea 73b4aad9 7ec83432 3288ac00 000000 + +File path: reorgTest/blk_3A.dat +Block 3A: + f9beb4d9 + 96020000 + + 01000000 7d338254 0506faab 0d4cf179 45dda023 49db51f9 6233f24c 28002258 + 00000000 5a15f573 1177a353 bdca7aab 20e16624 dfe90adc 70accadc 68016732 + 302c20a7 31b25f49 ffff001d 6a901440 + 03 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff04ad1b e7d5ffff ffff0100 f2052a01 00000043 4104ed83 + 704c95d8 29046f1a c2780621 1132102c 34e9ac7f fa1b7111 0658e5b9 d1bdedc4 + 16f5cefc 1db0625c d0c75de8 192d2b59 2d7e3b00 bcfb4a0e 860d880f d1fcac00 + 000000 + + 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb + bad253d3 77010000 008c4930 46022100 96ee0d02 b35fd61e 4960b44f f396f67e + 01fe17f9 de4e0c17 b6a963bd ab2b50a6 02210034 920d4daa 7e9f8abe 5675c931 + 495809f9 0b9c1189 d05fbaf1 dd6696a5 b0d8f301 41046868 0737c76d abb801cb + 2204f57d be4e4579 e4f710cd 67dc1b42 27592c81 e9b5cf02 b5ac9e8b 4c9f49be + 5251056b 6a6d011e 4c37f6b6 d17ede6b 55faa235 19e2ffff ffff0100 286bee00 + 00000019 76a914c5 22664fb0 e55cdc5c 0cea73b4 aad97ec8 34323288 ac000000 + 00 + + 01000000 01f287b5 e067e1cf 80f7da8a f89917b5 505094db d82412d9 35b665eb + bad253d3 77000000 008c4930 46022100 9cc67ddd aa6f592a 6b2babd4 d6ff954f + 25a784cf 4fe4bb13 afb9f49b 08955119 022100a2 d99545b7 94080757 fcf2b563 + f2e91287 86332f46 0ec6b90f f085fb28 41a69701 4104b95c 249d84f4 17e3e395 + a1274254 28b54067 1cc15881 eb828c17 b722a53f c599e21c a5e56c90 f340988d + 3933acc7 6beb832f d64cab07 8ddf3ce7 32923031 d1a8ffff ffff0100 ca9a3b00 + 00000019 76a914ee 26c56fc1 d942be8d 7a24b2a1 001dd894 69398088 ac000000 + 00 + +File path: reorgTest/blk_4A.dat +Block 4A: + f9beb4d9 + d4000000 + + 01000000 aae77468 2205667d 4f413a58 47cc8fe8 9795f1d5 645d5b24 1daf3c92 + 00000000 361c9cde a09637a0 d0c05c3b 4e7a5d91 9edb184a 0a4c7633 d92e2ddd + f04cb854 89b45f49 ffff001d 9e9aa1e8 + 01 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff0401b8 f3eaffff ffff0100 f2052a01 00000043 4104678a + fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 + bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 + 000000 + +File path: reorgTest/blk_5A.dat +Block 5A: + f9beb4d9 + 73010000 + + 01000000 ebc7d0de 9c31a71b 7f41d275 2c080ba4 11e1854b d45cb2cf 8c1e4624 + 00000000 a607774b 79b8eb50 b52a5a32 c1754281 ec67f626 9561df28 57d1fe6a + ea82c696 e1b65f49 ffff001d 4a263577 + 02 + + 01000000 01000000 00000000 00000000 00000000 00000000 00000000 00000000 + 00000000 00ffffff ff049971 0c7dffff ffff0100 f2052a01 00000043 4104678a + fdb0fe55 48271967 f1a67130 b7105cd6 a828e039 09a67962 e0ea1f61 deb649f6 + bc3f4cef 38c4f355 04e51ec1 12de5c38 4df7ba0b 8d578a4c 702b6bf1 1d5fac00 + 000000 + + 01000000 0163451d 1002611c 1388d5ba 4ddfdf99 196a86b5 990fb5b0 dc786207 + 4fdcb8ee d2000000 004a4930 46022100 8c8fd57b 48762135 8d8f3e69 19f33e08 + 804736ff 83db47aa 248512e2 6df9b8ba 022100b0 c59e5ee7 bfcbfcd1 a4d83da9 + 55fb260e fda7f42a 25522625 a3d6f2d9 1174a701 ffffffff 0100f205 2a010000 + 001976a9 14c52266 4fb0e55c dc5c0cea 73b4aad9 7ec83432 3288ac00 000000 + diff --git a/timesorter.go b/timesorter.go new file mode 100644 index 00000000..6cb8448d --- /dev/null +++ b/timesorter.go @@ -0,0 +1,31 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "time" +) + +// timeSorter implements sort.Interface to allow a slice of timestamps to +// be sorted. +type timeSorter []time.Time + +// Len returns the number of timestamps in the slice. It is part of the +// sort.Interface implementation. +func (s timeSorter) Len() int { + return len(s) +} + +// Swap swaps the timestamps at the passed indices. It is part of the +// sort.Interface implementation. +func (s timeSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less returns whether the timstamp with index i should sort before the +// timestamp with index j. It is part of the sort.Interface implementation. +func (s timeSorter) Less(i, j int) bool { + return s[i].Before(s[j]) +} diff --git a/txlookup.go b/txlookup.go new file mode 100644 index 00000000..aff9eae2 --- /dev/null +++ b/txlookup.go @@ -0,0 +1,248 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" + "github.com/conformal/btcdb" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" +) + +// txData contains contextual information about transactions such as which block +// they were found in and whether or not the outputs are spent. +type txData struct { + tx *btcwire.MsgTx + hash *btcwire.ShaHash + blockHeight int64 + spent []bool + err error +} + +// connectTransactions updates the passed map by applying transaction and +// spend information for all the transactions in the passed block. Only +// transactions in the passed map are updated. +func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Block) error { + // Loop through all of the transactions in the block to see if any of + // them are ones we need to update and spend based on the results map. + for i, tx := range block.MsgBlock().Transactions { + txHash, err := block.TxSha(i) + if err != nil { + return err + } + + // Update the transaction store with the transaction information + // if it's one of the requested transactions. + if txD, exists := txStore[*txHash]; exists { + txD.tx = tx + txD.blockHeight = block.Height() + txD.spent = make([]bool, len(tx.TxOut)) + txD.err = nil + } + + // Spend the origin transaction output. + for _, txIn := range tx.TxIn { + originHash := &txIn.PreviousOutpoint.Hash + originIndex := txIn.PreviousOutpoint.Index + if originTx, exists := txStore[*originHash]; exists { + originTx.spent[originIndex] = true + } + } + } + + return nil +} + +// disconnectTransactions updates the passed map by undoing transaction and +// spend information for all transactions in the passed block. Only +// transactions in the passed map are updated. +func disconnectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Block) error { + // Loop through all of the transactions in the block to see if any of + // them are ones were need to undo based on the results map. + for i, tx := range block.MsgBlock().Transactions { + txHash, err := block.TxSha(i) + if err != nil { + return err + } + + // Remove this transaction from the transaction store (this is a + // no-op if it's not there). + delete(txStore, *txHash) + + // Unspend the origin transaction output. + for _, txIn := range tx.TxIn { + originHash := &txIn.PreviousOutpoint.Hash + originIndex := txIn.PreviousOutpoint.Index + if originTx, exists := txStore[*originHash]; exists { + originTx.spent[originIndex] = false + } + } + } + + return nil +} + +// fetchTxList fetches transaction data about the provided list of transactions +// from the point of view of the given node. For example, a given node might +// be down a side chain where a transaction hasn't been spent from its point of +// view even though it might have been spent in the main chain (or another side +// chain). Another scenario is where a transaction exists from the point of +// view of the main chain, but doesn't exist in a side chain that branches +// before the block that contains the transaction on the main chain. +func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (map[btcwire.ShaHash]*txData, error) { + // Get the previous block node. This function is used over simply + // accessing node.parent directly as it will dynamically create previous + // block nodes as needed. This helps allow only the pieces of the chain + // that are needed to remain in memory. + prevNode, err := b.getPrevNodeFromNode(node) + if err != nil { + return nil, err + } + + // The transaction store map needs to have an entry for every requested + // transaction. By default, all the transactions are marked as missing. + // Each entry will be filled in with the appropriate data below. + txStore := make(map[btcwire.ShaHash]*txData) + for _, hash := range txList { + txStore[*hash] = &txData{hash: hash, err: btcdb.TxShaMissing} + } + + // Ask the database (main chain) for the list of transactions. This + // will return the information from the point of view of the end of the + // main chain. + txReplyList := b.db.FetchTxByShaList(txList) + for _, txReply := range txReplyList { + // Lookup the existing results entry to modify. Skip + // this reply if there is no corresponding entry in + // the transaction store map which really should not happen, but + // be safe. + txD, ok := txStore[*txReply.Sha] + if !ok { + continue + } + + // Fill in the transaction details. A copy is used here since + // there is no guarantee the returned data isn't cached and + // this code modifies the data. A bug caused by modifying the + // cached data would likely be difficult to track down and could + // cause subtle errors, so avoid the potential altogether. + txD.err = txReply.Err + if txReply.Err == nil { + txD.tx = txReply.Tx + txD.blockHeight = txReply.Height + txD.spent = make([]bool, len(txReply.TxSpent)) + copy(txD.spent, txReply.TxSpent) + } + } + + // At this point, we have the transaction data from the point of view + // of the end of the main (best) chain. If we haven't selected a best + // chain yet or we are extending the main (best) chain with a new block, + // everything is accurate, so return the results now. + if b.bestChain == nil || (prevNode != nil && prevNode.hash.IsEqual(b.bestChain.hash)) { + return txStore, nil + } + + // The requested node is either on a side chain or is a node on the main + // chain before the end of it. In either case, we need to undo the + // transactions and spend information for the blocks which would be + // disconnected during a reorganize to the point of view of the + // node just before the requested node. + detachNodes, attachNodes := b.getReorganizeNodes(prevNode) + for e := detachNodes.Front(); e != nil; e = e.Next() { + n := e.Value.(*blockNode) + block, err := b.db.FetchBlockBySha(n.hash) + if err != nil { + return nil, err + } + + disconnectTransactions(txStore, block) + } + + // The transaction store is now accurate to either the node where the + // requested node forks off the main chain (in the case where the + // requested node is on a side chain), or the requested node itself if + // the requested node is an old node on the main chain. Entries in the + // attachNodes list indicate the requested node is on a side chain, so + // if there are no nodes to attach, we're done. + if attachNodes.Len() == 0 { + return txStore, nil + } + + // The requested node is on a side chain, so we need to apply the + // transactions and spend information from each of the nodes to attach. + for e := attachNodes.Front(); e != nil; e = e.Next() { + n := e.Value.(*blockNode) + block, exists := b.blockCache[*n.hash] + if !exists { + return nil, fmt.Errorf("unable to find block %v in "+ + "side chain cache for transaction search", + n.hash) + } + + connectTransactions(txStore, block) + } + + return txStore, nil +} + +// fetchInputTransactions fetches the input transactions referenced by the +// transactions in the given block from its point of view. See fetchTxList +// for more details on what the point of view entails. +func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Block) (map[btcwire.ShaHash]*txData, error) { + // Build a map of in-flight transactions because some of the inputs in + // this block could be referencing other transactions in this block + // which are not yet in the chain. + txInFlight := map[btcwire.ShaHash]*btcwire.MsgTx{} + for i, tx := range block.MsgBlock().Transactions { + // Get transaction hash. It's safe to ignore the error since + // it's already cached in the nominal code path and the only + // way it can fail is if the index is out of range which is + // impossible here. + txHash, _ := block.TxSha(i) + txInFlight[*txHash] = tx + } + + // Loop through all of the transaction inputs (except for the coinbase + // which has no inputs) collecting them into lists of what is needed and + // what is already known (in-flight). + var txNeededList []*btcwire.ShaHash + txStore := make(map[btcwire.ShaHash]*txData) + for _, tx := range block.MsgBlock().Transactions[1:] { + for _, txIn := range tx.TxIn { + // Add an entry to the transaction store for the needed + // transaction with it set to missing by default. + originHash := &txIn.PreviousOutpoint.Hash + txD := &txData{hash: originHash, err: btcdb.TxShaMissing} + txStore[*originHash] = txD + + // The transaction is already in-flight, so update the + // transaction store acccordingly. Otherwise, we need + // it. + if tx, ok := txInFlight[*originHash]; ok { + txD.tx = tx + txD.blockHeight = node.height + txD.spent = make([]bool, len(tx.TxOut)) + txD.err = nil + } else { + txNeededList = append(txNeededList, originHash) + } + } + } + + // Request the input transaction from the point of view of the node. + txNeededStore, err := b.fetchTxList(node, txNeededList) + if err != nil { + return nil, err + } + + // Merge the results of the requested transactions and the in-flight + // transactions. + for _, txD := range txNeededStore { + txStore[*txD.hash] = txD + } + + return txStore, nil +} diff --git a/validate.go b/validate.go new file mode 100644 index 00000000..f30afd96 --- /dev/null +++ b/validate.go @@ -0,0 +1,877 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "encoding/binary" + "fmt" + "github.com/conformal/btcdb" + "github.com/conformal/btcscript" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "math" + "time" +) + +const ( + // satoshiPerBitcoin is the number of satoshi in one bitcoin (1 BTC). + satoshiPerBitcoin int64 = 1e8 + + // maxSatoshi is the maximum transaction amount allowed in satoshi. + maxSatoshi int64 = 21e6 * satoshiPerBitcoin + + // maxSigOpsPerBlock is the maximum number of signature operations + // allowed for a block. It is a fraction of the max block payload size. + maxSigOpsPerBlock = btcwire.MaxBlockPayload / 50 + + // lockTimeThreshold is the number below which a lock time is + // interpreted to be a block number. Since an average of one block + // is generated per 10 minutes, this allows blocks for about 9,512 + // years. However, if the field is interpreted as a timestamp, given + // the lock time is a uint32, the max is sometime around 2106. + lockTimeThreshold uint32 = 5e8 // Tue Nov 5 00:53:20 1985 UTC + + // minCoinbaseScriptLen is the minimum length a coinbase script can be. + minCoinbaseScriptLen = 2 + + // maxCoinbaseScriptLen is the maximum length a coinbase script can be. + maxCoinbaseScriptLen = 100 + + // medianTimeBlocks is the number of previous blocks which should be + // used to calculate the median time used to validate block timestamps. + medianTimeBlocks = 11 + + // serializedHeightVersion is the block version which changed block + // coinbases to start with the serialized block height. + serializedHeightVersion = 2 + + // baseSubsidy is the starting subsidy amount for mined blocks. This + // value is halved every subsidyHalvingInterval blocks. + baseSubsidy = 50 * satoshiPerBitcoin + + // subsidyHalvingInterval is the interval of blocks at which the + // baseSubsidy is continually halved. See calcBlockSubsidy for more + // details. + subsidyHalvingInterval = 210000 +) + +var ( + // coinbaseMaturity is the number of blocks required before newly + // mined bitcoins (coinbase transactions) can be spent. This is a + // variable as opposed to a constant because the tests need the ability + // to modify it. + coinbaseMaturity int64 = 100 + + // zeroHash is the zero value for a btcwire.ShaHash and is defined as + // a package level variable to avoid the need to create a new instance + // every time a check is needed. + zeroHash = &btcwire.ShaHash{} + + // block91842Hash is one of the two nodes which violate the rules + // set forth in BIP0030. It is defined as a package level variable to + // avoid the need to create a new instance every time a check is needed. + block91842Hash = newShaHashFromStr("00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec") + + // block91880Hash is one of the two nodes which violate the rules + // set forth in BIP0030. It is defined as a package level variable to + // avoid the need to create a new instance every time a check is needed. + block91880Hash = newShaHashFromStr("00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721") +) + +// isNullOutpoint determines whether or not a previous transaction output point +// is set. +func isNullOutpoint(outpoint *btcwire.OutPoint) bool { + if outpoint.Index == math.MaxUint32 && outpoint.Hash.IsEqual(zeroHash) { + return true + } + return false +} + +// isCoinBase determines whether or not a transaction is a coinbase. A coinbase +// is a special transaction created by miners that has no inputs. This is +// represented in the block chain by a transaction with a single input that has +// a previous output transaction index set to the maximum value along with a +// zero hash. +func isCoinBase(msgTx *btcwire.MsgTx) bool { + // A coin base must only have one transaction input. + if len(msgTx.TxIn) != 1 { + return false + } + + // The previous output of a coin base must have a max value index and + // a zero hash. + prevOut := msgTx.TxIn[0].PreviousOutpoint + if prevOut.Index != math.MaxUint32 || !prevOut.Hash.IsEqual(zeroHash) { + return false + } + + return true +} + +// isFinalized determines whether or not a transaction is finalized. +func isFinalizedTransaction(msgTx *btcwire.MsgTx, blockHeight int64, blockTime time.Time) bool { + // Lock time of zero means the transaction is finalized. + lockTime := msgTx.LockTime + if lockTime == 0 { + return true + } + + // The lock time field of a transaction is either a block height at + // which the transaction is finalized or a timestamp depending on if the + // value is before the lockTimeThreshold. When it is under the + // threshold it is a block height. + blockTimeOrHeight := int64(0) + if lockTime < lockTimeThreshold { + blockTimeOrHeight = blockHeight + } else { + blockTimeOrHeight = blockTime.Unix() + } + if int64(lockTime) < blockTimeOrHeight { + return true + } + + // At this point, the transaction's lock time hasn't occured yet, but + // the transaction might still be finalized if the sequence number + // for all transaction inputs is maxed out. + for _, txIn := range msgTx.TxIn { + if txIn.Sequence != math.MaxUint32 { + return false + } + } + return true +} + +// isBIP0030Node returns whether or not the passed node represents one of the +// two blocks that violate the BIP0030 rule which prevents transactions from +// overwriting old ones. +func isBIP0030Node(node *blockNode) bool { + if node.height == 91842 && node.hash.IsEqual(block91842Hash) { + return true + } + + if node.height == 91880 && node.hash.IsEqual(block91880Hash) { + return true + } + + return false +} + +// calcBlockSubsidy returns the subsidy amount a block at the provided height +// should have. This is mainly used for determining how much the coinbase for +// newly generated blocks awards as well as validating the coinbase for blocks +// has the expected value. +// +// The subsidy is halved every subsidyHalvingInterval blocks. Mathematically +// this is: baseSubsidy / 2^(height/subsidyHalvingInterval) +// +// At the target block generation rate this is approximately every 4 +// years. +func calcBlockSubsidy(height int64) int64 { + // Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval) + return baseSubsidy >> uint(height/subsidyHalvingInterval) +} + +// checkTransactionSanity performs some preliminary checks on a transaction to +// ensure it is sane. These checks are context free. +func checkTransactionSanity(tx *btcwire.MsgTx) error { + // A transaction must have at least one input. + if len(tx.TxIn) == 0 { + return RuleError("transaction has no inputs") + } + + // A transaction must have at least one output. + if len(tx.TxOut) == 0 { + return RuleError("transaction has no outputs") + } + + // NOTE: bitcoind does size limits checking here, but the size limits + // have already been checked by btcwire for incoming transactions. + // Also, btcwire checks the size limits on send too, so there is no need + // to double check it here. + + // Ensure the transaction amounts are in range. Each transaction + // output must not be negative or more than the max allowed per + // transaction. Also, the total of all outputs must abide by the same + // restrictions. All amounts in a transaction are in a unit value known + // as a satoshi. One bitcoin is a quantity of satoshi as defined by the + // satoshiPerBitcoin constant. + var totalSatoshi int64 + for _, txOut := range tx.TxOut { + satoshi := txOut.Value + if satoshi < 0 { + str := fmt.Sprintf("transaction output has negative "+ + "value of %v", satoshi) + return RuleError(str) + } + if satoshi > maxSatoshi { + str := fmt.Sprintf("transaction output value of %v is "+ + "higher than max allowed value of %v", satoshi, + maxSatoshi) + return RuleError(str) + } + + // TODO(davec): No need to check < 0 here as satoshi is + // guaranteed to be positive per the above check. Also need + // to add overflow checks. + totalSatoshi += satoshi + if totalSatoshi < 0 { + str := fmt.Sprintf("total value of all transaction "+ + "outputs has negative value of %v", totalSatoshi) + return RuleError(str) + } + if totalSatoshi > maxSatoshi { + str := fmt.Sprintf("total value of all transaction "+ + "outputs is %v which is higher than max "+ + "allowed value of %v", totalSatoshi, maxSatoshi) + return RuleError(str) + } + } + + // Check for duplicate transaction inputs. + existingTxOut := make(map[string]bool) + for _, txIn := range tx.TxIn { + prevOut := &txIn.PreviousOutpoint + key := fmt.Sprintf("%v%v", prevOut.Hash, prevOut.Index) + if _, exists := existingTxOut[key]; exists { + return RuleError("transaction contains duplicate outpoint") + } + existingTxOut[key] = true + } + + // Coinbase script length must be between min and max length. + if isCoinBase(tx) { + slen := len(tx.TxIn[0].SignatureScript) + if slen < minCoinbaseScriptLen || slen > maxCoinbaseScriptLen { + str := fmt.Sprintf("coinbase transaction script length "+ + "of %d is out of range (min: %d, max: %d)", + slen, minCoinbaseScriptLen, maxCoinbaseScriptLen) + return RuleError(str) + } + } else { + // Previous transaction outputs referenced by the inputs to this + // transaction must not be null. + for _, txIn := range tx.TxIn { + prevOut := &txIn.PreviousOutpoint + if isNullOutpoint(prevOut) { + return RuleError("transaction input refers to " + + "previous output that is null") + } + } + } + + return nil +} + +// checkProofOfWork ensures the block header bits which indicate the target +// difficulty is in min/max range and that the block hash is less than the +// target difficulty as claimed. +func checkProofOfWork(block *btcutil.Block) error { + // The target difficulty must be larger than zero. + header := block.MsgBlock().Header + target := CompactToBig(header.Bits) + if target.Sign() <= 0 { + str := fmt.Sprintf("block target difficulty of %064x is too low", + target) + return RuleError(str) + } + + // The target difficulty must be less than the maximum allowed. + if target.Cmp(powLimit) > 0 { + str := fmt.Sprintf("block target difficulty of %064x is "+ + "higher than max of %064x", target, powLimit) + return RuleError(str) + } + + // The block hash must be less than the claimed target. + blockHash, err := block.Sha() + if err != nil { + return err + } + hashNum := ShaHashToBig(blockHash) + if hashNum.Cmp(target) > 0 { + str := fmt.Sprintf("block hash of %064x is higher than "+ + "expected max of %064x", hashNum, target) + return RuleError(str) + } + + return nil +} + +// countSigOps returns the number of signature operations for all transaction +// input and output scripts in the provided transaction. This uses the +// quicker, but imprecise, signature operation counting mechanism from +// btcscript. +func countSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool) (int, error) { + // Choose the starting transaction input based on whether this is a + // coinbase transaction since the coinbase input script should not be + // executed. + txIns := msgTx.TxIn + if isCoinBaseTx { + txIns = txIns[1:] + } + + // Accumulate the number of signature operations in all transaction + // inputs (except the first input if this is a coinbase transaction). + totalSigOps := 0 + for _, txIn := range txIns { + numSigOps, err := btcscript.GetSigOpCount(txIn.SignatureScript) + if err != nil { + return 0, err + } + totalSigOps += numSigOps + } + + // Accumulate the number of signature operations in all transaction + // outputs. + for _, txOut := range msgTx.TxOut { + numSigOps, err := btcscript.GetSigOpCount(txOut.PkScript) + if err != nil { + return 0, err + } + totalSigOps += numSigOps + } + + return totalSigOps, nil +} + +// countP2SHSigOps returns the number of signature operations for all input +// transactions which are of the pay-to-script-hash type. This uses the +// precise, signature operation counting mechanism from btcscript which requires +// access to the input transaction scripts. +func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwire.ShaHash]*txData) (int, error) { + // Coinbase transactions have no interesting inputs. + if isCoinBaseTx { + return 0, nil + } + + // TODO(davec): Need to pass the cached version in. + txHash, err := msgTx.TxSha(btcwire.ProtocolVersion) + if err != nil { + return 0, err + } + + // Accumulate the number of signature operations in all transaction + // inputs. + totalSigOps := 0 + for _, txIn := range msgTx.TxIn { + // Ensure the referenced input transaction is available. + txInHash := &txIn.PreviousOutpoint.Hash + originTx, exists := txStore[*txInHash] + if !exists { + return 0, fmt.Errorf("unable to find input transaction "+ + "%v referenced from transaction %v", txHash, + txInHash) + } + + // Ensure the output index in the referenced transaction is + // available. + originTxIndex := txIn.PreviousOutpoint.Index + if originTxIndex >= uint32(len(originTx.tx.TxOut)) { + return 0, fmt.Errorf("out of bounds input index %d in "+ + "transaction %v referenced from transaction %v", + originTxIndex, txInHash, txHash) + } + + // We're only interested in pay-to-script-hash types, so skip + // this input if it's not one. + pkScript := originTx.tx.TxOut[originTxIndex].PkScript + if !btcscript.IsPayToScriptHash(pkScript) { + continue + } + + // Count the precise number of signature operations in the + // referenced public key script. + sigScript := txIn.SignatureScript + numSigOps, err := btcscript.GetPreciseSigOpCount(sigScript, + pkScript, true) + if err != nil { + return 0, err + } + + // We could potentially overflow the accumulator so check for + // overflow. + lastSigOps := totalSigOps + totalSigOps += numSigOps + if totalSigOps < lastSigOps { + return 0, fmt.Errorf("the public key script from "+ + "output index %d in transaction %v contains "+ + "too many signature operations - overflow", + originTxIndex, txInHash) + } + } + + return totalSigOps, nil +} + +// checkBlockSanity performs some preliminary checks on a block to ensure it is +// sane before continuing with block processing. These checks are context free. +func checkBlockSanity(block *btcutil.Block) error { + // NOTE: bitcoind does size limits checking here, but the size limits + // have already been checked by btcwire for incoming blocks. Also, + // btcwire checks the size limits on send too, so there is no need + // to double check it here. + + // Ensure the proof of work bits in the block header is in min/max range + // and the block hash is less than the target value described by the + // bits. + err := checkProofOfWork(block) + if err != nil { + return err + } + + // Ensure the block time is not more than 2 hours in the future. + msgBlock := block.MsgBlock() + header := &msgBlock.Header + if header.Timestamp.After(time.Now().Add(time.Hour * 2)) { + str := fmt.Sprintf("block timestamp of %v is too far in the "+ + "future", header.Timestamp) + return RuleError(str) + } + + // A block must have at least one transaction. + transactions := msgBlock.Transactions + if len(transactions) == 0 { + return RuleError("block does not contain any transactions") + } + + // The first transaction in a block must be a coinbase. + if !isCoinBase(transactions[0]) { + return RuleError("first transaction in block is not a coinbase") + } + + // A block must not have more than one coinbase. + for _, tx := range transactions[1:] { + if isCoinBase(tx) { + return RuleError("block contains more than one coinbase") + } + } + + // Do some preliminary checks on each transaction to ensure they are + // sane before continuing. + for _, tx := range transactions { + err := checkTransactionSanity(tx) + if err != nil { + return err + } + } + + // Build merkle tree and ensure the calculated merkle root matches the + // entry in the block header. This also has the effect of caching all + // of the transaction hashes in the block to speed up future hash + // checks. Bitcoind builds the tree here and checks the merkle root + // after the following checks, but there is no reason not to check the + // merkle root matches here. + merkles := BuildMerkleTreeStore(block) + calculatedMerkleRoot := merkles[len(merkles)-1] + if !header.MerkleRoot.IsEqual(calculatedMerkleRoot) { + str := fmt.Sprintf("block merkle root is invalid - got %v, "+ + "want %v", calculatedMerkleRoot, header.MerkleRoot) + return RuleError(str) + } + + // Check for duplicate transactions. This check will be fairly quick + // since the transaction hashes are already cached due to building the + // merkle tree above. + existingTxHashes := make(map[btcwire.ShaHash]bool) + txShas, err := block.TxShas() + if err != nil { + return err + } + for _, hash := range txShas { + if _, exists := existingTxHashes[*hash]; exists { + str := fmt.Sprintf("block contains duplicate "+ + "transaction %v", hash) + return RuleError(str) + } + existingTxHashes[*hash] = true + } + + // The number of signature operations must be less than the maximum + // allowed per block. + totalSigOps := 0 + for i, tx := range transactions { + // Since the first (and only the first) transaction has already + // been verified above to be a coinbase transaction, use i == 0 + // as an optimization for the flag to countSigOps for whether + // or not the transaction is a coinbase transaction rather than + // having to do a full coinbase check again. + numSigOps, err := countSigOps(tx, i == 0) + if err != nil { + return err + } + + // We could potentially overflow the accumulator so check for + // overflow. + lastSigOps := totalSigOps + totalSigOps += numSigOps + if totalSigOps < lastSigOps || totalSigOps > maxSigOpsPerBlock { + str := fmt.Sprintf("block contains too many signature "+ + "operations - got %v, max %v", totalSigOps, + maxSigOpsPerBlock) + return RuleError(str) + } + } + + return nil +} + +// checkSerializedHeight checks if the signature script in the passed +// transaction starts with the serialized block height of wantHeight. +func checkSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { + sigScript := coinbaseTx.TxIn[0].SignatureScript + if len(sigScript) < 4 { + str := "the coinbase signature script for blocks of " + + "version %d or greater must start with the " + + "serialized block height" + str = fmt.Sprintf(str, serializedHeightVersion) + return RuleError(str) + } + + serializedHeightBytes := make([]byte, 4, 4) + copy(serializedHeightBytes, sigScript[1:4]) + serializedHeight := binary.LittleEndian.Uint32(serializedHeightBytes) + if int64(serializedHeight) != wantHeight { + str := fmt.Sprintf("the coinbase signature script serialized "+ + "block height is %d when %d was expected", + serializedHeight, wantHeight) + return RuleError(str) + } + + return nil +} + +// isTransactionSpent returns whether or not the provided transaction is fully +// spent. A fully spent transaction is one where all outputs have been spent. +func isTransactionSpent(tx *txData) bool { + for _, isOutputSpent := range tx.spent { + if !isOutputSpent { + return false + } + } + return true +} + +// checkBIP0030 ensures blocks do not contain duplicate transactions which +// 'overwrite' older transactions that are not fully spent. This prevents an +// attack where a coinbase and all of its dependent transactions could be +// duplicated to effectively revert the overwritten transactions to a single +// confirmation thereby making them vulnerable to a double spend. +// +// For more details, see https://en.bitcoin.it/wiki/BIP_0030 and +// http://r6.ca/blog/20120206T005236Z.html. +func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { + // Attempt to fetch duplicate transactions for all of the transactions + // in this block from the point of view of the parent node. + fetchList, err := block.TxShas() + if err != nil { + return nil + } + txResults, err := b.fetchTxList(node, fetchList) + if err != nil { + return err + } + + // Examine the resulting data about the requested transactions. + for _, txD := range txResults { + switch txD.err { + // A duplicate transaction was not found. This is the most + // common case. + case btcdb.TxShaMissing: + continue + + // A duplicate transaction was found. This is only allowed if + // the duplicate transaction is fully spent. + case nil: + if !isTransactionSpent(txD) { + str := fmt.Sprintf("tried to overwrite "+ + "transaction %v at block height %d "+ + "that is not fully spent", txD.hash, + txD.blockHeight) + return RuleError(str) + } + + // Some other unexpected error occurred. Return it now. + default: + return txD.err + } + } + + return nil +} + +// checkTransactionInputs performs a series of checks on the inputs to a +// transaction to ensure they are valid. An example of some of the checks +// include verifying all inputs exist, ensuring the coinbase seasoning +// requirements are met, validating all values and fees are in the legal range +// and the total output amount doesn't exceed the input amount, and verifying +// the signatures to prove the spender was the owner of the bitcoins and +// therefore allowed to spend them. As it checks the inputs, it also calculates +// the total fees for the transaction and returns that value. +func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwire.ShaHash]*txData) (int64, error) { + // Coinbase transactions have no inputs. + if isCoinBase(tx) { + return 0, nil + } + + // TODO(davec): Need to pass the cached version in. + txHash, err := tx.TxSha(btcwire.ProtocolVersion) + if err != nil { + return 0, err + } + + var totalSatoshiIn int64 + for _, txIn := range tx.TxIn { + // Ensure the input is available. + txInHash := &txIn.PreviousOutpoint.Hash + originTx, exists := txStore[*txInHash] + if !exists { + str := fmt.Sprintf("unable to find input transaction "+ + "%v for transaction %v", txHash, txInHash) + return 0, RuleError(str) + } + + // Ensure the transaction is not spending coins which have not + // yet reached the required coinbase maturity. + if isCoinBase(originTx.tx) { + originHeight := originTx.blockHeight + blocksSincePrev := txHeight - originHeight + if blocksSincePrev < coinbaseMaturity { + str := fmt.Sprintf("tried to spend coinbase "+ + "transaction %v from height %v at "+ + "height %v before required maturity "+ + "of %v blocks", txHash, originHeight, + txHeight, coinbaseMaturity) + return 0, RuleError(str) + } + } + + // Ensure the transaction is not double spending coins. + originTxIndex := txIn.PreviousOutpoint.Index + if originTxIndex >= uint32(len(originTx.spent)) { + return 0, fmt.Errorf("out of bounds input index %d in "+ + "transaction %v referenced from transaction %v", + originTxIndex, txInHash, txHash) + } + if originTx.spent[originTxIndex] { + str := fmt.Sprintf("transaction %v tried to double "+ + "spend coins from transaction %v", txHash, + txInHash) + return 0, RuleError(str) + } + + // Ensure the transaction amounts are in range. Each of the + // output values of the input transactions must not be negative + // or more than the max allowed per transaction. All amounts in + // a transaction are in a unit value known as a satoshi. One + // bitcoin is a quantity of satoshi as defined by the + // satoshiPerBitcoin constant. + originTxSatoshi := originTx.tx.TxOut[originTxIndex].Value + if originTxSatoshi < 0 { + str := fmt.Sprintf("transaction output has negative "+ + "value of %v", originTxSatoshi) + return 0, RuleError(str) + } + if originTxSatoshi > maxSatoshi { + str := fmt.Sprintf("transaction output value of %v is "+ + "higher than max allowed value of %v", + originTxSatoshi, maxSatoshi) + return 0, RuleError(str) + } + + // The total of all outputs must not be more than the max + // allowed per transaction. Also, we could potentially overflow + // the accumulator so check for overflow. + lastSatoshiIn := totalSatoshiIn + totalSatoshiIn += originTxSatoshi + if totalSatoshiIn < lastSatoshiIn || totalSatoshiIn > maxSatoshi { + str := fmt.Sprintf("total value of all transaction "+ + "inputs is %v which is higher than max "+ + "allowed value of %v", totalSatoshiIn, + maxSatoshi) + return 0, RuleError(str) + } + } + + // Calculate the total output amount for this transaction. It is safe + // to ignore overflow and out of range errors here because those error + // conditions would have already been caught by checkTransactionSanity. + var totalSatoshiOut int64 + for _, txOut := range tx.TxOut { + totalSatoshiOut += txOut.Value + } + + // Ensure the transaction does not spend more than its inputs. + if totalSatoshiIn < totalSatoshiOut { + str := fmt.Sprintf("total value of all transaction inputs for "+ + "transaction %v is %v which is less than the amount "+ + "spent of %v", txHash, totalSatoshiIn, totalSatoshiOut) + return 0, RuleError(str) + } + + // NOTE: bitcoind checks if the transaction fees are < 0 here, but that + // is an impossible condition because of the check above that ensures + // the inputs are >= the outputs. + txFeeInSatoshi := totalSatoshiIn - totalSatoshiOut + return txFeeInSatoshi, nil +} + +// checkConnectBlock performs several checks to confirm connecting the passed +// block to the main chain (including whatever reorganization might be necessary +// to get this node to the main chain) does not violate any rules. +func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) error { + // If the side chain blocks end up in the database, a call to + // checkBlockSanity should be done here in case a previous version + // allowed a block that is no longer valid. However, since the + // implementation only currently uses memory for the side chain blocks, + // it isn't currently necessary. + + // TODO(davec): Keep a flag if this has already been done to avoid + // multiple runs. + + // The coinbase for the Genesis block is not spendable, so just return + // now. + if node.hash.IsEqual(&btcwire.GenesisHash) { + return nil + } + + // BIP0030 added a rule to prevent blocks which contain duplicate + // transactions that 'overwrite' older transactions which are not fully + // spent. See the documentation for checkBIP0030 for more details. + // + // There are two blocks in the chain which violate this + // rule, so the check must be skipped for those blocks. The + // isBIP0030Node function is used to determine if this block is one + // of the two blocks that must be skipped. + enforceBIP0030 := !isBIP0030Node(node) + if enforceBIP0030 { + err := b.checkBIP0030(node, block) + if err != nil { + return err + } + } + + // Request a map that contains all input transactions for the block from + // the point of view of its position within the block chain. These + // transactions are needed for verification of things such as + // transaction inputs, counting pay-to-script-hashes, and scripts. + txInputStore, err := b.fetchInputTransactions(node, block) + if err != nil { + return err + } + + // BIP0016 describes a pay-to-script-hash type that is considered a + // "standard" type. The rules for this BIP only apply to transactions + // after the timestmap defined by btcscript.Bip16Activation. See + // https://en.bitcoin.it/wiki/BIP_0016 for more details. + enforceBIP0016 := false + if node.timestamp.After(btcscript.Bip16Activation) { + enforceBIP0016 = true + } + + // The number of signature operations must be less than the maximum + // allowed per block. Note that the preliminary sanity checks on a + // block also include a check similar to this one, but this check + // expands the count to include a precise count of pay-to-script-hash + // signature operations in each of the input transaction public key + // scripts. + transactions := block.MsgBlock().Transactions + totalSigOps := 0 + for i, tx := range transactions { + // Since the first (and only the first) transaction has already + // been verified to be a coinbase transaction, use i == 0 + // as an optimization for the flag to countSigOps for whether + // or not the transaction is a coinbase transaction rather than + // having to do a full coinbase check again. + numsigOps, err := countSigOps(tx, i == 0) + if err != nil { + return err + } + if enforceBIP0016 { + numP2SHSigOps, err := countP2SHSigOps(tx, i == 0, + txInputStore) + if err != nil { + return err + } + numsigOps += numP2SHSigOps + } + + // Check for overflow or going over the limits. We have to do + // this on every loop to avoid overflow. + lastSigops := totalSigOps + totalSigOps += numsigOps + if totalSigOps < lastSigops || totalSigOps > maxSigOpsPerBlock { + str := fmt.Sprintf("block contains too many "+ + "signature operations - got %v, max %v", + totalSigOps, maxSigOpsPerBlock) + return RuleError(str) + } + } + + // Perform several checks on the inputs for each transaction. Also + // accumulate the total fees. This could technically be combined with + // the loop above instead of running another loop over the transactions, + // but by separating it we can avoid running the more expensive (though + // still relatively cheap as compared to running the scripts) checks + // against all the inputs when the signature operations are out of + // bounds. + var totalFees int64 + for _, tx := range transactions { + txFee, err := checkTransactionInputs(tx, node.height, txInputStore) + if err != nil { + return err + } + + // Sum the total fees and ensure we don't overflow the + // accumulator. + lastTotalFees := totalFees + totalFees += txFee + if totalFees < lastTotalFees { + return RuleError("total fees for block overflows " + + "accumulator") + } + } + + // The total output values of the coinbase transaction must not exceed + // the expected subsidy value plus total transaction fees gained from + // mining the block. It is safe to ignore overflow and out of range + // errors here because those error conditions would have already been + // caught by checkTransactionSanity. + var totalSatoshiOut int64 + for _, txOut := range transactions[0].TxOut { + totalSatoshiOut += txOut.Value + } + expectedSatoshiOut := calcBlockSubsidy(node.height) + totalFees + if totalSatoshiOut > expectedSatoshiOut { + str := fmt.Sprintf("coinbase transaction for block pays %v "+ + "which is more than expected value of %v", + totalSatoshiOut, expectedSatoshiOut) + return RuleError(str) + } + + // Don't run scripts if this node is before the latest known good + // checkpoint since the validity is verified via the checkpoints (all + // transactions are included in the merkle root hash and any changes + // will therefore be detected by the next checkpoint). This is a huge + // optimization because running the scripts is the most time consuming + // portion of block handling. + checkpoint := b.LatestCheckpoint() + runScripts := !b.noVerify + if checkpoint != nil && node.height <= checkpoint.Height { + runScripts = false + } + + // Now that the inexpensive checks are done and have passed, verify the + // transactions are actually allowed to spend the coins by running the + // expensive ECDSA signature check scripts. Doing this last helps + // prevent CPU exhaustion attacks. + if runScripts { + err := checkBlockScripts(block, txInputStore) + if err != nil { + return err + } + } + + return nil +} diff --git a/validate_test.go b/validate_test.go new file mode 100644 index 00000000..508aa9c5 --- /dev/null +++ b/validate_test.go @@ -0,0 +1,274 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "github.com/conformal/btcchain" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "testing" + "time" +) + +func TestCheckBlockSanity(t *testing.T) { + block := btcutil.NewBlock(&Block100000, btcwire.ProtocolVersion) + err := btcchain.TstCheckBlockSanity(block) + if err != nil { + t.Errorf("CheckBlockSanity: %v", err) + } +} + +// Block100000 defines block 100,000 of the block chain. It is used to +// test Block operations. +var Block100000 = btcwire.MsgBlock{ + Header: btcwire.BlockHeader{ + Version: 1, + PrevBlock: btcwire.ShaHash([32]byte{ // Make go vet happy. + 0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04, + 0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9, + 0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f, + 0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + }), // 000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250 + MerkleRoot: btcwire.ShaHash([32]byte{ // Make go vet happy. + 0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0, + 0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22, + 0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85, + 0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3, + }), // f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 + Timestamp: time.Unix(1293623863, 0), // 2010-12-29 11:57:43 +0000 UTC + Bits: 0x1b04864c, // 453281356 + Nonce: 0x10572b0f, // 274148111 + TxnCount: 4, + }, + Transactions: []*btcwire.MsgTx{ + &btcwire.MsgTx{ + Version: 1, + TxIn: []*btcwire.TxIn{ + &btcwire.TxIn{ + PreviousOutpoint: btcwire.OutPoint{ + Hash: btcwire.ShaHash{}, + Index: 0xffffffff, + }, + SignatureScript: []byte{ + 0x04, 0x4c, 0x86, 0x04, 0x1b, 0x02, 0x06, 0x02, + }, + Sequence: 0xffffffff, + }, + }, + TxOut: []*btcwire.TxOut{ + &btcwire.TxOut{ + Value: 0x12a05f200, // 5000000000 + PkScript: []byte{ + 0x41, // OP_DATA_65 + 0x04, 0x1b, 0x0e, 0x8c, 0x25, 0x67, 0xc1, 0x25, + 0x36, 0xaa, 0x13, 0x35, 0x7b, 0x79, 0xa0, 0x73, + 0xdc, 0x44, 0x44, 0xac, 0xb8, 0x3c, 0x4e, 0xc7, + 0xa0, 0xe2, 0xf9, 0x9d, 0xd7, 0x45, 0x75, 0x16, + 0xc5, 0x81, 0x72, 0x42, 0xda, 0x79, 0x69, 0x24, + 0xca, 0x4e, 0x99, 0x94, 0x7d, 0x08, 0x7f, 0xed, + 0xf9, 0xce, 0x46, 0x7c, 0xb9, 0xf7, 0xc6, 0x28, + 0x70, 0x78, 0xf8, 0x01, 0xdf, 0x27, 0x6f, 0xdf, + 0x84, // 65-byte signature + 0xac, // OP_CHECKSIG + }, + }, + }, + LockTime: 0, + }, + &btcwire.MsgTx{ + Version: 1, + TxIn: []*btcwire.TxIn{ + &btcwire.TxIn{ + PreviousOutpoint: btcwire.OutPoint{ + Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. + 0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60, + 0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac, + 0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07, + 0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87, + }), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03 + Index: 0, + }, + SignatureScript: []byte{ + 0x49, // OP_DATA_73 + 0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3, + 0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6, + 0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94, + 0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58, + 0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00, + 0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62, + 0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c, + 0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60, + 0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48, + 0x01, // 73-byte signature + 0x41, // OP_DATA_65 + 0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d, + 0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38, + 0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25, + 0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e, + 0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8, + 0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd, + 0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b, + 0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3, + 0xd3, // 65-byte pubkey + }, + Sequence: 0xffffffff, + }, + }, + TxOut: []*btcwire.TxOut{ + &btcwire.TxOut{ + Value: 0x2123e300, // 556000000 + PkScript: []byte{ + 0x76, // OP_DUP + 0xa9, // OP_HASH160 + 0x14, // OP_DATA_20 + 0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60, + 0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e, + 0xf7, 0xf5, 0x8b, 0x32, + 0x88, // OP_EQUALVERIFY + 0xac, // OP_CHECKSIG + }, + }, + &btcwire.TxOut{ + Value: 0x108e20f00, // 4444000000 + PkScript: []byte{ + 0x76, // OP_DUP + 0xa9, // OP_HASH160 + 0x14, // OP_DATA_20 + 0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f, + 0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b, + 0x52, 0xde, 0x3d, 0x7c, + 0x88, // OP_EQUALVERIFY + 0xac, // OP_CHECKSIG + }, + }, + }, + LockTime: 0, + }, + &btcwire.MsgTx{ + Version: 1, + TxIn: []*btcwire.TxIn{ + &btcwire.TxIn{ + PreviousOutpoint: btcwire.OutPoint{ + Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. + 0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d, + 0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27, + 0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65, + 0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf, + }), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3 + Index: 1, + }, + SignatureScript: []byte{ + 0x47, // OP_DATA_71 + 0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf, + 0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5, + 0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34, + 0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31, + 0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee, + 0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f, + 0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c, + 0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e, + 0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01, + 0x41, // OP_DATA_65 + 0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78, + 0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5, + 0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39, + 0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21, + 0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee, + 0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3, + 0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95, + 0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85, + 0x0f, // 65-byte pubkey + }, + Sequence: 0xffffffff, + }, + }, + TxOut: []*btcwire.TxOut{ + &btcwire.TxOut{ + Value: 0xf4240, // 1000000 + PkScript: []byte{ + 0x76, // OP_DUP + 0xa9, // OP_HASH160 + 0x14, // OP_DATA_20 + 0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04, + 0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d, + 0xad, 0xbe, 0x7e, 0x10, + 0x88, // OP_EQUALVERIFY + 0xac, // OP_CHECKSIG + }, + }, + &btcwire.TxOut{ + Value: 0x11d260c0, // 299000000 + PkScript: []byte{ + 0x76, // OP_DUP + 0xa9, // OP_HASH160 + 0x14, // OP_DATA_20 + 0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1, + 0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab, + 0xb3, 0x40, 0x9c, 0xd9, + 0x88, // OP_EQUALVERIFY + 0xac, // OP_CHECKSIG + }, + }, + }, + LockTime: 0, + }, + &btcwire.MsgTx{ + Version: 1, + TxIn: []*btcwire.TxIn{ + &btcwire.TxIn{ + PreviousOutpoint: btcwire.OutPoint{ + Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. + 0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73, + 0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac, + 0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90, + 0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4, + }), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b + Index: 0, + }, + SignatureScript: []byte{ + 0x49, // OP_DATA_73 + 0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2, + 0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c, + 0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd, + 0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f, + 0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00, + 0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14, + 0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb, + 0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c, + 0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3, + 0x01, // 73-byte signature + 0x41, // OP_DATA_65 + 0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97, + 0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18, + 0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17, + 0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94, + 0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65, + 0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f, + 0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce, + 0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f, + 0xbb, // 65-byte pubkey + }, + Sequence: 0xffffffff, + }, + }, + TxOut: []*btcwire.TxOut{ + &btcwire.TxOut{ + Value: 0xf4240, // 1000000 + PkScript: []byte{ + 0x76, // OP_DUP + 0xa9, // OP_HASH160 + 0x14, // OP_DATA_20 + 0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7, + 0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b, + 0xf2, 0xeb, 0x9e, 0xe0, + 0x88, // OP_EQUALVERIFY + 0xac, // OP_CHECKSIG + }, + }, + }, + LockTime: 0, + }, + }, +} From 355502c97087530b89e737fed3c3d4b5fe8f0764 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 19 Jul 2013 10:08:09 -0500 Subject: [PATCH 003/190] Update documentation for IsCheckpointCandidate. The bulleted list was not indented which caused godoc to show the documentation improperly. --- checkpoints.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/checkpoints.go b/checkpoints.go index ba3a4233..8f2077c3 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -167,14 +167,14 @@ func isNonstandardTransaction(tx *btcwire.MsgTx) bool { // checkpoint candidate. // // The factors used to determine a good checkpoint are: -// - The block must be in the main chain -// - The block must be at least 'CheckpointConfirmations' blocks prior to the -// current end of the main chain -// - The timestamps for the blocks before and after the checkpoint must have -// timestamps which are also before and after the checkpoint, respectively -// (due to the median time allowance this is not always the case) -// - The block must not contain any strange transaction such as those with -// nonstandard scripts +// - The block must be in the main chain +// - The block must be at least 'CheckpointConfirmations' blocks prior to the +// current end of the main chain +// - The timestamps for the blocks before and after the checkpoint must have +// timestamps which are also before and after the checkpoint, respectively +// (due to the median time allowance this is not always the case) +// - The block must not contain any strange transaction such as those with +// nonstandard scripts func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { // Checkpoints must be enabled. if b.noCheckpoints { From 20f7c2ecd07d5d7ed7ebe5aa47b979627362530f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 18 Jul 2013 10:06:35 -0500 Subject: [PATCH 004/190] Add tests for TimeSorter. --- internal_test.go | 7 +++++++ timesorter_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 timesorter_test.go diff --git a/internal_test.go b/internal_test.go index c5c9a404..d82fdb03 100644 --- a/internal_test.go +++ b/internal_test.go @@ -13,6 +13,7 @@ package btcchain import ( "github.com/conformal/btcutil" + "time" ) // TstCheckBlockSanity makes the internal checkBlockSanity function available to @@ -26,3 +27,9 @@ func TstCheckBlockSanity(block *btcutil.Block) error { func TstSetCoinbaseMaturity(maturity int64) { coinbaseMaturity = maturity } + +// TstTimeSorter makes the internal timeSorter type available to the test +// package. +func TstTimeSorter(times []time.Time) timeSorter { + return timeSorter(times) +} diff --git a/timesorter_test.go b/timesorter_test.go new file mode 100644 index 00000000..397feae0 --- /dev/null +++ b/timesorter_test.go @@ -0,0 +1,51 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "github.com/conformal/btcchain" + "reflect" + "sort" + "testing" + "time" +) + +// TestTimeSorter tests the timeSorter implementation. +func TestTimeSorter(t *testing.T) { + tests := []struct { + in []time.Time + want []time.Time + }{ + { + in: []time.Time{ + time.Unix(1351228575, 0), // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) + time.Unix(1351228575, 1), // Fri Oct 26 05:16:15 UTC 2012 (+1 nanosecond) + time.Unix(1348310759, 0), // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) + time.Unix(1305758502, 0), // Wed May 18 22:41:42 UTC 2011 (Block #125000) + time.Unix(1347777156, 0), // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) + time.Unix(1349492104, 0), // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) + }, + want: []time.Time{ + time.Unix(1305758502, 0), // Wed May 18 22:41:42 UTC 2011 (Block #125000) + time.Unix(1347777156, 0), // Sun Sep 16 06:32:36 UTC 2012 (Block #199000) + time.Unix(1348310759, 0), // Sat Sep 22 10:45:59 UTC 2012 (Block #200000) + time.Unix(1349492104, 0), // Sat Oct 6 02:55:04 UTC 2012 (Block #202000) + time.Unix(1351228575, 0), // Fri Oct 26 05:16:15 UTC 2012 (Block #205000) + time.Unix(1351228575, 1), // Fri Oct 26 05:16:15 UTC 2012 (+1 nanosecond) + }, + }, + } + + for i, test := range tests { + result := make([]time.Time, len(test.in)) + copy(result, test.in) + sort.Sort(btcchain.TstTimeSorter(result)) + if !reflect.DeepEqual(result, test.want) { + t.Errorf("timeSorter #%d got %v want %v", i, result, + test.want) + continue + } + } +} From d6d2b15901e3e1f8bd1376badfac4eca11eebe32 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 20 Jul 2013 02:39:07 -0500 Subject: [PATCH 005/190] Clarify BIP0034 is supported in package doco. --- doc.go | 1 + 1 file changed, 1 insertion(+) diff --git a/doc.go b/doc.go index a96b6ad8..7effc092 100644 --- a/doc.go +++ b/doc.go @@ -116,6 +116,7 @@ This package includes spec changes outlined by the following BIPs: BIP0016 (https://en.bitcoin.it/wiki/BIP_0016) BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) + BIP0034 (https://en.bitcoin.it/wiki/BIP_0034) Other important information From f3e542ff92c9cbfcd46b3ba6943b60026f7fb631 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 22 Jul 2013 01:06:53 -0500 Subject: [PATCH 006/190] Add negative test for duplicate block. This commit adds tests for the error path when processing a block that is already in the main chain. --- test_coverage.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_coverage.txt b/test_coverage.txt index 736687db..d2f3d9bc 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -44,9 +44,9 @@ github.com/conformal/btcchain/validate.go checkTransactionInputs 63.64% (28/ github.com/conformal/btcchain/validate.go checkTransactionSanity 62.16% (23/37) github.com/conformal/btcchain/txlookup.go connectTransactions 60.00% (9/15) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) +github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 59.09% (26/44) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/14) github.com/conformal/btcchain/validate.go checkProofOfWork 56.25% (9/16) -github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 54.55% (24/44) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) @@ -73,5 +73,5 @@ github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 59.02% (569/964) +github.com/conformal/btcchain ------------------------------------- 59.23% (571/964) From ebd4af80f0be633617ec9b786992c500c400a879 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 22 Jul 2013 03:20:00 -0500 Subject: [PATCH 007/190] Make CheckpointConfirmations 2016. After discussing the criteria used by the core developers on #btc-dev IRC channel, gmaxwell indicated they like to see at least 2016 blocks. This commit updates the checkpoint confirmations accordingly. --- checkpoints.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkpoints.go b/checkpoints.go index 8f2077c3..6ba4972e 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -11,7 +11,7 @@ import ( "github.com/conformal/btcwire" ) -const CheckpointConfirmations = 20 +const CheckpointConfirmations = 2016 // A checkpoint is a known good point in the block chain. Using checkpoints // allows a few optimizations for old blocks during initial download and also From 3c4292fae395cbacf971ccb4e29e175b78611f33 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 24 Jul 2013 11:12:25 -0500 Subject: [PATCH 008/190] Add parent to info print when adding orphans. --- process.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/process.go b/process.go index 5b9eef98..5b96a608 100644 --- a/process.go +++ b/process.go @@ -144,7 +144,8 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { prevHash := &blockHeader.PrevBlock if !prevHash.IsEqual(zeroHash) && !b.blockExists(prevHash) { // Add the orphan block to the orphan pool. - log.Infof("Adding orphan block %v", blockHash) + log.Infof("Adding orphan block %v with parent %v", blockHash, + prevHash) b.addOrphanBlock(block) // Get the hash for the head of the orphaned block chain for From f219ed5baf6803c7972e97efa87bcb424a72a836 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 24 Jul 2013 11:37:45 -0500 Subject: [PATCH 009/190] Add support for params based on active network. This commit modifies the code to use params based on the active network which paves the way for supporting the special rules and different genesis blocks used by the test networks. --- accept.go | 2 +- chain.go | 4 +-- difficulty.go | 15 ++++++----- internal_test.go | 4 +-- params.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++ process.go | 4 +-- test_coverage.txt | 23 ++++++++-------- validate.go | 7 ++--- validate_test.go | 18 ++++++++++++- 9 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 params.go diff --git a/accept.go b/accept.go index e52dad09..94fa73c7 100644 --- a/accept.go +++ b/accept.go @@ -32,7 +32,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // calculated difficulty based on the previous block and difficulty // retarget rules. blockHeader := block.MsgBlock().Header - expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode) + expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) if err != nil { return err } diff --git a/chain.go b/chain.go index 40e378ab..4113c914 100644 --- a/chain.go +++ b/chain.go @@ -339,7 +339,7 @@ func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { } // Genesis block. - if node.hash.IsEqual(&btcwire.GenesisHash) { + if node.hash.IsEqual(b.netParams().genesisHash) { return nil, nil } @@ -393,7 +393,7 @@ func (b *BlockChain) isMajorityVersion(minVer uint32, startNode *blockNode, numR func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) { // Genesis block. if startNode == nil { - return btcwire.GenesisBlock.Header.Timestamp, nil + return b.netParams().genesisBlock.Header.Timestamp, nil } // Create a slice of the previous few block timestamps used to calculate diff --git a/difficulty.go b/difficulty.go index c30ad7ac..c39182ec 100644 --- a/difficulty.go +++ b/difficulty.go @@ -6,6 +6,7 @@ package btcchain import ( "fmt" + "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math/big" "time" @@ -50,10 +51,6 @@ var ( // oneLsh256 is 1 shifted left 256 bits. It is defined here to avoid // the overhead of creating it multiple times. oneLsh256 = new(big.Int).Lsh(bigOne, 256) - - // powLimit is the highest proof of work value a bitcoin block can have. - // It is the value 2^224 - 1. - powLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) ) // ShaHashToBig converts a btcwire.ShaHash into a big.Int that can be used to @@ -185,11 +182,14 @@ func calcWork(bits uint32) *big.Rat { // can have given starting difficulty bits and a duration. It is mainly used to // verify that claimed proof of work by a block is sane as compared to a // known good checkpoint. -func calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { +func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { // Convert types used in the calculations below. durationVal := int64(duration) adjustmentFactor := big.NewInt(retargetAdjustmentFactor) + // Choose the correct proof of work limit for the active network. + powLimit := b.netParams().powLimit + // TODO(davec): Testnet has special rules. // Since easier difficulty equates to higher numbers, the easiest @@ -212,7 +212,10 @@ func calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { // calcNextRequiredDifficulty calculates the required difficulty for the block // after the passed previous block node based on the difficulty retarget rules. -func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode) (uint32, error) { +func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcutil.Block) (uint32, error) { + // Choose the correct proof of work limit for the active network. + powLimit := b.netParams().powLimit + // Genesis block. if lastNode == nil { return BigToCompact(powLimit), nil diff --git a/internal_test.go b/internal_test.go index d82fdb03..0ad1f9d4 100644 --- a/internal_test.go +++ b/internal_test.go @@ -18,8 +18,8 @@ import ( // TstCheckBlockSanity makes the internal checkBlockSanity function available to // the test package. -func TstCheckBlockSanity(block *btcutil.Block) error { - return checkBlockSanity(block) +func (b *BlockChain) TstCheckBlockSanity(block *btcutil.Block) error { + return b.checkBlockSanity(block) } // TstSetCoinbaseMaturity makes the ability to set the coinbase maturity diff --git a/params.go b/params.go new file mode 100644 index 00000000..5307e590 --- /dev/null +++ b/params.go @@ -0,0 +1,68 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "github.com/conformal/btcwire" + "math/big" +) + +// params is used to group parameters for various networks such as the main +// network and test networks. +type params struct { + genesisBlock *btcwire.MsgBlock + genesisHash *btcwire.ShaHash + powLimit *big.Int +} + +// mainNetParams contains parameters specific to the main network +// (btcwire.MainNet). +var mainNetParams = params{ + genesisBlock: &btcwire.GenesisBlock, + genesisHash: &btcwire.GenesisHash, + + // powLimit is the highest proof of work value a bitcoin block can have. + // It is the value 2^224 - 1 for the main network. + powLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), +} + +// regressionParams contains parameters specific to the regression test network +// (btcwire.TestNet). +var regressionParams = params{ + genesisBlock: &btcwire.TestNetGenesisBlock, + genesisHash: &btcwire.TestNetGenesisHash, + + // powLimit is the highest proof of work value a bitcoin block can have. + // It is the value 2^256 - 1 for the regression test network. + powLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne), +} + +// testNet3Params contains parameters specific to the test network (version 3) +// (btcwire.TestNet3). +var testNet3Params = params{ + genesisBlock: &btcwire.TestNet3GenesisBlock, + genesisHash: &btcwire.TestNet3GenesisHash, + + // powLimit is the highest proof of work value a bitcoin block can have. + // It is the value 2^224 - 1 for the test network (version 3). + powLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), +} + +// netParams returns parameters specific to the passed bitcoin network. +func (b *BlockChain) netParams() *params { + switch b.btcnet { + case btcwire.TestNet: + return ®ressionParams + + case btcwire.TestNet3: + return &testNet3Params + + // Return main net by default. + case btcwire.MainNet: + fallthrough + default: + return &mainNetParams + } +} diff --git a/process.go b/process.go index 5b96a608..876dc330 100644 --- a/process.go +++ b/process.go @@ -95,7 +95,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { } // Perform preliminary sanity checks on the block and its transactions. - err = checkBlockSanity(block) + err = b.checkBlockSanity(block) if err != nil { return err } @@ -129,7 +129,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { // expected based on elapsed time since the last checkpoint and // maximum adjustment allowed by the retarget rules. duration := blockHeader.Timestamp.Sub(checkpointTime) - requiredTarget := CompactToBig(calcEasiestDifficulty( + requiredTarget := CompactToBig(b.calcEasiestDifficulty( checkpointHeader.Bits, duration)) currentTarget := CompactToBig(blockHeader.Bits) if currentTarget.Cmp(requiredTarget) > 0 { diff --git a/test_coverage.txt b/test_coverage.txt index d2f3d9bc..ac6ba4c3 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -2,21 +2,21 @@ github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (12/12) github.com/conformal/btcchain/chain.go BlockChain.getOrphanRoot 100.00% (7/7) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) github.com/conformal/btcchain/difficulty.go calcWork 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) github.com/conformal/btcchain/process.go BlockChain.processOrphans 91.67% (11/12) @@ -37,30 +37,31 @@ github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10 github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 75.00% (12/16) github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 68.52% (37/54) -github.com/conformal/btcchain/validate.go checkBlockSanity 66.67% (30/45) +github.com/conformal/btcchain/validate.go BlockChain.checkBlockSanity 66.67% (30/45) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) github.com/conformal/btcchain/scriptval.go validateTxIn 64.71% (11/17) github.com/conformal/btcchain/validate.go checkTransactionInputs 63.64% (28/44) github.com/conformal/btcchain/validate.go checkTransactionSanity 62.16% (23/37) github.com/conformal/btcchain/txlookup.go connectTransactions 60.00% (9/15) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) +github.com/conformal/btcchain/params.go BlockChain.netParams 60.00% (3/5) github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 59.09% (26/44) +github.com/conformal/btcchain/validate.go BlockChain.checkProofOfWork 58.82% (10/17) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/14) -github.com/conformal/btcchain/validate.go checkProofOfWork 56.25% (9/16) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) -github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 49.23% (32/65) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 33.33% (4/12) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 33.33% (2/6) github.com/conformal/btcchain/validate.go isFinalizedTransaction 23.08% (3/13) github.com/conformal/btcchain/checkpoints.go BlockChain.findLatestKnownCheckpoint 18.18% (2/11) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 10.71% (3/28) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 13.79% (4/29) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/26) github.com/conformal/btcchain/difficulty.go BigToCompact 0.00% (0/16) github.com/conformal/btcchain/validate.go checkSerializedHeight 0.00% (0/12) -github.com/conformal/btcchain/difficulty.go calcEasiestDifficulty 0.00% (0/9) +github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/10) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) @@ -70,8 +71,8 @@ github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 59.23% (571/964) +github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 59.26% (576/972) diff --git a/validate.go b/validate.go index f30afd96..d5936a00 100644 --- a/validate.go +++ b/validate.go @@ -267,7 +267,7 @@ func checkTransactionSanity(tx *btcwire.MsgTx) error { // checkProofOfWork ensures the block header bits which indicate the target // difficulty is in min/max range and that the block hash is less than the // target difficulty as claimed. -func checkProofOfWork(block *btcutil.Block) error { +func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { // The target difficulty must be larger than zero. header := block.MsgBlock().Header target := CompactToBig(header.Bits) @@ -278,6 +278,7 @@ func checkProofOfWork(block *btcutil.Block) error { } // The target difficulty must be less than the maximum allowed. + powLimit := b.netParams().powLimit if target.Cmp(powLimit) > 0 { str := fmt.Sprintf("block target difficulty of %064x is "+ "higher than max of %064x", target, powLimit) @@ -407,7 +408,7 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir // checkBlockSanity performs some preliminary checks on a block to ensure it is // sane before continuing with block processing. These checks are context free. -func checkBlockSanity(block *btcutil.Block) error { +func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // NOTE: bitcoind does size limits checking here, but the size limits // have already been checked by btcwire for incoming blocks. Also, // btcwire checks the size limits on send too, so there is no need @@ -416,7 +417,7 @@ func checkBlockSanity(block *btcutil.Block) error { // Ensure the proof of work bits in the block header is in min/max range // and the block hash is less than the target value described by the // bits. - err := checkProofOfWork(block) + err := b.checkProofOfWork(block) if err != nil { return err } diff --git a/validate_test.go b/validate_test.go index 508aa9c5..1d84b8d3 100644 --- a/validate_test.go +++ b/validate_test.go @@ -6,15 +6,31 @@ package btcchain_test import ( "github.com/conformal/btcchain" + "github.com/conformal/btcdb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" + "os" "testing" "time" ) func TestCheckBlockSanity(t *testing.T) { + // Create a new test database. + dbName := "cbsanitytest.db" + _ = os.Remove(dbName) + db, err := btcdb.CreateDB("sqlite", dbName) + if err != nil { + t.Errorf("Error creating db: %v\n", err) + } + defer os.Remove(dbName) + defer db.Close() + + // Create a new BlockChain instance using the underlying database for + // the main bitcoin network and ignore notifications. + chain := btcchain.New(db, btcwire.MainNet, nil) + block := btcutil.NewBlock(&Block100000, btcwire.ProtocolVersion) - err := btcchain.TstCheckBlockSanity(block) + err = chain.TstCheckBlockSanity(block) if err != nil { t.Errorf("CheckBlockSanity: %v", err) } From 1deeb05627fcdf7562ac8c255f8f9387385b895d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 24 Jul 2013 12:31:14 -0500 Subject: [PATCH 010/190] Add a few log error messages. In addition to returning errors to the caller, log the error with a prefix in a few key places that helps identify the origin for errors. In some cases, the underlying error comes from a different subsystem such as the SQL database driver and the error messages can be fairly generic. --- accept.go | 4 ++++ chain.go | 1 + 2 files changed, 5 insertions(+) diff --git a/accept.go b/accept.go index 94fa73c7..58a7d150 100644 --- a/accept.go +++ b/accept.go @@ -19,6 +19,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // if this is the genesis block. prevNode, err := b.getPrevNodeFromBlock(block) if err != nil { + log.Errorf("getPrevNodeFromBlock: %v", err) return err } @@ -34,6 +35,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { blockHeader := block.MsgBlock().Header expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) if err != nil { + log.Errorf("calcNextRequiredDifficulty: %v", err) return err } blockDifficulty := blockHeader.Bits @@ -47,6 +49,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // the last several blocks (medianTimeBlocks). medianTime, err := b.calcPastMedianTime(prevNode) if err != nil { + log.Errorf("calcPastMedianTime: %v", err) return err } if !blockHeader.Timestamp.After(medianTime) { @@ -147,6 +150,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // also handles validation of the transaction scripts. err = b.connectBestChain(newNode, block) if err != nil { + log.Errorf("connectBestChain: %v", err) return err } diff --git a/chain.go b/chain.go index 4113c914..b9a6efe3 100644 --- a/chain.go +++ b/chain.go @@ -413,6 +413,7 @@ func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) var err error iterNode, err = b.getPrevNodeFromNode(iterNode) if err != nil { + log.Errorf("getPrevNodeFromNode: %v", err) return time.Time{}, err } } From 9787f46f6acbfacdad4baacaa2b235f766bfa456 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 24 Jul 2013 16:43:39 -0500 Subject: [PATCH 011/190] Implement testnet specific rules. This commit adds support for testnet specific rules when a new BlockChain is created against testnet. --- README.md | 1 - difficulty.go | 78 +++++++++++++++++++++++++++++++++++++++++++++-- test_coverage.txt | 25 +++++++-------- 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 2c9bf4d2..0860666f 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,6 @@ intentionally causes an error by attempting to process a duplicate block. ## TODO - Increase test coverage -- Add testnet specific rules - Profile and optimize - Expose some APIs for block verification (without actually inserting it) and transaction input lookups diff --git a/difficulty.go b/difficulty.go index c39182ec..4497da13 100644 --- a/difficulty.go +++ b/difficulty.go @@ -190,7 +190,17 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) // Choose the correct proof of work limit for the active network. powLimit := b.netParams().powLimit - // TODO(davec): Testnet has special rules. + // The test network rules allow minimum difficulty blocks after more + // than twice the desired amount of time needed to generate a block has + // elapsed. + switch b.btcnet { + case btcwire.TestNet: + fallthrough + case btcwire.TestNet3: + if durationVal > int64(targetSpacing)*2 { + return BigToCompact(powLimit) + } + } // Since easier difficulty equates to higher numbers, the easiest // difficulty for a given duration is the largest value possible given @@ -210,6 +220,36 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) return BigToCompact(newTarget) } +// findPrevTestNetDifficulty returns the difficulty of the previous block which +// did not have the special testnet minimum difficulty rule applied. +func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) { + // Search backwards through the chain for the last block without + // the special rule applied. + powLimitBits := BigToCompact(b.netParams().powLimit) + iterNode := startNode + for iterNode != nil && iterNode.height%blocksPerRetarget != 0 && iterNode.bits == powLimitBits { + // Get the previous block node. This function is used over + // simply accessing iterNode.parent directly as it will + // dynamically create previous block nodes as needed. This + // helps allow only the pieces of the chain that are needed + // to remain in memory. + var err error + iterNode, err = b.getPrevNodeFromNode(iterNode) + if err != nil { + log.Errorf("getPrevNodeFromNode: %v", err) + return 0, err + } + } + + // Return the found difficulty or the minimum difficulty if no + // appropriate block was found. + lastBits := powLimitBits + if iterNode != nil { + lastBits = iterNode.bits + } + return lastBits, nil +} + // calcNextRequiredDifficulty calculates the required difficulty for the block // after the passed previous block node based on the difficulty retarget rules. func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcutil.Block) (uint32, error) { @@ -224,8 +264,40 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu // Return the previous block's difficulty requirements if this block // is not at a difficulty retarget interval. if (lastNode.height+1)%blocksPerRetarget != 0 { - // TODO(davec): Testnet has special rules. - return lastNode.bits, nil + // The difficulty rules differ between networks. + switch b.btcnet { + // The test network rules allow minimum difficulty blocks after + // more than twice the desired amount of time needed to generate + // a block has elapsed. + case btcwire.TestNet: + fallthrough + case btcwire.TestNet3: + // Return minimum difficulty when more than twice the + // desired amount of time needed to generate a block has + // elapsed. + newBlockTime := block.MsgBlock().Header.Timestamp + allowMinTime := lastNode.timestamp.Add(targetSpacing * 2) + if newBlockTime.After(allowMinTime) { + return BigToCompact(powLimit), nil + } + + // The block was mined within the desired timeframe, so + // return the difficulty for the last block which did + // not have the special minimum difficulty rule applied. + prevBits, err := b.findPrevTestNetDifficulty(lastNode) + if err != nil { + return 0, err + } + return prevBits, nil + + // For the main network (or any unrecognized networks), simply + // return the previous block's difficulty. + case btcwire.MainNet: + fallthrough + default: + // Return the previous block's difficulty requirements. + return lastNode.bits, nil + } } // Get the block node at the previous retarget (targetTimespan days diff --git a/test_coverage.txt b/test_coverage.txt index ac6ba4c3..ae333a52 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -2,33 +2,33 @@ github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (12/12) github.com/conformal/btcchain/chain.go BlockChain.getOrphanRoot 100.00% (7/7) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) -github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) +github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) +github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/difficulty.go calcWork 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) github.com/conformal/btcchain/process.go BlockChain.processOrphans 91.67% (11/12) github.com/conformal/btcchain/txlookup.go disconnectTransactions 90.91% (10/11) github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxList 88.57% (31/35) github.com/conformal/btcchain/scriptval.go validateAllTxIn 87.88% (29/33) -github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 87.50% (14/16) github.com/conformal/btcchain/scriptval.go checkBlockScripts 87.50% (7/8) github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 86.96% (20/23) github.com/conformal/btcchain/validate.go countSigOps 86.67% (13/15) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) github.com/conformal/btcchain/validate.go isCoinBase 83.33% (5/6) +github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 80.77% (21/26) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 78.26% (18/23) @@ -51,17 +51,18 @@ github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/1 github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 49.23% (32/65) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 46.38% (32/69) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 33.33% (4/12) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 33.33% (2/6) github.com/conformal/btcchain/validate.go isFinalizedTransaction 23.08% (3/13) github.com/conformal/btcchain/checkpoints.go BlockChain.findLatestKnownCheckpoint 18.18% (2/11) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 13.79% (4/29) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 15.00% (6/40) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/26) github.com/conformal/btcchain/difficulty.go BigToCompact 0.00% (0/16) +github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/14) github.com/conformal/btcchain/validate.go checkSerializedHeight 0.00% (0/12) -github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/10) +github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) @@ -69,10 +70,10 @@ github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 59.26% (576/972) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 57.57% (578/1004) From b282678d9a49091b75a1c26cff7ff16703c528d2 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 26 Jul 2013 11:50:20 -0500 Subject: [PATCH 012/190] Spend outputs while checking transaction inputs. This commit modifies the double spend detection to handle double spends within the same block as well as side chains when doing the checks before reorganizing the chain. --- validate.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/validate.go b/validate.go index d5936a00..114dd19b 100644 --- a/validate.go +++ b/validate.go @@ -605,11 +605,11 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // checkTransactionInputs performs a series of checks on the inputs to a // transaction to ensure they are valid. An example of some of the checks // include verifying all inputs exist, ensuring the coinbase seasoning -// requirements are met, validating all values and fees are in the legal range -// and the total output amount doesn't exceed the input amount, and verifying -// the signatures to prove the spender was the owner of the bitcoins and -// therefore allowed to spend them. As it checks the inputs, it also calculates -// the total fees for the transaction and returns that value. +// requirements are met, detecting double spends, validating all values and fees +// are in the legal range and the total output amount doesn't exceed the input +// amount, and verifying the signatures to prove the spender was the owner of +// the bitcoins and therefore allowed to spend them. As it checks the inputs, +// it also calculates the total fees for the transaction and returns that value. func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwire.ShaHash]*txData) (int64, error) { // Coinbase transactions have no inputs. if isCoinBase(tx) { @@ -693,6 +693,9 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi maxSatoshi) return 0, RuleError(str) } + + // Mark the referenced output as spent. + originTx.spent[originTxIndex] = true } // Calculate the total output amount for this transaction. It is safe From ace58495c8ef07843eca3c7cd102d9295d0d9449 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 27 Jul 2013 16:45:59 -0500 Subject: [PATCH 013/190] Comment CheckpointConfirmations. --- checkpoints.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/checkpoints.go b/checkpoints.go index 6ba4972e..3bfce683 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -11,6 +11,8 @@ import ( "github.com/conformal/btcwire" ) +// CheckpointConfirmations is the number of blocks before the end of the current +// best block chain that a good checkpoint candidate must be. const CheckpointConfirmations = 2016 // A checkpoint is a known good point in the block chain. Using checkpoints From 761f666c4483b88da84d670f3ff86af1774d1708 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 27 Jul 2013 16:46:46 -0500 Subject: [PATCH 014/190] Use consistent form for Checkpoint comment. --- checkpoints.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/checkpoints.go b/checkpoints.go index 3bfce683..818b2fb9 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -15,9 +15,9 @@ import ( // best block chain that a good checkpoint candidate must be. const CheckpointConfirmations = 2016 -// A checkpoint is a known good point in the block chain. Using checkpoints -// allows a few optimizations for old blocks during initial download and also -// prevents forks from old blocks. +// Checkpoint identifies a known good point in the block chain. Using +// checkpoints allows a few optimizations for old blocks during initial download +// and also prevents forks from old blocks. // // Each checkpoint is selected by the core developers based upon several // factors. See the documentation for IsCheckpointCandidate for details From e82c97be3bc4778ba382e6f4b5c32b646b27fc39 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 12:35:01 -0500 Subject: [PATCH 015/190] Update examples for recent btcdb changes. Since creating a new database with btcdb no longer automatically inserts the main network genesis block, update the examples accordingly. --- README.md | 29 +++++++++++++++++++++++------ doc.go | 29 +++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0860666f..a5395400 100644 --- a/README.md +++ b/README.md @@ -82,19 +82,37 @@ intentionally causes an error by attempting to process a duplicate block. _ "github.com/conformal/btcdb/sqlite3" "github.com/conformal/btcutil" "github.com/conformal/btcwire" + "os" ) func main() { - // First, we create a new database to store the accepted blocks into. - // Typically this would be opening an existing database, but we create - // a new db here so this is a complete working example. - db, err := btcdb.CreateDB("sqlite", "example.db") + // Create a new database to store the accepted blocks into. Typically + // this would be opening an existing database, but we create a new db + // here so this is a complete working example. Also, typically the + // calls to os.Remove would not be used either, but again, we want + // a complete working example here, so we make sure to remove the + // database. + dbName := "example.db" + _ = os.Remove(dbName) + db, err := btcdb.CreateDB("sqlite", dbName) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } + defer os.Remove(dbName) // Ignore error. defer db.Close() + // Insert the main network genesis block. This is part of the initial + // database setup. Like above, this typically would not be needed when + // opening an existing database. + pver := btcwire.ProtocolVersion + genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock, pver) + _, err = db.InsertBlock(genesisBlock) + if err != nil { + fmt.Printf("Failed to insert genesis block: %v\n", err) + return + } + // Create a new BlockChain instance using the underlying database for // the main bitcoin network and ignore notifications. chain := btcchain.New(db, btcwire.MainNet, nil) @@ -102,8 +120,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - block := btcutil.NewBlock(&btcwire.GenesisBlock, btcwire.ProtocolVersion) - err = chain.ProcessBlock(block) + err = chain.ProcessBlock(genesisBlock) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/doc.go b/doc.go index 7effc092..4d068260 100644 --- a/doc.go +++ b/doc.go @@ -75,19 +75,37 @@ intentionally causes an error by attempting to process a duplicate block. _ "github.com/conformal/btcdb/sqlite3" "github.com/conformal/btcutil" "github.com/conformal/btcwire" + "os" ) func main() { - // First, we create a new database to store the accepted blocks into. - // Typically this would be opening an existing database, but we create - // a new db here so this is a complete working example. - db, err := btcdb.CreateDB("sqlite", "example.db") + // Create a new database to store the accepted blocks into. Typically + // this would be opening an existing database, but we create a new db + // here so this is a complete working example. Also, typically the + // calls to os.Remove would not be used either, but again, we want + // a complete working example here, so we make sure to remove the + // database. + dbName := "example.db" + _ = os.Remove(dbName) + db, err := btcdb.CreateDB("sqlite", dbName) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } + defer os.Remove(dbName) // Ignore error. defer db.Close() + // Insert the main network genesis block. This is part of the initial + // database setup. Like above, this typically would not be needed when + // opening an existing database. + pver := btcwire.ProtocolVersion + genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock, pver) + _, err = db.InsertBlock(genesisBlock) + if err != nil { + fmt.Printf("Failed to insert genesis block: %v\n", err) + return + } + // Create a new BlockChain instance using the underlying database for // the main bitcoin network and ignore notifications. chain := btcchain.New(db, btcwire.MainNet, nil) @@ -95,8 +113,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - block := btcutil.NewBlock(&btcwire.GenesisBlock, btcwire.ProtocolVersion) - err = chain.ProcessBlock(block) + err = chain.ProcessBlock(genesisBlock) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return From c3b330e42de48d8ae8b42731da84f7c41c54b715 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 15:48:52 -0500 Subject: [PATCH 016/190] Allow tx inputs to use txns earlier in same block. It is acceptable for a transaction input in a block to reference the output of another transaction in the same block only if the referenced transaction comes before the transaction referencing it. --- txlookup.go | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/txlookup.go b/txlookup.go index aff9eae2..db53ead3 100644 --- a/txlookup.go +++ b/txlookup.go @@ -193,16 +193,17 @@ func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (ma // for more details on what the point of view entails. func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Block) (map[btcwire.ShaHash]*txData, error) { // Build a map of in-flight transactions because some of the inputs in - // this block could be referencing other transactions in this block - // which are not yet in the chain. - txInFlight := map[btcwire.ShaHash]*btcwire.MsgTx{} - for i, tx := range block.MsgBlock().Transactions { + // this block could be referencing other transactions earlier in this + // block which are not yet in the chain. + txInFlight := map[btcwire.ShaHash]int{} + transactions := block.MsgBlock().Transactions + for i := range transactions { // Get transaction hash. It's safe to ignore the error since // it's already cached in the nominal code path and the only // way it can fail is if the index is out of range which is // impossible here. txHash, _ := block.TxSha(i) - txInFlight[*txHash] = tx + txInFlight[*txHash] = i } // Loop through all of the transaction inputs (except for the coinbase @@ -210,7 +211,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // what is already known (in-flight). var txNeededList []*btcwire.ShaHash txStore := make(map[btcwire.ShaHash]*txData) - for _, tx := range block.MsgBlock().Transactions[1:] { + for i, tx := range transactions[1:] { for _, txIn := range tx.TxIn { // Add an entry to the transaction store for the needed // transaction with it set to missing by default. @@ -218,13 +219,23 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txD := &txData{hash: originHash, err: btcdb.TxShaMissing} txStore[*originHash] = txD - // The transaction is already in-flight, so update the - // transaction store acccordingly. Otherwise, we need - // it. - if tx, ok := txInFlight[*originHash]; ok { - txD.tx = tx + // It is acceptable for a transaction input to reference + // the output of another transaction in this block only + // if the referenced transaction comes before the + // current one in this block. Update the transaction + // store acccordingly when this is the case. Otherwise, + // we still need the transaction. + // + // NOTE: The >= is correct here because i is one less + // than the actual position of the transaction within + // the block due to skipping the coinbase. + if inFlightIndex, ok := txInFlight[*originHash]; ok && + i >= inFlightIndex { + + originTx := transactions[inFlightIndex] + txD.tx = originTx txD.blockHeight = node.height - txD.spent = make([]bool, len(tx.TxOut)) + txD.spent = make([]bool, len(originTx.TxOut)) txD.err = nil } else { txNeededList = append(txNeededList, originHash) From 6409879e14fd99d6810e2775bfc005bc0eceb8f6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 16:18:15 -0500 Subject: [PATCH 017/190] Modify count sigops calls for new btcscript API. The btcscript API for GetSigOpCount and GetPreciseSigOpCount recently changed to no longer return an error. This change was necessary to mirror the behavior of bitcoind signature operations counting. This commit modifies the code accordingly to use the new API. --- validate.go | 65 +++++++++++++++-------------------------------------- 1 file changed, 18 insertions(+), 47 deletions(-) diff --git a/validate.go b/validate.go index 114dd19b..541bb67c 100644 --- a/validate.go +++ b/validate.go @@ -304,37 +304,23 @@ func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { // input and output scripts in the provided transaction. This uses the // quicker, but imprecise, signature operation counting mechanism from // btcscript. -func countSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool) (int, error) { - // Choose the starting transaction input based on whether this is a - // coinbase transaction since the coinbase input script should not be - // executed. - txIns := msgTx.TxIn - if isCoinBaseTx { - txIns = txIns[1:] - } - +func countSigOps(msgTx *btcwire.MsgTx) int { // Accumulate the number of signature operations in all transaction - // inputs (except the first input if this is a coinbase transaction). + // inputs. totalSigOps := 0 - for _, txIn := range txIns { - numSigOps, err := btcscript.GetSigOpCount(txIn.SignatureScript) - if err != nil { - return 0, err - } + for _, txIn := range msgTx.TxIn { + numSigOps := btcscript.GetSigOpCount(txIn.SignatureScript) totalSigOps += numSigOps } // Accumulate the number of signature operations in all transaction // outputs. for _, txOut := range msgTx.TxOut { - numSigOps, err := btcscript.GetSigOpCount(txOut.PkScript) - if err != nil { - return 0, err - } + numSigOps := btcscript.GetSigOpCount(txOut.PkScript) totalSigOps += numSigOps } - return totalSigOps, nil + return totalSigOps } // countP2SHSigOps returns the number of signature operations for all input @@ -360,7 +346,7 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir // Ensure the referenced input transaction is available. txInHash := &txIn.PreviousOutpoint.Hash originTx, exists := txStore[*txInHash] - if !exists { + if !exists || originTx.err != nil || originTx.tx == nil { return 0, fmt.Errorf("unable to find input transaction "+ "%v referenced from transaction %v", txHash, txInHash) @@ -385,11 +371,8 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir // Count the precise number of signature operations in the // referenced public key script. sigScript := txIn.SignatureScript - numSigOps, err := btcscript.GetPreciseSigOpCount(sigScript, - pkScript, true) - if err != nil { - return 0, err - } + numSigOps := btcscript.GetPreciseSigOpCount(sigScript, pkScript, + true) // We could potentially overflow the accumulator so check for // overflow. @@ -492,21 +475,11 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // The number of signature operations must be less than the maximum // allowed per block. totalSigOps := 0 - for i, tx := range transactions { - // Since the first (and only the first) transaction has already - // been verified above to be a coinbase transaction, use i == 0 - // as an optimization for the flag to countSigOps for whether - // or not the transaction is a coinbase transaction rather than - // having to do a full coinbase check again. - numSigOps, err := countSigOps(tx, i == 0) - if err != nil { - return err - } - + for _, tx := range transactions { // We could potentially overflow the accumulator so check for // overflow. lastSigOps := totalSigOps - totalSigOps += numSigOps + totalSigOps += countSigOps(tx) if totalSigOps < lastSigOps || totalSigOps > maxSigOpsPerBlock { str := fmt.Sprintf("block contains too many signature "+ "operations - got %v, max %v", totalSigOps, @@ -783,16 +756,14 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er transactions := block.MsgBlock().Transactions totalSigOps := 0 for i, tx := range transactions { - // Since the first (and only the first) transaction has already - // been verified to be a coinbase transaction, use i == 0 - // as an optimization for the flag to countSigOps for whether - // or not the transaction is a coinbase transaction rather than - // having to do a full coinbase check again. - numsigOps, err := countSigOps(tx, i == 0) - if err != nil { - return err - } + numsigOps := countSigOps(tx) if enforceBIP0016 { + // Since the first (and only the first) transaction has + // already been verified to be a coinbase transaction, + // use i == 0 as an optimization for the flag to + // countP2SHSigOps for whether or not the transaction is + // a coinbase transaction rather than having to do a + // full coinbase check again. numP2SHSigOps, err := countP2SHSigOps(tx, i == 0, txInputStore) if err != nil { From 882d1c1687800d6e1ff7f8f7827b165332352085 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 16:58:48 -0500 Subject: [PATCH 018/190] Ensure height is set on block as well as the node. Even though the code currently makes heavy use of nodes which will have the appropriate height, blocks which did not come from the database will not have a height set. As a result, this could possibly result in a height of 0 being used when unintended. By setting the block height in the block as soon as its known (regardless of the source), we can future proof against bugs that would likely be hard to track down. --- accept.go | 1 + 1 file changed, 1 insertion(+) diff --git a/accept.go b/accept.go index 58a7d150..7bad3454 100644 --- a/accept.go +++ b/accept.go @@ -28,6 +28,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { if prevNode != nil { blockHeight = prevNode.height + 1 } + block.SetHeight(blockHeight) // Ensure the difficulty specified in the block header matches the // calculated difficulty based on the previous block and difficulty From 077e1ec336ccbe911b40b51cc54ac8083be8e21c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 17:02:42 -0500 Subject: [PATCH 019/190] Improve second coinbase error message. Include the index at which the second coinbase transaction was found. --- validate.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/validate.go b/validate.go index 541bb67c..67f110c0 100644 --- a/validate.go +++ b/validate.go @@ -426,9 +426,11 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { } // A block must not have more than one coinbase. - for _, tx := range transactions[1:] { + for i, tx := range transactions[1:] { if isCoinBase(tx) { - return RuleError("block contains more than one coinbase") + str := fmt.Sprintf("block contains second coinbase at "+ + "index %d", i) + return RuleError(str) } } From 04d88d01ec160ec4936336e37a31f6756298dba0 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 19:50:00 -0500 Subject: [PATCH 020/190] Clarify mismatched merkle root error message. --- validate.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/validate.go b/validate.go index 67f110c0..758a6036 100644 --- a/validate.go +++ b/validate.go @@ -452,8 +452,9 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { merkles := BuildMerkleTreeStore(block) calculatedMerkleRoot := merkles[len(merkles)-1] if !header.MerkleRoot.IsEqual(calculatedMerkleRoot) { - str := fmt.Sprintf("block merkle root is invalid - got %v, "+ - "want %v", calculatedMerkleRoot, header.MerkleRoot) + str := fmt.Sprintf("block merkle root is invalid - block "+ + "header indicates %v, but calculated value is %v", + header.MerkleRoot, calculatedMerkleRoot) return RuleError(str) } From 829f187e4774f1fa9bd4b24662f483f4a765dba8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 20:21:24 -0500 Subject: [PATCH 021/190] Use network-specific genesis hash. The test in checkConnectBlock for whether or not the node is the genesis block needs to account for the genesis block of the specified network. --- validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.go b/validate.go index 758a6036..63b32735 100644 --- a/validate.go +++ b/validate.go @@ -712,7 +712,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // The coinbase for the Genesis block is not spendable, so just return // now. - if node.hash.IsEqual(&btcwire.GenesisHash) { + if node.hash.IsEqual(b.netParams().genesisHash) { return nil } From e5eaaee91c2a02645d37cfc7e26e429f3e202df1 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 22:31:05 -0500 Subject: [PATCH 022/190] Remove a couple of error logs that are not needed. --- accept.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/accept.go b/accept.go index 7bad3454..d03bc03a 100644 --- a/accept.go +++ b/accept.go @@ -36,7 +36,6 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { blockHeader := block.MsgBlock().Header expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) if err != nil { - log.Errorf("calcNextRequiredDifficulty: %v", err) return err } blockDifficulty := blockHeader.Bits @@ -151,7 +150,6 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // also handles validation of the transaction scripts. err = b.connectBestChain(newNode, block) if err != nil { - log.Errorf("connectBestChain: %v", err) return err } From 0e7791058a1a23fc6c320405c52a5fe95dcb301a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 29 Jul 2013 22:32:12 -0500 Subject: [PATCH 023/190] Add logging for chain forks and reorgs. This commit adds info level log statements when a block causes a chain fork, extends a side chain (fork), or causes a reorganize. When a reorg happens, the new and old chain heads along with the fork point are logged. --- chain.go | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/chain.go b/chain.go index b9a6efe3..691e2c6f 100644 --- a/chain.go +++ b/chain.go @@ -620,6 +620,19 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error delete(b.blockCache, *n.hash) } + // Log the point where the chain forked. + firstAttachNode := attachNodes.Front().Value.(*blockNode) + forkNode, err := b.getPrevNodeFromNode(firstAttachNode) + if err == nil { + log.Infof("REORGANIZE: Chain forks at %v", forkNode.hash) + } + + // Log the old and new best chain heads. + firstDetachNode := detachNodes.Front().Value.(*blockNode) + lastAttachNode := attachNodes.Back().Value.(*blockNode) + log.Infof("REORGANIZE: Old best chain head was %v", firstDetachNode.hash) + log.Infof("REORGANIZE: New best chain head is %v", lastAttachNode.hash) + return nil } @@ -670,8 +683,25 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) err if node.workSum.Cmp(b.bestChain.workSum) <= 0 { // Connect the parent node to this node. node.inMainChain = false - if node.parent != nil { - node.parent.children = append(node.parent.children, node) + node.parent.children = append(node.parent.children, node) + + // Find the fork point. + fork := node + for ; fork.parent != nil; fork = fork.parent { + if fork.inMainChain { + break + } + } + + // Log information about how the block is forking the chain. + if fork.hash.IsEqual(node.parent.hash) { + log.Infof("FORK: Block %v forks the chain at height %d"+ + "/block %v, but does not cause a reorganize", + node.hash, fork.height, fork.hash) + } else { + log.Infof("EXTEND FORK: Block %v extends a side chain "+ + "which forks the chain at height %d/block %v", + node.hash, fork.height, fork.hash) } return nil } @@ -686,6 +716,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) err detachNodes, attachNodes := b.getReorganizeNodes(node) // Reorganize the chain. + log.Infof("REORGANIZE: Block %v is causing a reorganize.", node.hash) err := b.reorganizeChain(detachNodes, attachNodes) if err != nil { return err From cef901ebad063edac29513cacff330a83e5c26db Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 30 Jul 2013 12:30:31 -0500 Subject: [PATCH 024/190] Export chain parameters. This commit exports the chain parameters used depending on the specific bitcoin network so callers can have access to this information if desired. --- chain.go | 4 ++-- difficulty.go | 6 ++--- params.go | 62 +++++++++++++++++++++++++++++++-------------------- validate.go | 4 ++-- 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/chain.go b/chain.go index 691e2c6f..f67b4330 100644 --- a/chain.go +++ b/chain.go @@ -339,7 +339,7 @@ func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { } // Genesis block. - if node.hash.IsEqual(b.netParams().genesisHash) { + if node.hash.IsEqual(b.chainParams().GenesisHash) { return nil, nil } @@ -393,7 +393,7 @@ func (b *BlockChain) isMajorityVersion(minVer uint32, startNode *blockNode, numR func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) { // Genesis block. if startNode == nil { - return b.netParams().genesisBlock.Header.Timestamp, nil + return b.chainParams().GenesisBlock.Header.Timestamp, nil } // Create a slice of the previous few block timestamps used to calculate diff --git a/difficulty.go b/difficulty.go index 4497da13..0ed4fdda 100644 --- a/difficulty.go +++ b/difficulty.go @@ -188,7 +188,7 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) adjustmentFactor := big.NewInt(retargetAdjustmentFactor) // Choose the correct proof of work limit for the active network. - powLimit := b.netParams().powLimit + powLimit := b.chainParams().PowLimit // The test network rules allow minimum difficulty blocks after more // than twice the desired amount of time needed to generate a block has @@ -225,7 +225,7 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) { // Search backwards through the chain for the last block without // the special rule applied. - powLimitBits := BigToCompact(b.netParams().powLimit) + powLimitBits := BigToCompact(b.chainParams().PowLimit) iterNode := startNode for iterNode != nil && iterNode.height%blocksPerRetarget != 0 && iterNode.bits == powLimitBits { // Get the previous block node. This function is used over @@ -254,7 +254,7 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er // after the passed previous block node based on the difficulty retarget rules. func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcutil.Block) (uint32, error) { // Choose the correct proof of work limit for the active network. - powLimit := b.netParams().powLimit + powLimit := b.chainParams().PowLimit // Genesis block. if lastNode == nil { diff --git a/params.go b/params.go index 5307e590..c879db2a 100644 --- a/params.go +++ b/params.go @@ -9,50 +9,64 @@ import ( "math/big" ) -// params is used to group parameters for various networks such as the main -// network and test networks. -type params struct { - genesisBlock *btcwire.MsgBlock - genesisHash *btcwire.ShaHash - powLimit *big.Int +// Params houses parameters unique to various bitcoin networks such as the main +// network and test networks. See ChainParams. +type Params struct { + // GenesisBlock is the genesis block for the specific network. + GenesisBlock *btcwire.MsgBlock + + // GenesisHash is the genesis block hash for the specific network. + GenesisHash *btcwire.ShaHash + + // PowLimit is the highest proof of work value a bitcoin block can have + // for the specific network. + PowLimit *big.Int } // mainNetParams contains parameters specific to the main network // (btcwire.MainNet). -var mainNetParams = params{ - genesisBlock: &btcwire.GenesisBlock, - genesisHash: &btcwire.GenesisHash, +var mainNetParams = Params{ + GenesisBlock: &btcwire.GenesisBlock, + GenesisHash: &btcwire.GenesisHash, - // powLimit is the highest proof of work value a bitcoin block can have. + // PowLimit is the highest proof of work value a bitcoin block can have. // It is the value 2^224 - 1 for the main network. - powLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), + PowLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), } // regressionParams contains parameters specific to the regression test network // (btcwire.TestNet). -var regressionParams = params{ - genesisBlock: &btcwire.TestNetGenesisBlock, - genesisHash: &btcwire.TestNetGenesisHash, +var regressionParams = Params{ + GenesisBlock: &btcwire.TestNetGenesisBlock, + GenesisHash: &btcwire.TestNetGenesisHash, - // powLimit is the highest proof of work value a bitcoin block can have. + // PowLimit is the highest proof of work value a bitcoin block can have. // It is the value 2^256 - 1 for the regression test network. - powLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne), + PowLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne), } // testNet3Params contains parameters specific to the test network (version 3) // (btcwire.TestNet3). -var testNet3Params = params{ - genesisBlock: &btcwire.TestNet3GenesisBlock, - genesisHash: &btcwire.TestNet3GenesisHash, +var testNet3Params = Params{ + GenesisBlock: &btcwire.TestNet3GenesisBlock, + GenesisHash: &btcwire.TestNet3GenesisHash, - // powLimit is the highest proof of work value a bitcoin block can have. + // PowLimit is the highest proof of work value a bitcoin block can have. // It is the value 2^224 - 1 for the test network (version 3). - powLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), + PowLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), } -// netParams returns parameters specific to the passed bitcoin network. -func (b *BlockChain) netParams() *params { - switch b.btcnet { +// chainParams returns chain parameters specific to the bitcoin network +// associated with the BlockChain instance. +func (b *BlockChain) chainParams() *Params { + return ChainParams(b.btcnet) +} + +// ChainParams returns chain parameters specific to the passed bitcoin network. +// It returns the parameters for btcwire.MainNet if the passed network is not +// supported. +func ChainParams(btcnet btcwire.BitcoinNet) *Params { + switch btcnet { case btcwire.TestNet: return ®ressionParams diff --git a/validate.go b/validate.go index 63b32735..c30e3ab6 100644 --- a/validate.go +++ b/validate.go @@ -278,7 +278,7 @@ func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { } // The target difficulty must be less than the maximum allowed. - powLimit := b.netParams().powLimit + powLimit := b.chainParams().PowLimit if target.Cmp(powLimit) > 0 { str := fmt.Sprintf("block target difficulty of %064x is "+ "higher than max of %064x", target, powLimit) @@ -712,7 +712,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // The coinbase for the Genesis block is not spendable, so just return // now. - if node.hash.IsEqual(b.netParams().genesisHash) { + if node.hash.IsEqual(b.chainParams().GenesisHash) { return nil } From 1e891b4e0b05cf757424cde68e8f0b1a0f7bb158 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 30 Jul 2013 12:58:28 -0500 Subject: [PATCH 025/190] Optimize proof of work limit bits handling. Rather than converting the proof of work limit to its compact representation multiple times during operation, do it once at package initialization time and export it via the chain parameters. --- difficulty.go | 10 ++++++---- params.go | 35 +++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/difficulty.go b/difficulty.go index 0ed4fdda..1f4089a5 100644 --- a/difficulty.go +++ b/difficulty.go @@ -189,6 +189,7 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) // Choose the correct proof of work limit for the active network. powLimit := b.chainParams().PowLimit + powLimitBits := b.chainParams().PowLimitBits // The test network rules allow minimum difficulty blocks after more // than twice the desired amount of time needed to generate a block has @@ -198,7 +199,7 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) fallthrough case btcwire.TestNet3: if durationVal > int64(targetSpacing)*2 { - return BigToCompact(powLimit) + return powLimitBits } } @@ -225,7 +226,7 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) { // Search backwards through the chain for the last block without // the special rule applied. - powLimitBits := BigToCompact(b.chainParams().PowLimit) + powLimitBits := b.chainParams().PowLimitBits iterNode := startNode for iterNode != nil && iterNode.height%blocksPerRetarget != 0 && iterNode.bits == powLimitBits { // Get the previous block node. This function is used over @@ -255,10 +256,11 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcutil.Block) (uint32, error) { // Choose the correct proof of work limit for the active network. powLimit := b.chainParams().PowLimit + powLimitBits := b.chainParams().PowLimitBits // Genesis block. if lastNode == nil { - return BigToCompact(powLimit), nil + return powLimitBits, nil } // Return the previous block's difficulty requirements if this block @@ -278,7 +280,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu newBlockTime := block.MsgBlock().Header.Timestamp allowMinTime := lastNode.timestamp.Add(targetSpacing * 2) if newBlockTime.After(allowMinTime) { - return BigToCompact(powLimit), nil + return powLimitBits, nil } // The block was mined within the desired timeframe, so diff --git a/params.go b/params.go index c879db2a..21d13658 100644 --- a/params.go +++ b/params.go @@ -21,39 +21,50 @@ type Params struct { // PowLimit is the highest proof of work value a bitcoin block can have // for the specific network. PowLimit *big.Int + + // PowLimitBits is the highest proof of work value a bitcoin block can + // have represented in compact form. See CompactToBig for more details + // on compact form. + PowLimitBits uint32 } +// mainPowLimit is the highest proof of work value a bitcoin block can have for +// the main network. It is the value 2^224 - 1. +var mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) + // mainNetParams contains parameters specific to the main network // (btcwire.MainNet). var mainNetParams = Params{ GenesisBlock: &btcwire.GenesisBlock, GenesisHash: &btcwire.GenesisHash, - - // PowLimit is the highest proof of work value a bitcoin block can have. - // It is the value 2^224 - 1 for the main network. - PowLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), + PowLimit: mainPowLimit, + PowLimitBits: BigToCompact(mainPowLimit), } +// regressionPowLimit is the highest proof of work value a bitcoin block can +// have. It is the value 2^256 - 1. +var regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) + // regressionParams contains parameters specific to the regression test network // (btcwire.TestNet). var regressionParams = Params{ GenesisBlock: &btcwire.TestNetGenesisBlock, GenesisHash: &btcwire.TestNetGenesisHash, - - // PowLimit is the highest proof of work value a bitcoin block can have. - // It is the value 2^256 - 1 for the regression test network. - PowLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne), + PowLimit: regressionPowLimit, + PowLimitBits: BigToCompact(regressionPowLimit), } +// testNetPowLimit is the highest proof of work value a bitcoin block can have +// for the test network (version 3). It is the value 2^224 - 1. +var testNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) + // testNet3Params contains parameters specific to the test network (version 3) // (btcwire.TestNet3). var testNet3Params = Params{ GenesisBlock: &btcwire.TestNet3GenesisBlock, GenesisHash: &btcwire.TestNet3GenesisHash, - - // PowLimit is the highest proof of work value a bitcoin block can have. - // It is the value 2^224 - 1 for the test network (version 3). - PowLimit: new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne), + PowLimit: testNetPowLimit, + PowLimitBits: BigToCompact(testNetPowLimit), } // chainParams returns chain parameters specific to the bitcoin network From 357160257c19524060ec79425c065f5039220138 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 30 Jul 2013 15:29:15 -0500 Subject: [PATCH 026/190] Allow checkpoints to work with all networks. Previously the main network checkpoints were being used for unrecognized networks. This commit changes the code so that no checkpoints are used in that scenario. --- checkpoints.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/checkpoints.go b/checkpoints.go index 818b2fb9..64e67e63 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -60,8 +60,9 @@ var checkpointDataMainNet = checkpointData{ checkpointsByHeight: nil, // Automatically generated in init. } -// checkpointDataTestNet contains checkpoint data for the test network. -var checkpointDataTestNet = checkpointData{ +// checkpointDataTestNet3 contains checkpoint data for the test network (version +// 3). +var checkpointDataTestNet3 = checkpointData{ checkpoints: []Checkpoint{ {546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, }, @@ -89,18 +90,18 @@ func (b *BlockChain) DisableCheckpoints(disable bool) { func (b *BlockChain) checkpointData() *checkpointData { switch b.btcnet { case btcwire.TestNet3: - return &checkpointDataTestNet + return &checkpointDataTestNet3 case btcwire.MainNet: - fallthrough - default: return &checkpointDataMainNet } + return nil } // LatestCheckpoint returns the most recent checkpoint (regardless of whether it -// is already known). When checkpoints are disabled it will return nil. +// is already known). When checkpoints are disabled or there are no checkpoints +// for the active network, it will return nil. func (b *BlockChain) LatestCheckpoint() *Checkpoint { - if b.noCheckpoints { + if b.noCheckpoints || b.checkpointData() == nil { return nil } @@ -112,7 +113,7 @@ func (b *BlockChain) LatestCheckpoint() *Checkpoint { // match the hard-coded checkpoint data. It also returns true if there is no // checkpoint data for the passed block height. func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool { - if b.noCheckpoints { + if b.noCheckpoints || b.checkpointData() == nil { return true } @@ -130,7 +131,7 @@ func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool // associated block. It returns nil if a checkpoint can't be found (this should // really only happen for blocks before the first checkpoint). func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) { - if b.noCheckpoints { + if b.noCheckpoints || b.checkpointData() == nil { return nil, nil } @@ -248,7 +249,7 @@ func init() { // when the package loads. checkpointInitializeList := []*checkpointData{ &checkpointDataMainNet, - &checkpointDataTestNet, + &checkpointDataTestNet3, } for _, data := range checkpointInitializeList { data.checkpointsByHeight = make(map[int64]*Checkpoint) From bb7f5da609da9f65414a180ad96bf508fb42e188 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 30 Jul 2013 18:04:58 -0500 Subject: [PATCH 027/190] Print transaction hash in script val errors. The txsha variable is already a pointer to the hash, so print the variable, not the address of it. --- scriptval.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scriptval.go b/scriptval.go index 37eec3b3..11852cdd 100644 --- a/scriptval.go +++ b/scriptval.go @@ -71,7 +71,7 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, pver ui processFunc := func(txInIdx int) { log.Tracef("validating tx %v input %v len %v", - &txsha, currentItem, len(job)) + txsha, currentItem, len(job)) txin := job[txInIdx] originTxSha := &txin.PreviousOutpoint.Hash origintxidx := txin.PreviousOutpoint.Index @@ -113,7 +113,7 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, pver ui } for i := 0; i < len(job); i++ { if resultErrors[i] != nil { - log.Warnf("tx %v failed input %v, err %v", &txsha, i, resultErrors[i]) + log.Warnf("tx %v failed input %v, err %v", txsha, i, resultErrors[i]) } } return From 72feef5194367297c39b4c66224f13fbbb4aac97 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 31 Jul 2013 09:14:02 -0500 Subject: [PATCH 028/190] Clarify reg test proof of work limit comment. --- params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params.go b/params.go index 21d13658..670f390f 100644 --- a/params.go +++ b/params.go @@ -42,7 +42,7 @@ var mainNetParams = Params{ } // regressionPowLimit is the highest proof of work value a bitcoin block can -// have. It is the value 2^256 - 1. +// have for the regression test network. It is the value 2^256 - 1. var regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // regressionParams contains parameters specific to the regression test network From 455c92a71616795d6deec1624dc86b9b24965f8a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 31 Jul 2013 09:20:11 -0500 Subject: [PATCH 029/190] Correct reg test proof of work limit comment. --- params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params.go b/params.go index 670f390f..685bad3e 100644 --- a/params.go +++ b/params.go @@ -42,7 +42,7 @@ var mainNetParams = Params{ } // regressionPowLimit is the highest proof of work value a bitcoin block can -// have for the regression test network. It is the value 2^256 - 1. +// have for the regression test network. It is the value 2^255 - 1. var regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // regressionParams contains parameters specific to the regression test network From 2d6a664d9dab6ee21ddf790116b49ce344e91040 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 31 Jul 2013 12:57:54 -0500 Subject: [PATCH 030/190] Greatly optimize best chain selection work values. Previously, the code was using big rational numbers for work values which resulted in carrying way too much precision around (and ultimately a lot of extra memory and computation to carry that precision). This commit converts the work values to big integers and calculates them with integer division. This is acceptable because the numerator is multiplied by 2^256 which is higher than the maximum possible proof of work. Therefore anything after the decimal is superfluous precision for the purposes of chain selection. Also, add a check for negative difficulty values when calculating the work value. Negative values won't occur in practice with valid blocks, but it's possible an invalid block could trigger the code path, so be safe and check for it. --- chain.go | 4 ++-- difficulty.go | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/chain.go b/chain.go index f67b4330..10ba4bbf 100644 --- a/chain.go +++ b/chain.go @@ -38,7 +38,7 @@ type blockNode struct { // workSum is the total amount of work in the chain up to and including // this node. - workSum *big.Rat + workSum *big.Int // inMainChain denotes whether the block node is currently on the // the main chain or not. This is used to help find the common @@ -85,7 +85,7 @@ type orphanBlock struct { // down the chain. It is used primarily to allow a new node to be dynamically // inserted from the database into the memory chain prior to nodes we already // have and update their work values accordingly. -func addChildrenWork(node *blockNode, work *big.Rat) { +func addChildrenWork(node *blockNode, work *big.Int) { for _, childNode := range node.children { childNode.workSum.Add(childNode.workSum, work) addChildrenWork(childNode, work) diff --git a/difficulty.go b/difficulty.go index 1f4089a5..013989d4 100644 --- a/difficulty.go +++ b/difficulty.go @@ -171,11 +171,18 @@ func BigToCompact(n *big.Int) uint32 { // accumulated must be the inverse of the difficulty. Also, in order to avoid // potential division by zero and really small floating point numbers, add 1 to // the denominator and multiply the numerator by 2^256. -func calcWork(bits uint32) *big.Rat { - // (1 << 256) / (difficultyNum + 1) +func calcWork(bits uint32) *big.Int { + // Return a work value of zero if the passed difficulty bits represent + // a negative number. Note this should not happen in practice with valid + // blocks, but an invalid block could trigger it. difficultyNum := CompactToBig(bits) + if difficultyNum.Sign() <= 0 { + return big.NewInt(0) + } + + // (1 << 256) / (difficultyNum + 1) denominator := new(big.Int).Add(difficultyNum, bigOne) - return new(big.Rat).SetFrac(oneLsh256, denominator) + return new(big.Int).Div(oneLsh256, denominator) } // calcEasiestDifficulty calculates the easiest possible difficulty that a block From 2988289d2e518ba10b38f534f35064490dc6451d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Aug 2013 11:31:42 -0500 Subject: [PATCH 031/190] Implement memory chain pruning. This commit implements pruning for the block nodes that form the memory chain which are no longer needed. The validation of a block only requires information from a set number of previous nodes. The initial code did not prune old nodes as they were no longer needed, but the vast majority of the infrastructure to support it was already in place as that was always the goal. This commit finishes implementing the missing bits to make it a reality. --- accept.go | 7 +++ chain.go | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 124 insertions(+), 8 deletions(-) diff --git a/accept.go b/accept.go index d03bc03a..d0d6e52b 100644 --- a/accept.go +++ b/accept.go @@ -136,6 +136,13 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { } } + // Prune block nodes which are no longer needed before creating a new + // node. + err = b.pruneBlockNodes() + if err != nil { + return err + } + // Create a new block node for the block and add it to the in-memory // block chain (could be either a side chain or the main chain). newNode := newBlockNode(block) diff --git a/chain.go b/chain.go index 10ba4bbf..b63d6d0a 100644 --- a/chain.go +++ b/chain.go @@ -15,8 +15,17 @@ import ( "time" ) -// maxOrphanBlocks is the maximum number of orphan blocks that can be queued. -const maxOrphanBlocks = 100 +const ( + // maxOrphanBlocks is the maximum number of orphan blocks that can be + // queued. + maxOrphanBlocks = 100 + + // minMemoryNodes is the minimum number of consecutive nodes needed + // in memory in order to perform all necessary validation. It is used + // to determine when it's safe to prune nodes from memory without + // causing constant dynamic reloading. + minMemoryNodes = blocksPerRetarget +) // blockNode represents a block within the block chain and is primarily used to // aid in selecting the best chain to be the main chain. The main chain is @@ -33,6 +42,12 @@ type blockNode struct { // hash is the double sha 256 of the block. hash *btcwire.ShaHash + // parentHash is the double sha 256 of the parent block. This is kept + // here over simply relying on parent.hash directly since block nodes + // are sparse and the parent node might not be in memory when its hash + // is needed. + parentHash *btcwire.ShaHash + // height is the position in the block chain. height int64 @@ -63,12 +78,13 @@ func newBlockNode(block *btcutil.Block) *blockNode { blockHeader := block.MsgBlock().Header node := blockNode{ - hash: blockSha, - workSum: calcWork(blockHeader.Bits), - height: block.Height(), - version: blockHeader.Version, - bits: blockHeader.Bits, - timestamp: blockHeader.Timestamp, + hash: blockSha, + parentHash: &blockHeader.PrevBlock, + workSum: calcWork(blockHeader.Bits), + height: block.Height(), + version: blockHeader.Version, + bits: blockHeader.Bits, + timestamp: blockHeader.Timestamp, } return &node } @@ -361,6 +377,99 @@ func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { return prevBlockNode, nil } +// removeBlockNode removes the passed block node from the memory chain by +// unlinking all of its children and removing it from the the node and +// dependency indices. +func (b *BlockChain) removeBlockNode(node *blockNode) error { + if node.parent != nil { + return fmt.Errorf("removeBlockNode must be called with a "+ + " node at the front of the chain - node %v", node.hash) + } + + // Remove the node from the node index. + delete(b.index, *node.hash) + + // Unlink all of the node's children. + for _, child := range node.children { + child.parent = nil + } + node.children = nil + + // Remove the reference from the dependency index. + prevHash := node.parentHash + if children, ok := b.depNodes[*prevHash]; ok { + // Find the node amongst the children of the + // dependencies for the parent hash and remove it. + for i, child := range children { + if child == node { + copy(children[i:], children[i+1:]) + children[len(children)-1] = nil + b.depNodes[*prevHash] = children[:len(children)-1] + } + } + + // Remove the map entry altogether if there are no + // longer any nodes which depend on the parent hash. + if len(b.depNodes[*prevHash]) == 0 { + delete(b.depNodes, *prevHash) + } + } + + return nil +} + +// pruneBlockNodes removes references to old block nodes which are no longer +// needed so they may be garbage collected. In order to validate block rules +// and choose the best chain, only a portion of the nodes which form the block +// chain are needed in memory. This function walks the chain backwards from the +// current best chain to find any nodes before the first needed block node. +func (b *BlockChain) pruneBlockNodes() error { + // Nothing to do if there is not a best chain selected yet. + if b.bestChain == nil { + return nil + } + + // Walk the chain backwards to find what should be the new root node. + // Intentionally use node.parent instead of getPrevNodeFromNode since + // the latter loads the node and the goal is to find nodes still in + // memory that can be pruned. + newRootNode := b.bestChain + for i := int64(0); i < minMemoryNodes-1 && newRootNode != nil; i++ { + newRootNode = newRootNode.parent + } + + // Nothing to do if there are not enough nodes. + if newRootNode == nil || newRootNode.parent == nil { + return nil + } + + // Push the nodes to delete on a list in reverse order since it's easier + // to prune them going forwards than it is backwards. This will + // typically end up being a single node since pruning is currently done + // just before each new node is created. However, that might be tuned + // later to only prune at intervals, so the code needs to account for + // the possibility of multiple nodes. + deleteNodes := list.New() + for node := newRootNode.parent; node != nil; node = node.parent { + deleteNodes.PushFront(node) + } + + // Loop through each node to prune, unlink its children, remove it from + // the dependency index, and remove it from the node index. + for e := deleteNodes.Front(); e != nil; e = e.Next() { + node := e.Value.(*blockNode) + err := b.removeBlockNode(node) + if err != nil { + return err + } + } + + // Set the new root node. + b.root = newRootNode + + return nil +} + // isMajorityVersion determines if a previous number of blocks in the chain // starting with startNode are at least the minimum passed version. func (b *BlockChain) isMajorityVersion(minVer uint32, startNode *blockNode, numRequired, numToCheck uint64) bool { From 5b697947a711c34fcc1b51c52676b975cebb5886 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Aug 2013 12:32:58 -0500 Subject: [PATCH 032/190] Optimize getPrevNodeFromNode. The recent pruning code made the parent hash for a node available directly as a field in the node. Make use of this in the getPrevNodeFromNode function to avoid having to load the full block data associated with the node to get the parent hash. --- chain.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/chain.go b/chain.go index b63d6d0a..bbd65f37 100644 --- a/chain.go +++ b/chain.go @@ -359,17 +359,9 @@ func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { return nil, nil } - // Load the actual block for this block node from the db to ascertain - // the previous hash. - block, err := b.db.FetchBlockBySha(node.hash) - if err != nil { - return nil, err - } - // Dynamically load the previous block from the block database, create // a new block node for it, and update the memory chain accordingly. - prevHash := &block.MsgBlock().Header.PrevBlock - prevBlockNode, err := b.loadBlockNode(prevHash) + prevBlockNode, err := b.loadBlockNode(node.parentHash) if err != nil { return nil, err } From 716075d0d0bcb74c2328507fc305b2b3fc13f362 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Aug 2013 17:10:59 -0500 Subject: [PATCH 033/190] Remove tesnet specific rules unsupported blurb. The testnet specific rules have been supported since commit 9787f46f6acbfacdad4baacaa2b235f766bfa456. --- doc.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc.go b/doc.go index 4d068260..04f70154 100644 --- a/doc.go +++ b/doc.go @@ -134,9 +134,5 @@ This package includes spec changes outlined by the following BIPs: BIP0016 (https://en.bitcoin.it/wiki/BIP_0016) BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) BIP0034 (https://en.bitcoin.it/wiki/BIP_0034) - -Other important information - -This package does not yet implement all of the unique rules for testnet. */ package btcchain From 1a5683e22003bfd83c33933c269f171dd9af89e8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Aug 2013 14:25:09 -0500 Subject: [PATCH 034/190] Add optimized initial block index load function. This commit adds a new optional function named GenerateInitialIndex. It generates the required number of initial block nodes in an optimized fashion. Since the memory block index is sparse and previous nodes are dynamically loaded as needed, this function is not stricty needed. However, during initial startup (when there are no nodes in memory yet), dynamically loading all of the required nodes on the fly in the usual way is much slower than preloading them. --- chain.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/chain.go b/chain.go index bbd65f37..e6bd5d8e 100644 --- a/chain.go +++ b/chain.go @@ -6,6 +6,7 @@ package btcchain import ( "container/list" + "errors" "fmt" "github.com/conformal/btcdb" "github.com/conformal/btcutil" @@ -27,6 +28,11 @@ const ( minMemoryNodes = blocksPerRetarget ) +// ErrIndexAlreadyInitialized describes an error that indicates the block index +// is already initialized. +var ErrIndexAlreadyInitialized = errors.New("the block index can only be " + + "initialized before it has been modified") + // blockNode represents a block within the block chain and is primarily used to // aid in selecting the best chain to be the main chain. The main chain is // stored into the block database. @@ -247,6 +253,53 @@ func (b *BlockChain) addOrphanBlock(block *btcutil.Block) { return } +// GenerateInitialIndex is an optional function which generates the required +// number of initial block nodes in an optimized fashion. This is optional +// because the memory block index is sparse and previous nodes are dynamically +// loaded as needed. However, during initial startup (when there are no nodes +// in memory yet), dynamically loading all of the required nodes on the fly in +// the usual way is much slower than preloading them. +// +// This function can only be called once and it must be called before any nodes +// are added to the block index. ErrIndexAlreadyInitialized is returned if +// the former is not the case. In practice, this means the function should be +// called directly after New. +func (b *BlockChain) GenerateInitialIndex() error { + // Return an error if the has already been modified. + if b.root != nil { + return ErrIndexAlreadyInitialized + } + + // Grab the latest block height for the main chain from the database. + _, endHeight, err := b.db.NewestSha() + if err != nil { + return err + } + + // Calculate the starting height based on the minimum number of nodes + // needed in memory. + startHeight := endHeight - (minMemoryNodes + 1) + if startHeight < 0 { + startHeight = 0 + } + + // Loop forwards through each block loading the node into the index for + // the block. + for i := startHeight; i <= endHeight; i++ { + hash, err := b.db.FetchBlockShaByHeight(i) + if err != nil { + return err + } + + _, err = b.loadBlockNode(hash) + if err != nil { + return err + } + } + + return nil +} + // loadBlockNode loads the block identified by hash from the block database, // creates a block node from it, and updates the memory block chain accordingly. // It is used mainly to dynamically load previous blocks from database as they From 0c2d4435ca65a455808b6b75cd6dfd1c023beb45 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Aug 2013 22:28:25 -0500 Subject: [PATCH 035/190] Make use of removeChildNode function. Rather than duplicating this code in the removeBlockNode function, use the existing function. --- chain.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/chain.go b/chain.go index e6bd5d8e..04617efb 100644 --- a/chain.go +++ b/chain.go @@ -445,13 +445,7 @@ func (b *BlockChain) removeBlockNode(node *blockNode) error { if children, ok := b.depNodes[*prevHash]; ok { // Find the node amongst the children of the // dependencies for the parent hash and remove it. - for i, child := range children { - if child == node { - copy(children[i:], children[i+1:]) - children[len(children)-1] = nil - b.depNodes[*prevHash] = children[:len(children)-1] - } - } + b.depNodes[*prevHash] = removeChildNode(children, node) // Remove the map entry altogether if there are no // longer any nodes which depend on the parent hash. From c00de3ffd579b2591dba65af6b1225ecd8e5132e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 4 Aug 2013 13:41:05 -0500 Subject: [PATCH 036/190] Fix a potential issue with removing orphan blocks. The range loop is over a local var, so the local variable needs to be updated and then set back into the chain instance after the range loop. --- chain.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chain.go b/chain.go index 04617efb..d68463bd 100644 --- a/chain.go +++ b/chain.go @@ -194,9 +194,10 @@ func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) { if hash.IsEqual(orphanHash) { copy(orphans[i:], orphans[i+1:]) orphans[len(orphans)-1] = nil - b.prevOrphans[*prevHash] = orphans[:len(orphans)-1] + orphans = orphans[:len(orphans)-1] } } + b.prevOrphans[*prevHash] = orphans // Remove the map entry altogether if there are no longer any orphans // which depend on the parent hash. From 10a62a37a36100ed88c80598d1e37af547004fc0 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 5 Aug 2013 15:20:35 -0500 Subject: [PATCH 037/190] Update for latest btcutil, btcscript, and btcwire. This commit updates the calls into btcutil, btcscript, and btcwire for the latest API changes which remove the need for the protocol version for serialization and deserialization of blocks and transactions. --- README.md | 3 +-- doc.go | 3 +-- merkle_test.go | 3 +-- reorganization_test.go | 2 +- scriptval.go | 11 +++++------ txlookup.go | 4 ++-- validate.go | 4 ++-- validate_test.go | 2 +- 8 files changed, 14 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index a5395400..1aec39dc 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,7 @@ intentionally causes an error by attempting to process a duplicate block. // Insert the main network genesis block. This is part of the initial // database setup. Like above, this typically would not be needed when // opening an existing database. - pver := btcwire.ProtocolVersion - genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock, pver) + genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) _, err = db.InsertBlock(genesisBlock) if err != nil { fmt.Printf("Failed to insert genesis block: %v\n", err) diff --git a/doc.go b/doc.go index 04f70154..00932b3a 100644 --- a/doc.go +++ b/doc.go @@ -98,8 +98,7 @@ intentionally causes an error by attempting to process a duplicate block. // Insert the main network genesis block. This is part of the initial // database setup. Like above, this typically would not be needed when // opening an existing database. - pver := btcwire.ProtocolVersion - genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock, pver) + genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) _, err = db.InsertBlock(genesisBlock) if err != nil { fmt.Printf("Failed to insert genesis block: %v\n", err) diff --git a/merkle_test.go b/merkle_test.go index cd2d4532..18ff1d20 100644 --- a/merkle_test.go +++ b/merkle_test.go @@ -7,13 +7,12 @@ package btcchain_test import ( "github.com/conformal/btcchain" "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "testing" ) // TestMerkle tests the BuildMerkleTreeStore API. func TestMerkle(t *testing.T) { - block := btcutil.NewBlock(&Block100000, btcwire.ProtocolVersion) + block := btcutil.NewBlock(&Block100000) merkles := btcchain.BuildMerkleTreeStore(block) calculatedMerkleRoot := merkles[len(merkles)-1] wantMerkle := &Block100000.Header.MerkleRoot diff --git a/reorganization_test.go b/reorganization_test.go index 70fcf054..87afbe44 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -122,7 +122,7 @@ func loadBlocks(filename string) (blocks []*btcutil.Block, err error) { // read block dr.Read(rbytes) - block, err = btcutil.NewBlockFromBytes(rbytes, btcwire.ProtocolVersion) + block, err = btcutil.NewBlockFromBytes(rbytes) if err != nil { return } diff --git a/scriptval.go b/scriptval.go index 11852cdd..139fc630 100644 --- a/scriptval.go +++ b/scriptval.go @@ -29,7 +29,7 @@ type txProcessList struct { // validateTxIn validates a the script pair for the passed spending transaction // (along with the specific input index) and origin transaction (with the // specific output index). -func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, pver uint32, timestamp time.Time, originTx *btcwire.MsgTx) error { +func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, timestamp time.Time, originTx *btcwire.MsgTx) error { // If the input transaction has no previous input, there is nothing // to check. originTxIdx := txin.PreviousOutpoint.Index @@ -46,7 +46,7 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b sigScript := txin.SignatureScript pkScript := originTx.TxOut[originTxIdx].PkScript engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, tx, - pver, timestamp.After(btcscript.Bip16Activation)) + timestamp.After(btcscript.Bip16Activation)) if err != nil { return err } @@ -62,7 +62,7 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b // validateAllTxIn validates the scripts for all of the passed transaction // inputs using multiple goroutines. -func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, pver uint32, timestamp time.Time, job []*btcwire.TxIn, txStore map[btcwire.ShaHash]*txData) (err error) { +func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, timestamp time.Time, job []*btcwire.TxIn, txStore map[btcwire.ShaHash]*txData) (err error) { c := make(chan txValidate) resultErrors := make([]error, len(job)) @@ -87,7 +87,7 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, pver ui originTx = txInfo.tx } err := validateTxIn(txInIdx, job[txInIdx], txsha, txValidator, - pver, timestamp, originTx) + timestamp, originTx) r := txValidate{txInIdx, err} c <- r } @@ -122,11 +122,10 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, pver ui // checkBlockScripts executes and validates the scripts for all transactions in // the passed block. func checkBlockScripts(block *btcutil.Block, txStore map[btcwire.ShaHash]*txData) error { - pver := block.ProtocolVersion() timestamp := block.MsgBlock().Header.Timestamp for i, tx := range block.MsgBlock().Transactions { txHash, _ := block.TxSha(i) - err := validateAllTxIn(txHash, tx, pver, timestamp, tx.TxIn, txStore) + err := validateAllTxIn(txHash, tx, timestamp, tx.TxIn, txStore) if err != nil { return err } diff --git a/txlookup.go b/txlookup.go index db53ead3..2cfb7ba6 100644 --- a/txlookup.go +++ b/txlookup.go @@ -22,7 +22,7 @@ type txData struct { } // connectTransactions updates the passed map by applying transaction and -// spend information for all the transactions in the passed block. Only +// spend information for all the transactions in the passed block. Only // transactions in the passed map are updated. func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of @@ -243,7 +243,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc } } - // Request the input transaction from the point of view of the node. + // Request the input transactions from the point of view of the node. txNeededStore, err := b.fetchTxList(node, txNeededList) if err != nil { return nil, err diff --git a/validate.go b/validate.go index c30e3ab6..5b7852f0 100644 --- a/validate.go +++ b/validate.go @@ -334,7 +334,7 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir } // TODO(davec): Need to pass the cached version in. - txHash, err := msgTx.TxSha(btcwire.ProtocolVersion) + txHash, err := msgTx.TxSha() if err != nil { return 0, err } @@ -593,7 +593,7 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi } // TODO(davec): Need to pass the cached version in. - txHash, err := tx.TxSha(btcwire.ProtocolVersion) + txHash, err := tx.TxSha() if err != nil { return 0, err } diff --git a/validate_test.go b/validate_test.go index 1d84b8d3..3718049a 100644 --- a/validate_test.go +++ b/validate_test.go @@ -29,7 +29,7 @@ func TestCheckBlockSanity(t *testing.T) { // the main bitcoin network and ignore notifications. chain := btcchain.New(db, btcwire.MainNet, nil) - block := btcutil.NewBlock(&Block100000, btcwire.ProtocolVersion) + block := btcutil.NewBlock(&Block100000) err = chain.TstCheckBlockSanity(block) if err != nil { t.Errorf("CheckBlockSanity: %v", err) From 2835238287bab2304fbf1d7cc17b3a78686b4e51 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 17 Aug 2013 14:05:36 -0500 Subject: [PATCH 038/190] Correct child and orphan block removal logic. It is not safe to remove elements from a slice while iterating them with the range statement since it does not reevaluate the slice on each iteration nor does it adjust the index for the modified slice. This commit modifies the code to use a for loop with an index (which does reevaluate on every iteration) and manually adjusts the index when elements are removed from the slice. --- chain.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/chain.go b/chain.go index d68463bd..c02a9199 100644 --- a/chain.go +++ b/chain.go @@ -122,11 +122,16 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { if node == nil { return children } - for i, n := range children { - if n.hash.IsEqual(node.hash) { + + // An indexing for loop is intentionally used over a range here as range + // does not reevaluate the slice on each iteration nor does it adjust + // the index for the modified slice. + for i := 0; i < len(children); i++ { + if children[i].hash.IsEqual(node.hash) { copy(children[i:], children[i+1:]) children[len(children)-1] = nil return children[:len(children)-1] + i-- } } return children @@ -186,15 +191,19 @@ func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) { orphanHash, _ := orphan.block.Sha() delete(b.orphans, *orphanHash) - // Remove the reference from the previous orphan index too. + // Remove the reference from the previous orphan index too. An indexing + // for loop is intentionally used over a range here as range does not + // reevaluate the slice on each iteration nor does it adjust the index + // for the modified slice. prevHash := &orphan.block.MsgBlock().Header.PrevBlock orphans := b.prevOrphans[*prevHash] - for i, ob := range orphans { - hash, _ := ob.block.Sha() + for i := 0; i < len(orphans); i++ { + hash, _ := orphans[i].block.Sha() if hash.IsEqual(orphanHash) { copy(orphans[i:], orphans[i+1:]) orphans[len(orphans)-1] = nil orphans = orphans[:len(orphans)-1] + i-- } } b.prevOrphans[*prevHash] = orphans From f4bae7dc41d8fa97483ec93ecdf5386e006c0f65 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 22 Aug 2013 14:37:06 -0500 Subject: [PATCH 039/190] Send orphan root in notifies instead of its parent. The notification for orphan blocks was sending the parent of orphan root instead of the orphan root itself. --- chain.go | 8 +++++--- process.go | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/chain.go b/chain.go index c02a9199..b69dafe6 100644 --- a/chain.go +++ b/chain.go @@ -168,19 +168,21 @@ func (b *BlockChain) DisableVerify(disable bool) { // getOrphanRoot returns the head of the chain for the provided hash from the // map of orphan blocks. -func (b *BlockChain) getOrphanRoot(sha *btcwire.ShaHash) *btcwire.ShaHash { +func (b *BlockChain) getOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash { // Keep looping while the parent of each orphaned block is // known and is an orphan itself. - prevHash := sha + orphanRoot := hash + prevHash := hash for { orphan, exists := b.orphans[*prevHash] if !exists { break } + orphanRoot = prevHash prevHash = &orphan.block.MsgBlock().Header.PrevBlock } - return prevHash + return orphanRoot } // removeOrphanBlock removes the passed orphan block from the orphan pool and diff --git a/process.go b/process.go index 876dc330..b608635a 100644 --- a/process.go +++ b/process.go @@ -151,7 +151,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { // Get the hash for the head of the orphaned block chain for // this block and notify the caller so it can request missing // blocks. - orphanRoot := b.getOrphanRoot(prevHash) + orphanRoot := b.getOrphanRoot(blockHash) b.sendNotification(NTOrphanBlock, orphanRoot) return nil } From 9d5f85558048b3a5b503c2ad2ab4b209fbb7efba Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 20 Aug 2013 11:13:39 -0500 Subject: [PATCH 040/190] Export GetOrphanRoot. This commit exposes GetOrphanRoot to callers. It also modifies the code to allow the function to be called in a concurrent safe manner. This allows the information to be safely obtained from multiple goroutines. --- chain.go | 23 +++++++++++++++++++++-- process.go | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/chain.go b/chain.go index b69dafe6..0f5a1b83 100644 --- a/chain.go +++ b/chain.go @@ -13,6 +13,7 @@ import ( "github.com/conformal/btcwire" "math/big" "sort" + "sync" "time" ) @@ -152,6 +153,7 @@ type BlockChain struct { orphans map[btcwire.ShaHash]*orphanBlock prevOrphans map[btcwire.ShaHash][]*orphanBlock oldestOrphan *orphanBlock + orphanLock sync.RWMutex blockCache map[btcwire.ShaHash]*btcutil.Block noVerify bool noCheckpoints bool @@ -166,9 +168,16 @@ func (b *BlockChain) DisableVerify(disable bool) { b.noVerify = disable } -// getOrphanRoot returns the head of the chain for the provided hash from the +// GetOrphanRoot returns the head of the chain for the provided hash from the // map of orphan blocks. -func (b *BlockChain) getOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash { +// +// This function is safe for concurrent access. +func (b *BlockChain) GetOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash { + // Protect concurrent access. Using a read lock only so multiple + // readers can query without blocking each other. + b.orphanLock.RLock() + defer b.orphanLock.RUnlock() + // Keep looping while the parent of each orphaned block is // known and is an orphan itself. orphanRoot := hash @@ -188,6 +197,10 @@ func (b *BlockChain) getOrphanRoot(hash *btcwire.ShaHash) *btcwire.ShaHash { // removeOrphanBlock removes the passed orphan block from the orphan pool and // previous orphan index. func (b *BlockChain) removeOrphanBlock(orphan *orphanBlock) { + // Protect concurrent access. + b.orphanLock.Lock() + defer b.orphanLock.Unlock() + // Remove the orphan block from the orphan pool. It's safe to ignore // the error on Sha since it's cached. orphanHash, _ := orphan.block.Sha() @@ -249,6 +262,12 @@ func (b *BlockChain) addOrphanBlock(block *btcutil.Block) { // errors would've been caught prior to calling this function. blockSha, _ := block.Sha() + // Protect concurrent access. This is intentionally done here instead + // of near the top since removeOrphanBlock does its own locking and + // the range iterator is not invalidated by removing map entries. + b.orphanLock.Lock() + b.orphanLock.Unlock() + // Insert the block into the orphan map with an expiration time // 1 hour from now. expiration := time.Now().Add(time.Hour) diff --git a/process.go b/process.go index b608635a..29aaa0bf 100644 --- a/process.go +++ b/process.go @@ -151,7 +151,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { // Get the hash for the head of the orphaned block chain for // this block and notify the caller so it can request missing // blocks. - orphanRoot := b.getOrphanRoot(blockHash) + orphanRoot := b.GetOrphanRoot(blockHash) b.sendNotification(NTOrphanBlock, orphanRoot) return nil } From 5c6911c775d79b61a9b35cd42b8a71b8dd78c0dc Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 20 Aug 2013 11:19:34 -0500 Subject: [PATCH 041/190] Add IsKnownOrphan function. This commit provides a new exported function, IsKnownOrphan, which can be used to determine if the passed hash is currently already known to the chain as an orphan. --- chain.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/chain.go b/chain.go index 0f5a1b83..1625d28d 100644 --- a/chain.go +++ b/chain.go @@ -168,6 +168,29 @@ func (b *BlockChain) DisableVerify(disable bool) { b.noVerify = disable } +// IsKnownOrphan returns whether the passed hash is currently a known orphan. +// Keep in mind that only a limited number of orphans are held onto for a +// limited amount of time, so this function must not be used as an absolute +// way to test if a block is an orphan block. A full block (as opposed to just +// its hash) must be passed to ProcessBlock for that purpose. However, calling +// ProcessBlock with an orphan that already exists results in an error, so this +// function provides a mechanism for a caller to intelligently detect *recent* +// duplicate orphans and react accordingly. +// +// This function is safe for concurrent access. +func (b *BlockChain) IsKnownOrphan(hash *btcwire.ShaHash) bool { + // Protect concurrent access. Using a read lock only so multiple + // readers can query without blocking each other. + b.orphanLock.RLock() + defer b.orphanLock.RUnlock() + + if _, exists := b.orphans[*hash]; exists { + return true + } + + return false +} + // GetOrphanRoot returns the head of the chain for the provided hash from the // map of orphan blocks. // From d0be0ed5eda5a79dfbc86c72e35f0a2b60d2f13e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 22 Aug 2013 15:50:57 -0500 Subject: [PATCH 042/190] Add HaveInventory function. This commit provides a new exported function, HaveInventory, which can be used to determine if the already has the item referenced by passed inventory vector. Currently it only provides support for blocks and cursory support for transactions in the main chain. Types that are unrecognized are returned as if they unknown as expected. --- chain.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/chain.go b/chain.go index 1625d28d..6758e6d2 100644 --- a/chain.go +++ b/chain.go @@ -168,6 +168,40 @@ func (b *BlockChain) DisableVerify(disable bool) { b.noVerify = disable } +// HaveInventory returns whether or not the chain instance has the inventory +// represented by the passed inventory vector. This includes checking all of +// the various places inventory can be when it is in different states such as +// part of the main chain, on a side chain, and orphans. +// +// This function is safe for concurrent access. +func (b *BlockChain) HaveInventory(inventoryVector *btcwire.InvVect) bool { + switch inventoryVector.Type { + case btcwire.InvVect_Block: + // Check the main chain and side chains. + if b.blockExists(&inventoryVector.Hash) { + return true + } + + // Check orphan blocks. + if b.IsKnownOrphan(&inventoryVector.Hash) { + return true + } + + case btcwire.InvVect_Tx: + // TODO(davec): Need to ultimately maintain a transaction pool + // of transactions that are not already in a block and check + // for the existing transaction there too. + + // Check if the transaction exists from the point of view of the + // end of the main chain. + return b.db.ExistsTxSha(&inventoryVector.Hash) + } + + // The requested inventory is either not known or is an unsupported + // type (which also implies it is not known). + return false +} + // IsKnownOrphan returns whether the passed hash is currently a known orphan. // Keep in mind that only a limited number of orphans are held onto for a // limited amount of time, so this function must not be used as an absolute From fc1b2e54d38a3803e835e67d254a2f79d788ba27 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 28 Aug 2013 10:42:38 -0500 Subject: [PATCH 043/190] Set best chain during GenerateInitialIndex. This commit modifies the GenerateInitialIndex function to update the best chain with each node as it is loaded. This allows the best chain to be set immediately upon generating the initial index which is a slight performance optimization. --- chain.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/chain.go b/chain.go index 6758e6d2..123b9aef 100644 --- a/chain.go +++ b/chain.go @@ -379,10 +379,13 @@ func (b *BlockChain) GenerateInitialIndex() error { return err } - _, err = b.loadBlockNode(hash) + node, err := b.loadBlockNode(hash) if err != nil { return err } + + // This node is now the end of the best chain. + b.bestChain = node } return nil From fc804aaec0f5067b88c5fc512515da44fc4ed768 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 28 Aug 2013 11:45:21 -0500 Subject: [PATCH 044/190] Add block locator infastructure. This commit adds a new type, BlockLocator, and supporting infrastructure to support generating block locators from a provided hash and getting a full block locator for the latest known block. This will likely be expanded in the future to provide the opposite functionality as well. That is to say the ability to lookup a block using a block locator. --- blocklocator.go | 140 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 blocklocator.go diff --git a/blocklocator.go b/blocklocator.go new file mode 100644 index 00000000..5ae9d5e2 --- /dev/null +++ b/blocklocator.go @@ -0,0 +1,140 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "github.com/conformal/btcwire" +) + +// BlockLocator is used to help locate a specific block. The algorithm for +// building the block locator is to add the hashes in reverse order until +// the genesis block is reached. In order to keep the list of locator hashes +// to a reasonable number of entries, first the most recent previous 10 block +// hashes are added, then the step is doubled each loop iteration to +// exponentially decrease the number of hashes as a function of the distance +// from the block being located. +type BlockLocator []*btcwire.ShaHash + +// BlockLocatorFromHash returns a block locator for the passed block hash. +// See BlockLocator for details on the algotirhm used to create a block locator. +// +// In addition to the general algorithm referenced above, there are a couple of +// special cases which are handled: +// +// - If the genesis hash is passed, there are no previous hashes to add and +// therefore the block locator will only consist of the genesis hash +// - If the passed hash is not currently known, the block locator will only +// consist of the passed hash +func (b *BlockChain) BlockLocatorFromHash(hash *btcwire.ShaHash) BlockLocator { + // The locator contains the requested hash at the very least. + locator := BlockLocator([]*btcwire.ShaHash{hash}) + + // Nothing more to do if a locator for the genesis hash was requested. + if hash.IsEqual(b.chainParams().GenesisHash) { + return locator + } + + // Attempt to find the height of the block that corresponds to the + // passed hash, and if it's on a side chain, find the height at which + // it forks from the main chain. + blockHeight := int64(-1) + forkHeight := int64(-1) + node, exists := b.index[*hash] + if !exists { + // Try to look up the height for passed block hash. Assume an + // error means it doesn't exist and just return the locator for + // the block itself. + block, err := b.db.FetchBlockBySha(hash) + if err != nil { + return locator + } + blockHeight = block.Height() + + } else { + blockHeight = node.height + + // Find the height at which this node forks from the main chain + // if the node is on a side chain. + if !node.inMainChain { + for n := node; n.parent != nil; n = n.parent { + if n.inMainChain { + forkHeight = n.height + break + } + } + } + } + + // Generate the block locators according to the algorithm described in + // in the BlockLocator comment and make sure to leave room for the + // final genesis hash. + iterNode := node + increment := int64(1) + for len(locator) < btcwire.MaxBlockLocatorsPerMsg-1 { + // Once there are 10 locators, exponentially increase the + // distance between each block locator. + if len(locator) > 10 { + increment *= 2 + } + blockHeight -= increment + if blockHeight < 1 { + break + } + + // As long as this is still on the side chain, walk backwards + // along the side chain nodes to each block height. + if forkHeight != -1 && blockHeight > forkHeight { + // Intentionally use parent field instead of the + // getPrevNodeFromNode function since we don't want to + // dynamically load nodes when building block locators. + // Side chain blocks should always be in memory already, + // and if they aren't for some reason it's ok to skip + // them. + for iterNode != nil && blockHeight > iterNode.height { + iterNode = iterNode.parent + } + if iterNode != nil && iterNode.height == blockHeight { + locator = append(locator, iterNode.hash) + } + continue + } + + // The desired block height is in the main chain, so look it up + // from the main chain database. + h, err := b.db.FetchBlockShaByHeight(blockHeight) + if err != nil { + // This shouldn't happen and it's ok to ignore block + // locators, so just continue to the next one. + log.Warnf("Lookup of known valid height failed %v", + blockHeight) + continue + } + locator = append(locator, h) + } + + // Append the appropriate genesis block. + locator = append(locator, b.chainParams().GenesisHash) + return locator +} + +// LatestBlockLocator returns a block locator for the latest known tip of the +// main (best) chain. +func (b *BlockChain) LatestBlockLocator() (BlockLocator, error) { + // Lookup the latest main chain hash if the best chain hasn't been set + // yet. + if b.bestChain == nil { + // Get the latest block hash for the main chain from the + // database. + hash, _, err := b.db.NewestSha() + if err != nil { + return nil, err + } + + return b.BlockLocatorFromHash(hash), nil + } + + // The best chain is set, so use its hash. + return b.BlockLocatorFromHash(b.bestChain.hash), nil +} From ffa56b437c74a25732306f514687efdd19d74c6c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 28 Aug 2013 13:46:17 -0500 Subject: [PATCH 045/190] Correct error msg for missing input transaction. The error message for missing input transaction had the referenced and referencing transactions backwards. --- validate.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/validate.go b/validate.go index 5b7852f0..73f8d60d 100644 --- a/validate.go +++ b/validate.go @@ -348,8 +348,8 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir originTx, exists := txStore[*txInHash] if !exists || originTx.err != nil || originTx.tx == nil { return 0, fmt.Errorf("unable to find input transaction "+ - "%v referenced from transaction %v", txHash, - txInHash) + "%v referenced from transaction %v", txInHash, + txHash) } // Ensure the output index in the referenced transaction is From 117765ba7c26412c9a432f4b05763027e66e87f6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 28 Aug 2013 13:50:47 -0500 Subject: [PATCH 046/190] Correct error message in other input tx lookup. --- validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.go b/validate.go index 73f8d60d..c072b00f 100644 --- a/validate.go +++ b/validate.go @@ -605,7 +605,7 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi originTx, exists := txStore[*txInHash] if !exists { str := fmt.Sprintf("unable to find input transaction "+ - "%v for transaction %v", txHash, txInHash) + "%v for transaction %v", txInHash, txHash) return 0, RuleError(str) } From 4ac899e26f61900ddf01e3123103eeff0d00cba4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 29 Aug 2013 08:56:27 -0500 Subject: [PATCH 047/190] Clear disconnected transactions. Rather than removing disconnected transactions from the node viewpoint transaction store, clear the entry instead. This is needed for the connect code to update transactions that were removed on the other side of a chain fork. --- txlookup.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/txlookup.go b/txlookup.go index 2cfb7ba6..50f5c184 100644 --- a/txlookup.go +++ b/txlookup.go @@ -60,22 +60,31 @@ func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Blo // transactions in the passed map are updated. func disconnectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of - // them are ones were need to undo based on the results map. + // them are ones that need to be undone based on the transaction store. for i, tx := range block.MsgBlock().Transactions { txHash, err := block.TxSha(i) if err != nil { return err } - // Remove this transaction from the transaction store (this is a - // no-op if it's not there). - delete(txStore, *txHash) + // Clear this transaction from the transaction store if needed. + // Only clear it rather than deleting it because the transaction + // connect code relies on its presence to decide whether or not + // to update the store and any transactions which exist on both + // sides of a fork would otherwise not be updated. + if txD, exists := txStore[*txHash]; exists { + txD.tx = nil + txD.blockHeight = 0 + txD.spent = nil + txD.err = btcdb.TxShaMissing + } // Unspend the origin transaction output. for _, txIn := range tx.TxIn { originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index - if originTx, exists := txStore[*originHash]; exists { + originTx, exists := txStore[*originHash] + if exists && originTx.tx != nil && originTx.err == nil { originTx.spent[originIndex] = false } } From 49f6b7d35df2a4dea377e481a7d53ec5c1a4cb8d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 29 Aug 2013 12:01:19 -0500 Subject: [PATCH 048/190] Add checkpoint at block 250000. --- checkpoints.go | 1 + 1 file changed, 1 insertion(+) diff --git a/checkpoints.go b/checkpoints.go index 64e67e63..4f4c4019 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -56,6 +56,7 @@ var checkpointDataMainNet = checkpointData{ {210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, {216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, {225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, + {250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, }, checkpointsByHeight: nil, // Automatically generated in init. } From 0ba8cb9187b5a68e61c7f09068d2c9425733ced3 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 6 Sep 2013 11:05:04 -0500 Subject: [PATCH 049/190] Send notification in their own goroutine. Since the notification channel is provided by the caller and it may or may not be buffered, send notifications in their own goroutine so the chain processing code does not have to wait around on the caller to process the notification before continuing. --- notifications.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/notifications.go b/notifications.go index 5cc544f2..bd3dfe9a 100644 --- a/notifications.go +++ b/notifications.go @@ -70,7 +70,9 @@ func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { return } - // Generate and send the notification. - n := Notification{Type: typ, Data: data} - b.notifications <- &n + // Generate and send the notification asynchronously. + go func() { + n := Notification{Type: typ, Data: data} + b.notifications <- &n + }() } From b557a33f7ce0ce59a02f6c308de44dba137f9e62 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Sep 2013 19:35:36 -0500 Subject: [PATCH 050/190] Send orphan hash in notifications instead of root. Rather than sending the root of the an orphan chain when sending an orphan notification, send the hash of the orphan block itself. The caller can then call the GetOrphanRoot function with the hash to get the root of the orphan chain as needed. This is being changed since it's cleaner and more detministic sending the hash for the orphan block that was just processed rather than sending a possibly different hash depending on whether there is an orphan chain or not. --- notifications.go | 5 +++-- process.go | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/notifications.go b/notifications.go index bd3dfe9a..4ad7b376 100644 --- a/notifications.go +++ b/notifications.go @@ -14,8 +14,9 @@ type NotificationType int // Constants for the type of a notification message. const ( // NTOrphanBlock indicates an orphan block was processed and the - // associated block hash is the root of all known orphans which should - // be used to request the missing blocks. + // associated block hash should be passed to the GetOrphanRoot function + // to find the root of all known orphans which should then be used to + // request the missing blocks. NTOrphanBlock NotificationType = iota // NTBlockAccepted indicates the associated block was accepted into diff --git a/process.go b/process.go index 29aaa0bf..98e120f4 100644 --- a/process.go +++ b/process.go @@ -148,11 +148,8 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { prevHash) b.addOrphanBlock(block) - // Get the hash for the head of the orphaned block chain for - // this block and notify the caller so it can request missing - // blocks. - orphanRoot := b.GetOrphanRoot(blockHash) - b.sendNotification(NTOrphanBlock, orphanRoot) + // Notify the caller so it can request missing blocks. + b.sendNotification(NTOrphanBlock, blockHash) return nil } From 00b183a8b51600d7a248a9d35b83207bd3083896 Mon Sep 17 00:00:00 2001 From: Dale Rahn Date: Thu, 19 Sep 2013 15:09:18 -0400 Subject: [PATCH 051/190] Remove unreachable statement. ok davec@ --- chain.go | 1 - 1 file changed, 1 deletion(-) diff --git a/chain.go b/chain.go index 123b9aef..03aecd21 100644 --- a/chain.go +++ b/chain.go @@ -132,7 +132,6 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { copy(children[i:], children[i+1:]) children[len(children)-1] = nil return children[:len(children)-1] - i-- } } return children From d1f1fe075289e709062e8d62c73078f30fb17c5a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 21 Sep 2013 09:23:26 -0500 Subject: [PATCH 052/190] Revert "Send notification in their own goroutine." After discussion with others and thinking about the notification channel some more, we've decided to leave it up to the caller to quickly handle notifications. While it is true that notification should be handled quickly to not block the chain processing code unnecessarily, launching a goroutine in chain means the notifications are no longer necessarily in order. Also, if the caller is not properly handling the notifications, the goroutines end up sicking around forever. By leaving it up to the caller to quickly handle the notification or launch a goroutine as necessary for the caller, it provides the flexibility to ensure proper notification ordering as well as control over other things such as how to handle backpressure. --- notifications.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/notifications.go b/notifications.go index 4ad7b376..51ac0c8a 100644 --- a/notifications.go +++ b/notifications.go @@ -71,9 +71,7 @@ func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { return } - // Generate and send the notification asynchronously. - go func() { - n := Notification{Type: typ, Data: data} - b.notifications <- &n - }() + // Generate and send the notification. + n := Notification{Type: typ, Data: data} + b.notifications <- &n } From 2f743b482185096a04dacdae9afb7e08498ecc5b Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 25 Sep 2013 20:20:53 -0500 Subject: [PATCH 053/190] Pre-allocate space for high use slices. This commit modifies the code to choose sane defaults for the backing arrays for slices that involve a lot of appends such block locators, hash processing, and needed transactions. This is an optimization to avoid the overhead of growing the backing arrays and copying the data multiple times in the most common case. This also prevents a leak in Go GC which will likely ultimatley be fixed, but the efficiecy gains alone are worth the change. --- blocklocator.go | 3 ++- process.go | 7 ++++++- txlookup.go | 12 +++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/blocklocator.go b/blocklocator.go index 5ae9d5e2..a3258f25 100644 --- a/blocklocator.go +++ b/blocklocator.go @@ -29,7 +29,8 @@ type BlockLocator []*btcwire.ShaHash // consist of the passed hash func (b *BlockChain) BlockLocatorFromHash(hash *btcwire.ShaHash) BlockLocator { // The locator contains the requested hash at the very least. - locator := BlockLocator([]*btcwire.ShaHash{hash}) + locator := make(BlockLocator, 0, btcwire.MaxBlockLocatorsPerMsg) + locator = append(locator, hash) // Nothing more to do if a locator for the genesis hash was requested. if hash.IsEqual(b.chainParams().GenesisHash) { diff --git a/process.go b/process.go index 98e120f4..60894d68 100644 --- a/process.go +++ b/process.go @@ -38,10 +38,15 @@ func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { // It repeats the process for the newly accepted blocks (to detect further // orphans which may no longer be orphans) until there are no more. func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { - processHashes := []*btcwire.ShaHash{hash} + // Start with processing at least the passed hash. Leave a little room + // for additional orphan blocks that need to be processed without + // needing to grow the array in the common case. + processHashes := make([]*btcwire.ShaHash, 0, 10) + processHashes = append(processHashes, hash) for len(processHashes) > 0 { // Pop the first hash to process from the slice. processHash := processHashes[0] + processHashes[0] = nil // Prevent GC leak. processHashes = processHashes[1:] // Look up all orphans that are parented by the block we just diff --git a/txlookup.go b/txlookup.go index 50f5c184..0cc08a88 100644 --- a/txlookup.go +++ b/txlookup.go @@ -215,10 +215,20 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txInFlight[*txHash] = i } + // Make a reasonable guess for the maximum number of needed input + // transactions to use as the starting point for the needed transactions + // array. The array will dynamically grow as needed, but it's much less + // overhead to avoid growing and copying the array multiple times in the + // common case. Each block usually has no more than ten inputs per + // transaction, so use that as a reasonable starting point. A block + // with 2,000 transactions would only result in around 156KB on a 64-bit + // system using this approach. + maxNeededHint := (len(transactions) - 1) * 10 + txNeededList := make([]*btcwire.ShaHash, 0, maxNeededHint) + // Loop through all of the transaction inputs (except for the coinbase // which has no inputs) collecting them into lists of what is needed and // what is already known (in-flight). - var txNeededList []*btcwire.ShaHash txStore := make(map[btcwire.ShaHash]*txData) for i, tx := range transactions[1:] { for _, txIn := range tx.TxIn { From fc69776371f3cb48b59a29e9f7fdc3b8ab37f0bd Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:21:35 -0500 Subject: [PATCH 054/190] Expose a transaction store and related functions. Several of the functions require a map of contextual transaction data to use as a source for referenced transactions. This commit exports the underlying TxData type and creates a new type TxStore, which is a map of points to the under TxData. In addition, this commit exposes a new function, FetchTransactionStore, which returns a transaction store (TxStore) containing all of the transactions referenced by the passed transaction, as well as the existing transaction if it already exists. This paves the way for subsequent commits which will expose some of the functions which depend on this transaction store. --- scriptval.go | 21 +++---- txlookup.go | 165 ++++++++++++++++++++++++++++++++++----------------- validate.go | 39 ++++++------ 3 files changed, 140 insertions(+), 85 deletions(-) diff --git a/scriptval.go b/scriptval.go index 139fc630..e4335110 100644 --- a/scriptval.go +++ b/scriptval.go @@ -60,10 +60,11 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b return nil } -// validateAllTxIn validates the scripts for all of the passed transaction -// inputs using multiple goroutines. -func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, timestamp time.Time, job []*btcwire.TxIn, txStore map[btcwire.ShaHash]*txData) (err error) { +// validateAllTxIn validates the scripts for the passed transaction using +// multiple goroutines. +func validateAllTxIn(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, timestamp time.Time, txStore TxStore) (err error) { c := make(chan txValidate) + job := tx.TxIn resultErrors := make([]error, len(job)) var currentItem int @@ -71,7 +72,7 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, timesta processFunc := func(txInIdx int) { log.Tracef("validating tx %v input %v len %v", - txsha, currentItem, len(job)) + txHash, currentItem, len(job)) txin := job[txInIdx] originTxSha := &txin.PreviousOutpoint.Hash origintxidx := txin.PreviousOutpoint.Index @@ -84,10 +85,10 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, timesta fmt.Printf("obj not found in txStore %v", originTxSha) } - originTx = txInfo.tx + originTx = txInfo.Tx } - err := validateTxIn(txInIdx, job[txInIdx], txsha, txValidator, - timestamp, originTx) + err := validateTxIn(txInIdx, job[txInIdx], txHash, tx, timestamp, + originTx) r := txValidate{txInIdx, err} c <- r } @@ -113,7 +114,7 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, timesta } for i := 0; i < len(job); i++ { if resultErrors[i] != nil { - log.Warnf("tx %v failed input %v, err %v", txsha, i, resultErrors[i]) + log.Warnf("tx %v failed input %v, err %v", txHash, i, resultErrors[i]) } } return @@ -121,11 +122,11 @@ func validateAllTxIn(txsha *btcwire.ShaHash, txValidator *btcwire.MsgTx, timesta // checkBlockScripts executes and validates the scripts for all transactions in // the passed block. -func checkBlockScripts(block *btcutil.Block, txStore map[btcwire.ShaHash]*txData) error { +func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { timestamp := block.MsgBlock().Header.Timestamp for i, tx := range block.MsgBlock().Transactions { txHash, _ := block.TxSha(i) - err := validateAllTxIn(txHash, tx, timestamp, tx.TxIn, txStore) + err := validateAllTxIn(tx, txHash, timestamp, txStore) if err != nil { return err } diff --git a/txlookup.go b/txlookup.go index 0cc08a88..af9cf876 100644 --- a/txlookup.go +++ b/txlookup.go @@ -11,20 +11,26 @@ import ( "github.com/conformal/btcwire" ) -// txData contains contextual information about transactions such as which block +// TxData contains contextual information about transactions such as which block // they were found in and whether or not the outputs are spent. -type txData struct { - tx *btcwire.MsgTx - hash *btcwire.ShaHash - blockHeight int64 - spent []bool - err error +type TxData struct { + Tx *btcwire.MsgTx + Hash *btcwire.ShaHash + BlockHeight int64 + Spent []bool + Err error } +// TxStore is used to store transactions needed by other transactions for things +// such as script validation and double spend prevention. This also allows the +// transaction data to be treated as a view since it can contain the information +// from the point-of-view of different points in the chain. +type TxStore map[btcwire.ShaHash]*TxData + // connectTransactions updates the passed map by applying transaction and // spend information for all the transactions in the passed block. Only // transactions in the passed map are updated. -func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Block) error { +func connectTransactions(txStore TxStore, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of // them are ones we need to update and spend based on the results map. for i, tx := range block.MsgBlock().Transactions { @@ -36,10 +42,10 @@ func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Blo // Update the transaction store with the transaction information // if it's one of the requested transactions. if txD, exists := txStore[*txHash]; exists { - txD.tx = tx - txD.blockHeight = block.Height() - txD.spent = make([]bool, len(tx.TxOut)) - txD.err = nil + txD.Tx = tx + txD.BlockHeight = block.Height() + txD.Spent = make([]bool, len(tx.TxOut)) + txD.Err = nil } // Spend the origin transaction output. @@ -47,7 +53,7 @@ func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Blo originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index if originTx, exists := txStore[*originHash]; exists { - originTx.spent[originIndex] = true + originTx.Spent[originIndex] = true } } } @@ -58,7 +64,7 @@ func connectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Blo // disconnectTransactions updates the passed map by undoing transaction and // spend information for all transactions in the passed block. Only // transactions in the passed map are updated. -func disconnectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil.Block) error { +func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of // them are ones that need to be undone based on the transaction store. for i, tx := range block.MsgBlock().Transactions { @@ -73,10 +79,10 @@ func disconnectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil. // to update the store and any transactions which exist on both // sides of a fork would otherwise not be updated. if txD, exists := txStore[*txHash]; exists { - txD.tx = nil - txD.blockHeight = 0 - txD.spent = nil - txD.err = btcdb.TxShaMissing + txD.Tx = nil + txD.BlockHeight = 0 + txD.Spent = nil + txD.Err = btcdb.TxShaMissing } // Unspend the origin transaction output. @@ -84,8 +90,8 @@ func disconnectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil. originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index originTx, exists := txStore[*originHash] - if exists && originTx.tx != nil && originTx.err == nil { - originTx.spent[originIndex] = false + if exists && originTx.Tx != nil && originTx.Err == nil { + originTx.Spent[originIndex] = false } } } @@ -94,34 +100,20 @@ func disconnectTransactions(txStore map[btcwire.ShaHash]*txData, block *btcutil. } // fetchTxList fetches transaction data about the provided list of transactions -// from the point of view of the given node. For example, a given node might -// be down a side chain where a transaction hasn't been spent from its point of -// view even though it might have been spent in the main chain (or another side -// chain). Another scenario is where a transaction exists from the point of -// view of the main chain, but doesn't exist in a side chain that branches -// before the block that contains the transaction on the main chain. -func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (map[btcwire.ShaHash]*txData, error) { - // Get the previous block node. This function is used over simply - // accessing node.parent directly as it will dynamically create previous - // block nodes as needed. This helps allow only the pieces of the chain - // that are needed to remain in memory. - prevNode, err := b.getPrevNodeFromNode(node) - if err != nil { - return nil, err - } - +// from the point of view of the end of the main chain. +func fetchTxListMain(db btcdb.Db, txList []*btcwire.ShaHash) TxStore { // The transaction store map needs to have an entry for every requested // transaction. By default, all the transactions are marked as missing. // Each entry will be filled in with the appropriate data below. - txStore := make(map[btcwire.ShaHash]*txData) + txStore := make(TxStore) for _, hash := range txList { - txStore[*hash] = &txData{hash: hash, err: btcdb.TxShaMissing} + txStore[*hash] = &TxData{Hash: hash, Err: btcdb.TxShaMissing} } // Ask the database (main chain) for the list of transactions. This // will return the information from the point of view of the end of the // main chain. - txReplyList := b.db.FetchTxByShaList(txList) + txReplyList := db.FetchTxByShaList(txList) for _, txReply := range txReplyList { // Lookup the existing results entry to modify. Skip // this reply if there is no corresponding entry in @@ -137,19 +129,42 @@ func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (ma // this code modifies the data. A bug caused by modifying the // cached data would likely be difficult to track down and could // cause subtle errors, so avoid the potential altogether. - txD.err = txReply.Err + txD.Err = txReply.Err if txReply.Err == nil { - txD.tx = txReply.Tx - txD.blockHeight = txReply.Height - txD.spent = make([]bool, len(txReply.TxSpent)) - copy(txD.spent, txReply.TxSpent) + txD.Tx = txReply.Tx + txD.BlockHeight = txReply.Height + txD.Spent = make([]bool, len(txReply.TxSpent)) + copy(txD.Spent, txReply.TxSpent) } } - // At this point, we have the transaction data from the point of view - // of the end of the main (best) chain. If we haven't selected a best - // chain yet or we are extending the main (best) chain with a new block, - // everything is accurate, so return the results now. + return txStore +} + +// fetchTxList fetches transaction data about the provided list of transactions +// from the point of view of the given node. For example, a given node might +// be down a side chain where a transaction hasn't been spent from its point of +// view even though it might have been spent in the main chain (or another side +// chain). Another scenario is where a transaction exists from the point of +// view of the main chain, but doesn't exist in a side chain that branches +// before the block that contains the transaction on the main chain. +func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (TxStore, error) { + // Get the previous block node. This function is used over simply + // accessing node.parent directly as it will dynamically create previous + // block nodes as needed. This helps allow only the pieces of the chain + // that are needed to remain in memory. + prevNode, err := b.getPrevNodeFromNode(node) + if err != nil { + return nil, err + } + + // Fetch the requested list from the point of view of the end of the + // main (best) chain. + txStore := fetchTxListMain(b.db, txList) + + // If we haven't selected a best chain yet or we are extending the main + // (best) chain with a new block, everything is accurate, so return the + // results now. if b.bestChain == nil || (prevNode != nil && prevNode.hash.IsEqual(b.bestChain.hash)) { return txStore, nil } @@ -200,7 +215,7 @@ func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (ma // fetchInputTransactions fetches the input transactions referenced by the // transactions in the given block from its point of view. See fetchTxList // for more details on what the point of view entails. -func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Block) (map[btcwire.ShaHash]*txData, error) { +func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Block) (TxStore, error) { // Build a map of in-flight transactions because some of the inputs in // this block could be referencing other transactions earlier in this // block which are not yet in the chain. @@ -229,13 +244,13 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // Loop through all of the transaction inputs (except for the coinbase // which has no inputs) collecting them into lists of what is needed and // what is already known (in-flight). - txStore := make(map[btcwire.ShaHash]*txData) + txStore := make(TxStore) for i, tx := range transactions[1:] { for _, txIn := range tx.TxIn { // Add an entry to the transaction store for the needed // transaction with it set to missing by default. originHash := &txIn.PreviousOutpoint.Hash - txD := &txData{hash: originHash, err: btcdb.TxShaMissing} + txD := &TxData{Hash: originHash, Err: btcdb.TxShaMissing} txStore[*originHash] = txD // It is acceptable for a transaction input to reference @@ -252,10 +267,10 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc i >= inFlightIndex { originTx := transactions[inFlightIndex] - txD.tx = originTx - txD.blockHeight = node.height - txD.spent = make([]bool, len(originTx.TxOut)) - txD.err = nil + txD.Tx = originTx + txD.BlockHeight = node.height + txD.Spent = make([]bool, len(originTx.TxOut)) + txD.Err = nil } else { txNeededList = append(txNeededList, originHash) } @@ -271,7 +286,45 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // Merge the results of the requested transactions and the in-flight // transactions. for _, txD := range txNeededStore { - txStore[*txD.hash] = txD + txStore[*txD.Hash] = txD + } + + return txStore, nil +} + +// FetchTransactionStore fetches the input transactions referenced by the +// passed transaction from the point of view of the end of the main chain. It +// also attempts to fetch the transaction itself so the returned TxStore can be +// examined for duplicate transactions. +func (b *BlockChain) FetchTransactionStore(tx *btcwire.MsgTx) (TxStore, error) { + txHash, err := tx.TxSha() + if err != nil { + return nil, err + } + + // Create list big + txNeededList := make([]*btcwire.ShaHash, 0, len(tx.TxIn)+1) + txNeededList = append(txNeededList, &txHash) + + // Loop through all of the transaction inputs collecting them into lists of what is needed and + // what is already known (in-flight). + txStore := make(TxStore) + for _, txIn := range tx.TxIn { + // Add an entry to the transaction store for the needed + // transaction with it set to missing by default. + originHash := &txIn.PreviousOutpoint.Hash + txD := &TxData{Hash: originHash, Err: btcdb.TxShaMissing} + txStore[*originHash] = txD + txNeededList = append(txNeededList, originHash) + } + + // Request the input transactions from the point of view of the node. + txNeededStore := fetchTxListMain(b.db, txNeededList) + + // Merge the results of the requested transactions and the in-flight + // transactions. + for _, txD := range txNeededStore { + txStore[*txD.Hash] = txD } return txStore, nil diff --git a/validate.go b/validate.go index c072b00f..c6dcf535 100644 --- a/validate.go +++ b/validate.go @@ -327,7 +327,7 @@ func countSigOps(msgTx *btcwire.MsgTx) int { // transactions which are of the pay-to-script-hash type. This uses the // precise, signature operation counting mechanism from btcscript which requires // access to the input transaction scripts. -func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwire.ShaHash]*txData) (int, error) { +func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) (int, error) { // Coinbase transactions have no interesting inputs. if isCoinBaseTx { return 0, nil @@ -346,7 +346,7 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir // Ensure the referenced input transaction is available. txInHash := &txIn.PreviousOutpoint.Hash originTx, exists := txStore[*txInHash] - if !exists || originTx.err != nil || originTx.tx == nil { + if !exists || originTx.Err != nil || originTx.Tx == nil { return 0, fmt.Errorf("unable to find input transaction "+ "%v referenced from transaction %v", txInHash, txHash) @@ -355,7 +355,7 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir // Ensure the output index in the referenced transaction is // available. originTxIndex := txIn.PreviousOutpoint.Index - if originTxIndex >= uint32(len(originTx.tx.TxOut)) { + if originTxIndex >= uint32(len(originTx.Tx.TxOut)) { return 0, fmt.Errorf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", originTxIndex, txInHash, txHash) @@ -363,7 +363,7 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore map[btcwir // We're only interested in pay-to-script-hash types, so skip // this input if it's not one. - pkScript := originTx.tx.TxOut[originTxIndex].PkScript + pkScript := originTx.Tx.TxOut[originTxIndex].PkScript if !btcscript.IsPayToScriptHash(pkScript) { continue } @@ -519,10 +519,11 @@ func checkSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { return nil } -// isTransactionSpent returns whether or not the provided transaction is fully -// spent. A fully spent transaction is one where all outputs have been spent. -func isTransactionSpent(tx *txData) bool { - for _, isOutputSpent := range tx.spent { +// isTransactionSpent returns whether or not the provided transaction data +// describes a fully spent transaction. A fully spent transaction is one where +// all outputs have been spent. +func isTransactionSpent(txD *TxData) bool { + for _, isOutputSpent := range txD.Spent { if !isOutputSpent { return false } @@ -552,7 +553,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // Examine the resulting data about the requested transactions. for _, txD := range txResults { - switch txD.err { + switch txD.Err { // A duplicate transaction was not found. This is the most // common case. case btcdb.TxShaMissing: @@ -564,14 +565,14 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { if !isTransactionSpent(txD) { str := fmt.Sprintf("tried to overwrite "+ "transaction %v at block height %d "+ - "that is not fully spent", txD.hash, - txD.blockHeight) + "that is not fully spent", txD.Hash, + txD.BlockHeight) return RuleError(str) } // Some other unexpected error occurred. Return it now. default: - return txD.err + return txD.Err } } @@ -586,7 +587,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // amount, and verifying the signatures to prove the spender was the owner of // the bitcoins and therefore allowed to spend them. As it checks the inputs, // it also calculates the total fees for the transaction and returns that value. -func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwire.ShaHash]*txData) (int64, error) { +func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) (int64, error) { // Coinbase transactions have no inputs. if isCoinBase(tx) { return 0, nil @@ -611,8 +612,8 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi // Ensure the transaction is not spending coins which have not // yet reached the required coinbase maturity. - if isCoinBase(originTx.tx) { - originHeight := originTx.blockHeight + if isCoinBase(originTx.Tx) { + originHeight := originTx.BlockHeight blocksSincePrev := txHeight - originHeight if blocksSincePrev < coinbaseMaturity { str := fmt.Sprintf("tried to spend coinbase "+ @@ -626,12 +627,12 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi // Ensure the transaction is not double spending coins. originTxIndex := txIn.PreviousOutpoint.Index - if originTxIndex >= uint32(len(originTx.spent)) { + if originTxIndex >= uint32(len(originTx.Spent)) { return 0, fmt.Errorf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", originTxIndex, txInHash, txHash) } - if originTx.spent[originTxIndex] { + if originTx.Spent[originTxIndex] { str := fmt.Sprintf("transaction %v tried to double "+ "spend coins from transaction %v", txHash, txInHash) @@ -644,7 +645,7 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi // a transaction are in a unit value known as a satoshi. One // bitcoin is a quantity of satoshi as defined by the // satoshiPerBitcoin constant. - originTxSatoshi := originTx.tx.TxOut[originTxIndex].Value + originTxSatoshi := originTx.Tx.TxOut[originTxIndex].Value if originTxSatoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ "value of %v", originTxSatoshi) @@ -671,7 +672,7 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore map[btcwi } // Mark the referenced output as spent. - originTx.spent[originTxIndex] = true + originTx.Spent[originTxIndex] = true } // Calculate the total output amount for this transaction. It is safe From 4eb135618a26671e9821fb607991883bec7ea571 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:40:07 -0500 Subject: [PATCH 055/190] Export the IsFinalizedTransaction function. --- accept.go | 2 +- validate.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accept.go b/accept.go index d0d6e52b..444eddb4 100644 --- a/accept.go +++ b/accept.go @@ -60,7 +60,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // Ensure all transactions in the block are finalized. for i, tx := range block.MsgBlock().Transactions { - if !isFinalizedTransaction(tx, blockHeight, blockHeader.Timestamp) { + if !IsFinalizedTransaction(tx, blockHeight, blockHeader.Timestamp) { // Use the TxSha function from the block rather // than the transaction itself since the block version // is cached. Also, it's safe to ignore the error here diff --git a/validate.go b/validate.go index c6dcf535..b8cb9f31 100644 --- a/validate.go +++ b/validate.go @@ -110,8 +110,8 @@ func isCoinBase(msgTx *btcwire.MsgTx) bool { return true } -// isFinalized determines whether or not a transaction is finalized. -func isFinalizedTransaction(msgTx *btcwire.MsgTx, blockHeight int64, blockTime time.Time) bool { +// IsFinalizedTransaction determines whether or not a transaction is finalized. +func IsFinalizedTransaction(msgTx *btcwire.MsgTx, blockHeight int64, blockTime time.Time) bool { // Lock time of zero means the transaction is finalized. lockTime := msgTx.LockTime if lockTime == 0 { From 6695cd15bb4a9ccd2e412a05f4ceba9f0d6c40a1 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:41:51 -0500 Subject: [PATCH 056/190] Export the IsCoinbase function. --- validate.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/validate.go b/validate.go index b8cb9f31..941897fe 100644 --- a/validate.go +++ b/validate.go @@ -89,12 +89,12 @@ func isNullOutpoint(outpoint *btcwire.OutPoint) bool { return false } -// isCoinBase determines whether or not a transaction is a coinbase. A coinbase +// IsCoinBase determines whether or not a transaction is a coinbase. A coinbase // is a special transaction created by miners that has no inputs. This is // represented in the block chain by a transaction with a single input that has // a previous output transaction index set to the maximum value along with a // zero hash. -func isCoinBase(msgTx *btcwire.MsgTx) bool { +func IsCoinBase(msgTx *btcwire.MsgTx) bool { // A coin base must only have one transaction input. if len(msgTx.TxIn) != 1 { return false @@ -241,7 +241,7 @@ func checkTransactionSanity(tx *btcwire.MsgTx) error { } // Coinbase script length must be between min and max length. - if isCoinBase(tx) { + if IsCoinBase(tx) { slen := len(tx.TxIn[0].SignatureScript) if slen < minCoinbaseScriptLen || slen > maxCoinbaseScriptLen { str := fmt.Sprintf("coinbase transaction script length "+ @@ -421,13 +421,13 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { } // The first transaction in a block must be a coinbase. - if !isCoinBase(transactions[0]) { + if !IsCoinBase(transactions[0]) { return RuleError("first transaction in block is not a coinbase") } // A block must not have more than one coinbase. for i, tx := range transactions[1:] { - if isCoinBase(tx) { + if IsCoinBase(tx) { str := fmt.Sprintf("block contains second coinbase at "+ "index %d", i) return RuleError(str) @@ -589,7 +589,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // it also calculates the total fees for the transaction and returns that value. func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) (int64, error) { // Coinbase transactions have no inputs. - if isCoinBase(tx) { + if IsCoinBase(tx) { return 0, nil } @@ -612,7 +612,7 @@ func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) // Ensure the transaction is not spending coins which have not // yet reached the required coinbase maturity. - if isCoinBase(originTx.Tx) { + if IsCoinBase(originTx.Tx) { originHeight := originTx.BlockHeight blocksSincePrev := txHeight - originHeight if blocksSincePrev < coinbaseMaturity { From e576962cb3c391ad5f97f258b594bef61b0f436c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:43:10 -0500 Subject: [PATCH 057/190] Export the CheckTransactionSanity function. --- validate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/validate.go b/validate.go index 941897fe..824f1260 100644 --- a/validate.go +++ b/validate.go @@ -173,9 +173,9 @@ func calcBlockSubsidy(height int64) int64 { return baseSubsidy >> uint(height/subsidyHalvingInterval) } -// checkTransactionSanity performs some preliminary checks on a transaction to +// CheckTransactionSanity performs some preliminary checks on a transaction to // ensure it is sane. These checks are context free. -func checkTransactionSanity(tx *btcwire.MsgTx) error { +func CheckTransactionSanity(tx *btcwire.MsgTx) error { // A transaction must have at least one input. if len(tx.TxIn) == 0 { return RuleError("transaction has no inputs") @@ -437,7 +437,7 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // Do some preliminary checks on each transaction to ensure they are // sane before continuing. for _, tx := range transactions { - err := checkTransactionSanity(tx) + err := CheckTransactionSanity(tx) if err != nil { return err } From 3c7511a34b4a39af98d8858653d7a041a92029d1 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:44:01 -0500 Subject: [PATCH 058/190] Export the CheckTransactionInputs function. --- validate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/validate.go b/validate.go index 824f1260..ebe56326 100644 --- a/validate.go +++ b/validate.go @@ -579,7 +579,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { return nil } -// checkTransactionInputs performs a series of checks on the inputs to a +// CheckTransactionInputs performs a series of checks on the inputs to a // transaction to ensure they are valid. An example of some of the checks // include verifying all inputs exist, ensuring the coinbase seasoning // requirements are met, detecting double spends, validating all values and fees @@ -587,7 +587,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // amount, and verifying the signatures to prove the spender was the owner of // the bitcoins and therefore allowed to spend them. As it checks the inputs, // it also calculates the total fees for the transaction and returns that value. -func checkTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) (int64, error) { +func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) (int64, error) { // Coinbase transactions have no inputs. if IsCoinBase(tx) { return 0, nil @@ -797,7 +797,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // bounds. var totalFees int64 for _, tx := range transactions { - txFee, err := checkTransactionInputs(tx, node.height, txInputStore) + txFee, err := CheckTransactionInputs(tx, node.height, txInputStore) if err != nil { return err } From baa4c366188d82f3255e8c5a719fb7d1249bffa2 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:47:37 -0500 Subject: [PATCH 059/190] Export ValdiateTransactionScript function. This function allows the caller to execute and validate all scripts for the passed transaction (which includes signature verification). --- scriptval.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scriptval.go b/scriptval.go index e4335110..b1d13036 100644 --- a/scriptval.go +++ b/scriptval.go @@ -60,9 +60,9 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b return nil } -// validateAllTxIn validates the scripts for the passed transaction using -// multiple goroutines. -func validateAllTxIn(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, timestamp time.Time, txStore TxStore) (err error) { +// ValidateTransactionScripts validates the scripts for the passed transaction +// using multiple goroutines. +func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, timestamp time.Time, txStore TxStore) (err error) { c := make(chan txValidate) job := tx.TxIn resultErrors := make([]error, len(job)) @@ -126,7 +126,7 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { timestamp := block.MsgBlock().Header.Timestamp for i, tx := range block.MsgBlock().Transactions { txHash, _ := block.TxSha(i) - err := validateAllTxIn(tx, txHash, timestamp, txStore) + err := ValidateTransactionScripts(tx, txHash, timestamp, txStore) if err != nil { return err } From 5efc3ea23faefadbfeff9fbeff69abe69382d066 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 16:50:10 -0500 Subject: [PATCH 060/190] Remove a couple of outdated comments. --- chain.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/chain.go b/chain.go index 03aecd21..7c4c6a08 100644 --- a/chain.go +++ b/chain.go @@ -740,8 +740,6 @@ func (b *BlockChain) connectBlock(node *blockNode, block *btcutil.Block) error { return err } - // TODO(davec): Remove transactions from memory transaction pool. - // Add the new node to the memory main chain indices for faster // lookups. node.inMainChain = true @@ -778,8 +776,6 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block) erro return err } - // TODO(davec): Put transactions back in memory transaction pool. - // Put block in the side chain cache. node.inMainChain = false b.blockCache[*node.hash] = block From b04b4c27ea2e0604e7822196f43bf6eccd25c522 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Sep 2013 17:00:23 -0500 Subject: [PATCH 061/190] Update the TODO section of README.md to latest. --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 1aec39dc..b68366cf 100644 --- a/README.md +++ b/README.md @@ -130,9 +130,7 @@ intentionally causes an error by attempting to process a duplicate block. ## TODO - Increase test coverage -- Profile and optimize -- Expose some APIs for block verification (without actually inserting it) and - transaction input lookups +- Expose some APIs for block verification (without actually inserting it) ## GPG Verification Key From e54fb96d80973e99d8f60cb403ea1bcd08dab918 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 2 Oct 2013 10:26:44 -0500 Subject: [PATCH 062/190] Test tx lookup validity in CheckInputTransactions. This commit modifies CheckInputTransactions to ensure that not only must a transaction exist in the transaction store, it must also not have any errors associated with it or be nil. --- validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.go b/validate.go index ebe56326..b1e9a354 100644 --- a/validate.go +++ b/validate.go @@ -604,7 +604,7 @@ func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) // Ensure the input is available. txInHash := &txIn.PreviousOutpoint.Hash originTx, exists := txStore[*txInHash] - if !exists { + if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input transaction "+ "%v for transaction %v", txInHash, txHash) return 0, RuleError(str) From 667eaa1562a4b201c29ac37fc9cd174bba61d1ce Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 2 Oct 2013 21:16:38 -0500 Subject: [PATCH 063/190] Move to a callback for notifications. Rather than using a channel for notifictions, use a callback instead. There are several issues that arise with async notifications via a channel, so use a callback instead. The caller can always make the notifications async by using channels in the provided callback if needed. --- chain.go | 14 +++++++------- notifications.go | 16 ++++++++++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/chain.go b/chain.go index 7c4c6a08..157f02a2 100644 --- a/chain.go +++ b/chain.go @@ -144,7 +144,7 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { type BlockChain struct { db btcdb.Db btcnet btcwire.BitcoinNet - notifications chan *Notification + notifications NotificationCallback root *blockNode bestChain *blockNode index map[btcwire.ShaHash]*blockNode @@ -960,12 +960,12 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) err } // New returns a BlockChain instance for the passed bitcoin network using the -// provided backing database. It accepts a channel on which asynchronous -// notifications will be sent when various events take place. See the -// documentation for Notification and NotificationType for details on the -// types and contents of notifications. The provided channel can be nil if the -// caller is not interested in receiving notifications. -func New(db btcdb.Db, btcnet btcwire.BitcoinNet, c chan *Notification) *BlockChain { +// provided backing database. It accepts a callback on which notifications +// will be sent when various events take place. See the documentation for +// Notification and NotificationType for details on the types and contents of +// notifications. The provided callback can be nil if the caller is not +// interested in receiving notifications. +func New(db btcdb.Db, btcnet btcwire.BitcoinNet, c NotificationCallback) *BlockChain { b := BlockChain{ db: db, btcnet: btcnet, diff --git a/notifications.go b/notifications.go index 51ac0c8a..a4ba98b1 100644 --- a/notifications.go +++ b/notifications.go @@ -11,6 +11,10 @@ import ( // NotificationType represents the type of a notification message. type NotificationType int +// NotificationCallback is used for a caller to provide a callback for +// notifications about various chain events. +type NotificationCallback func(*Notification) + // Constants for the type of a notification message. const ( // NTOrphanBlock indicates an orphan block was processed and the @@ -50,10 +54,9 @@ func (n NotificationType) String() string { return fmt.Sprintf("Unknown Notification Type (%d)", int(n)) } -// Notification defines an asynchronous notification that is sent to the caller -// over the notification channel provided during the call to New and consists -// of a notification type as well as associated data that depends on the type as -// follows: +// Notification defines notification that is sent to the caller via the callback +// function provided during the call to New and consists of a notification type +// as well as associated data that depends on the type as follows: // - NTOrphanBlock: *btcwire.ShaHash // - NTBlockAccepted: *btcutil.Block // - NTBlockConnected: *btcutil.Block @@ -64,7 +67,8 @@ type Notification struct { } // sendNotification sends a notification with the passed type and data if the -// caller requested notifications by providing a channel in the call to New. +// caller requested notifications by providing a callback function in the call +// to New. func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { // Ignore it if the caller didn't request notifications. if b.notifications == nil { @@ -73,5 +77,5 @@ func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { // Generate and send the notification. n := Notification{Type: typ, Data: data} - b.notifications <- &n + b.notifications(&n) } From b06aa1672a34746063319655136a343956d30ce9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 23 Sep 2013 08:20:54 -0500 Subject: [PATCH 064/190] Initial implementation of IsCurrent func. This commit adds a new function, IsCurrent, which can be used to determine whether or not the chain believes it is current. Update. --- chain.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/chain.go b/chain.go index 157f02a2..9441b1fc 100644 --- a/chain.go +++ b/chain.go @@ -959,6 +959,38 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) err return nil } +// IsCurrent returns whether or not the chain believes it is current. Several +// factors are used to guess, but the key factors that allow the chain to +// believe it is current are: +// - Latest block height is after the latest checkpoint (if enabled) +// - Latest block has a timestamp newer than 24 hours ago +// +// This function is NOT safe for concurrent access. +func (b *BlockChain) IsCurrent() bool { + // Not current if there isn't a main (best) chain yet. + if b.bestChain == nil { + return false + } + + // Not current if the latest main (best) chain height is before the + // latest known good checkpoint (when checkpoints are enabled). + checkpoint := b.LatestCheckpoint() + if checkpoint != nil && b.bestChain.height < checkpoint.Height { + return false + } + + // Not current if the latest best block has a timestamp before 24 hours + // ago. + now := time.Now() + if b.bestChain.timestamp.Before(now.Add(-24 * time.Hour)) { + return false + } + + // The chain appears to be current if the above checks did not report + // otherwise. + return true +} + // New returns a BlockChain instance for the passed bitcoin network using the // provided backing database. It accepts a callback on which notifications // will be sent when various events take place. See the documentation for From d58fb25d98b5f747bd8497a17d89c38168327a5f Mon Sep 17 00:00:00 2001 From: Dale Rahn Date: Thu, 3 Oct 2013 16:43:36 -0400 Subject: [PATCH 065/190] Update btcchain for btcdb API change. --- txlookup.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/txlookup.go b/txlookup.go index af9cf876..f5729f74 100644 --- a/txlookup.go +++ b/txlookup.go @@ -113,7 +113,7 @@ func fetchTxListMain(db btcdb.Db, txList []*btcwire.ShaHash) TxStore { // Ask the database (main chain) for the list of transactions. This // will return the information from the point of view of the end of the // main chain. - txReplyList := db.FetchTxByShaList(txList) + txReplyList := db.FetchUnSpentTxByShaList(txList) for _, txReply := range txReplyList { // Lookup the existing results entry to modify. Skip // this reply if there is no corresponding entry in From 9841403c58106487ab32623dccb7b647cded5ca8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 4 Oct 2013 12:11:58 -0500 Subject: [PATCH 066/190] Correct comment on fetchTxListMain. --- txlookup.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/txlookup.go b/txlookup.go index f5729f74..21abfb24 100644 --- a/txlookup.go +++ b/txlookup.go @@ -99,8 +99,8 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { return nil } -// fetchTxList fetches transaction data about the provided list of transactions -// from the point of view of the end of the main chain. +// fetchTxListMain fetches transaction data about the provided list of +// transactions from the point of view of the end of the main chain. func fetchTxListMain(db btcdb.Db, txList []*btcwire.ShaHash) TxStore { // The transaction store map needs to have an entry for every requested // transaction. By default, all the transactions are marked as missing. From 4151416b16a7b76e54eeec5ae4da7a99f91ad2b9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 4 Oct 2013 13:41:24 -0500 Subject: [PATCH 067/190] Change processing block log message to trace. When running debug level logging, the only thing that really matters is whether the block was accepted or not. --- process.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process.go b/process.go index 60894d68..c3ca793d 100644 --- a/process.go +++ b/process.go @@ -85,7 +85,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { if err != nil { return err } - log.Debugf("Processing block %v", blockHash) + log.Tracef("Processing block %v", blockHash) // The block must not already exist in the main chain or side chains. if b.blockExists(blockHash) { From bce548cb99df01646a9238d6f6a6357a117490ed Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 6 Oct 2013 13:51:10 -0500 Subject: [PATCH 068/190] Update reorg test to insert genesis block first. btcdb was changed a while back to not insert the genesis block by default. This commit modifies the reorg test to insert it as required so not all blocks are orphans. --- reorganization_test.go | 6 +++ test_coverage.txt | 97 +++++++++++++++++++++++------------------- 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/reorganization_test.go b/reorganization_test.go index 87afbe44..69f22b0f 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -56,6 +56,12 @@ func TestReorganization(t *testing.T) { defer os.Remove(dbname) defer db.Close() + // Insert the main network genesis block. + genesis := btcutil.NewBlock(&btcwire.GenesisBlock) + if _, err := db.InsertBlock(genesis); err != nil { + t.Errorf("Failed to insert genesis block: %v", err) + } + // Since we're not dealing with the real block chain, disable // checkpoints and set the coinbase maturity to 1. blockChain := btcchain.New(db, btcwire.MainNet, nil) diff --git a/test_coverage.txt b/test_coverage.txt index ae333a52..e0681766 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,79 +1,90 @@ -github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (12/12) -github.com/conformal/btcchain/chain.go BlockChain.getOrphanRoot 100.00% (7/7) +github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) +github.com/conformal/btcchain/validate.go countSigOps 100.00% (8/8) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) -github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) +github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) -github.com/conformal/btcchain/difficulty.go calcWork 100.00% (3/3) +github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) -github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) -github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) github.com/conformal/btcchain/log.go init 100.00% (1/1) +github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) +github.com/conformal/btcchain/txlookup.go disconnectTransactions 93.75% (15/16) +github.com/conformal/btcchain/txlookup.go fetchTxListMain 93.33% (14/15) +github.com/conformal/btcchain/process.go BlockChain.processOrphans 92.86% (13/14) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) -github.com/conformal/btcchain/process.go BlockChain.processOrphans 91.67% (11/12) -github.com/conformal/btcchain/txlookup.go disconnectTransactions 90.91% (10/11) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxList 88.57% (31/35) -github.com/conformal/btcchain/scriptval.go validateAllTxIn 87.88% (29/33) -github.com/conformal/btcchain/scriptval.go checkBlockScripts 87.50% (7/8) -github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 86.96% (20/23) -github.com/conformal/btcchain/validate.go countSigOps 86.67% (13/15) +github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 90.00% (27/30) +github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 88.89% (8/9) +github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 88.24% (30/34) +github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 88.24% (15/17) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxList 86.36% (19/22) +github.com/conformal/btcchain/scriptval.go checkBlockScripts 85.71% (6/7) +github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) -github.com/conformal/btcchain/validate.go isCoinBase 83.33% (5/6) -github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) -github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 80.77% (21/26) +github.com/conformal/btcchain/validate.go IsCoinBase 83.33% (5/6) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 78.26% (18/23) -github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) +github.com/conformal/btcchain/difficulty.go calcWork 80.00% (4/5) +github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 76.92% (20/26) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) -github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 75.00% (12/16) +github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) -github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 68.52% (37/54) -github.com/conformal/btcchain/validate.go BlockChain.checkBlockSanity 66.67% (30/45) +github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 69.23% (36/52) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) +github.com/conformal/btcchain/validate.go BlockChain.checkBlockSanity 65.12% (28/43) github.com/conformal/btcchain/scriptval.go validateTxIn 64.71% (11/17) -github.com/conformal/btcchain/validate.go checkTransactionInputs 63.64% (28/44) -github.com/conformal/btcchain/validate.go checkTransactionSanity 62.16% (23/37) +github.com/conformal/btcchain/validate.go CheckTransactionInputs 64.44% (29/45) +github.com/conformal/btcchain/validate.go CheckTransactionSanity 62.16% (23/37) github.com/conformal/btcchain/txlookup.go connectTransactions 60.00% (9/15) +github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) -github.com/conformal/btcchain/params.go BlockChain.netParams 60.00% (3/5) -github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 59.09% (26/44) github.com/conformal/btcchain/validate.go BlockChain.checkProofOfWork 58.82% (10/17) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/14) +github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 55.81% (24/43) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 53.52% (38/71) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) -github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 46.38% (32/69) -github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 33.33% (4/12) +github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 33.33% (2/6) -github.com/conformal/btcchain/validate.go isFinalizedTransaction 23.08% (3/13) +github.com/conformal/btcchain/validate.go IsFinalizedTransaction 23.08% (3/13) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 19.51% (8/41) github.com/conformal/btcchain/checkpoints.go BlockChain.findLatestKnownCheckpoint 18.18% (2/11) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 15.00% (6/40) +github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) -github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/26) -github.com/conformal/btcchain/difficulty.go BigToCompact 0.00% (0/16) -github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/14) +github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/24) +github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/17) +github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/15) +github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) github.com/conformal/btcchain/validate.go checkSerializedHeight 0.00% (0/12) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) +github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) +github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) +github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) +github.com/conformal/btcchain/chain.go BlockChain.HaveInventory 0.00% (0/7) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) +github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 0.00% (0/5) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) -github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 57.57% (578/1004) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) +github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 53.97% (625/1158) From 0b334bc841e5ee8fc8deda8f6a72a86c3e344134 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 6 Oct 2013 13:01:54 -0500 Subject: [PATCH 069/190] Correct reading of serialized height in coinbase. This commit corrects the reading of the serialized height in coinbase transactions for block height of version 2 or greater. On mainnet, the serialized height is always 3 bytes and will continue to be so for something like another ~159 years, so there was no issue with mainnet. However on testnet, there are some version 2 blocks which are low enough in the chain to only take 2 bytes to serialize. In addition, this commit adds a full tests for the relavant function including negative tests and variable length serialized lengths for block heights. Closes #1. --- internal_test.go | 7 +++++++ test_coverage.txt | 30 ++++++++++++++-------------- validate.go | 19 +++++++++++++----- validate_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 20 deletions(-) diff --git a/internal_test.go b/internal_test.go index 0ad1f9d4..b919d543 100644 --- a/internal_test.go +++ b/internal_test.go @@ -13,6 +13,7 @@ package btcchain import ( "github.com/conformal/btcutil" + "github.com/conformal/btcwire" "time" ) @@ -33,3 +34,9 @@ func TstSetCoinbaseMaturity(maturity int64) { func TstTimeSorter(times []time.Time) timeSorter { return timeSorter(times) } + +// TstCheckSerializedHeight makes the internal checkSerializedHeight function +// available to the test package. +func TstCheckSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { + return checkSerializedHeight(coinbaseTx, wantHeight) +} diff --git a/test_coverage.txt b/test_coverage.txt index e0681766..12a4ee8a 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,27 +1,28 @@ +github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) github.com/conformal/btcchain/validate.go countSigOps 100.00% (8/8) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) -github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) +github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) github.com/conformal/btcchain/chain.go New 100.00% (2/2) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) -github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) github.com/conformal/btcchain/txlookup.go disconnectTransactions 93.75% (15/16) github.com/conformal/btcchain/txlookup.go fetchTxListMain 93.33% (14/15) -github.com/conformal/btcchain/process.go BlockChain.processOrphans 92.86% (13/14) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) +github.com/conformal/btcchain/process.go BlockChain.processOrphans 92.86% (13/14) github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 90.00% (27/30) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 88.89% (8/9) github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 88.24% (30/34) @@ -64,27 +65,26 @@ github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/24) github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/17) -github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/15) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) -github.com/conformal/btcchain/validate.go checkSerializedHeight 0.00% (0/12) +github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/15) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) -github.com/conformal/btcchain/chain.go BlockChain.HaveInventory 0.00% (0/7) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) +github.com/conformal/btcchain/chain.go BlockChain.HaveInventory 0.00% (0/7) github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 0.00% (0/5) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 0.00% (0/5) github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) -github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 53.97% (625/1158) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 55.20% (642/1163) diff --git a/validate.go b/validate.go index b1e9a354..b22a54fc 100644 --- a/validate.go +++ b/validate.go @@ -498,17 +498,26 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // transaction starts with the serialized block height of wantHeight. func checkSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { sigScript := coinbaseTx.TxIn[0].SignatureScript - if len(sigScript) < 4 { + if len(sigScript) < 1 { str := "the coinbase signature script for blocks of " + "version %d or greater must start with the " + - "serialized block height" + "length of the serialized block height" str = fmt.Sprintf(str, serializedHeightVersion) return RuleError(str) } - serializedHeightBytes := make([]byte, 4, 4) - copy(serializedHeightBytes, sigScript[1:4]) - serializedHeight := binary.LittleEndian.Uint32(serializedHeightBytes) + serializedLen := int(sigScript[0]) + if len(sigScript[1:]) < serializedLen { + str := "the coinbase signature script for blocks of " + + "version %d or greater must start with the " + + "serialized block height" + str = fmt.Sprintf(str, serializedLen) + return RuleError(str) + } + + serializedHeightBytes := make([]byte, 8, 8) + copy(serializedHeightBytes, sigScript[1:serializedLen+1]) + serializedHeight := binary.LittleEndian.Uint64(serializedHeightBytes) if int64(serializedHeight) != wantHeight { str := fmt.Sprintf("the coinbase signature script serialized "+ "block height is %d when %d was expected", diff --git a/validate_test.go b/validate_test.go index 3718049a..1b2998cd 100644 --- a/validate_test.go +++ b/validate_test.go @@ -9,7 +9,9 @@ import ( "github.com/conformal/btcdb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" + "math" "os" + "reflect" "testing" "time" ) @@ -36,6 +38,54 @@ func TestCheckBlockSanity(t *testing.T) { } } +// TestCheckSerializedHeight tests the checkSerializedHeight function with +// various serialized heights and also does negative tests to ensure errors +// and handled properly. +func TestCheckSerializedHeight(t *testing.T) { + // Create an empty coinbase template to be used in the tests below. + coinbaseOutpoint := btcwire.NewOutPoint(&btcwire.ShaHash{}, math.MaxUint32) + coinbaseTx := btcwire.NewMsgTx() + coinbaseTx.Version = 2 + coinbaseTx.AddTxIn(btcwire.NewTxIn(coinbaseOutpoint, nil)) + + // + tests := []struct { + sigScript []byte // Serialized data + wantHeight int64 // Expected height + err error // Expected error type + }{ + // No serialized height length. + {[]byte{}, 0, btcchain.RuleError("")}, + // Serialized height length with no height bytes. + {[]byte{0x02}, 0, btcchain.RuleError("")}, + // Serialized height length with too few height bytes. + {[]byte{0x02, 0x4a}, 0, btcchain.RuleError("")}, + // Serialized height that needs 2 bytes to encode. + {[]byte{0x02, 0x4a, 0x52}, 21066, nil}, + // Serialized height that needs 2 bytes to encode, but backwards + // endianness. + {[]byte{0x02, 0x4a, 0x52}, 19026, btcchain.RuleError("")}, + // Serialized height that needs 3 bytes to encode. + {[]byte{0x03, 0x40, 0x0d, 0x03}, 200000, nil}, + // Serialized height that needs 3 bytes to encode, but backwards + // endianness. + {[]byte{0x03, 0x40, 0x0d, 0x03}, 1074594560, btcchain.RuleError("")}, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + tx := coinbaseTx.Copy() + tx.TxIn[0].SignatureScript = test.sigScript + + err := btcchain.TstCheckSerializedHeight(tx, test.wantHeight) + if reflect.TypeOf(err) != reflect.TypeOf(test.err) { + t.Errorf("checkSerializedHeight #%d wrong error type "+ + "got: %v <%T>, want: %T", i, err, err, test.err) + continue + } + } +} + // Block100000 defines block 100,000 of the block chain. It is used to // test Block operations. var Block100000 = btcwire.MsgBlock{ From b911e7e455a11993785ee68f87c6f839485acf0f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 8 Oct 2013 12:32:15 -0500 Subject: [PATCH 070/190] Replace HaveInventory with HaveBlock. The original thought was that chain would also house the transaction memory pool, but that ultimately was decided against. As a result, it only makes sense to query chain for blocks rather than generic inventory. --- chain.go | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/chain.go b/chain.go index 9441b1fc..4e396ce7 100644 --- a/chain.go +++ b/chain.go @@ -167,38 +167,13 @@ func (b *BlockChain) DisableVerify(disable bool) { b.noVerify = disable } -// HaveInventory returns whether or not the chain instance has the inventory -// represented by the passed inventory vector. This includes checking all of -// the various places inventory can be when it is in different states such as -// part of the main chain, on a side chain, and orphans. +// HaveBlock returns whether or not the chain instance has the block represented +// by the passed hash. This includes checking the various places a block can +// be like part of the main chain, on a side chain, or in the orphan pool. // -// This function is safe for concurrent access. -func (b *BlockChain) HaveInventory(inventoryVector *btcwire.InvVect) bool { - switch inventoryVector.Type { - case btcwire.InvVect_Block: - // Check the main chain and side chains. - if b.blockExists(&inventoryVector.Hash) { - return true - } - - // Check orphan blocks. - if b.IsKnownOrphan(&inventoryVector.Hash) { - return true - } - - case btcwire.InvVect_Tx: - // TODO(davec): Need to ultimately maintain a transaction pool - // of transactions that are not already in a block and check - // for the existing transaction there too. - - // Check if the transaction exists from the point of view of the - // end of the main chain. - return b.db.ExistsTxSha(&inventoryVector.Hash) - } - - // The requested inventory is either not known or is an unsupported - // type (which also implies it is not known). - return false +// This function is NOT safe for concurrent access. +func (b *BlockChain) HaveBlock(hash *btcwire.ShaHash) bool { + return b.IsKnownOrphan(hash) && b.blockExists(hash) } // IsKnownOrphan returns whether the passed hash is currently a known orphan. From cdc3002c85bf010d65c5d29d6782a0632b1e3a18 Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Wed, 9 Oct 2013 16:35:33 +0100 Subject: [PATCH 071/190] Fix previous. We care if we have the block OR it is an orphan, not both. --- chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain.go b/chain.go index 4e396ce7..ff487ed4 100644 --- a/chain.go +++ b/chain.go @@ -173,7 +173,7 @@ func (b *BlockChain) DisableVerify(disable bool) { // // This function is NOT safe for concurrent access. func (b *BlockChain) HaveBlock(hash *btcwire.ShaHash) bool { - return b.IsKnownOrphan(hash) && b.blockExists(hash) + return b.IsKnownOrphan(hash) || b.blockExists(hash) } // IsKnownOrphan returns whether the passed hash is currently a known orphan. From 6d078d8115ba699b0fdfc47150334e06f99bec9f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 9 Oct 2013 18:29:53 -0500 Subject: [PATCH 072/190] Implement chain setup infrastructure in the tests. This commit implents a basic infrastructure to be used throughout the tests for creating a new chain instance that is ready to have tests run against it. It also returns a teardown function the caller can use to clean up after it is done testing. This paves the way for adding more tests. --- common_test.go | 74 ++++++++++++++++++++++++++++++++++++++++++ reorganization_test.go | 28 +++++----------- validate_test.go | 18 +++------- 3 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 common_test.go diff --git a/common_test.go b/common_test.go new file mode 100644 index 00000000..340718a7 --- /dev/null +++ b/common_test.go @@ -0,0 +1,74 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "fmt" + "github.com/conformal/btcchain" + "github.com/conformal/btcdb" + _ "github.com/conformal/btcdb/ldb" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "os" + "path/filepath" +) + +// testDbRoot is the root directory used to create all test databases. +const testDbRoot = "testdbs" + +// filesExists returns whether or not the named file or directory exists. +func fileExists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + +// chainSetup is used to create a new db and chain instance with the genesis +// block already inserted. In addition to the new chain instnce, it returns +// a teardown function the caller should invoke when done testing to clean up. +func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { + // Create the root directory for test databases. + if !fileExists(testDbRoot) { + if err := os.MkdirAll(testDbRoot, 0700); err != nil { + err := fmt.Errorf("unable to create test db root: %v", err) + return nil, nil, err + } + } + + // Create a new database to store the accepted blocks into. + dbPath := filepath.Join(testDbRoot, dbName) + _ = os.RemoveAll(dbPath) + db, err := btcdb.CreateDB("leveldb", dbPath) + if err != nil { + return nil, nil, fmt.Errorf("error creating db: %v", err) + } + + // Setup a teardown function for cleaning up. This function is returned + // to the caller to be invoked when it is done testing. + teardown := func() { + dbVersionPath := filepath.Join(testDbRoot, dbName+".ver") + db.Sync() + db.Close() + os.RemoveAll(dbPath) + os.Remove(dbVersionPath) + os.RemoveAll(testDbRoot) + } + + // Insert the main network genesis block. This is part of the initial + // database setup. + genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) + _, err = db.InsertBlock(genesisBlock) + if err != nil { + teardown() + err := fmt.Errorf("failed to insert genesis block: %v", err) + return nil, nil, err + } + + chain := btcchain.New(db, btcwire.MainNet, nil) + return chain, teardown, nil +} diff --git a/reorganization_test.go b/reorganization_test.go index 69f22b0f..dbb902bb 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -8,8 +8,6 @@ import ( "compress/bzip2" "encoding/binary" "github.com/conformal/btcchain" - "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/sqlite3" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "io" @@ -26,7 +24,7 @@ import ( func TestReorganization(t *testing.T) { // Intentionally load the side chain blocks out of order to ensure // orphans are handled properly along with chain reorganization. - testFiles := [...]string{ + testFiles := []string{ "blk_0_to_4.dat.bz2", "blk_4A.dat.bz2", "blk_5A.dat.bz2", @@ -46,36 +44,26 @@ func TestReorganization(t *testing.T) { t.Logf("Number of blocks: %v\n", len(blocks)) - dbname := "chaintest" - _ = os.Remove(dbname) - db, err := btcdb.CreateDB("sqlite", dbname) + // Create a new database and chain instance to run tests against. + chain, teardownFunc, err := chainSetup("reorg") if err != nil { - t.Errorf("Error creating db: %v\n", err) - } - // Clean up - defer os.Remove(dbname) - defer db.Close() - - // Insert the main network genesis block. - genesis := btcutil.NewBlock(&btcwire.GenesisBlock) - if _, err := db.InsertBlock(genesis); err != nil { - t.Errorf("Failed to insert genesis block: %v", err) + t.Errorf("Failed to setup chain instance: %v", err) + return } + defer teardownFunc() // Since we're not dealing with the real block chain, disable // checkpoints and set the coinbase maturity to 1. - blockChain := btcchain.New(db, btcwire.MainNet, nil) - blockChain.DisableCheckpoints(true) + chain.DisableCheckpoints(true) btcchain.TstSetCoinbaseMaturity(1) for i := 1; i < len(blocks); i++ { - err = blockChain.ProcessBlock(blocks[i]) + err = chain.ProcessBlock(blocks[i]) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return } } - db.Sync() return } diff --git a/validate_test.go b/validate_test.go index 1b2998cd..5cde8f1a 100644 --- a/validate_test.go +++ b/validate_test.go @@ -6,30 +6,22 @@ package btcchain_test import ( "github.com/conformal/btcchain" - "github.com/conformal/btcdb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" - "os" "reflect" "testing" "time" ) func TestCheckBlockSanity(t *testing.T) { - // Create a new test database. - dbName := "cbsanitytest.db" - _ = os.Remove(dbName) - db, err := btcdb.CreateDB("sqlite", dbName) + // Create a new database and chain instance to run tests against. + chain, teardownFunc, err := chainSetup("cbsanity") if err != nil { - t.Errorf("Error creating db: %v\n", err) + t.Errorf("Failed to setup chain instance: %v", err) + return } - defer os.Remove(dbName) - defer db.Close() - - // Create a new BlockChain instance using the underlying database for - // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, btcwire.MainNet, nil) + defer teardownFunc() block := btcutil.NewBlock(&Block100000) err = chain.TstCheckBlockSanity(block) From 32790d52d893b378f212fd1b36107d9f67f3f262 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 9 Oct 2013 18:43:22 -0500 Subject: [PATCH 073/190] Add tests for HaveBlock. This commit adds tests to ensure HaveBlock works properly with blocks on the main chain, a side chain, orphans, and missing blocks. --- chain_test.go | 95 +++++++++++++++++++++++++++++++++++++++++++++++ test_coverage.txt | 42 ++++++++++----------- 2 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 chain_test.go diff --git a/chain_test.go b/chain_test.go new file mode 100644 index 00000000..509a276f --- /dev/null +++ b/chain_test.go @@ -0,0 +1,95 @@ +// Copyright (c) 2013 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "github.com/conformal/btcchain" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" + "testing" +) + +// TestHaveBlock tests the HaveBlock API to ensure proper functionality. +func TestHaveBlock(t *testing.T) { + // Load up blocks such that there is a side chain. + // (genesis block) -> 1 -> 2 -> 3 -> 4 + // \-> 3a + // orphans are handled properly along with chain reorganization. + testFiles := []string{ + "blk_0_to_4.dat.bz2", + "blk_3A.dat.bz2", + } + + var blocks []*btcutil.Block + for _, file := range testFiles { + blockTmp, err := loadBlocks(file) + if err != nil { + t.Errorf("Error loading file: %v\n", err) + return + } + for _, block := range blockTmp { + blocks = append(blocks, block) + } + } + + // Create a new database and chain instance to run tests against. + chain, teardownFunc, err := chainSetup("haveblock") + if err != nil { + t.Errorf("Failed to setup chain instance: %v", err) + return + } + defer teardownFunc() + + // Since we're not dealing with the real block chain, disable + // checkpoints and set the coinbase maturity to 1. + chain.DisableCheckpoints(true) + btcchain.TstSetCoinbaseMaturity(1) + + for i := 1; i < len(blocks); i++ { + err = chain.ProcessBlock(blocks[i]) + if err != nil { + t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) + return + } + } + + // Insert an orphan block. + if err := chain.ProcessBlock(btcutil.NewBlock(&Block100000)); err != nil { + t.Errorf("Unable to process block: %v", err) + return + } + + tests := []struct { + hash string + want bool + }{ + // Genesis block should be present (in the main chain). + {hash: btcwire.GenesisHash.String(), want: true}, + + // Block 3a should be present (on a side chain). + {hash: "00000000474284d20067a4d33f6a02284e6ef70764a3a26d6a5b9df52ef663dd", want: true}, + + // Block 100000 should be present (as an orphan). + {hash: "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506", want: true}, + + // Random hashes should not be availble. + {hash: "123", want: false}, + } + + for i, test := range tests { + hash, err := btcwire.NewShaHashFromStr(test.hash) + if err != nil { + t.Errorf("NewShaHashFromStr: %v", err) + continue + } + + result := chain.HaveBlock(hash) + if result != test.want { + t.Errorf("HaveBlock #%d got %v want %v", i, result, + test.want) + continue + } + } +} diff --git a/test_coverage.txt b/test_coverage.txt index 12a4ee8a..99bb8a74 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -3,38 +3,40 @@ github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/ github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) github.com/conformal/btcchain/validate.go countSigOps 100.00% (8/8) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) -github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) +github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) -github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) github.com/conformal/btcchain/chain.go New 100.00% (2/2) -github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) -github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) github.com/conformal/btcchain/txlookup.go disconnectTransactions 93.75% (15/16) github.com/conformal/btcchain/txlookup.go fetchTxListMain 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) github.com/conformal/btcchain/process.go BlockChain.processOrphans 92.86% (13/14) github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 90.00% (27/30) -github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 88.89% (8/9) github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 88.24% (30/34) -github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 88.24% (15/17) github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxList 86.36% (19/22) github.com/conformal/btcchain/scriptval.go checkBlockScripts 85.71% (6/7) github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) github.com/conformal/btcchain/validate.go IsCoinBase 83.33% (5/6) +github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) github.com/conformal/btcchain/difficulty.go calcWork 80.00% (4/5) github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) +github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 76.92% (20/26) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) @@ -50,41 +52,39 @@ github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) github.com/conformal/btcchain/validate.go BlockChain.checkProofOfWork 58.82% (10/17) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/14) -github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 55.81% (24/43) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 53.52% (38/71) +github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 53.49% (23/43) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 49.30% (35/71) github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 33.33% (2/6) github.com/conformal/btcchain/validate.go IsFinalizedTransaction 23.08% (3/13) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 19.51% (8/41) github.com/conformal/btcchain/checkpoints.go BlockChain.findLatestKnownCheckpoint 18.18% (2/11) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.07% (7/41) github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/24) github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/17) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/15) -github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) +github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) -github.com/conformal/btcchain/chain.go BlockChain.HaveInventory 0.00% (0/7) github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 0.00% (0/5) github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 55.20% (642/1163) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 55.40% (641/1157) From e888372019cf164be1d7ec2871806d02deeba503 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 10 Oct 2013 12:23:46 -0500 Subject: [PATCH 074/190] Optimize transaction lookups. This commit modifies the transaction lookup code to use a set instead of a slice (list). This allows the lookup to automatically prevent duplicate requests to the database. Previously, the code simply added every referenced transaction to a list without checking for duplicates, which led to multiple requests against the database for the same transaction. It also meant the request list could grow quite large with all of the duplicates using far more memory than required. While the end result was accurate, operating that way is not as efficient as only requesting unique transactions. --- chain_test.go | 1 - test_coverage.txt | 12 ++++----- txlookup.go | 68 +++++++++++++++++------------------------------ validate.go | 6 ++++- 4 files changed, 35 insertions(+), 52 deletions(-) diff --git a/chain_test.go b/chain_test.go index 509a276f..8f1d1050 100644 --- a/chain_test.go +++ b/chain_test.go @@ -16,7 +16,6 @@ func TestHaveBlock(t *testing.T) { // Load up blocks such that there is a side chain. // (genesis block) -> 1 -> 2 -> 3 -> 4 // \-> 3a - // orphans are handled properly along with chain reorganization. testFiles := []string{ "blk_0_to_4.dat.bz2", "blk_3A.dat.bz2", diff --git a/test_coverage.txt b/test_coverage.txt index 99bb8a74..0841e446 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -20,14 +20,14 @@ github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) github.com/conformal/btcchain/log.go init 100.00% (1/1) +github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 94.44% (17/18) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) github.com/conformal/btcchain/txlookup.go disconnectTransactions 93.75% (15/16) -github.com/conformal/btcchain/txlookup.go fetchTxListMain 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) github.com/conformal/btcchain/process.go BlockChain.processOrphans 92.86% (13/14) github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 90.00% (27/30) github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 88.24% (30/34) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxList 86.36% (19/22) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.36% (19/22) github.com/conformal/btcchain/scriptval.go checkBlockScripts 85.71% (6/7) github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) @@ -37,13 +37,14 @@ github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% ( github.com/conformal/btcchain/difficulty.go calcWork 80.00% (4/5) github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 76.92% (20/26) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 76.00% (19/25) github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 69.23% (36/52) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) github.com/conformal/btcchain/validate.go BlockChain.checkBlockSanity 65.12% (28/43) +github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 64.71% (11/17) github.com/conformal/btcchain/scriptval.go validateTxIn 64.71% (11/17) github.com/conformal/btcchain/validate.go CheckTransactionInputs 64.44% (29/45) github.com/conformal/btcchain/validate.go CheckTransactionSanity 62.16% (23/37) @@ -51,7 +52,6 @@ github.com/conformal/btcchain/txlookup.go connectTransactions 60.00% (9/15) github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) github.com/conformal/btcchain/validate.go BlockChain.checkProofOfWork 58.82% (10/17) -github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 57.14% (8/14) github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 53.49% (23/43) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) @@ -68,10 +68,10 @@ github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/24) github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/17) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) -github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/15) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) +github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/9) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) @@ -86,5 +86,5 @@ github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 55.40% (641/1157) +github.com/conformal/btcchain ------------------------------------- 55.88% (646/1156) diff --git a/txlookup.go b/txlookup.go index 21abfb24..5b1ee446 100644 --- a/txlookup.go +++ b/txlookup.go @@ -99,15 +99,18 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { return nil } -// fetchTxListMain fetches transaction data about the provided list of +// fetchTxStoreMain fetches transaction data about the provided set of // transactions from the point of view of the end of the main chain. -func fetchTxListMain(db btcdb.Db, txList []*btcwire.ShaHash) TxStore { +func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool) TxStore { // The transaction store map needs to have an entry for every requested // transaction. By default, all the transactions are marked as missing. // Each entry will be filled in with the appropriate data below. + txList := make([]*btcwire.ShaHash, 0, len(txSet)) txStore := make(TxStore) - for _, hash := range txList { - txStore[*hash] = &TxData{Hash: hash, Err: btcdb.TxShaMissing} + for hash := range txSet { + hashCopy := hash + txStore[hash] = &TxData{Hash: &hashCopy, Err: btcdb.TxShaMissing} + txList = append(txList, &hashCopy) } // Ask the database (main chain) for the list of transactions. This @@ -141,14 +144,14 @@ func fetchTxListMain(db btcdb.Db, txList []*btcwire.ShaHash) TxStore { return txStore } -// fetchTxList fetches transaction data about the provided list of transactions +// fetchTxStore fetches transaction data about the provided set of transactions // from the point of view of the given node. For example, a given node might // be down a side chain where a transaction hasn't been spent from its point of // view even though it might have been spent in the main chain (or another side // chain). Another scenario is where a transaction exists from the point of // view of the main chain, but doesn't exist in a side chain that branches // before the block that contains the transaction on the main chain. -func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (TxStore, error) { +func (b *BlockChain) fetchTxStore(node *blockNode, txSet map[btcwire.ShaHash]bool) (TxStore, error) { // Get the previous block node. This function is used over simply // accessing node.parent directly as it will dynamically create previous // block nodes as needed. This helps allow only the pieces of the chain @@ -158,9 +161,9 @@ func (b *BlockChain) fetchTxList(node *blockNode, txList []*btcwire.ShaHash) (Tx return nil, err } - // Fetch the requested list from the point of view of the end of the + // Fetch the requested set from the point of view of the end of the // main (best) chain. - txStore := fetchTxListMain(b.db, txList) + txStore := fetchTxStoreMain(b.db, txSet) // If we haven't selected a best chain yet or we are extending the main // (best) chain with a new block, everything is accurate, so return the @@ -230,20 +233,10 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txInFlight[*txHash] = i } - // Make a reasonable guess for the maximum number of needed input - // transactions to use as the starting point for the needed transactions - // array. The array will dynamically grow as needed, but it's much less - // overhead to avoid growing and copying the array multiple times in the - // common case. Each block usually has no more than ten inputs per - // transaction, so use that as a reasonable starting point. A block - // with 2,000 transactions would only result in around 156KB on a 64-bit - // system using this approach. - maxNeededHint := (len(transactions) - 1) * 10 - txNeededList := make([]*btcwire.ShaHash, 0, maxNeededHint) - // Loop through all of the transaction inputs (except for the coinbase - // which has no inputs) collecting them into lists of what is needed and + // which has no inputs) collecting them into sets of what is needed and // what is already known (in-flight). + txNeededSet := make(map[btcwire.ShaHash]bool) txStore := make(TxStore) for i, tx := range transactions[1:] { for _, txIn := range tx.TxIn { @@ -272,13 +265,13 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txD.Spent = make([]bool, len(originTx.TxOut)) txD.Err = nil } else { - txNeededList = append(txNeededList, originHash) + txNeededSet[*originHash] = true } } } // Request the input transactions from the point of view of the node. - txNeededStore, err := b.fetchTxList(node, txNeededList) + txNeededStore, err := b.fetchTxStore(node, txNeededSet) if err != nil { return nil, err } @@ -302,30 +295,17 @@ func (b *BlockChain) FetchTransactionStore(tx *btcwire.MsgTx) (TxStore, error) { return nil, err } - // Create list big - txNeededList := make([]*btcwire.ShaHash, 0, len(tx.TxIn)+1) - txNeededList = append(txNeededList, &txHash) - - // Loop through all of the transaction inputs collecting them into lists of what is needed and - // what is already known (in-flight). - txStore := make(TxStore) + // Create a set of needed transactions from the transactions referenced + // by the inputs of the passed transaction. Also, add the passed + // transaction itself as a way for the caller to detect duplicates. + txNeededSet := make(map[btcwire.ShaHash]bool) + txNeededSet[txHash] = true for _, txIn := range tx.TxIn { - // Add an entry to the transaction store for the needed - // transaction with it set to missing by default. - originHash := &txIn.PreviousOutpoint.Hash - txD := &TxData{Hash: originHash, Err: btcdb.TxShaMissing} - txStore[*originHash] = txD - txNeededList = append(txNeededList, originHash) - } - - // Request the input transactions from the point of view of the node. - txNeededStore := fetchTxListMain(b.db, txNeededList) - - // Merge the results of the requested transactions and the in-flight - // transactions. - for _, txD := range txNeededStore { - txStore[*txD.Hash] = txD + txNeededSet[txIn.PreviousOutpoint.Hash] = true } + // Request the input transactions from the point of view of the end of + // the main chain. + txStore := fetchTxStoreMain(b.db, txNeededSet) return txStore, nil } diff --git a/validate.go b/validate.go index b22a54fc..9ab3d0c5 100644 --- a/validate.go +++ b/validate.go @@ -555,7 +555,11 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { if err != nil { return nil } - txResults, err := b.fetchTxList(node, fetchList) + fetchSet := make(map[btcwire.ShaHash]bool) + for _, txHash := range fetchList { + fetchSet[*txHash] = true + } + txResults, err := b.fetchTxStore(node, fetchSet) if err != nil { return err } From 39e7e5c4a1ca2a8c8ee45dcbe568eb553dfe6bc9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 11 Oct 2013 10:22:23 -0500 Subject: [PATCH 075/190] Add minor optimization to transaction store fetch. This commit adds a quick check to the transaction store fetch code which simply returns an empty store if no hashes were requested rather than bothering the db with an empty list. --- txlookup.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/txlookup.go b/txlookup.go index 5b1ee446..8cf8dbb1 100644 --- a/txlookup.go +++ b/txlookup.go @@ -102,11 +102,16 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // fetchTxStoreMain fetches transaction data about the provided set of // transactions from the point of view of the end of the main chain. func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool) TxStore { + // Just return an empty store now if there are no requested hashes. + txStore := make(TxStore) + if len(txSet) == 0 { + return txStore + } + // The transaction store map needs to have an entry for every requested // transaction. By default, all the transactions are marked as missing. // Each entry will be filled in with the appropriate data below. txList := make([]*btcwire.ShaHash, 0, len(txSet)) - txStore := make(TxStore) for hash := range txSet { hashCopy := hash txStore[hash] = &TxData{Hash: &hashCopy, Err: btcdb.TxShaMissing} From 8be23c89aea8a7a55a952298b28604914c610348 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 11 Oct 2013 10:24:13 -0500 Subject: [PATCH 076/190] Cleanup a few comments. --- accept.go | 3 ++- blocklocator.go | 4 ++-- chain.go | 6 +++--- validate.go | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/accept.go b/accept.go index 444eddb4..5e66436f 100644 --- a/accept.go +++ b/accept.go @@ -23,7 +23,8 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { return err } - // The height of this block one more than the referenced previous block. + // The height of this block is one more than the referenced previous + // block. blockHeight := int64(0) if prevNode != nil { blockHeight = prevNode.height + 1 diff --git a/blocklocator.go b/blocklocator.go index a3258f25..fb2d408b 100644 --- a/blocklocator.go +++ b/blocklocator.go @@ -38,8 +38,8 @@ func (b *BlockChain) BlockLocatorFromHash(hash *btcwire.ShaHash) BlockLocator { } // Attempt to find the height of the block that corresponds to the - // passed hash, and if it's on a side chain, find the height at which - // it forks from the main chain. + // passed hash, and if it's on a side chain, also find the height at + // which it forks from the main chain. blockHeight := int64(-1) forkHeight := int64(-1) node, exists := b.index[*hash] diff --git a/chain.go b/chain.go index ff487ed4..0be5bc96 100644 --- a/chain.go +++ b/chain.go @@ -758,8 +758,8 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block) erro // This node's parent is now the end of the best chain. b.bestChain = node.parent - // Notify the caller that the block was disconnect from the main chain. - // The caller would typically want to react with actions such as + // Notify the caller that the block was disconnected from the main + // chain. The caller would typically want to react with actions such as // updating wallets. b.sendNotification(NTBlockDisconnected, block) @@ -789,7 +789,7 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // // NOTE: bitcoind does these checks directly when it connects a block. // The downside to that approach is that if any of these checks fail - // after disconneting some blocks or attaching others, all of the + // after disconnecting some blocks or attaching others, all of the // operations have to be rolled back to get the chain back into the // state it was before the rule violation (or other failure). There are // at least a couple of ways accomplish that rollback, but both involve diff --git a/validate.go b/validate.go index 9ab3d0c5..352ce33c 100644 --- a/validate.go +++ b/validate.go @@ -790,7 +790,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er } // Check for overflow or going over the limits. We have to do - // this on every loop to avoid overflow. + // this on every loop iteration to avoid overflow. lastSigops := totalSigOps totalSigOps += numsigOps if totalSigOps < lastSigops || totalSigOps > maxSigOpsPerBlock { From b680d3539f075e3d9797236b4e6c2d1972a3e8e8 Mon Sep 17 00:00:00 2001 From: Dale Rahn Date: Fri, 11 Oct 2013 18:14:58 -0400 Subject: [PATCH 077/190] Revive old validate Tx in parallel code, faster... requested by davec, cleanup/polish in-tree. --- scriptval.go | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/scriptval.go b/scriptval.go index b1d13036..72a67cf7 100644 --- a/scriptval.go +++ b/scriptval.go @@ -124,11 +124,41 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, time // the passed block. func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { timestamp := block.MsgBlock().Header.Timestamp - for i, tx := range block.MsgBlock().Transactions { - txHash, _ := block.TxSha(i) + + txList := block.MsgBlock().Transactions + c := make(chan txValidate) + resultErrors := make([]error, len(txList)) + + var currentItem int + var completedItems int + processFunc := func(txIdx int) { + tx := txList[txIdx] + txHash, _ := block.TxSha(txIdx) + err := ValidateTransactionScripts(tx, txHash, timestamp, txStore) - if err != nil { - return err + r := txValidate{txIdx, err} + c <- r + } + for currentItem = 0; currentItem < len(txList) && currentItem < 8; currentItem++ { + go processFunc(currentItem) + } + for completedItems < len(txList) { + select { + case result := <-c: + completedItems++ + resultErrors[result.txIndex] = result.err + // would be nice to determine if we could stop + // on early errors here instead of running more. + + if currentItem < len(txList) { + go processFunc(currentItem) + currentItem++ + } + } + } + for i := 0; i < len(txList); i++ { + if resultErrors[i] != nil { + return resultErrors[i] } } From e5ba199eed1818aa82da07067cf17396f0381789 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 13 Oct 2013 02:06:18 -0500 Subject: [PATCH 078/190] Add example to BlockLocator comments. --- blocklocator.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/blocklocator.go b/blocklocator.go index fb2d408b..0e783b4e 100644 --- a/blocklocator.go +++ b/blocklocator.go @@ -15,6 +15,14 @@ import ( // hashes are added, then the step is doubled each loop iteration to // exponentially decrease the number of hashes as a function of the distance // from the block being located. +// +// For example, assume you have a block chain with a side chain as depicted +// below: +// genesis -> 1 -> 2 -> ... -> 15 -> 16 -> 17 -> 18 +// \-> 16a -> 17a +// +// The block locator for block 17a would be the hashes of blocks: +// [17a 16a 15 14 13 12 11 10 9 8 6 2 genesis] type BlockLocator []*btcwire.ShaHash // BlockLocatorFromHash returns a block locator for the passed block hash. From 9a29855c16a620f5e318cb697f4e0d643a8ee1a3 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 13 Oct 2013 02:36:23 -0500 Subject: [PATCH 079/190] Convert inability to find input tx to a RuleError. This commit modifies the errors that result from missing expected input transactions to a RuleError. This allows the caller to detect a block was rejected due to a rule violation as opposed to an unexpected error. --- validate.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/validate.go b/validate.go index 352ce33c..2b51fbd0 100644 --- a/validate.go +++ b/validate.go @@ -347,18 +347,20 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) ( txInHash := &txIn.PreviousOutpoint.Hash originTx, exists := txStore[*txInHash] if !exists || originTx.Err != nil || originTx.Tx == nil { - return 0, fmt.Errorf("unable to find input transaction "+ + str := fmt.Sprintf("unable to find input transaction "+ "%v referenced from transaction %v", txInHash, txHash) + return 0, RuleError(str) } // Ensure the output index in the referenced transaction is // available. originTxIndex := txIn.PreviousOutpoint.Index if originTxIndex >= uint32(len(originTx.Tx.TxOut)) { - return 0, fmt.Errorf("out of bounds input index %d in "+ + str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", originTxIndex, txInHash, txHash) + return 0, RuleError(str) } // We're only interested in pay-to-script-hash types, so skip @@ -379,10 +381,11 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) ( lastSigOps := totalSigOps totalSigOps += numSigOps if totalSigOps < lastSigOps { - return 0, fmt.Errorf("the public key script from "+ + str := fmt.Sprintf("the public key script from "+ "output index %d in transaction %v contains "+ "too many signature operations - overflow", originTxIndex, txInHash) + return 0, RuleError(str) } } From d7e057a0200391e660ea226295f8c00b7773a508 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 13 Oct 2013 02:27:50 -0500 Subject: [PATCH 080/190] Make use of new spent vs unspent btcdb APIs. This commit modifies the code to make use of the new btcd APIs that allow fetching of transaction lists which either do or do not include fully spent transactions. It is more efficient to avoid fetching fully spent transactions from the database when they aren't needed. --- txlookup.go | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/txlookup.go b/txlookup.go index 8cf8dbb1..193f5331 100644 --- a/txlookup.go +++ b/txlookup.go @@ -100,8 +100,10 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { } // fetchTxStoreMain fetches transaction data about the provided set of -// transactions from the point of view of the end of the main chain. -func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool) TxStore { +// transactions from the point of view of the end of the main chain. It takes +// a flag which specifies whether or not fully spent transaction should be +// included in the results. +func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool, includeSpent bool) TxStore { // Just return an empty store now if there are no requested hashes. txStore := make(TxStore) if len(txSet) == 0 { @@ -120,8 +122,13 @@ func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool) TxStore { // Ask the database (main chain) for the list of transactions. This // will return the information from the point of view of the end of the - // main chain. - txReplyList := db.FetchUnSpentTxByShaList(txList) + // main chain. Choose whether or not to include fully spent + // transactions depending on the passed flag. + fetchFunc := db.FetchUnSpentTxByShaList + if includeSpent { + fetchFunc = db.FetchTxByShaList + } + txReplyList := fetchFunc(txList) for _, txReply := range txReplyList { // Lookup the existing results entry to modify. Skip // this reply if there is no corresponding entry in @@ -166,17 +173,22 @@ func (b *BlockChain) fetchTxStore(node *blockNode, txSet map[btcwire.ShaHash]boo return nil, err } - // Fetch the requested set from the point of view of the end of the - // main (best) chain. - txStore := fetchTxStoreMain(b.db, txSet) - // If we haven't selected a best chain yet or we are extending the main - // (best) chain with a new block, everything is accurate, so return the - // results now. + // (best) chain with a new block, fetch the requested set from the point + // of view of the end of the main (best) chain without including fully + // spent transactions in the results. This is a little more efficient + // since it means less transaction lookups are needed. if b.bestChain == nil || (prevNode != nil && prevNode.hash.IsEqual(b.bestChain.hash)) { + txStore := fetchTxStoreMain(b.db, txSet, false) return txStore, nil } + // Fetch the requested set from the point of view of the end of the + // main (best) chain including fully spent transactions. The fully + // spent transactions are needed because the following code unspends + // them to get the correct point of view. + txStore := fetchTxStoreMain(b.db, txSet, true) + // The requested node is either on a side chain or is a node on the main // chain before the end of it. In either case, we need to undo the // transactions and spend information for the blocks which would be @@ -310,7 +322,9 @@ func (b *BlockChain) FetchTransactionStore(tx *btcwire.MsgTx) (TxStore, error) { } // Request the input transactions from the point of view of the end of - // the main chain. - txStore := fetchTxStoreMain(b.db, txNeededSet) + // the main chain without including fully spent trasactions in the + // results. Fully spent transactions are only needed for chain + // reorganization which does not apply here. + txStore := fetchTxStoreMain(b.db, txNeededSet, false) return txStore, nil } From c88338d22725d7cf5fcdef75f2e41e8288887739 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 13 Oct 2013 16:07:06 -0500 Subject: [PATCH 081/190] Slightly optimize GenerateInitialIndex. Rather than fetching the hash of each block individually 2k+ times, make use of the FetchHeightRange function so all of the most recent hashes can be fetched at once. --- chain.go | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/chain.go b/chain.go index 0be5bc96..3f078459 100644 --- a/chain.go +++ b/chain.go @@ -347,19 +347,42 @@ func (b *BlockChain) GenerateInitialIndex() error { // Loop forwards through each block loading the node into the index for // the block. - for i := startHeight; i <= endHeight; i++ { - hash, err := b.db.FetchBlockShaByHeight(i) + // + // Due to a bug in the SQLite btcdb driver, the FetchBlockBySha call is + // limited to a maximum number of hashes per invocation. Since SQLite + // is going to be nuked eventually, the bug isn't being fixed in the + // driver. In the mean time, work around the issue by calling + // FetchBlockBySha multiple times with the appropriate indices as needed. + for start := startHeight; start < endHeight; { + hashList, err := b.db.FetchHeightRange(start, endHeight+1) if err != nil { return err } - node, err := b.loadBlockNode(hash) - if err != nil { - return err + // The database did not return any further hashes. Break out of + // the loop now. + if len(hashList) == 0 { + break } - // This node is now the end of the best chain. - b.bestChain = node + // Loop forwards through each block loading the node into the + // index for the block. + for _, hash := range hashList { + // Make a copy of the hash to make sure there are no references + // into the list so it can be freed. + hashCopy := hash + node, err := b.loadBlockNode(&hashCopy) + if err != nil { + return err + } + + // This node is now the end of the best chain. + b.bestChain = node + } + + // Start at the next block after the latest one on the next loop + // iteration. + start += int64(len(hashList)) } return nil From b7b9823f6cb9e790157ccdb2938f823b400c8a30 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 15 Oct 2013 09:46:16 -0500 Subject: [PATCH 082/190] Fix potential issue with dependent orphans. This commit modifies the main processing loop for orphan dependencies (orphans that are processed due to their parents showing up) to use an index based for loop over range. Since the Go range statement does not reevaluate on every iteration, it was previously possible under certain circumstances for the slice to be changed out from under the range statement while processing the orphan blocks. --- process.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/process.go b/process.go index c3ca793d..72ecd445 100644 --- a/process.go +++ b/process.go @@ -53,13 +53,25 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { // accepted. This will typically only be one, but it could // be multiple if multiple blocks are mined and broadcast // around the same time. The one with the most proof of work - // will eventually win out. - for _, orphan := range b.prevOrphans[*processHash] { + // will eventually win out. An indexing for loop is + // intentionally used over a range here as range does not + // reevaluate the slice on each iteration nor does it adjust the + // index for the modified slice. + for i := 0; i < len(b.prevOrphans[*processHash]); i++ { + orphan := b.prevOrphans[*processHash][i] + if orphan == nil { + log.Warnf("Found a nil entry at index %d in the "+ + "orphan dependency list for block %v", i, + processHash) + continue + } + // Remove the orphan from the orphan pool. // It's safe to ignore the error on Sha since the hash // is already cached. orphanHash, _ := orphan.block.Sha() b.removeOrphanBlock(orphan) + i-- // Potentially accept the block into the block chain. err := b.maybeAcceptBlock(orphan.block) From 89d86d07ac89d60b84b28482c1181ac871ee7b6a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 25 Oct 2013 10:33:37 -0500 Subject: [PATCH 083/190] ValidateTransactionScripts now accepts script flags. This commit modifies the ValidateTransactionScripts API to accept the recently added ScriptFlags from btcscript. This provides flexibility to the caller to choose validation behavior based on those new flags. --- scriptval.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/scriptval.go b/scriptval.go index 72a67cf7..8426e14f 100644 --- a/scriptval.go +++ b/scriptval.go @@ -10,7 +10,6 @@ import ( "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" - "time" ) // txValidate is used to track results of validating scripts for each @@ -29,7 +28,7 @@ type txProcessList struct { // validateTxIn validates a the script pair for the passed spending transaction // (along with the specific input index) and origin transaction (with the // specific output index). -func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, timestamp time.Time, originTx *btcwire.MsgTx) error { +func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, originTx *btcwire.MsgTx, flags btcscript.ScriptFlags) error { // If the input transaction has no previous input, there is nothing // to check. originTxIdx := txin.PreviousOutpoint.Index @@ -39,14 +38,15 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b if originTxIdx >= uint32(len(originTx.TxOut)) { originTxSha := &txin.PreviousOutpoint.Hash - log.Warnf("unable to locate source tx %v spending tx %v", originTxSha, &txSha) + log.Warnf("unable to locate source tx %v spending tx %v", + originTxSha, &txSha) return fmt.Errorf("invalid index %x", originTxIdx) } sigScript := txin.SignatureScript pkScript := originTx.TxOut[originTxIdx].PkScript engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, tx, - timestamp.After(btcscript.Bip16Activation)) + flags) if err != nil { return err } @@ -62,7 +62,7 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b // ValidateTransactionScripts validates the scripts for the passed transaction // using multiple goroutines. -func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, timestamp time.Time, txStore TxStore) (err error) { +func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txStore TxStore, flags btcscript.ScriptFlags) (err error) { c := make(chan txValidate) job := tx.TxIn resultErrors := make([]error, len(job)) @@ -87,8 +87,8 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, time } originTx = txInfo.Tx } - err := validateTxIn(txInIdx, job[txInIdx], txHash, tx, timestamp, - originTx) + err := validateTxIn(txInIdx, job[txInIdx], txHash, tx, originTx, + flags) r := txValidate{txInIdx, err} c <- r } @@ -123,7 +123,12 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, time // checkBlockScripts executes and validates the scripts for all transactions in // the passed block. func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { - timestamp := block.MsgBlock().Header.Timestamp + // Setup the script validation flags. Blocks created after the BIP0016 + // activation time need to have the pay-to-script-hash checks enabled. + var flags btcscript.ScriptFlags + if block.MsgBlock().Header.Timestamp.After(btcscript.Bip16Activation) { + flags |= btcscript.ScriptBip16 + } txList := block.MsgBlock().Transactions c := make(chan txValidate) @@ -135,7 +140,7 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { tx := txList[txIdx] txHash, _ := block.TxSha(txIdx) - err := ValidateTransactionScripts(tx, txHash, timestamp, txStore) + err := ValidateTransactionScripts(tx, txHash, txStore, flags) r := txValidate{txIdx, err} c <- r } From b6e4ae44419ab5efa232eb32bfcb2d45023918be Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 26 Oct 2013 14:31:15 -0500 Subject: [PATCH 084/190] Optimize duplicate transaction input check. Profiling showed the duplicate transaction input check was taking around 6% of the total CheckTransactionSanity processing time. This was largely due to using fmt.Sprintf to generate the map key. This commit modifies the check instead to use the actual output as a map key. The following benchmark results show the difference: Before: BenchmarkOldDuplicatInputCheck 100000 21787 ns/op After: BenchmarkNewDuplicatInputCheck 2000000 937 ns/op Closes #2 --- validate.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/validate.go b/validate.go index 2b51fbd0..00ed8ff2 100644 --- a/validate.go +++ b/validate.go @@ -230,14 +230,12 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { } // Check for duplicate transaction inputs. - existingTxOut := make(map[string]bool) + existingTxOut := make(map[btcwire.OutPoint]bool) for _, txIn := range tx.TxIn { - prevOut := &txIn.PreviousOutpoint - key := fmt.Sprintf("%v%v", prevOut.Hash, prevOut.Index) - if _, exists := existingTxOut[key]; exists { + if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists { return RuleError("transaction contains duplicate outpoint") } - existingTxOut[key] = true + existingTxOut[txIn.PreviousOutpoint] = true } // Coinbase script length must be between min and max length. From 6165e9b95bf1fb7914dc9220c85b223117c9b5e3 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 28 Oct 2013 15:17:53 -0500 Subject: [PATCH 085/190] Convert API to use new btcutil.Tx. This is part of the ongoing transaction hash optimization effort noted in conformal/btcd#25. --- accept.go | 12 ++------ checkpoints.go | 6 ++-- internal_test.go | 3 +- merkle.go | 12 ++------ scriptval.go | 39 +++++++++-------------- txlookup.go | 55 +++++++++++---------------------- validate.go | 80 ++++++++++++++++++++++-------------------------- validate_test.go | 5 +-- 8 files changed, 83 insertions(+), 129 deletions(-) diff --git a/accept.go b/accept.go index 5e66436f..8908aa8f 100644 --- a/accept.go +++ b/accept.go @@ -60,16 +60,10 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { } // Ensure all transactions in the block are finalized. - for i, tx := range block.MsgBlock().Transactions { + for _, tx := range block.Transactions() { if !IsFinalizedTransaction(tx, blockHeight, blockHeader.Timestamp) { - // Use the TxSha function from the block rather - // than the transaction itself since the block version - // is cached. Also, it's safe to ignore the error here - // since the only reason TxSha can fail is if the index - // is out of range which is impossible here. - txSha, _ := block.TxSha(i) str := fmt.Sprintf("block contains unfinalized "+ - "transaction %v", txSha) + "transaction %v", tx.Sha()) return RuleError(str) } } @@ -129,7 +123,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { if prevNode != nil { expectedHeight = prevNode.height + 1 } - coinbaseTx := block.MsgBlock().Transactions[0] + coinbaseTx := block.Transactions()[0] err := checkSerializedHeight(coinbaseTx, expectedHeight) if err != nil { return err diff --git a/checkpoints.go b/checkpoints.go index 4f4c4019..a0b3ff84 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -154,11 +154,11 @@ func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) { // isNonstandardTransaction determines whether a transaction contains any // scripts which are not one of the standard types. -func isNonstandardTransaction(tx *btcwire.MsgTx) bool { +func isNonstandardTransaction(tx *btcutil.Tx) bool { // TODO(davec): Should there be checks for the input signature scripts? // Check all of the output public key scripts for non-standard scripts. - for _, txOut := range tx.TxOut { + for _, txOut := range tx.MsgTx().TxOut { scriptClass := btcscript.GetScriptClass(txOut.PkScript) if scriptClass == btcscript.NonStandardTy { return true @@ -235,7 +235,7 @@ func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { // A checkpoint must have transactions that only contain standard // scripts. - for _, tx := range block.MsgBlock().Transactions { + for _, tx := range block.Transactions() { if isNonstandardTransaction(tx) { return false, nil } diff --git a/internal_test.go b/internal_test.go index b919d543..282804f9 100644 --- a/internal_test.go +++ b/internal_test.go @@ -13,7 +13,6 @@ package btcchain import ( "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "time" ) @@ -37,6 +36,6 @@ func TstTimeSorter(times []time.Time) timeSorter { // TstCheckSerializedHeight makes the internal checkSerializedHeight function // available to the test package. -func TstCheckSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { +func TstCheckSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { return checkSerializedHeight(coinbaseTx, wantHeight) } diff --git a/merkle.go b/merkle.go index e0aa0053..b0e2f1d7 100644 --- a/merkle.go +++ b/merkle.go @@ -69,21 +69,15 @@ func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire. // Since this function uses nodes that are pointers to the hashes, empty nodes // will be nil. func BuildMerkleTreeStore(block *btcutil.Block) []*btcwire.ShaHash { - numTransactions := len(block.MsgBlock().Transactions) - // Calculate how many entries are required to hold the binary merkle // tree as a linear array and create an array of that size. - nextPoT := nextPowerOfTwo(numTransactions) + nextPoT := nextPowerOfTwo(len(block.Transactions())) arraySize := nextPoT*2 - 1 merkles := make([]*btcwire.ShaHash, arraySize) // Create the base transaction shas and populate the array with them. - for i := 0; i < numTransactions; i++ { - // Ignore the error since the only reason TxSha can fail is - // if the index is out of range which is impossible here due - // to using a loop over the existing transactions. - sha, _ := block.TxSha(i) - merkles[i] = sha + for i, tx := range block.Transactions() { + merkles[i] = tx.Sha() } // Start the array offset after the last transaction and adjusted to the diff --git a/scriptval.go b/scriptval.go index 8426e14f..64e51be4 100644 --- a/scriptval.go +++ b/scriptval.go @@ -19,16 +19,10 @@ type txValidate struct { err error } -// txProcessList -type txProcessList struct { - txsha btcwire.ShaHash - tx *btcwire.MsgTx -} - // validateTxIn validates a the script pair for the passed spending transaction // (along with the specific input index) and origin transaction (with the // specific output index). -func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *btcwire.MsgTx, originTx *btcwire.MsgTx, flags btcscript.ScriptFlags) error { +func validateTxIn(txInIdx int, txin *btcwire.TxIn, tx *btcutil.Tx, originTx *btcutil.Tx, flags btcscript.ScriptFlags) error { // If the input transaction has no previous input, there is nothing // to check. originTxIdx := txin.PreviousOutpoint.Index @@ -36,17 +30,17 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b return nil } - if originTxIdx >= uint32(len(originTx.TxOut)) { + if originTxIdx >= uint32(len(originTx.MsgTx().TxOut)) { originTxSha := &txin.PreviousOutpoint.Hash log.Warnf("unable to locate source tx %v spending tx %v", - originTxSha, &txSha) + originTxSha, tx.Sha()) return fmt.Errorf("invalid index %x", originTxIdx) } sigScript := txin.SignatureScript - pkScript := originTx.TxOut[originTxIdx].PkScript - engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, tx, - flags) + pkScript := originTx.MsgTx().TxOut[originTxIdx].PkScript + engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, + tx.MsgTx(), flags) if err != nil { return err } @@ -62,9 +56,9 @@ func validateTxIn(txInIdx int, txin *btcwire.TxIn, txSha *btcwire.ShaHash, tx *b // ValidateTransactionScripts validates the scripts for the passed transaction // using multiple goroutines. -func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txStore TxStore, flags btcscript.ScriptFlags) (err error) { +func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript.ScriptFlags) (err error) { c := make(chan txValidate) - job := tx.TxIn + job := tx.MsgTx().TxIn resultErrors := make([]error, len(job)) var currentItem int @@ -72,12 +66,12 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txSt processFunc := func(txInIdx int) { log.Tracef("validating tx %v input %v len %v", - txHash, currentItem, len(job)) + tx.Sha(), currentItem, len(job)) txin := job[txInIdx] originTxSha := &txin.PreviousOutpoint.Hash origintxidx := txin.PreviousOutpoint.Index - var originTx *btcwire.MsgTx + var originTx *btcutil.Tx if origintxidx != math.MaxUint32 { txInfo, ok := txStore[*originTxSha] if !ok { @@ -87,8 +81,7 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txSt } originTx = txInfo.Tx } - err := validateTxIn(txInIdx, job[txInIdx], txHash, tx, originTx, - flags) + err := validateTxIn(txInIdx, txin, tx, originTx, flags) r := txValidate{txInIdx, err} c <- r } @@ -114,7 +107,8 @@ func ValidateTransactionScripts(tx *btcwire.MsgTx, txHash *btcwire.ShaHash, txSt } for i := 0; i < len(job); i++ { if resultErrors[i] != nil { - log.Warnf("tx %v failed input %v, err %v", txHash, i, resultErrors[i]) + log.Warnf("tx %v failed input %v, err %v", tx.Sha(), i, + resultErrors[i]) } } return @@ -130,17 +124,14 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { flags |= btcscript.ScriptBip16 } - txList := block.MsgBlock().Transactions + txList := block.Transactions() c := make(chan txValidate) resultErrors := make([]error, len(txList)) var currentItem int var completedItems int processFunc := func(txIdx int) { - tx := txList[txIdx] - txHash, _ := block.TxSha(txIdx) - - err := ValidateTransactionScripts(tx, txHash, txStore, flags) + err := ValidateTransactionScripts(txList[txIdx], txStore, flags) r := txValidate{txIdx, err} c <- r } diff --git a/txlookup.go b/txlookup.go index 193f5331..3d5c1df2 100644 --- a/txlookup.go +++ b/txlookup.go @@ -14,7 +14,7 @@ import ( // TxData contains contextual information about transactions such as which block // they were found in and whether or not the outputs are spent. type TxData struct { - Tx *btcwire.MsgTx + Tx *btcutil.Tx Hash *btcwire.ShaHash BlockHeight int64 Spent []bool @@ -33,23 +33,19 @@ type TxStore map[btcwire.ShaHash]*TxData func connectTransactions(txStore TxStore, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of // them are ones we need to update and spend based on the results map. - for i, tx := range block.MsgBlock().Transactions { - txHash, err := block.TxSha(i) - if err != nil { - return err - } - + for _, tx := range block.Transactions() { // Update the transaction store with the transaction information // if it's one of the requested transactions. - if txD, exists := txStore[*txHash]; exists { + msgTx := tx.MsgTx() + if txD, exists := txStore[*tx.Sha()]; exists { txD.Tx = tx txD.BlockHeight = block.Height() - txD.Spent = make([]bool, len(tx.TxOut)) + txD.Spent = make([]bool, len(msgTx.TxOut)) txD.Err = nil } // Spend the origin transaction output. - for _, txIn := range tx.TxIn { + for _, txIn := range msgTx.TxIn { originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index if originTx, exists := txStore[*originHash]; exists { @@ -67,18 +63,13 @@ func connectTransactions(txStore TxStore, block *btcutil.Block) error { func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // Loop through all of the transactions in the block to see if any of // them are ones that need to be undone based on the transaction store. - for i, tx := range block.MsgBlock().Transactions { - txHash, err := block.TxSha(i) - if err != nil { - return err - } - + for _, tx := range block.Transactions() { // Clear this transaction from the transaction store if needed. // Only clear it rather than deleting it because the transaction // connect code relies on its presence to decide whether or not // to update the store and any transactions which exist on both // sides of a fork would otherwise not be updated. - if txD, exists := txStore[*txHash]; exists { + if txD, exists := txStore[*tx.Sha()]; exists { txD.Tx = nil txD.BlockHeight = 0 txD.Spent = nil @@ -86,7 +77,7 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { } // Unspend the origin transaction output. - for _, txIn := range tx.TxIn { + for _, txIn := range tx.MsgTx().TxIn { originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index originTx, exists := txStore[*originHash] @@ -146,7 +137,7 @@ func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool, includeSpent // cause subtle errors, so avoid the potential altogether. txD.Err = txReply.Err if txReply.Err == nil { - txD.Tx = txReply.Tx + txD.Tx = btcutil.NewTx(txReply.Tx) txD.BlockHeight = txReply.Height txD.Spent = make([]bool, len(txReply.TxSpent)) copy(txD.Spent, txReply.TxSpent) @@ -240,14 +231,9 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // this block could be referencing other transactions earlier in this // block which are not yet in the chain. txInFlight := map[btcwire.ShaHash]int{} - transactions := block.MsgBlock().Transactions - for i := range transactions { - // Get transaction hash. It's safe to ignore the error since - // it's already cached in the nominal code path and the only - // way it can fail is if the index is out of range which is - // impossible here. - txHash, _ := block.TxSha(i) - txInFlight[*txHash] = i + transactions := block.Transactions() + for i, tx := range transactions { + txInFlight[*tx.Sha()] = i } // Loop through all of the transaction inputs (except for the coinbase @@ -256,7 +242,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txNeededSet := make(map[btcwire.ShaHash]bool) txStore := make(TxStore) for i, tx := range transactions[1:] { - for _, txIn := range tx.TxIn { + for _, txIn := range tx.MsgTx().TxIn { // Add an entry to the transaction store for the needed // transaction with it set to missing by default. originHash := &txIn.PreviousOutpoint.Hash @@ -279,7 +265,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc originTx := transactions[inFlightIndex] txD.Tx = originTx txD.BlockHeight = node.height - txD.Spent = make([]bool, len(originTx.TxOut)) + txD.Spent = make([]bool, len(originTx.MsgTx().TxOut)) txD.Err = nil } else { txNeededSet[*originHash] = true @@ -306,18 +292,13 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // passed transaction from the point of view of the end of the main chain. It // also attempts to fetch the transaction itself so the returned TxStore can be // examined for duplicate transactions. -func (b *BlockChain) FetchTransactionStore(tx *btcwire.MsgTx) (TxStore, error) { - txHash, err := tx.TxSha() - if err != nil { - return nil, err - } - +func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx) (TxStore, error) { // Create a set of needed transactions from the transactions referenced // by the inputs of the passed transaction. Also, add the passed // transaction itself as a way for the caller to detect duplicates. txNeededSet := make(map[btcwire.ShaHash]bool) - txNeededSet[txHash] = true - for _, txIn := range tx.TxIn { + txNeededSet[*tx.Sha()] = true + for _, txIn := range tx.MsgTx().TxIn { txNeededSet[txIn.PreviousOutpoint.Hash] = true } diff --git a/validate.go b/validate.go index 00ed8ff2..88b677fd 100644 --- a/validate.go +++ b/validate.go @@ -94,7 +94,9 @@ func isNullOutpoint(outpoint *btcwire.OutPoint) bool { // represented in the block chain by a transaction with a single input that has // a previous output transaction index set to the maximum value along with a // zero hash. -func IsCoinBase(msgTx *btcwire.MsgTx) bool { +func IsCoinBase(tx *btcutil.Tx) bool { + msgTx := tx.MsgTx() + // A coin base must only have one transaction input. if len(msgTx.TxIn) != 1 { return false @@ -111,7 +113,9 @@ func IsCoinBase(msgTx *btcwire.MsgTx) bool { } // IsFinalizedTransaction determines whether or not a transaction is finalized. -func IsFinalizedTransaction(msgTx *btcwire.MsgTx, blockHeight int64, blockTime time.Time) bool { +func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int64, blockTime time.Time) bool { + msgTx := tx.MsgTx() + // Lock time of zero means the transaction is finalized. lockTime := msgTx.LockTime if lockTime == 0 { @@ -175,14 +179,15 @@ func calcBlockSubsidy(height int64) int64 { // CheckTransactionSanity performs some preliminary checks on a transaction to // ensure it is sane. These checks are context free. -func CheckTransactionSanity(tx *btcwire.MsgTx) error { +func CheckTransactionSanity(tx *btcutil.Tx) error { // A transaction must have at least one input. - if len(tx.TxIn) == 0 { + msgTx := tx.MsgTx() + if len(msgTx.TxIn) == 0 { return RuleError("transaction has no inputs") } // A transaction must have at least one output. - if len(tx.TxOut) == 0 { + if len(msgTx.TxOut) == 0 { return RuleError("transaction has no outputs") } @@ -198,7 +203,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { // as a satoshi. One bitcoin is a quantity of satoshi as defined by the // satoshiPerBitcoin constant. var totalSatoshi int64 - for _, txOut := range tx.TxOut { + for _, txOut := range msgTx.TxOut { satoshi := txOut.Value if satoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ @@ -231,7 +236,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { // Check for duplicate transaction inputs. existingTxOut := make(map[btcwire.OutPoint]bool) - for _, txIn := range tx.TxIn { + for _, txIn := range msgTx.TxIn { if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists { return RuleError("transaction contains duplicate outpoint") } @@ -240,7 +245,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { // Coinbase script length must be between min and max length. if IsCoinBase(tx) { - slen := len(tx.TxIn[0].SignatureScript) + slen := len(msgTx.TxIn[0].SignatureScript) if slen < minCoinbaseScriptLen || slen > maxCoinbaseScriptLen { str := fmt.Sprintf("coinbase transaction script length "+ "of %d is out of range (min: %d, max: %d)", @@ -250,7 +255,7 @@ func CheckTransactionSanity(tx *btcwire.MsgTx) error { } else { // Previous transaction outputs referenced by the inputs to this // transaction must not be null. - for _, txIn := range tx.TxIn { + for _, txIn := range msgTx.TxIn { prevOut := &txIn.PreviousOutpoint if isNullOutpoint(prevOut) { return RuleError("transaction input refers to " + @@ -302,7 +307,9 @@ func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { // input and output scripts in the provided transaction. This uses the // quicker, but imprecise, signature operation counting mechanism from // btcscript. -func countSigOps(msgTx *btcwire.MsgTx) int { +func countSigOps(tx *btcutil.Tx) int { + msgTx := tx.MsgTx() + // Accumulate the number of signature operations in all transaction // inputs. totalSigOps := 0 @@ -325,20 +332,15 @@ func countSigOps(msgTx *btcwire.MsgTx) int { // transactions which are of the pay-to-script-hash type. This uses the // precise, signature operation counting mechanism from btcscript which requires // access to the input transaction scripts. -func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) (int, error) { +func countP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, error) { // Coinbase transactions have no interesting inputs. if isCoinBaseTx { return 0, nil } - // TODO(davec): Need to pass the cached version in. - txHash, err := msgTx.TxSha() - if err != nil { - return 0, err - } - // Accumulate the number of signature operations in all transaction // inputs. + msgTx := tx.MsgTx() totalSigOps := 0 for _, txIn := range msgTx.TxIn { // Ensure the referenced input transaction is available. @@ -347,23 +349,24 @@ func countP2SHSigOps(msgTx *btcwire.MsgTx, isCoinBaseTx bool, txStore TxStore) ( if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input transaction "+ "%v referenced from transaction %v", txInHash, - txHash) + tx.Sha()) return 0, RuleError(str) } + originMsgTx := originTx.Tx.MsgTx() // Ensure the output index in the referenced transaction is // available. originTxIndex := txIn.PreviousOutpoint.Index - if originTxIndex >= uint32(len(originTx.Tx.TxOut)) { + if originTxIndex >= uint32(len(originMsgTx.TxOut)) { str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", - originTxIndex, txInHash, txHash) + originTxIndex, txInHash, tx.Sha()) return 0, RuleError(str) } // We're only interested in pay-to-script-hash types, so skip // this input if it's not one. - pkScript := originTx.Tx.TxOut[originTxIndex].PkScript + pkScript := originMsgTx.TxOut[originTxIndex].PkScript if !btcscript.IsPayToScriptHash(pkScript) { continue } @@ -407,8 +410,7 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { } // Ensure the block time is not more than 2 hours in the future. - msgBlock := block.MsgBlock() - header := &msgBlock.Header + header := &block.MsgBlock().Header if header.Timestamp.After(time.Now().Add(time.Hour * 2)) { str := fmt.Sprintf("block timestamp of %v is too far in the "+ "future", header.Timestamp) @@ -416,7 +418,7 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { } // A block must have at least one transaction. - transactions := msgBlock.Transactions + transactions := block.Transactions() if len(transactions) == 0 { return RuleError("block does not contain any transactions") } @@ -463,11 +465,8 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // since the transaction hashes are already cached due to building the // merkle tree above. existingTxHashes := make(map[btcwire.ShaHash]bool) - txShas, err := block.TxShas() - if err != nil { - return err - } - for _, hash := range txShas { + for _, tx := range transactions { + hash := tx.Sha() if _, exists := existingTxHashes[*hash]; exists { str := fmt.Sprintf("block contains duplicate "+ "transaction %v", hash) @@ -497,8 +496,8 @@ func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { // checkSerializedHeight checks if the signature script in the passed // transaction starts with the serialized block height of wantHeight. -func checkSerializedHeight(coinbaseTx *btcwire.MsgTx, wantHeight int64) error { - sigScript := coinbaseTx.TxIn[0].SignatureScript +func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { + sigScript := coinbaseTx.MsgTx().TxIn[0].SignatureScript if len(sigScript) < 1 { str := "the coinbase signature script for blocks of " + "version %d or greater must start with the " + @@ -601,20 +600,15 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // amount, and verifying the signatures to prove the spender was the owner of // the bitcoins and therefore allowed to spend them. As it checks the inputs, // it also calculates the total fees for the transaction and returns that value. -func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) (int64, error) { +func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (int64, error) { // Coinbase transactions have no inputs. if IsCoinBase(tx) { return 0, nil } - // TODO(davec): Need to pass the cached version in. - txHash, err := tx.TxSha() - if err != nil { - return 0, err - } - + txHash := tx.Sha() var totalSatoshiIn int64 - for _, txIn := range tx.TxIn { + for _, txIn := range tx.MsgTx().TxIn { // Ensure the input is available. txInHash := &txIn.PreviousOutpoint.Hash originTx, exists := txStore[*txInHash] @@ -659,7 +653,7 @@ func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) // a transaction are in a unit value known as a satoshi. One // bitcoin is a quantity of satoshi as defined by the // satoshiPerBitcoin constant. - originTxSatoshi := originTx.Tx.TxOut[originTxIndex].Value + originTxSatoshi := originTx.Tx.MsgTx().TxOut[originTxIndex].Value if originTxSatoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ "value of %v", originTxSatoshi) @@ -693,7 +687,7 @@ func CheckTransactionInputs(tx *btcwire.MsgTx, txHeight int64, txStore TxStore) // to ignore overflow and out of range errors here because those error // conditions would have already been caught by checkTransactionSanity. var totalSatoshiOut int64 - for _, txOut := range tx.TxOut { + for _, txOut := range tx.MsgTx().TxOut { totalSatoshiOut += txOut.Value } @@ -771,7 +765,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // expands the count to include a precise count of pay-to-script-hash // signature operations in each of the input transaction public key // scripts. - transactions := block.MsgBlock().Transactions + transactions := block.Transactions() totalSigOps := 0 for i, tx := range transactions { numsigOps := countSigOps(tx) @@ -832,7 +826,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // errors here because those error conditions would have already been // caught by checkTransactionSanity. var totalSatoshiOut int64 - for _, txOut := range transactions[0].TxOut { + for _, txOut := range transactions[0].MsgTx().TxOut { totalSatoshiOut += txOut.Value } expectedSatoshiOut := calcBlockSubsidy(node.height) + totalFees diff --git a/validate_test.go b/validate_test.go index 5cde8f1a..004c490b 100644 --- a/validate_test.go +++ b/validate_test.go @@ -66,8 +66,9 @@ func TestCheckSerializedHeight(t *testing.T) { t.Logf("Running %d tests", len(tests)) for i, test := range tests { - tx := coinbaseTx.Copy() - tx.TxIn[0].SignatureScript = test.sigScript + msgTx := coinbaseTx.Copy() + msgTx.TxIn[0].SignatureScript = test.sigScript + tx := btcutil.NewTx(msgTx) err := btcchain.TstCheckSerializedHeight(tx, test.wantHeight) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { From 8271a118086237125a9ffdc1b181744238ee8ed8 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 29 Oct 2013 14:57:31 -0400 Subject: [PATCH 086/190] add SatoshiPerBitcent constant and export SatoshiPerBitcoin and MaxSatoshi --- validate.go | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/validate.go b/validate.go index 88b677fd..dbeb2580 100644 --- a/validate.go +++ b/validate.go @@ -16,11 +16,14 @@ import ( ) const ( - // satoshiPerBitcoin is the number of satoshi in one bitcoin (1 BTC). - satoshiPerBitcoin int64 = 1e8 + // SatoshiPerBitcent is the number of satoshi in one bitcoin cent. + SatoshiPerBitcent int64 = 1e6 - // maxSatoshi is the maximum transaction amount allowed in satoshi. - maxSatoshi int64 = 21e6 * satoshiPerBitcoin + // SatoshiPerBitcoin is the number of satoshi in one bitcoin (1 BTC). + SatoshiPerBitcoin int64 = 1e8 + + // MaxSatoshi is the maximum transaction amount allowed in satoshi. + MaxSatoshi int64 = 21e6 * SatoshiPerBitcoin // maxSigOpsPerBlock is the maximum number of signature operations // allowed for a block. It is a fraction of the max block payload size. @@ -49,7 +52,7 @@ const ( // baseSubsidy is the starting subsidy amount for mined blocks. This // value is halved every subsidyHalvingInterval blocks. - baseSubsidy = 50 * satoshiPerBitcoin + baseSubsidy = 50 * SatoshiPerBitcoin // subsidyHalvingInterval is the interval of blocks at which the // baseSubsidy is continually halved. See calcBlockSubsidy for more @@ -201,7 +204,7 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // transaction. Also, the total of all outputs must abide by the same // restrictions. All amounts in a transaction are in a unit value known // as a satoshi. One bitcoin is a quantity of satoshi as defined by the - // satoshiPerBitcoin constant. + // SatoshiPerBitcoin constant. var totalSatoshi int64 for _, txOut := range msgTx.TxOut { satoshi := txOut.Value @@ -210,10 +213,10 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { "value of %v", satoshi) return RuleError(str) } - if satoshi > maxSatoshi { + if satoshi > MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", satoshi, - maxSatoshi) + MaxSatoshi) return RuleError(str) } @@ -226,10 +229,10 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { "outputs has negative value of %v", totalSatoshi) return RuleError(str) } - if totalSatoshi > maxSatoshi { + if totalSatoshi > MaxSatoshi { str := fmt.Sprintf("total value of all transaction "+ "outputs is %v which is higher than max "+ - "allowed value of %v", totalSatoshi, maxSatoshi) + "allowed value of %v", totalSatoshi, MaxSatoshi) return RuleError(str) } } @@ -652,17 +655,17 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in // or more than the max allowed per transaction. All amounts in // a transaction are in a unit value known as a satoshi. One // bitcoin is a quantity of satoshi as defined by the - // satoshiPerBitcoin constant. + // SatoshiPerBitcoin constant. originTxSatoshi := originTx.Tx.MsgTx().TxOut[originTxIndex].Value if originTxSatoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ "value of %v", originTxSatoshi) return 0, RuleError(str) } - if originTxSatoshi > maxSatoshi { + if originTxSatoshi > MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", - originTxSatoshi, maxSatoshi) + originTxSatoshi, MaxSatoshi) return 0, RuleError(str) } @@ -671,11 +674,11 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in // the accumulator so check for overflow. lastSatoshiIn := totalSatoshiIn totalSatoshiIn += originTxSatoshi - if totalSatoshiIn < lastSatoshiIn || totalSatoshiIn > maxSatoshi { + if totalSatoshiIn < lastSatoshiIn || totalSatoshiIn > MaxSatoshi { str := fmt.Sprintf("total value of all transaction "+ "inputs is %v which is higher than max "+ "allowed value of %v", totalSatoshiIn, - maxSatoshi) + MaxSatoshi) return 0, RuleError(str) } From 36941cc42768c15d969f62459c042aaed73acd96 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 29 Oct 2013 16:08:12 -0400 Subject: [PATCH 087/190] Remove the satoshi consts and use them from btcutil instead. --- validate.go | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/validate.go b/validate.go index dbeb2580..3e6ef567 100644 --- a/validate.go +++ b/validate.go @@ -16,15 +16,6 @@ import ( ) const ( - // SatoshiPerBitcent is the number of satoshi in one bitcoin cent. - SatoshiPerBitcent int64 = 1e6 - - // SatoshiPerBitcoin is the number of satoshi in one bitcoin (1 BTC). - SatoshiPerBitcoin int64 = 1e8 - - // MaxSatoshi is the maximum transaction amount allowed in satoshi. - MaxSatoshi int64 = 21e6 * SatoshiPerBitcoin - // maxSigOpsPerBlock is the maximum number of signature operations // allowed for a block. It is a fraction of the max block payload size. maxSigOpsPerBlock = btcwire.MaxBlockPayload / 50 @@ -52,7 +43,7 @@ const ( // baseSubsidy is the starting subsidy amount for mined blocks. This // value is halved every subsidyHalvingInterval blocks. - baseSubsidy = 50 * SatoshiPerBitcoin + baseSubsidy = 50 * btcutil.SatoshiPerBitcoin // subsidyHalvingInterval is the interval of blocks at which the // baseSubsidy is continually halved. See calcBlockSubsidy for more @@ -213,10 +204,10 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { "value of %v", satoshi) return RuleError(str) } - if satoshi > MaxSatoshi { + if satoshi > btcutil.MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", satoshi, - MaxSatoshi) + btcutil.MaxSatoshi) return RuleError(str) } @@ -229,10 +220,11 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { "outputs has negative value of %v", totalSatoshi) return RuleError(str) } - if totalSatoshi > MaxSatoshi { + if totalSatoshi > btcutil.MaxSatoshi { str := fmt.Sprintf("total value of all transaction "+ "outputs is %v which is higher than max "+ - "allowed value of %v", totalSatoshi, MaxSatoshi) + "allowed value of %v", totalSatoshi, + btcutil.MaxSatoshi) return RuleError(str) } } @@ -662,10 +654,10 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in "value of %v", originTxSatoshi) return 0, RuleError(str) } - if originTxSatoshi > MaxSatoshi { + if originTxSatoshi > btcutil.MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", - originTxSatoshi, MaxSatoshi) + originTxSatoshi, btcutil.MaxSatoshi) return 0, RuleError(str) } @@ -674,11 +666,12 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in // the accumulator so check for overflow. lastSatoshiIn := totalSatoshiIn totalSatoshiIn += originTxSatoshi - if totalSatoshiIn < lastSatoshiIn || totalSatoshiIn > MaxSatoshi { + if totalSatoshiIn < lastSatoshiIn || + totalSatoshiIn > btcutil.MaxSatoshi { str := fmt.Sprintf("total value of all transaction "+ "inputs is %v which is higher than max "+ "allowed value of %v", totalSatoshiIn, - MaxSatoshi) + btcutil.MaxSatoshi) return 0, RuleError(str) } From 09b53a8fcaca4892c5d082f85dec4f9da51ec39d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 7 Nov 2013 15:38:35 -0600 Subject: [PATCH 088/190] Export the CheckBlockSanity function. --- internal_test.go | 6 ------ process.go | 2 +- validate.go | 4 ++-- validate_test.go | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/internal_test.go b/internal_test.go index 282804f9..f364167c 100644 --- a/internal_test.go +++ b/internal_test.go @@ -16,12 +16,6 @@ import ( "time" ) -// TstCheckBlockSanity makes the internal checkBlockSanity function available to -// the test package. -func (b *BlockChain) TstCheckBlockSanity(block *btcutil.Block) error { - return b.checkBlockSanity(block) -} - // TstSetCoinbaseMaturity makes the ability to set the coinbase maturity // available to the test package. func TstSetCoinbaseMaturity(maturity int64) { diff --git a/process.go b/process.go index 72ecd445..fa4e70dc 100644 --- a/process.go +++ b/process.go @@ -112,7 +112,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { } // Perform preliminary sanity checks on the block and its transactions. - err = b.checkBlockSanity(block) + err = b.CheckBlockSanity(block) if err != nil { return err } diff --git a/validate.go b/validate.go index 3e6ef567..700c0045 100644 --- a/validate.go +++ b/validate.go @@ -388,9 +388,9 @@ func countP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e return totalSigOps, nil } -// checkBlockSanity performs some preliminary checks on a block to ensure it is +// CheckBlockSanity performs some preliminary checks on a block to ensure it is // sane before continuing with block processing. These checks are context free. -func (b *BlockChain) checkBlockSanity(block *btcutil.Block) error { +func (b *BlockChain) CheckBlockSanity(block *btcutil.Block) error { // NOTE: bitcoind does size limits checking here, but the size limits // have already been checked by btcwire for incoming blocks. Also, // btcwire checks the size limits on send too, so there is no need diff --git a/validate_test.go b/validate_test.go index 004c490b..6ce1e09a 100644 --- a/validate_test.go +++ b/validate_test.go @@ -24,7 +24,7 @@ func TestCheckBlockSanity(t *testing.T) { defer teardownFunc() block := btcutil.NewBlock(&Block100000) - err = chain.TstCheckBlockSanity(block) + err = chain.CheckBlockSanity(block) if err != nil { t.Errorf("CheckBlockSanity: %v", err) } From 5295be070dbb85de218f472c01e6d5066ba049b4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 7 Nov 2013 16:06:01 -0600 Subject: [PATCH 089/190] Make the CheckBlockSanity function context free. Rather than defining CheckBlockSanity as a member of a BlockChain instance, define it at the root level so it is truly context free as intended. In order to make it context free, the proof of work limit is now a required parameter. --- process.go | 2 +- validate.go | 8 ++++---- validate_test.go | 11 ++--------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/process.go b/process.go index fa4e70dc..89ad0726 100644 --- a/process.go +++ b/process.go @@ -112,7 +112,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { } // Perform preliminary sanity checks on the block and its transactions. - err = b.CheckBlockSanity(block) + err = CheckBlockSanity(block, b.chainParams().PowLimit) if err != nil { return err } diff --git a/validate.go b/validate.go index 700c0045..bc61aaf8 100644 --- a/validate.go +++ b/validate.go @@ -12,6 +12,7 @@ import ( "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" + "math/big" "time" ) @@ -265,7 +266,7 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // checkProofOfWork ensures the block header bits which indicate the target // difficulty is in min/max range and that the block hash is less than the // target difficulty as claimed. -func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { +func checkProofOfWork(block *btcutil.Block, powLimit *big.Int) error { // The target difficulty must be larger than zero. header := block.MsgBlock().Header target := CompactToBig(header.Bits) @@ -276,7 +277,6 @@ func (b *BlockChain) checkProofOfWork(block *btcutil.Block) error { } // The target difficulty must be less than the maximum allowed. - powLimit := b.chainParams().PowLimit if target.Cmp(powLimit) > 0 { str := fmt.Sprintf("block target difficulty of %064x is "+ "higher than max of %064x", target, powLimit) @@ -390,7 +390,7 @@ func countP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e // CheckBlockSanity performs some preliminary checks on a block to ensure it is // sane before continuing with block processing. These checks are context free. -func (b *BlockChain) CheckBlockSanity(block *btcutil.Block) error { +func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { // NOTE: bitcoind does size limits checking here, but the size limits // have already been checked by btcwire for incoming blocks. Also, // btcwire checks the size limits on send too, so there is no need @@ -399,7 +399,7 @@ func (b *BlockChain) CheckBlockSanity(block *btcutil.Block) error { // Ensure the proof of work bits in the block header is in min/max range // and the block hash is less than the target value described by the // bits. - err := b.checkProofOfWork(block) + err := checkProofOfWork(block, powLimit) if err != nil { return err } diff --git a/validate_test.go b/validate_test.go index 6ce1e09a..a04148d5 100644 --- a/validate_test.go +++ b/validate_test.go @@ -15,16 +15,9 @@ import ( ) func TestCheckBlockSanity(t *testing.T) { - // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := chainSetup("cbsanity") - if err != nil { - t.Errorf("Failed to setup chain instance: %v", err) - return - } - defer teardownFunc() - + powLimit := btcchain.ChainParams(btcwire.MainNet).PowLimit block := btcutil.NewBlock(&Block100000) - err = chain.CheckBlockSanity(block) + err := btcchain.CheckBlockSanity(block, powLimit) if err != nil { t.Errorf("CheckBlockSanity: %v", err) } From d0bbcacfc0d385cee4aa98901a53b0b5ee037779 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 8 Nov 2013 02:52:31 -0500 Subject: [PATCH 090/190] Modify the tests to use memory database backend. This commit modifies the tests to setup a chain instance backed by the new memory database backend for btcdb. This allows the tests to avoid creating and cleaning up files and also allows the tests to run faster since it can all happen in memory. The chainSetup function has also been changed to provide logic to switch on the database type to allow for easy changing of the backend to a different database type as needed. For example, it could be useful to provide extra testing against new database backends. --- common_test.go | 87 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/common_test.go b/common_test.go index 340718a7..22751ca6 100644 --- a/common_test.go +++ b/common_test.go @@ -9,12 +9,16 @@ import ( "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" + _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "os" "path/filepath" ) +// testDbType is the database backend type to use for the tests. +const testDbType = "memdb" + // testDbRoot is the root directory used to create all test databases. const testDbRoot = "testdbs" @@ -28,41 +32,78 @@ func fileExists(name string) bool { return true } +// isSupportedDbType returns whether or not the passed database type is +// currently supported. +func isSupportedDbType(dbType string) bool { + supportedDBs := btcdb.SupportedDBs() + for _, sDbType := range supportedDBs { + if dbType == sDbType { + return true + } + } + + return false +} + // chainSetup is used to create a new db and chain instance with the genesis // block already inserted. In addition to the new chain instnce, it returns // a teardown function the caller should invoke when done testing to clean up. func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { - // Create the root directory for test databases. - if !fileExists(testDbRoot) { - if err := os.MkdirAll(testDbRoot, 0700); err != nil { - err := fmt.Errorf("unable to create test db root: %v", err) - return nil, nil, err + if !isSupportedDbType(testDbType) { + return nil, nil, fmt.Errorf("unsupported db type %v", testDbType) + } + + // Handle memory database specially since it doesn't need the disk + // specific handling. + var db btcdb.Db + var teardown func() + if testDbType == "memdb" { + ndb, err := btcdb.CreateDB(testDbType, "") + if err != nil { + return nil, nil, fmt.Errorf("error creating db: %v", err) } - } + db = ndb - // Create a new database to store the accepted blocks into. - dbPath := filepath.Join(testDbRoot, dbName) - _ = os.RemoveAll(dbPath) - db, err := btcdb.CreateDB("leveldb", dbPath) - if err != nil { - return nil, nil, fmt.Errorf("error creating db: %v", err) - } + // Setup a teardown function for cleaning up. This function is + // returned to the caller to be invoked when it is done testing. + teardown = func() { + db.Close() + } + } else { + // Create the root directory for test databases. + if !fileExists(testDbRoot) { + if err := os.MkdirAll(testDbRoot, 0700); err != nil { + err := fmt.Errorf("unable to create test db "+ + "root: %v", err) + return nil, nil, err + } + } - // Setup a teardown function for cleaning up. This function is returned - // to the caller to be invoked when it is done testing. - teardown := func() { - dbVersionPath := filepath.Join(testDbRoot, dbName+".ver") - db.Sync() - db.Close() - os.RemoveAll(dbPath) - os.Remove(dbVersionPath) - os.RemoveAll(testDbRoot) + // Create a new database to store the accepted blocks into. + dbPath := filepath.Join(testDbRoot, dbName) + _ = os.RemoveAll(dbPath) + ndb, err := btcdb.CreateDB(testDbType, dbPath) + if err != nil { + return nil, nil, fmt.Errorf("error creating db: %v", err) + } + db = ndb + + // Setup a teardown function for cleaning up. This function is + // returned to the caller to be invoked when it is done testing. + teardown = func() { + dbVersionPath := filepath.Join(testDbRoot, dbName+".ver") + db.Sync() + db.Close() + os.RemoveAll(dbPath) + os.Remove(dbVersionPath) + os.RemoveAll(testDbRoot) + } } // Insert the main network genesis block. This is part of the initial // database setup. genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) - _, err = db.InsertBlock(genesisBlock) + _, err := db.InsertBlock(genesisBlock) if err != nil { teardown() err := fmt.Errorf("failed to insert genesis block: %v", err) From 2300b357319ccf3c27029ef90da7eb7f9ff792ba Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 12 Nov 2013 20:11:55 -0600 Subject: [PATCH 091/190] Add checkpoint at block height 267300. --- checkpoints.go | 1 + 1 file changed, 1 insertion(+) diff --git a/checkpoints.go b/checkpoints.go index a0b3ff84..5edfc816 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -57,6 +57,7 @@ var checkpointDataMainNet = checkpointData{ {216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, {225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, {250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, + {267300, newShaHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, }, checkpointsByHeight: nil, // Automatically generated in init. } From 8a19f269ca791738258e7ddfd2e6767fcb02b9a4 Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Thu, 21 Nov 2013 18:23:45 +0000 Subject: [PATCH 092/190] use passed in parameter and not global in log message. Should shut up the race detector (and make the printf more correct) --- scriptval.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scriptval.go b/scriptval.go index 64e51be4..3ed201fe 100644 --- a/scriptval.go +++ b/scriptval.go @@ -66,7 +66,7 @@ func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript processFunc := func(txInIdx int) { log.Tracef("validating tx %v input %v len %v", - tx.Sha(), currentItem, len(job)) + tx.Sha(), txInIdx, len(job)) txin := job[txInIdx] originTxSha := &txin.PreviousOutpoint.Hash origintxidx := txin.PreviousOutpoint.Index From f7f51a1e43b56b97c96a273a76397186d666d5ed Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 21 Nov 2013 09:35:08 -0600 Subject: [PATCH 093/190] Use btclog for logging. --- log.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/log.go b/log.go index 0c273bd3..cf463449 100644 --- a/log.go +++ b/log.go @@ -6,14 +6,14 @@ package btcchain import ( "errors" - "github.com/conformal/seelog" + "github.com/conformal/btclog" "io" ) // log is a logger that is initialized with no output filters. This // means the package will not perform any logging by default until the caller // requests it. -var log seelog.LoggerInterface +var log btclog.Logger // The default amount of logging is none. func init() { @@ -23,26 +23,31 @@ func init() { // DisableLog disables all library log output. Logging output is disabled // by default until either UseLogger or SetLogWriter are called. func DisableLog() { - log = seelog.Disabled + log = btclog.Disabled } // UseLogger uses a specified Logger to output package logging info. // This should be used in preference to SetLogWriter if the caller is also -// using seelog. -func UseLogger(logger seelog.LoggerInterface) { +// using btclog. +func UseLogger(logger btclog.Logger) { log = logger } // SetLogWriter uses a specified io.Writer to output package logging info. // This allows a caller to direct package logging output without needing a -// dependency on seelog. If the caller is also using seelog, UseLogger should +// dependency on seelog. If the caller is also using btclog, UseLogger should // be used instead. -func SetLogWriter(w io.Writer) error { +func SetLogWriter(w io.Writer, level string) error { if w == nil { return errors.New("nil writer") } - l, err := seelog.LoggerFromWriterWithMinLevel(w, seelog.TraceLvl) + lvl, ok := btclog.LogLevelFromString(level) + if !ok { + return errors.New("invalid log level") + } + + l, err := btclog.NewLoggerFromWriter(w, lvl) if err != nil { return err } From decc1e8c692f63199e4bdd2d54121d2018187f1c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Dec 2013 04:42:57 -0600 Subject: [PATCH 094/190] Add support for TravisCI. Also add TravisCI build status badge to README.md. --- .travis.yml | 4 ++++ README.md | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..a189282b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: go +go: + - release + - tip diff --git a/README.md b/README.md index b68366cf..a4704e31 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ btcchain ======== +[![Build Status](https://travis-ci.org/conformal/btcchain.png?branch=master)] +(https://travis-ci.org/conformal/btcchain) + Package btcchain implements bitcoin block handling and chain selection rules. The test coverage is currently only around 60%, but will be increasing over time. See `test_coverage.txt` for the gocov coverage report. Alternatively, if From 55331de532b4a4749e242cc434f86e7cd0255166 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 10 Dec 2013 16:10:14 -0600 Subject: [PATCH 095/190] Configure TravisCI to pull pkgs needed for tests. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a189282b..59c603be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,3 +2,4 @@ language: go go: - release - tip +install: go get -d -t -v ./... From 992d11830cdf4455bf2f5074764971e291c4b643 Mon Sep 17 00:00:00 2001 From: Dale Rahn Date: Mon, 18 Nov 2013 16:23:51 -0500 Subject: [PATCH 096/190] Implement a fast path for the Initial Block Download. It is not necessary to do all of the transaction validation on blocks if they have been confirmed to be in the block chain leading up to the final checkpoint in a given blockschain. This algorithm fetches block headers from the peer, then once it has established the full blockchain connection, it requests blocks. Any blocks before the final checkpoint pass true for fastAdd on btcchain operation, which causes it to do less valiation on the block. --- accept.go | 183 ++++++++++++++++++++++------------------- chain.go | 19 +++-- chain_test.go | 4 +- doc.go | 2 +- process.go | 39 ++++----- reorganization_test.go | 2 +- 6 files changed, 138 insertions(+), 111 deletions(-) diff --git a/accept.go b/accept.go index 8908aa8f..f69bf8be 100644 --- a/accept.go +++ b/accept.go @@ -14,7 +14,11 @@ import ( // It performs several validation checks which depend on its position within // the block chain before adding it. The block is expected to have already gone // through ProcessBlock before calling this function with it. -func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { +// The fastAdd argument modifies the behavior of the function by avoiding the +// somewhat expensive operation: BIP34 validation, it also passes the argument +// down to connectBestChain() + +func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error { // Get a block node for the block previous to this one. Will be nil // if this is the genesis block. prevNode, err := b.getPrevNodeFromBlock(block) @@ -31,43 +35,49 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { } block.SetHeight(blockHeight) - // Ensure the difficulty specified in the block header matches the - // calculated difficulty based on the previous block and difficulty - // retarget rules. blockHeader := block.MsgBlock().Header - expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) - if err != nil { - return err - } - blockDifficulty := blockHeader.Bits - if blockDifficulty != expectedDifficulty { - str := "block difficulty of %d is not the expected value of %d" - str = fmt.Sprintf(str, blockDifficulty, expectedDifficulty) - return RuleError(str) - } - // Ensure the timestamp for the block header is after the median time of - // the last several blocks (medianTimeBlocks). - medianTime, err := b.calcPastMedianTime(prevNode) - if err != nil { - log.Errorf("calcPastMedianTime: %v", err) - return err - } - if !blockHeader.Timestamp.After(medianTime) { - str := "block timestamp of %v is not after expected %v" - str = fmt.Sprintf(str, blockHeader.Timestamp, medianTime) - return RuleError(str) - } - - // Ensure all transactions in the block are finalized. - for _, tx := range block.Transactions() { - if !IsFinalizedTransaction(tx, blockHeight, blockHeader.Timestamp) { - str := fmt.Sprintf("block contains unfinalized "+ - "transaction %v", tx.Sha()) + if !fastAdd { + // Ensure the difficulty specified in the block header matches + // the calculated difficulty based on the previous block and + // difficulty + // retarget rules. + expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) + if err != nil { + return err + } + blockDifficulty := blockHeader.Bits + if blockDifficulty != expectedDifficulty { + str := "block difficulty of %d is not the expected value of %d" + str = fmt.Sprintf(str, blockDifficulty, expectedDifficulty) return RuleError(str) } - } + // Ensure the timestamp for the block header is after the + // median time of the last several blocks (medianTimeBlocks). + medianTime, err := b.calcPastMedianTime(prevNode) + if err != nil { + log.Errorf("calcPastMedianTime: %v", err) + return err + } + if !blockHeader.Timestamp.After(medianTime) { + str := "block timestamp of %v is not after expected %v" + str = fmt.Sprintf(str, blockHeader.Timestamp, + medianTime) + return RuleError(str) + } + + // Ensure all transactions in the block are finalized. + for _, tx := range block.Transactions() { + if !IsFinalizedTransaction(tx, blockHeight, + blockHeader.Timestamp) { + str := fmt.Sprintf("block contains "+ + "unfinalized transaction %v", tx.Sha()) + return RuleError(str) + } + } + + } // Ensure chain matches up to predetermined checkpoints. // It's safe to ignore the error on Sha since it's already cached. blockHash, _ := block.Sha() @@ -83,59 +93,66 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { return RuleError(str) } - // Reject version 1 blocks once a majority of the network has upgraded. - // Rules: - // 95% (950 / 1000) for main network - // 75% (75 / 100) for the test network - // This is part of BIP_0034. - if blockHeader.Version == 1 { - minRequired := uint64(950) - numToCheck := uint64(1000) - if b.btcnet == btcwire.TestNet3 || b.btcnet == btcwire.TestNet { - minRequired = 75 - numToCheck = 100 - } - if b.isMajorityVersion(2, prevNode, minRequired, numToCheck) { - str := "new blocks with version %d are no longer valid" - str = fmt.Sprintf(str, blockHeader.Version) - return RuleError(str) - } - } - - // Ensure coinbase starts with serialized block heights for blocks - // whose version is the serializedHeightVersion or newer once a majority - // of the network has upgraded. - // Rules: - // 75% (750 / 1000) for main network - // 51% (51 / 100) for the test network - // This is part of BIP_0034. - if blockHeader.Version >= serializedHeightVersion { - minRequired := uint64(750) - numToCheck := uint64(1000) - if b.btcnet == btcwire.TestNet3 || b.btcnet == btcwire.TestNet { - minRequired = 51 - numToCheck = 100 - } - if b.isMajorityVersion(serializedHeightVersion, prevNode, - minRequired, numToCheck) { - - expectedHeight := int64(0) - if prevNode != nil { - expectedHeight = prevNode.height + 1 + if !fastAdd { + // Reject version 1 blocks once a majority of the network has + // upgraded. + // Rules: + // 95% (950 / 1000) for main network + // 75% (75 / 100) for the test network + // This is part of BIP_0034. + if blockHeader.Version == 1 { + minRequired := uint64(950) + numToCheck := uint64(1000) + if b.btcnet == btcwire.TestNet3 || b.btcnet == + btcwire.TestNet { + minRequired = 75 + numToCheck = 100 } - coinbaseTx := block.Transactions()[0] - err := checkSerializedHeight(coinbaseTx, expectedHeight) - if err != nil { - return err + if b.isMajorityVersion(2, prevNode, minRequired, + numToCheck) { + str := "new blocks with version %d are no longer valid" + str = fmt.Sprintf(str, blockHeader.Version) + return RuleError(str) } } - } - // Prune block nodes which are no longer needed before creating a new - // node. - err = b.pruneBlockNodes() - if err != nil { - return err + // Ensure coinbase starts with serialized block heights for + // blocks whose version is the serializedHeightVersion or + // newer once a majority of the network has upgraded. + // Rules: + // 75% (750 / 1000) for main network + // 51% (51 / 100) for the test network + // This is part of BIP_0034. + if blockHeader.Version >= serializedHeightVersion { + minRequired := uint64(750) + numToCheck := uint64(1000) + if b.btcnet == btcwire.TestNet3 || b.btcnet == + btcwire.TestNet { + minRequired = 51 + numToCheck = 100 + } + if b.isMajorityVersion(serializedHeightVersion, + prevNode, minRequired, numToCheck) { + + expectedHeight := int64(0) + if prevNode != nil { + expectedHeight = prevNode.height + 1 + } + coinbaseTx := block.Transactions()[0] + err := checkSerializedHeight(coinbaseTx, + expectedHeight) + if err != nil { + return err + } + } + } + + // Prune block nodes which are no longer needed before creating + // a new node. + err = b.pruneBlockNodes() + if err != nil { + return err + } } // Create a new block node for the block and add it to the in-memory @@ -150,7 +167,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block) error { // Connect the passed block to the chain while respecting proper chain // selection according to the chain with the most proof of work. This // also handles validation of the transaction scripts. - err = b.connectBestChain(newNode, block) + err = b.connectBestChain(newNode, block, fastAdd) if err != nil { return err } diff --git a/chain.go b/chain.go index 3f078459..44bdf9d2 100644 --- a/chain.go +++ b/chain.go @@ -874,7 +874,10 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // chain. However, it may also be extending (or creating) a side chain (fork) // which may or may not end up becoming the main chain depending on which fork // cumulatively has the most proof of work. -func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) error { +// The fastAdd argument avoids the call to checkConnectBlock which does +// several expensive transaction validation operations. + +func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fastAdd bool) error { // We haven't selected a best chain yet or we are extending the main // (best) chain with a new block. This is the most common case. if b.bestChain == nil || node.parent.hash.IsEqual(b.bestChain.hash) { @@ -883,13 +886,15 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) err // be necessary to get this node to the main chain) without // violating any rules and without actually connecting the // block. - err := b.checkConnectBlock(node, block) - if err != nil { - return err + if !fastAdd { + err := b.checkConnectBlock(node, block) + if err != nil { + return err + } } // Connect the block to the main chain. - err = b.connectBlock(node, block) + err := b.connectBlock(node, block) if err != nil { return err } @@ -901,6 +906,10 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block) err return nil } + if fastAdd { + bsha, _ := block.Sha() + log.Warnf("fastAdd set in the side chain case? %v\n", bsha) + } // We're extending (or creating) a side chain which may or may not // become the main chain, but in either case we need the block stored diff --git a/chain_test.go b/chain_test.go index 8f1d1050..c167e8c6 100644 --- a/chain_test.go +++ b/chain_test.go @@ -47,7 +47,7 @@ func TestHaveBlock(t *testing.T) { btcchain.TstSetCoinbaseMaturity(1) for i := 1; i < len(blocks); i++ { - err = chain.ProcessBlock(blocks[i]) + err = chain.ProcessBlock(blocks[i], false) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return @@ -55,7 +55,7 @@ func TestHaveBlock(t *testing.T) { } // Insert an orphan block. - if err := chain.ProcessBlock(btcutil.NewBlock(&Block100000)); err != nil { + if err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), false); err != nil { t.Errorf("Unable to process block: %v", err) return } diff --git a/doc.go b/doc.go index 00932b3a..f31a71e4 100644 --- a/doc.go +++ b/doc.go @@ -112,7 +112,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - err = chain.ProcessBlock(genesisBlock) + err = chain.ProcessBlock(genesisBlock, false) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/process.go b/process.go index 89ad0726..9cdf7be0 100644 --- a/process.go +++ b/process.go @@ -74,7 +74,7 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { i-- // Potentially accept the block into the block chain. - err := b.maybeAcceptBlock(orphan.block) + err := b.maybeAcceptBlock(orphan.block, false) if err != nil { return err } @@ -92,7 +92,7 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { // the block chain. It includes functionality such as rejecting duplicate // blocks, ensuring blocks follow all rules, orphan handling, and insertion into // the block chain along with best chain selection and reorganization. -func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { +func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { blockHash, err := block.Sha() if err != nil { return err @@ -138,22 +138,23 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { blockHeader.Timestamp, checkpointTime) return RuleError(str) } - - // Even though the checks prior to now have already ensured the - // proof of work exceeds the claimed amount, the claimed amount - // is a field in the block header which could be forged. This - // check ensures the proof of work is at least the minimum - // expected based on elapsed time since the last checkpoint and - // maximum adjustment allowed by the retarget rules. - duration := blockHeader.Timestamp.Sub(checkpointTime) - requiredTarget := CompactToBig(b.calcEasiestDifficulty( - checkpointHeader.Bits, duration)) - currentTarget := CompactToBig(blockHeader.Bits) - if currentTarget.Cmp(requiredTarget) > 0 { - str := fmt.Sprintf("block target difficulty of %064x "+ - "is too low when compared to the previous "+ - "checkpoint", currentTarget) - return RuleError(str) + if !fastAdd { + // Even though the checks prior to now have already ensured the + // proof of work exceeds the claimed amount, the claimed amount + // is a field in the block header which could be forged. This + // check ensures the proof of work is at least the minimum + // expected based on elapsed time since the last checkpoint and + // maximum adjustment allowed by the retarget rules. + duration := blockHeader.Timestamp.Sub(checkpointTime) + requiredTarget := CompactToBig(b.calcEasiestDifficulty( + checkpointHeader.Bits, duration)) + currentTarget := CompactToBig(blockHeader.Bits) + if currentTarget.Cmp(requiredTarget) > 0 { + str := fmt.Sprintf("block target difficulty of %064x "+ + "is too low when compared to the previous "+ + "checkpoint", currentTarget) + return RuleError(str) + } } } @@ -172,7 +173,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block) error { // The block has passed all context independent checks and appears sane // enough to potentially accept it into the block chain. - err = b.maybeAcceptBlock(block) + err = b.maybeAcceptBlock(block, fastAdd) if err != nil { return err } diff --git a/reorganization_test.go b/reorganization_test.go index dbb902bb..df67d435 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -58,7 +58,7 @@ func TestReorganization(t *testing.T) { btcchain.TstSetCoinbaseMaturity(1) for i := 1; i < len(blocks); i++ { - err = chain.ProcessBlock(blocks[i]) + err = chain.ProcessBlock(blocks[i], false) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return From 18ac5c848a7e3f690719f9afa26b52b886270ced Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 8 Jan 2014 23:52:54 -0600 Subject: [PATCH 097/190] Add 2014 to copyright dates. --- LICENSE | 2 +- accept.go | 2 +- blocklocator.go | 2 +- chain.go | 2 +- chain_test.go | 2 +- checkpoints.go | 2 +- common_test.go | 2 +- difficulty.go | 2 +- doc.go | 2 +- internal_test.go | 2 +- log.go | 2 +- merkle.go | 2 +- merkle_test.go | 2 +- notifications.go | 2 +- params.go | 2 +- process.go | 2 +- reorganization_test.go | 2 +- scriptval.go | 2 +- timesorter.go | 2 +- timesorter_test.go | 2 +- txlookup.go | 2 +- validate.go | 2 +- validate_test.go | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/LICENSE b/LICENSE index 0d760cbb..992dd50d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013 Conformal Systems LLC. +Copyright (c) 2013-2014 Conformal Systems LLC. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/accept.go b/accept.go index f69bf8be..764437ac 100644 --- a/accept.go +++ b/accept.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/blocklocator.go b/blocklocator.go index 0e783b4e..5a1dd150 100644 --- a/blocklocator.go +++ b/blocklocator.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/chain.go b/chain.go index 44bdf9d2..f47726c4 100644 --- a/chain.go +++ b/chain.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/chain_test.go b/chain_test.go index c167e8c6..37659a02 100644 --- a/chain_test.go +++ b/chain_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/checkpoints.go b/checkpoints.go index 5edfc816..47951dc1 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/common_test.go b/common_test.go index 22751ca6..c95f88bd 100644 --- a/common_test.go +++ b/common_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/difficulty.go b/difficulty.go index 013989d4..62f2d2eb 100644 --- a/difficulty.go +++ b/difficulty.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/doc.go b/doc.go index f31a71e4..4138509e 100644 --- a/doc.go +++ b/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/internal_test.go b/internal_test.go index f364167c..840c0c5e 100644 --- a/internal_test.go +++ b/internal_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/log.go b/log.go index cf463449..22a60ebd 100644 --- a/log.go +++ b/log.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/merkle.go b/merkle.go index b0e2f1d7..fdee30e1 100644 --- a/merkle.go +++ b/merkle.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/merkle_test.go b/merkle_test.go index 18ff1d20..6fbae40a 100644 --- a/merkle_test.go +++ b/merkle_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/notifications.go b/notifications.go index a4ba98b1..813ffa35 100644 --- a/notifications.go +++ b/notifications.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/params.go b/params.go index 685bad3e..fa468698 100644 --- a/params.go +++ b/params.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/process.go b/process.go index 9cdf7be0..ced8042d 100644 --- a/process.go +++ b/process.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/reorganization_test.go b/reorganization_test.go index df67d435..df407725 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/scriptval.go b/scriptval.go index 3ed201fe..26360eb2 100644 --- a/scriptval.go +++ b/scriptval.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/timesorter.go b/timesorter.go index 6cb8448d..744726d7 100644 --- a/timesorter.go +++ b/timesorter.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/timesorter_test.go b/timesorter_test.go index 397feae0..bd4b2fe0 100644 --- a/timesorter_test.go +++ b/timesorter_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/txlookup.go b/txlookup.go index 3d5c1df2..b2773414 100644 --- a/txlookup.go +++ b/txlookup.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/validate.go b/validate.go index bc61aaf8..8ea9f519 100644 --- a/validate.go +++ b/validate.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. diff --git a/validate_test.go b/validate_test.go index a04148d5..b1b09073 100644 --- a/validate_test.go +++ b/validate_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013 Conformal Systems LLC. +// Copyright (c) 2013-2014 Conformal Systems LLC. // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. From 28f485a1d1163b378972708cd478f24e64384b3d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 9 Jan 2014 11:36:25 -0600 Subject: [PATCH 098/190] Fix a couple of style nits. --- accept.go | 5 ++--- chain.go | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/accept.go b/accept.go index 764437ac..2e51279c 100644 --- a/accept.go +++ b/accept.go @@ -17,7 +17,6 @@ import ( // The fastAdd argument modifies the behavior of the function by avoiding the // somewhat expensive operation: BIP34 validation, it also passes the argument // down to connectBestChain() - func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error { // Get a block node for the block previous to this one. Will be nil // if this is the genesis block. @@ -40,8 +39,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error if !fastAdd { // Ensure the difficulty specified in the block header matches // the calculated difficulty based on the previous block and - // difficulty - // retarget rules. + // difficulty retarget rules. expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) if err != nil { return err @@ -78,6 +76,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error } } + // Ensure chain matches up to predetermined checkpoints. // It's safe to ignore the error on Sha since it's already cached. blockHash, _ := block.Sha() diff --git a/chain.go b/chain.go index f47726c4..cf6dc532 100644 --- a/chain.go +++ b/chain.go @@ -876,7 +876,6 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // cumulatively has the most proof of work. // The fastAdd argument avoids the call to checkConnectBlock which does // several expensive transaction validation operations. - func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fastAdd bool) error { // We haven't selected a best chain yet or we are extending the main // (best) chain with a new block. This is the most common case. From 84f6089bc911ada900537040b49eb7a3684ec2a8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 16 Jan 2014 12:48:37 -0600 Subject: [PATCH 099/190] Rework and improve async script validation logic. The previous script validation logic entailed starting up a hard-coded number of goroutines to process the transaction scripts in parallel. In particular, one goroutine (up to 8 max) was started per transaction in a block and another one was started for each input script pair in the each transaction. This resulted in 64 goroutines simultaneously running scripts and verifying cryptographic signatures. This could easily lead to the overall system feeling sluggish. Further the previous design could also result in bursty behavior since the number of inputs to a transaction as well as its complexity can vary widely between transactions. For example, starting 2 goroutines (one to process the transaction and one for actual script pair validation) to verify a transaction with a single input was not desirable. Finally, the previous design validated all transactions and inputs regardless of a failure in one of the other scripts. This really didn't have a big impact since it's quite rare that blocks with invalid verifications are being processed, but it was a potential way DoS vector. This commit changes the logic in a few ways to improve things: - The max number of validation goroutines is now based on the number of cores in the system - All transaction inputs from all transactions in the block are collated into a single list which is fed through the aforementioned validation goroutines - The validation CPU usage is much more consistent due to the collation of inputs - A validation error in any goroutine immediately stops validation of all remaining inputs - The errors have been improved to include context about what tx script pair failed as opposed to showing the information as a warning This closes conformal/btcd#59. --- scriptval.go | 300 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 193 insertions(+), 107 deletions(-) diff --git a/scriptval.go b/scriptval.go index 26360eb2..3e0e7598 100644 --- a/scriptval.go +++ b/scriptval.go @@ -10,108 +10,199 @@ import ( "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" + "runtime" ) -// txValidate is used to track results of validating scripts for each -// transaction input index. -type txValidate struct { - txIndex int - err error +// txValidateItem holds a transaction along with which input to validate. +type txValidateItem struct { + txInIndex int + txIn *btcwire.TxIn + tx *btcutil.Tx } -// validateTxIn validates a the script pair for the passed spending transaction -// (along with the specific input index) and origin transaction (with the -// specific output index). -func validateTxIn(txInIdx int, txin *btcwire.TxIn, tx *btcutil.Tx, originTx *btcutil.Tx, flags btcscript.ScriptFlags) error { - // If the input transaction has no previous input, there is nothing - // to check. - originTxIdx := txin.PreviousOutpoint.Index - if originTxIdx == math.MaxUint32 { +// txValidator provides a type which asynchronously validates transaction +// inputs. It provides several channels for communication and a processing +// function that is intended to be in run multiple goroutines. +type txValidator struct { + validateChan chan *txValidateItem + quitChan chan bool + resultChan chan error + txStore TxStore + flags btcscript.ScriptFlags +} + +// sendResult sends the result of a script pair validation on the internal +// result channel while respecting the quit channel. The allows orderly +// shutdown when the validation process is aborted early due to a validation +// error in one of the other goroutines. +func (v *txValidator) sendResult(result error) { + select { + case v.resultChan <- result: + case <-v.quitChan: + } +} + +// validateHandler consumes items to validate from the internal validate channel +// and returns the result of the validation on the internal result channel. It +// must be run as a goroutine. +func (v *txValidator) validateHandler() { +out: + for { + select { + case txVI := <-v.validateChan: + // Ensure the referenced input transaction is available. + //txIn := txVI.tx.MsgTx().TxIn[txVI.txInIdx] + txIn := txVI.txIn + txInHash := &txIn.PreviousOutpoint.Hash + originTx, exists := v.txStore[*txInHash] + if !exists || originTx.Err != nil || originTx.Tx == nil { + err := fmt.Errorf("unable to find input "+ + "transaction %v referenced from "+ + "transaction %v", txInHash, + txVI.tx.Sha()) + v.sendResult(err) + break out + } + originMsgTx := originTx.Tx.MsgTx() + + // Ensure the output index in the referenced transaction + // is available. + originTxIndex := txIn.PreviousOutpoint.Index + if originTxIndex >= uint32(len(originMsgTx.TxOut)) { + err := fmt.Errorf("out of bounds "+ + "input index %d in transaction %v "+ + "referenced from transaction %v", + originTxIndex, txInHash, txVI.tx.Sha()) + v.sendResult(err) + break out + } + + // Create a new script engine for the script pair. + sigScript := txIn.SignatureScript + pkScript := originMsgTx.TxOut[originTxIndex].PkScript + engine, err := btcscript.NewScript(sigScript, pkScript, + txVI.txInIndex, txVI.tx.MsgTx(), v.flags) + if err != nil { + v.sendResult(err) + break out + } + + // Execute the script pair. + if err := engine.Execute(); err != nil { + err := fmt.Errorf("validate of input "+ + "%d failed: %v", txVI.txInIndex, err) + v.sendResult(err) + break out + } + + // Validation succeeded. + v.sendResult(nil) + + case <-v.quitChan: + break out + } + } +} + +// Validate validates the scripts for all of the passed transaction inputs using +// multiple goroutines. +func (v *txValidator) Validate(items []*txValidateItem) error { + if len(items) == 0 { return nil } - if originTxIdx >= uint32(len(originTx.MsgTx().TxOut)) { - originTxSha := &txin.PreviousOutpoint.Hash - log.Warnf("unable to locate source tx %v spending tx %v", - originTxSha, tx.Sha()) - return fmt.Errorf("invalid index %x", originTxIdx) + // Limit the number of goroutines to do script validation based on the + // number of processor cores. This help ensure the system stays + // reasonably responsive under heavy load. + maxGoRoutines := runtime.NumCPU() * 3 + if maxGoRoutines <= 0 { + maxGoRoutines = 1 + } + if maxGoRoutines > len(items) { + maxGoRoutines = len(items) } - sigScript := txin.SignatureScript - pkScript := originTx.MsgTx().TxOut[originTxIdx].PkScript - engine, err := btcscript.NewScript(sigScript, pkScript, txInIdx, - tx.MsgTx(), flags) - if err != nil { - return err + // Start up validation handlers that are used to asynchronously + // validate each transaction input. + for i := 0; i < maxGoRoutines; i++ { + go v.validateHandler() } - err = engine.Execute() - if err != nil { - log.Warnf("validate of input %v failed: %v", txInIdx, err) - return err + // Validate each of the inputs. The quit channel is closed when any + // errors occur so all processing goroutines exit regardless of which + // input had the validation error. + numInputs := len(items) + currentItem := 0 + processedItems := 0 + for processedItems < numInputs { + // Only send items while there are still items that need to + // be processed. The select statement will never select a nil + // channel. + var validateChan chan *txValidateItem + var item *txValidateItem + if currentItem < numInputs { + validateChan = v.validateChan + item = items[currentItem] + } + + select { + case validateChan <- item: + currentItem++ + + case err := <-v.resultChan: + processedItems++ + if err != nil { + close(v.quitChan) + return err + } + } } + close(v.quitChan) return nil } +// newTxValidator returns a new instance of txValidator to be used for +// validating transaction scripts asynchronously. +func newTxValidator(txStore TxStore, flags btcscript.ScriptFlags) *txValidator { + return &txValidator{ + validateChan: make(chan *txValidateItem), + quitChan: make(chan bool), + resultChan: make(chan error), + txStore: txStore, + flags: flags, + } +} + // ValidateTransactionScripts validates the scripts for the passed transaction // using multiple goroutines. -func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript.ScriptFlags) (err error) { - c := make(chan txValidate) - job := tx.MsgTx().TxIn - resultErrors := make([]error, len(job)) - - var currentItem int - var completedItems int - - processFunc := func(txInIdx int) { - log.Tracef("validating tx %v input %v len %v", - tx.Sha(), txInIdx, len(job)) - txin := job[txInIdx] - originTxSha := &txin.PreviousOutpoint.Hash - origintxidx := txin.PreviousOutpoint.Index - - var originTx *btcutil.Tx - if origintxidx != math.MaxUint32 { - txInfo, ok := txStore[*originTxSha] - if !ok { - //wtf? - fmt.Printf("obj not found in txStore %v", - originTxSha) - } - originTx = txInfo.Tx +func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript.ScriptFlags) error { + // Collect all of the transaction inputs and required information for + // validation. + txIns := tx.MsgTx().TxIn + txValItems := make([]*txValidateItem, 0, len(txIns)) + for txInIdx, txIn := range txIns { + // Skip coinbases. + if txIn.PreviousOutpoint.Index == math.MaxUint32 { + continue } - err := validateTxIn(txInIdx, txin, tx, originTx, flags) - r := txValidate{txInIdx, err} - c <- r - } - for currentItem = 0; currentItem < len(job) && currentItem < 16; currentItem++ { - go processFunc(currentItem) - } - for completedItems < len(job) { - select { - case result := <-c: - completedItems++ - resultErrors[result.txIndex] = result.err - // would be nice to determine if we could stop - // on early errors here instead of running more. - if err == nil { - err = result.err - } - if currentItem < len(job) { - go processFunc(currentItem) - currentItem++ - } + txVI := &txValidateItem{ + txInIndex: txInIdx, + txIn: txIn, + tx: tx, } + txValItems = append(txValItems, txVI) } - for i := 0; i < len(job); i++ { - if resultErrors[i] != nil { - log.Warnf("tx %v failed input %v, err %v", tx.Sha(), i, - resultErrors[i]) - } + + // Validate all of the inputs. + validator := newTxValidator(txStore, flags) + if err := validator.Validate(txValItems); err != nil { + return err } - return + + return nil + } // checkBlockScripts executes and validates the scripts for all transactions in @@ -124,38 +215,33 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { flags |= btcscript.ScriptBip16 } - txList := block.Transactions() - c := make(chan txValidate) - resultErrors := make([]error, len(txList)) - - var currentItem int - var completedItems int - processFunc := func(txIdx int) { - err := ValidateTransactionScripts(txList[txIdx], txStore, flags) - r := txValidate{txIdx, err} - c <- r + // Collect all of the transaction inputs and required information for + // validation for all transactions in the block into a single slice. + numInputs := 0 + for _, tx := range block.Transactions() { + numInputs += len(tx.MsgTx().TxIn) } - for currentItem = 0; currentItem < len(txList) && currentItem < 8; currentItem++ { - go processFunc(currentItem) - } - for completedItems < len(txList) { - select { - case result := <-c: - completedItems++ - resultErrors[result.txIndex] = result.err - // would be nice to determine if we could stop - // on early errors here instead of running more. - - if currentItem < len(txList) { - go processFunc(currentItem) - currentItem++ + txValItems := make([]*txValidateItem, 0, numInputs) + for _, tx := range block.Transactions() { + for txInIdx, txIn := range tx.MsgTx().TxIn { + // Skip coinbases. + if txIn.PreviousOutpoint.Index == math.MaxUint32 { + continue } + + txVI := &txValidateItem{ + txInIndex: txInIdx, + txIn: txIn, + tx: tx, + } + txValItems = append(txValItems, txVI) } } - for i := 0; i < len(txList); i++ { - if resultErrors[i] != nil { - return resultErrors[i] - } + + // Validate all of the inputs. + validator := newTxValidator(txStore, flags) + if err := validator.Validate(txValItems); err != nil { + return err } return nil From 03394d6309531e18282de0c53277f9548d6760c5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 17 Jan 2014 00:48:32 -0600 Subject: [PATCH 100/190] Bring README.md and doc.go examples up to date. Since sqlite is now deprecated, update the examples to use levelb. Also, add false to the ProcessBlock calls for the fastAdd parameter. --- README.md | 6 +++--- doc.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a4704e31..42e67b80 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ intentionally causes an error by attempting to process a duplicate block. "fmt" "github.com/conformal/btcchain" "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/sqlite3" + _ "github.com/conformal/btcdb/ldb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "os" @@ -97,7 +97,7 @@ intentionally causes an error by attempting to process a duplicate block. // database. dbName := "example.db" _ = os.Remove(dbName) - db, err := btcdb.CreateDB("sqlite", dbName) + db, err := btcdb.CreateDB("leveldb", dbName) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return @@ -122,7 +122,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - err = chain.ProcessBlock(genesisBlock) + err = chain.ProcessBlock(genesisBlock, false) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/doc.go b/doc.go index 4138509e..33a27b80 100644 --- a/doc.go +++ b/doc.go @@ -72,7 +72,7 @@ intentionally causes an error by attempting to process a duplicate block. "fmt" "github.com/conformal/btcchain" "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/sqlite3" + _ "github.com/conformal/btcdb/ldb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "os" @@ -87,7 +87,7 @@ intentionally causes an error by attempting to process a duplicate block. // database. dbName := "example.db" _ = os.Remove(dbName) - db, err := btcdb.CreateDB("sqlite", dbName) + db, err := btcdb.CreateDB("leveldb", dbName) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return From 4c13410e62a396874b3b64eeb0c60c3e41754dfb Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 17 Jan 2014 00:51:28 -0600 Subject: [PATCH 101/190] Update README.md TODO. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 42e67b80..f80ed381 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,6 @@ intentionally causes an error by attempting to process a duplicate block. ## TODO - Increase test coverage -- Expose some APIs for block verification (without actually inserting it) ## GPG Verification Key From 1b54badde1b8ef67a3963230ec70a77e7a2c34bc Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 17 Jan 2014 00:07:02 -0600 Subject: [PATCH 102/190] Improve efficiency of checkpoint tracking. Previously the code performed a database query for every checkpoint (going backwards) to find the latest known checkpoint on every block. This was particularly noticabled near the beginning of the block chain when there are still several checkpoints that haven't been reached yet. This commit changes the logic to cache the latest known checkpoint while keeping track of when it needs to be updated once a new later known checkpoint has been reached. While here, also add a log message when a checkpoint has been reached and verified. --- chain.go | 30 +++++++------- checkpoints.go | 106 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 110 insertions(+), 26 deletions(-) diff --git a/chain.go b/chain.go index cf6dc532..52a005ce 100644 --- a/chain.go +++ b/chain.go @@ -142,20 +142,22 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { // follow all rules, orphan handling, checkpoint handling, and best chain // selection with reorganization. type BlockChain struct { - db btcdb.Db - btcnet btcwire.BitcoinNet - notifications NotificationCallback - root *blockNode - bestChain *blockNode - index map[btcwire.ShaHash]*blockNode - depNodes map[btcwire.ShaHash][]*blockNode - orphans map[btcwire.ShaHash]*orphanBlock - prevOrphans map[btcwire.ShaHash][]*orphanBlock - oldestOrphan *orphanBlock - orphanLock sync.RWMutex - blockCache map[btcwire.ShaHash]*btcutil.Block - noVerify bool - noCheckpoints bool + db btcdb.Db + btcnet btcwire.BitcoinNet + notifications NotificationCallback + root *blockNode + bestChain *blockNode + index map[btcwire.ShaHash]*blockNode + depNodes map[btcwire.ShaHash][]*blockNode + orphans map[btcwire.ShaHash]*orphanBlock + prevOrphans map[btcwire.ShaHash][]*orphanBlock + oldestOrphan *orphanBlock + orphanLock sync.RWMutex + blockCache map[btcwire.ShaHash]*btcutil.Block + noVerify bool + noCheckpoints bool + nextCheckpoint *Checkpoint + checkpointBlock *btcutil.Block } // DisableVerify provides a mechanism to disable transaction script validation diff --git a/checkpoints.go b/checkpoints.go index 47951dc1..f6ff4577 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -125,10 +125,16 @@ func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool return true } - return checkpoint.Hash.IsEqual(hash) + if !checkpoint.Hash.IsEqual(hash) { + return false + } + + log.Infof("Verfied checkpoint at height %d/block %s", checkpoint.Height, + checkpoint.Hash) + return true } -// findClosestKnownCheckpoint finds the most recent checkpoint that is already +// findLatestKnownCheckpoint finds the most recent checkpoint that is already // available in the downloaded portion of the block chain and returns the // associated block. It returns nil if a checkpoint can't be found (this should // really only happen for blocks before the first checkpoint). @@ -137,20 +143,96 @@ func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) { return nil, nil } - // Loop backwards through the available checkpoints to find one that - // we already have. + // No checkpoints. checkpoints := b.checkpointData().checkpoints - clen := len(checkpoints) - for i := clen - 1; i >= 0; i-- { - if b.db.ExistsSha(checkpoints[i].Hash) { - block, err := b.db.FetchBlockBySha(checkpoints[i].Hash) - if err != nil { - return nil, err + numCheckpoints := len(checkpoints) + if numCheckpoints == 0 { + return nil, nil + } + + // Perform the initial search to find and cache the latest known + // checkpoint if the best chain is not known yet or we haven't already + // previously searched. + if b.bestChain == nil || (b.checkpointBlock == nil && b.nextCheckpoint == nil) { + // Loop backwards through the available checkpoints to find one + // that we already have. + checkpointIndex := -1 + for i := numCheckpoints - 1; i >= 0; i-- { + if b.db.ExistsSha(checkpoints[i].Hash) { + checkpointIndex = i + break } - return block, nil + } + + // No known latest checkpoint. This will only happen on blocks + // before the first known checkpoint. So, set the next expected + // checkpoint to the first checkpoint and return the fact there + // is no latest known checkpoint block. + if checkpointIndex == -1 { + b.nextCheckpoint = &checkpoints[0] + return nil, nil + } + + // Cache the latest known checkpoint block for future lookups. + checkpoint := checkpoints[checkpointIndex] + block, err := b.db.FetchBlockBySha(checkpoint.Hash) + if err != nil { + return nil, err + } + b.checkpointBlock = block + + // Set the next expected checkpoint block accordingly. + b.nextCheckpoint = nil + if checkpointIndex < numCheckpoints-1 { + b.nextCheckpoint = &checkpoints[checkpointIndex+1] + } + + return block, nil + } + + // At this point we've already searched for the latest known checkpoint, + // so when there is no next checkpoint, the current checkpoint lockin + // will always be the latest known checkpoint. + if b.nextCheckpoint == nil { + return b.checkpointBlock, nil + } + + // When there is a next checkpoint and the height of the current best + // chain does not exceed it, the current checkpoint lockin is still + // the latest known checkpoint. + if b.bestChain.height < b.nextCheckpoint.Height { + return b.checkpointBlock, nil + } + + // We've reached or exceeded the next checkpoint height. Note that + // once a checkpoint lockin has been reached, forks are prevented from + // any blocks before the checkpoint, so we don't have to worry about the + // checkpoint going away out from under us due to a chain reorganize. + + // Cache the latest known checkpoint block for future lookups. Note + // that if this lookup fails something is very wrong since the chain + // has already passed the checkpoint which was verified as accurate + // before inserting it. + block, err := b.db.FetchBlockBySha(b.nextCheckpoint.Hash) + if err != nil { + return nil, err + } + b.checkpointBlock = block + + // Set the next expected checkpoint. + checkpointIndex := -1 + for i := numCheckpoints - 1; i >= 0; i-- { + if checkpoints[i].Hash.IsEqual(b.nextCheckpoint.Hash) { + checkpointIndex = i + break } } - return nil, nil + b.nextCheckpoint = nil + if checkpointIndex != -1 && checkpointIndex < numCheckpoints-1 { + b.nextCheckpoint = &checkpoints[checkpointIndex+1] + } + + return b.checkpointBlock, nil } // isNonstandardTransaction determines whether a transaction contains any From be277b7230125aabfd87f8db4e5dd93f4fd03d9d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 19 Jan 2014 12:32:30 -0600 Subject: [PATCH 103/190] Update for recent btcwire API changes. --- validate_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/validate_test.go b/validate_test.go index b1b09073..a16786cb 100644 --- a/validate_test.go +++ b/validate_test.go @@ -92,7 +92,6 @@ var Block100000 = btcwire.MsgBlock{ Timestamp: time.Unix(1293623863, 0), // 2010-12-29 11:57:43 +0000 UTC Bits: 0x1b04864c, // 453281356 Nonce: 0x10572b0f, // 274148111 - TxnCount: 4, }, Transactions: []*btcwire.MsgTx{ &btcwire.MsgTx{ From 1626994433f20b65d6f8da7603a0f70ffb15c2aa Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 19 Jan 2014 12:38:31 -0600 Subject: [PATCH 104/190] Avoid copying block headers in convenience locals. This commit modifies local variables that are used for more convenient access to a block's header to use pointers. This avoids copying the header multiple times. --- accept.go | 3 +-- process.go | 4 ++-- validate.go | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/accept.go b/accept.go index 2e51279c..a0609ae4 100644 --- a/accept.go +++ b/accept.go @@ -34,8 +34,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error } block.SetHeight(blockHeight) - blockHeader := block.MsgBlock().Header - + blockHeader := &block.MsgBlock().Header if !fastAdd { // Ensure the difficulty specified in the block header matches // the calculated difficulty based on the previous block and diff --git a/process.go b/process.go index ced8042d..42d08181 100644 --- a/process.go +++ b/process.go @@ -123,14 +123,14 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { // easy to mine, but otherwise bogus, blocks that could be used to eat // memory, and ensuring expected (versus claimed) proof of work // requirements since the last checkpoint are met. - blockHeader := block.MsgBlock().Header + blockHeader := &block.MsgBlock().Header checkpointBlock, err := b.findLatestKnownCheckpoint() if err != nil { return err } if checkpointBlock != nil { // Ensure the block timestamp is after the checkpoint timestamp. - checkpointHeader := checkpointBlock.MsgBlock().Header + checkpointHeader := &checkpointBlock.MsgBlock().Header checkpointTime := checkpointHeader.Timestamp if blockHeader.Timestamp.Before(checkpointTime) { str := fmt.Sprintf("block %v has timestamp %v before "+ diff --git a/validate.go b/validate.go index 8ea9f519..ecee9208 100644 --- a/validate.go +++ b/validate.go @@ -268,8 +268,7 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // target difficulty as claimed. func checkProofOfWork(block *btcutil.Block, powLimit *big.Int) error { // The target difficulty must be larger than zero. - header := block.MsgBlock().Header - target := CompactToBig(header.Bits) + target := CompactToBig(block.MsgBlock().Header.Bits) if target.Sign() <= 0 { str := fmt.Sprintf("block target difficulty of %064x is too low", target) From 583406ee5115c3123405b1e68ea275039e6bf15f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 19 Jan 2014 13:00:12 -0600 Subject: [PATCH 105/190] Use block headers to generate node index. This commit changes the node index creation to use block headers instead of full blocks. This speeds up the initial node index generation since it doesn't require loading a bunch of full blocks at startup. --- accept.go | 2 +- chain.go | 30 ++++++++++++++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/accept.go b/accept.go index a0609ae4..318c251c 100644 --- a/accept.go +++ b/accept.go @@ -155,7 +155,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error // Create a new block node for the block and add it to the in-memory // block chain (could be either a side chain or the main chain). - newNode := newBlockNode(block) + newNode := newBlockNode(blockHeader, blockHash, blockHeight) if prevNode != nil { newNode.parent = prevNode newNode.height = blockHeight diff --git a/chain.go b/chain.go index 52a005ce..9727b8b4 100644 --- a/chain.go +++ b/chain.go @@ -73,22 +73,16 @@ type blockNode struct { timestamp time.Time } -// newBlockNode returns a new block node for the given block. It is completely -// disconnected from the chain and the workSum value is just the work for the -// passed block. The work sum is updated accordingly when the node is inserted -// into a chain. -func newBlockNode(block *btcutil.Block) *blockNode { - // Get the block sha. It's ok to ignore the error here since - // sha has already been called and an error there would have caused - // an exit before this function is called. - blockSha, _ := block.Sha() - - blockHeader := block.MsgBlock().Header +// newBlockNode returns a new block node for the given block header. It is +// completely disconnected from the chain and the workSum value is just the work +// for the passed block. The work sum is updated accordingly when the node is +// inserted into a chain. +func newBlockNode(blockHeader *btcwire.BlockHeader, blockSha *btcwire.ShaHash, height int64) *blockNode { node := blockNode{ hash: blockSha, parentHash: &blockHeader.PrevBlock, workSum: calcWork(blockHeader.Bits), - height: block.Height(), + height: height, version: blockHeader.Version, bits: blockHeader.Bits, timestamp: blockHeader.Timestamp, @@ -395,14 +389,18 @@ func (b *BlockChain) GenerateInitialIndex() error { // It is used mainly to dynamically load previous blocks from database as they // are needed to avoid needing to put the entire block chain in memory. func (b *BlockChain) loadBlockNode(hash *btcwire.ShaHash) (*blockNode, error) { - // Load the block from the db. - block, err := b.db.FetchBlockBySha(hash) + // Load the block header and height from the db. + blockHeader, err := b.db.FetchBlockHeaderBySha(hash) + if err != nil { + return nil, err + } + blockHeight, err := b.db.FetchBlockHeightBySha(hash) if err != nil { return nil, err } // Create the new block node for the block and set the work. - node := newBlockNode(block) + node := newBlockNode(blockHeader, hash, blockHeight) node.inMainChain = true // Add the node to the chain. @@ -414,7 +412,7 @@ func (b *BlockChain) loadBlockNode(hash *btcwire.ShaHash) (*blockNode, error) { // therefore is an error to insert into the chain // 4) Neither 1 or 2 is true, but this is the first node being added // to the tree, so it's the root. - prevHash := &block.MsgBlock().Header.PrevBlock + prevHash := &blockHeader.PrevBlock if parentNode, ok := b.index[*prevHash]; ok { // Case 1 -- This node is a child of an existing block node. // Update the node's work sum with the sum of the parent node's From e2dba2a07490cf10a317c96cdaa58d1f3ed2bb88 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 19 Jan 2014 20:13:53 -0600 Subject: [PATCH 106/190] Update for recent btcdb API changes. --- common_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common_test.go b/common_test.go index c95f88bd..d84d9f93 100644 --- a/common_test.go +++ b/common_test.go @@ -58,7 +58,7 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { var db btcdb.Db var teardown func() if testDbType == "memdb" { - ndb, err := btcdb.CreateDB(testDbType, "") + ndb, err := btcdb.CreateDB(testDbType) if err != nil { return nil, nil, fmt.Errorf("error creating db: %v", err) } From d0d74b4e3e7c8826f8c7003007938ef283d4eaa7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 20 Jan 2014 11:01:39 -0600 Subject: [PATCH 107/190] Add checkpoint at block height 279000. --- checkpoints.go | 1 + 1 file changed, 1 insertion(+) diff --git a/checkpoints.go b/checkpoints.go index f6ff4577..c4ef014e 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -58,6 +58,7 @@ var checkpointDataMainNet = checkpointData{ {225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, {250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, {267300, newShaHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, + {279000, newShaHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, }, checkpointsByHeight: nil, // Automatically generated in init. } From ad65bee735e7a4f0695ae3ee98586eb9f1fced41 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 22 Jan 2014 13:17:41 -0500 Subject: [PATCH 108/190] fix typo --- checkpoints.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checkpoints.go b/checkpoints.go index c4ef014e..384b9160 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -130,7 +130,7 @@ func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool return false } - log.Infof("Verfied checkpoint at height %d/block %s", checkpoint.Height, + log.Infof("Verified checkpoint at height %d/block %s", checkpoint.Height, checkpoint.Hash) return true } From 7390a62a8df9b9b03a46e24b66f3cf228edea322 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 28 Jan 2014 13:34:42 -0600 Subject: [PATCH 109/190] Correct internal node children on reorg. Previously the code was only adding a new block node as a child in the inernal node index for the cases it extended the main chain or a side chain and not for a node which caused a reorg. This resulted in the block node pruning code not clearing the parent link of reorged nodes which ultimately led to a sanity check error accordingly. This commit resolves the issue by ensuring new block nodes are added as children of their respective parents in all cases. Closes #4. --- chain.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/chain.go b/chain.go index 9727b8b4..bf4e75a2 100644 --- a/chain.go +++ b/chain.go @@ -825,7 +825,6 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error if err != nil { return err } - } // Disconnect blocks from the main chain. @@ -918,13 +917,13 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fas b.blockCache[*node.hash] = block b.index[*node.hash] = node + // Connect the parent node to this node. + node.inMainChain = false + node.parent.children = append(node.parent.children, node) + // We're extending (or creating) a side chain, but the cumulative // work for this new side chain is not enough to make it the new chain. if node.workSum.Cmp(b.bestChain.workSum) <= 0 { - // Connect the parent node to this node. - node.inMainChain = false - node.parent.children = append(node.parent.children, node) - // Find the fork point. fork := node for ; fork.parent != nil; fork = fork.parent { From 6a9997583ac655cfb2096afc799463036444b1fd Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 28 Jan 2014 13:45:49 -0600 Subject: [PATCH 110/190] Prune the block node index in fast add mode too. The recent addition of the fast add path to support headers first was not running the block node index pruning code which removes unneeded block nodes from memory. This resulted in higher memory usage than needed in fast add mode. --- accept.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/accept.go b/accept.go index 318c251c..65ac2819 100644 --- a/accept.go +++ b/accept.go @@ -144,13 +144,13 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error } } } + } - // Prune block nodes which are no longer needed before creating - // a new node. - err = b.pruneBlockNodes() - if err != nil { - return err - } + // Prune block nodes which are no longer needed before creating + // a new node. + err = b.pruneBlockNodes() + if err != nil { + return err } // Create a new block node for the block and add it to the in-memory From be2e4c5860bdbd2db42c473bb6c31c1954d14022 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 31 Jan 2014 19:51:24 -0600 Subject: [PATCH 111/190] Add new function to get the checkpoints. Previously there was only a function to get the latest checkpoint. This commit exposes a new function named Checkpoints which returns a slice of checkpoints ordered by height for the active network or nil when checkpoints are disabled. --- checkpoints.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/checkpoints.go b/checkpoints.go index 384b9160..c52218cf 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -100,6 +100,17 @@ func (b *BlockChain) checkpointData() *checkpointData { return nil } +// Checkpoints returns a slice of checkpoints (regardless of whether they are +// already known). When checkpoints are disabled or there are no checkpoints +// for the active network, it will return nil. +func (b *BlockChain) Checkpoints() []Checkpoint { + if b.noCheckpoints || b.checkpointData() == nil { + return nil + } + + return b.checkpointData().checkpoints +} + // LatestCheckpoint returns the most recent checkpoint (regardless of whether it // is already known). When checkpoints are disabled or there are no checkpoints // for the active network, it will return nil. From b7ef1f0946d3e41b4cb1880a3f06568152376d7e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 3 Feb 2014 20:03:06 -0600 Subject: [PATCH 112/190] Include transaction hash in failed input val error. --- scriptval.go | 3 ++- validate.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scriptval.go b/scriptval.go index 3e0e7598..4efdd274 100644 --- a/scriptval.go +++ b/scriptval.go @@ -90,7 +90,8 @@ out: // Execute the script pair. if err := engine.Execute(); err != nil { err := fmt.Errorf("validate of input "+ - "%d failed: %v", txVI.txInIndex, err) + "%d from transaction %s failed: %v", + txVI.txInIndex, txInHash, err) v.sendResult(err) break out } diff --git a/validate.go b/validate.go index ecee9208..28555404 100644 --- a/validate.go +++ b/validate.go @@ -747,7 +747,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // BIP0016 describes a pay-to-script-hash type that is considered a // "standard" type. The rules for this BIP only apply to transactions - // after the timestmap defined by btcscript.Bip16Activation. See + // after the timestamp defined by btcscript.Bip16Activation. See // https://en.bitcoin.it/wiki/BIP_0016 for more details. enforceBIP0016 := false if node.timestamp.After(btcscript.Bip16Activation) { From bb4ea7d59ab14e27eeac9ebce1fcd9b3b1b16b2c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 3 Feb 2014 20:27:13 -0600 Subject: [PATCH 113/190] Include in/out script bytes in script val error. --- scriptval.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scriptval.go b/scriptval.go index 4efdd274..f3badf19 100644 --- a/scriptval.go +++ b/scriptval.go @@ -90,8 +90,10 @@ out: // Execute the script pair. if err := engine.Execute(); err != nil { err := fmt.Errorf("validate of input "+ - "%d from transaction %s failed: %v", - txVI.txInIndex, txInHash, err) + "%d from transaction %s failed: %v "+ + "(input script bytes %x, prev output "+ + "script bytes %x)", txVI.txInIndex, + txInHash, err, sigScript, pkScript) v.sendResult(err) break out } From e1f66f6103a8775f5a21bf2c531d0167a8789100 Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 4 Feb 2014 16:16:53 -0500 Subject: [PATCH 114/190] gofmt --- validate_test.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/validate_test.go b/validate_test.go index a16786cb..551592b4 100644 --- a/validate_test.go +++ b/validate_test.go @@ -94,10 +94,10 @@ var Block100000 = btcwire.MsgBlock{ Nonce: 0x10572b0f, // 274148111 }, Transactions: []*btcwire.MsgTx{ - &btcwire.MsgTx{ + { Version: 1, TxIn: []*btcwire.TxIn{ - &btcwire.TxIn{ + { PreviousOutpoint: btcwire.OutPoint{ Hash: btcwire.ShaHash{}, Index: 0xffffffff, @@ -109,7 +109,7 @@ var Block100000 = btcwire.MsgBlock{ }, }, TxOut: []*btcwire.TxOut{ - &btcwire.TxOut{ + { Value: 0x12a05f200, // 5000000000 PkScript: []byte{ 0x41, // OP_DATA_65 @@ -128,10 +128,10 @@ var Block100000 = btcwire.MsgBlock{ }, LockTime: 0, }, - &btcwire.MsgTx{ + { Version: 1, TxIn: []*btcwire.TxIn{ - &btcwire.TxIn{ + { PreviousOutpoint: btcwire.OutPoint{ Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. 0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60, @@ -168,7 +168,7 @@ var Block100000 = btcwire.MsgBlock{ }, }, TxOut: []*btcwire.TxOut{ - &btcwire.TxOut{ + { Value: 0x2123e300, // 556000000 PkScript: []byte{ 0x76, // OP_DUP @@ -181,7 +181,7 @@ var Block100000 = btcwire.MsgBlock{ 0xac, // OP_CHECKSIG }, }, - &btcwire.TxOut{ + { Value: 0x108e20f00, // 4444000000 PkScript: []byte{ 0x76, // OP_DUP @@ -197,10 +197,10 @@ var Block100000 = btcwire.MsgBlock{ }, LockTime: 0, }, - &btcwire.MsgTx{ + { Version: 1, TxIn: []*btcwire.TxIn{ - &btcwire.TxIn{ + { PreviousOutpoint: btcwire.OutPoint{ Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. 0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d, @@ -236,7 +236,7 @@ var Block100000 = btcwire.MsgBlock{ }, }, TxOut: []*btcwire.TxOut{ - &btcwire.TxOut{ + { Value: 0xf4240, // 1000000 PkScript: []byte{ 0x76, // OP_DUP @@ -249,7 +249,7 @@ var Block100000 = btcwire.MsgBlock{ 0xac, // OP_CHECKSIG }, }, - &btcwire.TxOut{ + { Value: 0x11d260c0, // 299000000 PkScript: []byte{ 0x76, // OP_DUP @@ -265,10 +265,10 @@ var Block100000 = btcwire.MsgBlock{ }, LockTime: 0, }, - &btcwire.MsgTx{ + { Version: 1, TxIn: []*btcwire.TxIn{ - &btcwire.TxIn{ + { PreviousOutpoint: btcwire.OutPoint{ Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. 0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73, @@ -305,7 +305,7 @@ var Block100000 = btcwire.MsgBlock{ }, }, TxOut: []*btcwire.TxOut{ - &btcwire.TxOut{ + { Value: 0xf4240, // 1000000 PkScript: []byte{ 0x76, // OP_DUP From 190ef70aced3bb1892060f72e5fd1b99b6d461d5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 7 Feb 2014 16:23:11 -0600 Subject: [PATCH 115/190] Export CalcWork and BlocksPerRetarget. This commit makes the CalcWork function and BlocksPerRetarget variable available to external packages. --- chain.go | 4 ++-- difficulty.go | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/chain.go b/chain.go index bf4e75a2..575b94c4 100644 --- a/chain.go +++ b/chain.go @@ -26,7 +26,7 @@ const ( // in memory in order to perform all necessary validation. It is used // to determine when it's safe to prune nodes from memory without // causing constant dynamic reloading. - minMemoryNodes = blocksPerRetarget + minMemoryNodes = BlocksPerRetarget ) // ErrIndexAlreadyInitialized describes an error that indicates the block index @@ -81,7 +81,7 @@ func newBlockNode(blockHeader *btcwire.BlockHeader, blockSha *btcwire.ShaHash, h node := blockNode{ hash: blockSha, parentHash: &blockHeader.PrevBlock, - workSum: calcWork(blockHeader.Bits), + workSum: CalcWork(blockHeader.Bits), height: height, version: blockHeader.Version, bits: blockHeader.Bits, diff --git a/difficulty.go b/difficulty.go index 62f2d2eb..77b9558c 100644 --- a/difficulty.go +++ b/difficulty.go @@ -22,10 +22,10 @@ const ( // targetSpacing is the desired amount of time to generate each block. targetSpacing = time.Minute * 10 - // blocksPerRetarget is the number of blocks between each difficulty + // BlocksPerRetarget is the number of blocks between each difficulty // retarget. It is calculated based on the desired block generation // rate. - blocksPerRetarget = int64(targetTimespan / targetSpacing) + BlocksPerRetarget = int64(targetTimespan / targetSpacing) // retargetAdjustmentFactor is the adjustment factor used to limit // the minimum and maximum amount of adjustment that can occur between @@ -161,7 +161,7 @@ func BigToCompact(n *big.Int) uint32 { return compact } -// calcWork calculates a work value from difficulty bits. Bitcoin increases +// CalcWork calculates a work value from difficulty bits. Bitcoin increases // the difficulty for generating a block by decreasing the value which the // generated hash must be less than. This difficulty target is stored in each // block header using a compact representation as described in the documenation @@ -169,9 +169,9 @@ func BigToCompact(n *big.Int) uint32 { // the most proof of work (highest difficulty). Since a lower target difficulty // value equates to higher actual difficulty, the work value which will be // accumulated must be the inverse of the difficulty. Also, in order to avoid -// potential division by zero and really small floating point numbers, add 1 to -// the denominator and multiply the numerator by 2^256. -func calcWork(bits uint32) *big.Int { +// potential division by zero and really small floating point numbers, the +// result adds 1 to the denominator and multiplies the numerator by 2^256. +func CalcWork(bits uint32) *big.Int { // Return a work value of zero if the passed difficulty bits represent // a negative number. Note this should not happen in practice with valid // blocks, but an invalid block could trigger it. @@ -235,7 +235,7 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er // the special rule applied. powLimitBits := b.chainParams().PowLimitBits iterNode := startNode - for iterNode != nil && iterNode.height%blocksPerRetarget != 0 && iterNode.bits == powLimitBits { + for iterNode != nil && iterNode.height%BlocksPerRetarget != 0 && iterNode.bits == powLimitBits { // Get the previous block node. This function is used over // simply accessing iterNode.parent directly as it will // dynamically create previous block nodes as needed. This @@ -272,7 +272,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu // Return the previous block's difficulty requirements if this block // is not at a difficulty retarget interval. - if (lastNode.height+1)%blocksPerRetarget != 0 { + if (lastNode.height+1)%BlocksPerRetarget != 0 { // The difficulty rules differ between networks. switch b.btcnet { // The test network rules allow minimum difficulty blocks after @@ -312,7 +312,7 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu // Get the block node at the previous retarget (targetTimespan days // worth of blocks). firstNode := lastNode - for i := int64(0); i < blocksPerRetarget-1 && firstNode != nil; i++ { + for i := int64(0); i < BlocksPerRetarget-1 && firstNode != nil; i++ { // Get the previous block node. This function is used over // simply accessing firstNode.parent directly as it will // dynamically create previous block nodes as needed. This From 149d8176b0ff0b1fc848bca46ab8bca2079b7ab8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 9 Feb 2014 01:34:08 -0600 Subject: [PATCH 116/190] Fix an issue causing excessive memory consumption. This commit resolves an issue where the block node index was forcing entire blocks to be kept in memory thereby forcing excessive memory usage. For example, prior to this change, the memory usage could consume upwards of 1.5GB while importing bootstrap.dat via the addblock utility. With this change the entire import takes <150MB. This also has the same memory reduction to btcd since it uses the same code path. --- chain.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chain.go b/chain.go index 575b94c4..70e527ee 100644 --- a/chain.go +++ b/chain.go @@ -78,9 +78,13 @@ type blockNode struct { // for the passed block. The work sum is updated accordingly when the node is // inserted into a chain. func newBlockNode(blockHeader *btcwire.BlockHeader, blockSha *btcwire.ShaHash, height int64) *blockNode { + // Make a copy of the hash so the node doesn't keep a reference to part + // of the full block/block header preventing it from being garbage + // collected. + prevHash := blockHeader.PrevBlock node := blockNode{ hash: blockSha, - parentHash: &blockHeader.PrevBlock, + parentHash: &prevHash, workSum: CalcWork(blockHeader.Bits), height: height, version: blockHeader.Version, From 50b6e10b5781772b0f6a506535f575d81a95dc7a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 21 Feb 2014 13:02:59 -0600 Subject: [PATCH 117/190] Reject blocks that fork before previous checkpoint. This commit adds an additional check to the block acceptance rules which prevents new blocks that fork the main chain before the previous known good checkpoint. This prevents storage of new, otherwise valid, blocks from building off of old blocks which are likely at a much easier difficulty and therefore could be used to waste cache and disk space. Note this is slightly different than the other existing check which prevents blocks with a timestamp before the timestamp of the latest known good checkpoint since that check effectively prevents old side chain blocks that already existed (per the claimed timestamp). ok drahn@ --- accept.go | 16 ++++++++++++++++ process.go | 8 ++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/accept.go b/accept.go index 65ac2819..98674eec 100644 --- a/accept.go +++ b/accept.go @@ -91,6 +91,22 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error return RuleError(str) } + // Find the latest known good checkpoint and prevent blocks which fork + // the main chain before it. This prevents storage of new, otherwise + // valid, blocks which build off of old blocks that are likely at a + // much easier difficulty and therefore could be used to waste cache and + // disk space. + checkpointBlock, err := b.findLatestKnownCheckpoint() + if err != nil { + return err + } + if checkpointBlock != nil && blockHeight < checkpointBlock.Height() { + str := fmt.Sprintf("block at height %d forks the main chain "+ + "before the previous checkpoint at height %d", + blockHeight, checkpointBlock.Height()) + return RuleError(str) + } + if !fastAdd { // Reject version 1 blocks once a majority of the network has // upgraded. diff --git a/process.go b/process.go index 42d08181..281a36c0 100644 --- a/process.go +++ b/process.go @@ -119,10 +119,10 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { // Find the latest known checkpoint and perform some additional checks // based on the checkpoint. This provides a few nice properties such as - // preventing forks from blocks before the last checkpoint, rejecting - // easy to mine, but otherwise bogus, blocks that could be used to eat - // memory, and ensuring expected (versus claimed) proof of work - // requirements since the last checkpoint are met. + // preventing old side chain blocks before the last checkpoint, + // rejecting easy to mine, but otherwise bogus, blocks that could be + // used to eat memory, and ensuring expected (versus claimed) proof of + // work requirements since the last checkpoint are met. blockHeader := &block.MsgBlock().Header checkpointBlock, err := b.findLatestKnownCheckpoint() if err != nil { From b25bf566b09bde9144a08af8ba1a693c5dd03c74 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 21 Feb 2014 15:03:44 -0600 Subject: [PATCH 118/190] Rename findLatestKnownCheckpoint. The name findLatestKnownCheckpoint is confusing and doesn't really convey the fact the purpose of the function is to the find the checkpoint prior to the current known block. Therefore, rename the function to findPreviousCheckpoint for clarity. Also, update some comments to follow suit. --- accept.go | 11 +++++------ checkpoints.go | 4 ++-- process.go | 8 ++++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/accept.go b/accept.go index 98674eec..f6b288fc 100644 --- a/accept.go +++ b/accept.go @@ -91,12 +91,11 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error return RuleError(str) } - // Find the latest known good checkpoint and prevent blocks which fork - // the main chain before it. This prevents storage of new, otherwise - // valid, blocks which build off of old blocks that are likely at a - // much easier difficulty and therefore could be used to waste cache and - // disk space. - checkpointBlock, err := b.findLatestKnownCheckpoint() + // Find the previous checkpoint and prevent blocks which fork the main + // chain before it. This prevents storage of new, otherwise valid, + // blocks which build off of old blocks that are likely at a much easier + // difficulty and therefore could be used to waste cache and disk space. + checkpointBlock, err := b.findPreviousCheckpoint() if err != nil { return err } diff --git a/checkpoints.go b/checkpoints.go index c52218cf..ade891d9 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -146,11 +146,11 @@ func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool return true } -// findLatestKnownCheckpoint finds the most recent checkpoint that is already +// findPreviousCheckpoint finds the most recent checkpoint that is already // available in the downloaded portion of the block chain and returns the // associated block. It returns nil if a checkpoint can't be found (this should // really only happen for blocks before the first checkpoint). -func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) { +func (b *BlockChain) findPreviousCheckpoint() (*btcutil.Block, error) { if b.noCheckpoints || b.checkpointData() == nil { return nil, nil } diff --git a/process.go b/process.go index 281a36c0..a9d26a8c 100644 --- a/process.go +++ b/process.go @@ -117,14 +117,14 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { return err } - // Find the latest known checkpoint and perform some additional checks - // based on the checkpoint. This provides a few nice properties such as + // Find the previous checkpoint and perform some additional checks based + // on the checkpoint. This provides a few nice properties such as // preventing old side chain blocks before the last checkpoint, // rejecting easy to mine, but otherwise bogus, blocks that could be // used to eat memory, and ensuring expected (versus claimed) proof of - // work requirements since the last checkpoint are met. + // work requirements since the previous checkpoint are met. blockHeader := &block.MsgBlock().Header - checkpointBlock, err := b.findLatestKnownCheckpoint() + checkpointBlock, err := b.findPreviousCheckpoint() if err != nil { return err } From bfef4e4a317c2bc7b867e7922f21c2fbcd1db2b0 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 23 Feb 2014 14:25:15 -0600 Subject: [PATCH 119/190] Make regtest subsidy halving interval 150. This commit moves the subsidy halving interval to the chain params so it can be configured per network. With that change it sets the regression test halving interval to 150 to match the regression test params of the reference implementation. This was pointed out by @flammit. --- params.go | 32 ++++++++++++++++++++------------ validate.go | 17 ++++++----------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/params.go b/params.go index fa468698..1ce1fec2 100644 --- a/params.go +++ b/params.go @@ -26,6 +26,11 @@ type Params struct { // have represented in compact form. See CompactToBig for more details // on compact form. PowLimitBits uint32 + + // SubsidyHalvingInterval is the interval of blocks at which the + // baseSubsidy is continually halved. Mathematically this is: + // baseSubsidy / 2^(height/SubsidyHalvingInterval) + SubsidyHalvingInterval int64 } // mainPowLimit is the highest proof of work value a bitcoin block can have for @@ -35,10 +40,11 @@ var mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) // mainNetParams contains parameters specific to the main network // (btcwire.MainNet). var mainNetParams = Params{ - GenesisBlock: &btcwire.GenesisBlock, - GenesisHash: &btcwire.GenesisHash, - PowLimit: mainPowLimit, - PowLimitBits: BigToCompact(mainPowLimit), + GenesisBlock: &btcwire.GenesisBlock, + GenesisHash: &btcwire.GenesisHash, + PowLimit: mainPowLimit, + PowLimitBits: BigToCompact(mainPowLimit), + SubsidyHalvingInterval: 210000, } // regressionPowLimit is the highest proof of work value a bitcoin block can @@ -48,10 +54,11 @@ var regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) // regressionParams contains parameters specific to the regression test network // (btcwire.TestNet). var regressionParams = Params{ - GenesisBlock: &btcwire.TestNetGenesisBlock, - GenesisHash: &btcwire.TestNetGenesisHash, - PowLimit: regressionPowLimit, - PowLimitBits: BigToCompact(regressionPowLimit), + GenesisBlock: &btcwire.TestNetGenesisBlock, + GenesisHash: &btcwire.TestNetGenesisHash, + PowLimit: regressionPowLimit, + PowLimitBits: BigToCompact(regressionPowLimit), + SubsidyHalvingInterval: 150, } // testNetPowLimit is the highest proof of work value a bitcoin block can have @@ -61,10 +68,11 @@ var testNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) // testNet3Params contains parameters specific to the test network (version 3) // (btcwire.TestNet3). var testNet3Params = Params{ - GenesisBlock: &btcwire.TestNet3GenesisBlock, - GenesisHash: &btcwire.TestNet3GenesisHash, - PowLimit: testNetPowLimit, - PowLimitBits: BigToCompact(testNetPowLimit), + GenesisBlock: &btcwire.TestNet3GenesisBlock, + GenesisHash: &btcwire.TestNet3GenesisHash, + PowLimit: testNetPowLimit, + PowLimitBits: BigToCompact(testNetPowLimit), + SubsidyHalvingInterval: 210000, } // chainParams returns chain parameters specific to the bitcoin network diff --git a/validate.go b/validate.go index 28555404..703741e1 100644 --- a/validate.go +++ b/validate.go @@ -43,13 +43,8 @@ const ( serializedHeightVersion = 2 // baseSubsidy is the starting subsidy amount for mined blocks. This - // value is halved every subsidyHalvingInterval blocks. + // value is halved every SubsidyHalvingInterval blocks. baseSubsidy = 50 * btcutil.SatoshiPerBitcoin - - // subsidyHalvingInterval is the interval of blocks at which the - // baseSubsidy is continually halved. See calcBlockSubsidy for more - // details. - subsidyHalvingInterval = 210000 ) var ( @@ -162,14 +157,14 @@ func isBIP0030Node(node *blockNode) bool { // newly generated blocks awards as well as validating the coinbase for blocks // has the expected value. // -// The subsidy is halved every subsidyHalvingInterval blocks. Mathematically -// this is: baseSubsidy / 2^(height/subsidyHalvingInterval) +// The subsidy is halved every SubsidyHalvingInterval blocks. Mathematically +// this is: baseSubsidy / 2^(height/SubsidyHalvingInterval) // // At the target block generation rate this is approximately every 4 // years. -func calcBlockSubsidy(height int64) int64 { +func (b *BlockChain) calcBlockSubsidy(height int64) int64 { // Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval) - return baseSubsidy >> uint(height/subsidyHalvingInterval) + return baseSubsidy >> uint(height/b.chainParams().SubsidyHalvingInterval) } // CheckTransactionSanity performs some preliminary checks on a transaction to @@ -824,7 +819,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er for _, txOut := range transactions[0].MsgTx().TxOut { totalSatoshiOut += txOut.Value } - expectedSatoshiOut := calcBlockSubsidy(node.height) + totalFees + expectedSatoshiOut := b.calcBlockSubsidy(node.height) + totalFees if totalSatoshiOut > expectedSatoshiOut { str := fmt.Sprintf("coinbase transaction for block pays %v "+ "which is more than expected value of %v", From 1c052a01d802535900812ac1c55a6b585ecd8fc8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 24 Feb 2014 10:17:13 -0600 Subject: [PATCH 120/190] Reject blocks with high precision timestamps. This commit adds an additional sanity check to ensure the block that is being processed does not contain a timestamp with a precision higher than one second. This is necessary because the consensus rules only deal with whole seconds in the time comparisons whereas the internal data structures make use of Go time.Time values which support up to nanosecond precision. Also, add a test to ensure the new functionality works as expected. ok @owainga --- test_coverage.txt | 86 +++++++++++++++++++++++++---------------------- validate.go | 13 ++++++- validate_test.go | 9 +++++ 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/test_coverage.txt b/test_coverage.txt index 0841e446..87b56e96 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,90 +1,94 @@ github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) -github.com/conformal/btcchain/validate.go countSigOps 100.00% (8/8) +github.com/conformal/btcchain/txlookup.go disconnectTransactions 100.00% (13/13) +github.com/conformal/btcchain/validate.go countSigOps 100.00% (9/9) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) -github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) -github.com/conformal/btcchain/chain.go newBlockNode 100.00% (4/4) +github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) -github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) -github.com/conformal/btcchain/validate.go calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/chain.go New 100.00% (2/2) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/validate.go BlockChain.calcBlockSubsidy 100.00% (1/1) github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 94.44% (17/18) -github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 94.12% (16/17) -github.com/conformal/btcchain/txlookup.go disconnectTransactions 93.75% (15/16) +github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) +github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) -github.com/conformal/btcchain/process.go BlockChain.processOrphans 92.86% (13/14) -github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 90.00% (27/30) -github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 88.24% (30/34) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.36% (19/22) -github.com/conformal/btcchain/scriptval.go checkBlockScripts 85.71% (6/7) +github.com/conformal/btcchain/scriptval.go txValidator.Validate 88.46% (23/26) +github.com/conformal/btcchain/scriptval.go checkBlockScripts 88.24% (15/17) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.96% (20/23) +github.com/conformal/btcchain/validate.go IsCoinBase 85.71% (6/7) +github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) +github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) -github.com/conformal/btcchain/validate.go IsCoinBase 83.33% (5/6) github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) -github.com/conformal/btcchain/difficulty.go calcWork 80.00% (4/5) +github.com/conformal/btcchain/difficulty.go CalcWork 80.00% (4/5) github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 76.00% (19/25) +github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 75.00% (18/24) github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 69.23% (36/52) +github.com/conformal/btcchain/validate.go CheckBlockSanity 67.44% (29/43) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) -github.com/conformal/btcchain/validate.go BlockChain.checkBlockSanity 65.12% (28/43) +github.com/conformal/btcchain/validate.go CheckTransactionInputs 65.12% (28/43) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 64.71% (11/17) -github.com/conformal/btcchain/scriptval.go validateTxIn 64.71% (11/17) -github.com/conformal/btcchain/validate.go CheckTransactionInputs 64.44% (29/45) -github.com/conformal/btcchain/validate.go CheckTransactionSanity 62.16% (23/37) -github.com/conformal/btcchain/txlookup.go connectTransactions 60.00% (9/15) -github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) +github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) +github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) -github.com/conformal/btcchain/validate.go BlockChain.checkProofOfWork 58.82% (10/17) -github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 53.49% (23/43) -github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 50.00% (11/22) +github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) +github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 59.26% (16/27) +github.com/conformal/btcchain/validate.go checkProofOfWork 53.33% (8/15) +github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 52.27% (23/44) +github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 52.00% (13/25) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 51.28% (40/78) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) -github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 49.30% (35/71) +github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) -github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 33.33% (2/6) -github.com/conformal/btcchain/validate.go IsFinalizedTransaction 23.08% (3/13) -github.com/conformal/btcchain/checkpoints.go BlockChain.findLatestKnownCheckpoint 18.18% (2/11) +github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) +github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.07% (7/41) +github.com/conformal/btcchain/checkpoints.go BlockChain.findPreviousCheckpoint 4.88% (2/41) github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) -github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/24) -github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/17) +github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/26) +github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/22) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) -github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) +github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) -github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/9) +github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) +github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/10) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) -github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/7) github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) +github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) +github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 55.88% (646/1156) +github.com/conformal/btcchain ------------------------------------- 53.75% (666/1239) diff --git a/validate.go b/validate.go index 703741e1..3c4ce604 100644 --- a/validate.go +++ b/validate.go @@ -398,8 +398,19 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { return err } - // Ensure the block time is not more than 2 hours in the future. + // A block timestamp must not have a greater precision than one second. + // This check is necessary because Go time.Time values support + // nanosecond precision whereas the consensus rules only apply to + // seconds and it's much nicer to deal with standard Go time values + // instead of converting to seconds everywhere. header := &block.MsgBlock().Header + if !header.Timestamp.Equal(time.Unix(header.Timestamp.Unix(), 0)) { + str := fmt.Sprintf("block timestamp of %v has a higher "+ + "precision than one second", header.Timestamp) + return RuleError(str) + } + + // Ensure the block time is not more than 2 hours in the future. if header.Timestamp.After(time.Now().Add(time.Hour * 2)) { str := fmt.Sprintf("block timestamp of %v is too far in the "+ "future", header.Timestamp) diff --git a/validate_test.go b/validate_test.go index 551592b4..00bd4894 100644 --- a/validate_test.go +++ b/validate_test.go @@ -21,6 +21,15 @@ func TestCheckBlockSanity(t *testing.T) { if err != nil { t.Errorf("CheckBlockSanity: %v", err) } + + // Ensure a block that has a timestamp with a precision higher than one + // second fails. + timestamp := block.MsgBlock().Header.Timestamp + block.MsgBlock().Header.Timestamp = timestamp.Add(time.Nanosecond) + err = btcchain.CheckBlockSanity(block, powLimit) + if err == nil { + t.Errorf("CheckBlockSanity: error is nil when it shouldn't be") + } } // TestCheckSerializedHeight tests the checkSerializedHeight function with From a56dfc7ff4395a4d4e795c9aa6726ad595d06b9d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 25 Feb 2014 00:31:58 -0600 Subject: [PATCH 121/190] Export CalcBlockSubsidy function. --- validate.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/validate.go b/validate.go index 3c4ce604..9ff74481 100644 --- a/validate.go +++ b/validate.go @@ -152,19 +152,20 @@ func isBIP0030Node(node *blockNode) bool { return false } -// calcBlockSubsidy returns the subsidy amount a block at the provided height +// CalcBlockSubsidy returns the subsidy amount a block at the provided height // should have. This is mainly used for determining how much the coinbase for // newly generated blocks awards as well as validating the coinbase for blocks // has the expected value. // // The subsidy is halved every SubsidyHalvingInterval blocks. Mathematically -// this is: baseSubsidy / 2^(height/SubsidyHalvingInterval) +// this is: baseSubsidy / 2^(height/subsidyHalvingInterval) // -// At the target block generation rate this is approximately every 4 -// years. -func (b *BlockChain) calcBlockSubsidy(height int64) int64 { +// At the target block generation rate for the main network, this is +// approximately every 4 years. +func CalcBlockSubsidy(height int64, btcnet btcwire.BitcoinNet) int64 { // Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval) - return baseSubsidy >> uint(height/b.chainParams().SubsidyHalvingInterval) + return baseSubsidy >> + uint(height/ChainParams(btcnet).SubsidyHalvingInterval) } // CheckTransactionSanity performs some preliminary checks on a transaction to @@ -830,7 +831,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er for _, txOut := range transactions[0].MsgTx().TxOut { totalSatoshiOut += txOut.Value } - expectedSatoshiOut := b.calcBlockSubsidy(node.height) + totalFees + expectedSatoshiOut := CalcBlockSubsidy(node.height, b.btcnet) + totalFees if totalSatoshiOut > expectedSatoshiOut { str := fmt.Sprintf("coinbase transaction for block pays %v "+ "which is more than expected value of %v", From 87ecac2072f701693b8f97008830ef6b67c1051e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 28 Feb 2014 12:16:56 -0600 Subject: [PATCH 122/190] Export CountSigOps function. --- validate.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/validate.go b/validate.go index 9ff74481..822d220f 100644 --- a/validate.go +++ b/validate.go @@ -293,11 +293,11 @@ func checkProofOfWork(block *btcutil.Block, powLimit *big.Int) error { return nil } -// countSigOps returns the number of signature operations for all transaction +// CountSigOps returns the number of signature operations for all transaction // input and output scripts in the provided transaction. This uses the // quicker, but imprecise, signature operation counting mechanism from // btcscript. -func countSigOps(tx *btcutil.Tx) int { +func CountSigOps(tx *btcutil.Tx) int { msgTx := tx.MsgTx() // Accumulate the number of signature operations in all transaction @@ -483,7 +483,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { // We could potentially overflow the accumulator so check for // overflow. lastSigOps := totalSigOps - totalSigOps += countSigOps(tx) + totalSigOps += CountSigOps(tx) if totalSigOps < lastSigOps || totalSigOps > maxSigOpsPerBlock { str := fmt.Sprintf("block contains too many signature "+ "operations - got %v, max %v", totalSigOps, @@ -770,7 +770,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er transactions := block.Transactions() totalSigOps := 0 for i, tx := range transactions { - numsigOps := countSigOps(tx) + numsigOps := CountSigOps(tx) if enforceBIP0016 { // Since the first (and only the first) transaction has // already been verified to be a coinbase transaction, From 82edb203e53e71a0766f298ec86499cc71c5ff46 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 28 Feb 2014 12:23:50 -0600 Subject: [PATCH 123/190] Export MaxSigOpsPerBlock. --- validate.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/validate.go b/validate.go index 822d220f..3c4019cc 100644 --- a/validate.go +++ b/validate.go @@ -17,9 +17,9 @@ import ( ) const ( - // maxSigOpsPerBlock is the maximum number of signature operations + // MaxSigOpsPerBlock is the maximum number of signature operations // allowed for a block. It is a fraction of the max block payload size. - maxSigOpsPerBlock = btcwire.MaxBlockPayload / 50 + MaxSigOpsPerBlock = btcwire.MaxBlockPayload / 50 // lockTimeThreshold is the number below which a lock time is // interpreted to be a block number. Since an average of one block @@ -484,10 +484,10 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { // overflow. lastSigOps := totalSigOps totalSigOps += CountSigOps(tx) - if totalSigOps < lastSigOps || totalSigOps > maxSigOpsPerBlock { + if totalSigOps < lastSigOps || totalSigOps > MaxSigOpsPerBlock { str := fmt.Sprintf("block contains too many signature "+ "operations - got %v, max %v", totalSigOps, - maxSigOpsPerBlock) + MaxSigOpsPerBlock) return RuleError(str) } } @@ -790,10 +790,10 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // this on every loop iteration to avoid overflow. lastSigops := totalSigOps totalSigOps += numsigOps - if totalSigOps < lastSigops || totalSigOps > maxSigOpsPerBlock { + if totalSigOps < lastSigops || totalSigOps > MaxSigOpsPerBlock { str := fmt.Sprintf("block contains too many "+ "signature operations - got %v, max %v", - totalSigOps, maxSigOpsPerBlock) + totalSigOps, MaxSigOpsPerBlock) return RuleError(str) } } From ec641751a8be3b3f2e72e271de1092f0427508e5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 1 Mar 2014 21:16:06 -0600 Subject: [PATCH 124/190] Change BuildMerkleTreeStore to accept transactions. This commit modifies the BuildMerkleTreeStore function to accept a slice of btcutil.Tx transactions as opposed to a full block. This allows more flexibility when calculating merkle roots since a full block may not be created yet (particularly when generating blocks that need to be solved in mining). Previously, the BuildMerkleTreeStore function accepted a btcutil.Block because originally the block itself cached the transaction hashes and it was necessary to have access to the block to make use of the cached transactions. However, the code has since been improved such that it caches transaction hashes directly in each btcutil.Tx. This means the code can remain as efficient as before while allowing the individual transacitons to be passed. --- merkle.go | 16 ++++++++-------- merkle_test.go | 2 +- validate.go | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/merkle.go b/merkle.go index fdee30e1..f74ef2a3 100644 --- a/merkle.go +++ b/merkle.go @@ -40,11 +40,11 @@ func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire. return newSha } -// BuildMerkleTreeStore creates a merkle tree from block, stores it using a -// linear array, and returns a slice of the backing array. A linear array was -// chosen as opposed to an actual tree structure since it uses about half as -// much memory. The following describes a merkle tree and how it is stored in -// a linear array. +// BuildMerkleTreeStore creates a merkle tree from a slice of transactions, +// stores it using a linear array, and returns a slice of the backing array. A +// linear array was chosen as opposed to an actual tree structure since it uses +// about half as much memory. The following describes a merkle tree and how it +// is stored in a linear array. // // A merkle tree is a tree in which every non-leaf node is the hash of its // children nodes. A diagram depicting how this works for bitcoin transactions @@ -68,15 +68,15 @@ func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire. // are calculated by concatenating the left node with itself before hashing. // Since this function uses nodes that are pointers to the hashes, empty nodes // will be nil. -func BuildMerkleTreeStore(block *btcutil.Block) []*btcwire.ShaHash { +func BuildMerkleTreeStore(transactions []*btcutil.Tx) []*btcwire.ShaHash { // Calculate how many entries are required to hold the binary merkle // tree as a linear array and create an array of that size. - nextPoT := nextPowerOfTwo(len(block.Transactions())) + nextPoT := nextPowerOfTwo(len(transactions)) arraySize := nextPoT*2 - 1 merkles := make([]*btcwire.ShaHash, arraySize) // Create the base transaction shas and populate the array with them. - for i, tx := range block.Transactions() { + for i, tx := range transactions { merkles[i] = tx.Sha() } diff --git a/merkle_test.go b/merkle_test.go index 6fbae40a..01a9af77 100644 --- a/merkle_test.go +++ b/merkle_test.go @@ -13,7 +13,7 @@ import ( // TestMerkle tests the BuildMerkleTreeStore API. func TestMerkle(t *testing.T) { block := btcutil.NewBlock(&Block100000) - merkles := btcchain.BuildMerkleTreeStore(block) + merkles := btcchain.BuildMerkleTreeStore(block.Transactions()) calculatedMerkleRoot := merkles[len(merkles)-1] wantMerkle := &Block100000.Header.MerkleRoot if !wantMerkle.IsEqual(calculatedMerkleRoot) { diff --git a/validate.go b/validate.go index 3c4019cc..20bdf8c2 100644 --- a/validate.go +++ b/validate.go @@ -453,7 +453,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { // checks. Bitcoind builds the tree here and checks the merkle root // after the following checks, but there is no reason not to check the // merkle root matches here. - merkles := BuildMerkleTreeStore(block) + merkles := BuildMerkleTreeStore(block.Transactions()) calculatedMerkleRoot := merkles[len(merkles)-1] if !header.MerkleRoot.IsEqual(calculatedMerkleRoot) { str := fmt.Sprintf("block merkle root is invalid - block "+ From b59a15d07eeb0d396040ac9c6e1bed061ed1eed5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 1 Mar 2014 21:50:11 -0600 Subject: [PATCH 125/190] Export CountP2SHSigOps. --- validate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/validate.go b/validate.go index 20bdf8c2..e156a79a 100644 --- a/validate.go +++ b/validate.go @@ -318,11 +318,11 @@ func CountSigOps(tx *btcutil.Tx) int { return totalSigOps } -// countP2SHSigOps returns the number of signature operations for all input +// CountP2SHSigOps returns the number of signature operations for all input // transactions which are of the pay-to-script-hash type. This uses the // precise, signature operation counting mechanism from btcscript which requires // access to the input transaction scripts. -func countP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, error) { +func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, error) { // Coinbase transactions have no interesting inputs. if isCoinBaseTx { return 0, nil @@ -778,7 +778,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // countP2SHSigOps for whether or not the transaction is // a coinbase transaction rather than having to do a // full coinbase check again. - numP2SHSigOps, err := countP2SHSigOps(tx, i == 0, + numP2SHSigOps, err := CountP2SHSigOps(tx, i == 0, txInputStore) if err != nil { return err From b041971ca88d3d61106f6b5f6006201b89cda93a Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 2 Mar 2014 12:17:36 -0600 Subject: [PATCH 126/190] Export CalcNextRequiredDifficutly function. This commit exports a new variant of the existing internal calcNextRequiredDifficulty function which calculates and returns the next required difficulty for a block after the end of the current best chain based on the difficulty retarget rules. In order to support the exported function the internal one was slightly modified to accept the block timestamp instead of an entire block since the timestamp is all that is needed and the caller of the exported function might next have a full block yet. --- accept.go | 3 ++- difficulty.go | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/accept.go b/accept.go index f6b288fc..e3087fff 100644 --- a/accept.go +++ b/accept.go @@ -39,7 +39,8 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error // Ensure the difficulty specified in the block header matches // the calculated difficulty based on the previous block and // difficulty retarget rules. - expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) + expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, + block.MsgBlock().Header.Timestamp) if err != nil { return err } diff --git a/difficulty.go b/difficulty.go index 77b9558c..99168aea 100644 --- a/difficulty.go +++ b/difficulty.go @@ -6,7 +6,6 @@ package btcchain import ( "fmt" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math/big" "time" @@ -260,7 +259,10 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er // calcNextRequiredDifficulty calculates the required difficulty for the block // after the passed previous block node based on the difficulty retarget rules. -func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcutil.Block) (uint32, error) { +// This function differs from the exported CalcNextRequiredDifficulty in that +// the exported version uses the current best chain as the previous block node +// while this function accepts any block node. +func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTime time.Time) (uint32, error) { // Choose the correct proof of work limit for the active network. powLimit := b.chainParams().PowLimit powLimitBits := b.chainParams().PowLimitBits @@ -284,7 +286,6 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu // Return minimum difficulty when more than twice the // desired amount of time needed to generate a block has // elapsed. - newBlockTime := block.MsgBlock().Header.Timestamp allowMinTime := lastNode.timestamp.Add(targetSpacing * 2) if newBlockTime.After(allowMinTime) { return powLimitBits, nil @@ -367,3 +368,12 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu return newTargetBits, nil } + +// CalcNextRequiredDifficulty calculates the required difficulty for the block +// after the end of the current best chain based on the difficulty retarget +// rules. +// +// This function is NOT safe for concurrent access. +func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) { + return b.calcNextRequiredDifficulty(b.bestChain, timestamp) +} From acdce27f9f6b9c275af9c1b6f8ab762b20adf335 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 9 Mar 2014 11:04:47 -0500 Subject: [PATCH 127/190] Defer unlock of orphan mutex in addOrphanBlock. This was pointed out by saracen on the btcd IRC channel. --- chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain.go b/chain.go index 70e527ee..4b51e4b0 100644 --- a/chain.go +++ b/chain.go @@ -297,7 +297,7 @@ func (b *BlockChain) addOrphanBlock(block *btcutil.Block) { // of near the top since removeOrphanBlock does its own locking and // the range iterator is not invalidated by removing map entries. b.orphanLock.Lock() - b.orphanLock.Unlock() + defer b.orphanLock.Unlock() // Insert the block into the orphan map with an expiration time // 1 hour from now. From 1676ecd7a6b3ccc3bc75e427b4d6a497e406a198 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 11 Mar 2014 13:18:27 -0500 Subject: [PATCH 128/190] Export CheckConnectBlock function. This commit makes a slight variant of the existing checkConnectBlock function available to external callers. The new exported version checks if the passed block will connect to the end of the current main chain. In order to support this, a few other small modifications have been made to the initial index generation and the existing checkConnectBlock since it previously made some assumptions about the state of genesis block which can no longer be assumed due accepting blocks from callers directly. Also, add a quick test to ensure the new function fails when checking if the genesis block will connect again when it's already inserted. --- chain.go | 8 ++++---- test_coverage.txt | 40 +++++++++++++++++++++------------------- validate.go | 35 +++++++++++++++++++++++++++++++---- validate_test.go | 24 ++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/chain.go b/chain.go index 4b51e4b0..9d4bb1f3 100644 --- a/chain.go +++ b/chain.go @@ -340,7 +340,7 @@ func (b *BlockChain) GenerateInitialIndex() error { // Calculate the starting height based on the minimum number of nodes // needed in memory. - startHeight := endHeight - (minMemoryNodes + 1) + startHeight := endHeight - minMemoryNodes if startHeight < 0 { startHeight = 0 } @@ -353,7 +353,7 @@ func (b *BlockChain) GenerateInitialIndex() error { // is going to be nuked eventually, the bug isn't being fixed in the // driver. In the mean time, work around the issue by calling // FetchBlockBySha multiple times with the appropriate indices as needed. - for start := startHeight; start < endHeight; { + for start := startHeight; start <= endHeight; { hashList, err := b.db.FetchHeightRange(start, endHeight+1) if err != nil { return err @@ -368,8 +368,8 @@ func (b *BlockChain) GenerateInitialIndex() error { // Loop forwards through each block loading the node into the // index for the block. for _, hash := range hashList { - // Make a copy of the hash to make sure there are no references - // into the list so it can be freed. + // Make a copy of the hash to make sure there are no + // references into the list so it can be freed. hashCopy := hash node, err := b.loadBlockNode(&hashCopy) if err != nil { diff --git a/test_coverage.txt b/test_coverage.txt index 87b56e96..ca3ea7e1 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -2,27 +2,28 @@ github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) github.com/conformal/btcchain/txlookup.go disconnectTransactions 100.00% (13/13) -github.com/conformal/btcchain/validate.go countSigOps 100.00% (9/9) +github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) +github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) -github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) github.com/conformal/btcchain/chain.go New 100.00% (2/2) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/validate.go BlockChain.calcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/validate.go CalcBlockSubsidy 100.00% (1/1) github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) @@ -35,19 +36,21 @@ github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29 github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) +github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) github.com/conformal/btcchain/difficulty.go CalcWork 80.00% (4/5) github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) +github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 77.27% (17/22) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 75.00% (18/24) github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) -github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 69.23% (36/52) +github.com/conformal/btcchain/validate.go isTransactionSpent 75.00% (3/4) +github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 71.15% (37/52) github.com/conformal/btcchain/validate.go CheckBlockSanity 67.44% (29/43) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) github.com/conformal/btcchain/validate.go CheckTransactionInputs 65.12% (28/43) -github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 64.71% (11/17) github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) @@ -63,12 +66,11 @@ github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50 github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.07% (7/41) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.50% (7/40) github.com/conformal/btcchain/checkpoints.go BlockChain.findPreviousCheckpoint 4.88% (2/41) github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) -github.com/conformal/btcchain/validate.go countP2SHSigOps 0.00% (0/26) -github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 0.00% (0/22) +github.com/conformal/btcchain/validate.go CountP2SHSigOps 0.00% (0/26) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) @@ -81,14 +83,14 @@ github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0 github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) -github.com/conformal/btcchain/validate.go isTransactionSpent 0.00% (0/4) -github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) -github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 53.75% (666/1239) +github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) +github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 55.94% (697/1246) diff --git a/validate.go b/validate.go index e156a79a..71428570 100644 --- a/validate.go +++ b/validate.go @@ -711,6 +711,15 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in // checkConnectBlock performs several checks to confirm connecting the passed // block to the main chain (including whatever reorganization might be necessary // to get this node to the main chain) does not violate any rules. +// +// The CheckConnectBlock function makes use of this function to perform the +// bulk of its work. The only difference is this function accepts a node which +// may or may not require reorganization to connect it to the main chain whereas +// CheckConnectBlock creates a new node which specifically connects to the end +// of the current main chain and then calls this function with that node. +// +// See the comments for CheckConnectBlock for some examples of the type of +// checks performed by this function. func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) error { // If the side chain blocks end up in the database, a call to // checkBlockSanity should be done here in case a previous version @@ -718,12 +727,9 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // implementation only currently uses memory for the side chain blocks, // it isn't currently necessary. - // TODO(davec): Keep a flag if this has already been done to avoid - // multiple runs. - // The coinbase for the Genesis block is not spendable, so just return // now. - if node.hash.IsEqual(b.chainParams().GenesisHash) { + if node.hash.IsEqual(b.chainParams().GenesisHash) && b.bestChain == nil { return nil } @@ -864,3 +870,24 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er return nil } + +// CheckConnectBlock performs several checks to confirm connecting the passed +// block to the main chain does not violate any rules. An example of some of +// the checks performed are ensuring connecting the block would not cause any +// duplicate transaction hashes for old transactions that aren't already fully +// spent, double spends, exceeding the maximum allowed signature operations +// per block, invalid values in relation to the expected block subisidy, or +// fail transaction script validation. +// +// This function is NOT safe for concurrent access. +func (b *BlockChain) CheckConnectBlock(block *btcutil.Block) error { + prevNode := b.bestChain + blockSha, _ := block.Sha() + newNode := newBlockNode(&block.MsgBlock().Header, blockSha, block.Height()) + if prevNode != nil { + newNode.parent = prevNode + newNode.workSum.Add(prevNode.workSum, newNode.workSum) + } + + return b.checkConnectBlock(newNode, block) +} diff --git a/validate_test.go b/validate_test.go index 00bd4894..0157cedd 100644 --- a/validate_test.go +++ b/validate_test.go @@ -14,6 +14,30 @@ import ( "time" ) +// TestCheckConnectBlock tests the CheckConnectBlock function to ensure it +// fails +func TestCheckConnectBlock(t *testing.T) { + // Create a new database and chain instance to run tests against. + chain, teardownFunc, err := chainSetup("checkconnectblock") + if err != nil { + t.Errorf("Failed to setup chain instance: %v", err) + return + } + defer teardownFunc() + + err = chain.GenerateInitialIndex() + if err != nil { + t.Errorf("GenerateInitialIndex: %v", err) + } + + // The genesis block should fail to connect since it's already + // inserted. + err = chain.CheckConnectBlock(btcutil.NewBlock(&btcwire.GenesisBlock)) + if err == nil { + t.Errorf("CheckConnectBlock: Did not received expected error") + } +} + func TestCheckBlockSanity(t *testing.T) { powLimit := btcchain.ChainParams(btcwire.MainNet).PowLimit block := btcutil.NewBlock(&Block100000) From 936b4eaa2d3c557ee71dd97fc75572b34316537c Mon Sep 17 00:00:00 2001 From: David Hill Date: Tue, 11 Mar 2014 22:33:56 -0400 Subject: [PATCH 129/190] add unit testing for BigToCompact, CompactToBig, and CalcWork --- difficulty_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++ test_coverage.txt | 34 +++++++++++----------- 2 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 difficulty_test.go diff --git a/difficulty_test.go b/difficulty_test.go new file mode 100644 index 00000000..b29271f2 --- /dev/null +++ b/difficulty_test.go @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "github.com/conformal/btcchain" + "math/big" + "testing" +) + +func TestBigToCompact(t *testing.T) { + tests := []struct { + in int64 + out uint32 + }{ + {0, 0}, + {-1, 25231360}, + } + + for x, test := range tests { + n := big.NewInt(test.in) + r := btcchain.BigToCompact(n) + if r != test.out { + t.Errorf("TestBigToCompact test #%d failed: got %d want %d\n", + x, r, test.out) + return + } + } +} + +func TestCompactToBig(t *testing.T) { + tests := []struct { + in uint32 + out int64 + }{ + {10000000, 0}, + } + + for x, test := range tests { + n := btcchain.CompactToBig(test.in) + want := big.NewInt(test.out) + if n.Cmp(want) != 0 { + t.Errorf("TestCompactToBig test #%d failed: got %d want %d\n", + x, n.Int64(), want.Int64()) + return + } + } +} + +func TestCalcWork(t *testing.T) { + tests := []struct { + in uint32 + out int64 + }{ + {10000000, 0}, + } + + for x, test := range tests { + bits := uint32(test.in) + + r := btcchain.CalcWork(bits) + if r.Int64() != test.out { + t.Errorf("TestCalcWork test #%d failed: got %v want %d\n", + x, r.Int64(), test.out) + return + } + } +} diff --git a/test_coverage.txt b/test_coverage.txt index ca3ea7e1..a160aa2c 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,22 +1,25 @@ github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) +github.com/conformal/btcchain/difficulty.go BigToCompact 100.00% (16/16) github.com/conformal/btcchain/txlookup.go disconnectTransactions 100.00% (13/13) +github.com/conformal/btcchain/difficulty.go CompactToBig 100.00% (12/12) github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) @@ -35,17 +38,14 @@ github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.29% (2 github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) -github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 82.35% (14/17) +github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) -github.com/conformal/btcchain/difficulty.go CalcWork 80.00% (4/5) github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 77.27% (17/22) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 75.00% (18/24) -github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) -github.com/conformal/btcchain/difficulty.go CompactToBig 75.00% (9/12) github.com/conformal/btcchain/validate.go isTransactionSpent 75.00% (3/4) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 71.15% (37/52) github.com/conformal/btcchain/validate.go CheckBlockSanity 67.44% (29/43) @@ -53,20 +53,20 @@ github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) github.com/conformal/btcchain/validate.go CheckTransactionInputs 65.12% (28/43) github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) -github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) +github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 59.26% (16/27) +github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 53.85% (14/26) github.com/conformal/btcchain/validate.go checkProofOfWork 53.33% (8/15) github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 52.27% (23/44) -github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 52.00% (13/25) github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 51.28% (40/78) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) -github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) +github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.50% (7/40) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.07% (7/41) github.com/conformal/btcchain/checkpoints.go BlockChain.findPreviousCheckpoint 4.88% (2/41) github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) @@ -83,14 +83,14 @@ github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0 github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) -github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) -github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) +github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 55.94% (697/1246) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 56.57% (706/1248) From 6dd7785276d5537e16ae546e9d19f32edb7c3591 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 15 Mar 2014 15:01:48 -0500 Subject: [PATCH 130/190] Export coinbase script length limits. This commit exports the MinCoinbaseScriptLen and MaxCoinbaseScriptLen constants. --- validate.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/validate.go b/validate.go index 71428570..92a73f19 100644 --- a/validate.go +++ b/validate.go @@ -28,11 +28,11 @@ const ( // the lock time is a uint32, the max is sometime around 2106. lockTimeThreshold uint32 = 5e8 // Tue Nov 5 00:53:20 1985 UTC - // minCoinbaseScriptLen is the minimum length a coinbase script can be. - minCoinbaseScriptLen = 2 + // MinCoinbaseScriptLen is the minimum length a coinbase script can be. + MinCoinbaseScriptLen = 2 - // maxCoinbaseScriptLen is the maximum length a coinbase script can be. - maxCoinbaseScriptLen = 100 + // MaxCoinbaseScriptLen is the maximum length a coinbase script can be. + MaxCoinbaseScriptLen = 100 // medianTimeBlocks is the number of previous blocks which should be // used to calculate the median time used to validate block timestamps. @@ -238,10 +238,10 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // Coinbase script length must be between min and max length. if IsCoinBase(tx) { slen := len(msgTx.TxIn[0].SignatureScript) - if slen < minCoinbaseScriptLen || slen > maxCoinbaseScriptLen { + if slen < MinCoinbaseScriptLen || slen > MaxCoinbaseScriptLen { str := fmt.Sprintf("coinbase transaction script length "+ "of %d is out of range (min: %d, max: %d)", - slen, minCoinbaseScriptLen, maxCoinbaseScriptLen) + slen, MinCoinbaseScriptLen, MaxCoinbaseScriptLen) return RuleError(str) } } else { From 96f9b8893562d9dad9163f6bd9f09125e3e5bb94 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 15 Mar 2014 15:04:10 -0500 Subject: [PATCH 131/190] Export CalcPastMedianTime function. This commit makes a slight variant of the existing calcPastMedianTime function available to external callers. The new exported version calculates the past median time from the end of the current main chain versus an arbitrary block node. --- chain.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/chain.go b/chain.go index 9d4bb1f3..a587ac24 100644 --- a/chain.go +++ b/chain.go @@ -680,6 +680,15 @@ func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) return medianTimestamp, nil } +// CalcPastMedianTime calculates the median time of the previous few blocks +// prior to, and including, the end of the current best chain. It is primarily +// used to ensure new blocks have sane timestamps. +// +// This function is NOT safe for concurrent access. +func (b *BlockChain) CalcPastMedianTime() (time.Time, error) { + return b.calcPastMedianTime(b.bestChain) +} + // getReorganizeNodes finds the fork point between the main chain and the passed // node and returns a list of block nodes that would need to be detached from // the main chain and a list of block nodes that would need to be attached to From 67ebfa0e80f4711bd19f99525b3c47bbfd71ad91 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 24 Mar 2014 13:14:04 -0500 Subject: [PATCH 132/190] Update checkBIP0030 to not use deprecated function. Rather than using the deprecated TxShas function on a btcutil.Block, convert the checkBIP0030 to use the newer preferred method of ranging over the Transactions to obtain the cached hash of each transaction. This is also a little more efficient since it can avoid creating and caching an extra slice to keep the hashes in addition to having the hash cached with each transaction. --- validate.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/validate.go b/validate.go index 92a73f19..717ec096 100644 --- a/validate.go +++ b/validate.go @@ -552,13 +552,9 @@ func isTransactionSpent(txD *TxData) bool { func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // Attempt to fetch duplicate transactions for all of the transactions // in this block from the point of view of the parent node. - fetchList, err := block.TxShas() - if err != nil { - return nil - } fetchSet := make(map[btcwire.ShaHash]bool) - for _, txHash := range fetchList { - fetchSet[*txHash] = true + for _, tx := range block.Transactions() { + fetchSet[*tx.Sha()] = true } txResults, err := b.fetchTxStore(node, fetchSet) if err != nil { From 38a694e309737c1c18366f8d592ac9160fcf0a88 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 28 Mar 2014 13:07:26 -0500 Subject: [PATCH 133/190] Correct maturity debug print. This commit corrects the debug log print to use the hash of referenced coinbase transaction instead of the hash of the current transation when a coinbase maturity is not met. --- validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.go b/validate.go index 717ec096..27b85b4e 100644 --- a/validate.go +++ b/validate.go @@ -624,7 +624,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in str := fmt.Sprintf("tried to spend coinbase "+ "transaction %v from height %v at "+ "height %v before required maturity "+ - "of %v blocks", txHash, originHeight, + "of %v blocks", txInHash, originHeight, txHeight, coinbaseMaturity) return 0, RuleError(str) } From 958ea38fdd8aca1b7ad9b8fe36bb7edc1259171f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 28 Mar 2014 14:32:12 -0500 Subject: [PATCH 134/190] Export CheckProofOfWork function. --- validate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/validate.go b/validate.go index 27b85b4e..a30a8ca7 100644 --- a/validate.go +++ b/validate.go @@ -259,10 +259,10 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { return nil } -// checkProofOfWork ensures the block header bits which indicate the target +// CheckProofOfWork ensures the block header bits which indicate the target // difficulty is in min/max range and that the block hash is less than the // target difficulty as claimed. -func checkProofOfWork(block *btcutil.Block, powLimit *big.Int) error { +func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { // The target difficulty must be larger than zero. target := CompactToBig(block.MsgBlock().Header.Bits) if target.Sign() <= 0 { @@ -394,7 +394,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { // Ensure the proof of work bits in the block header is in min/max range // and the block hash is less than the target value described by the // bits. - err := checkProofOfWork(block, powLimit) + err := CheckProofOfWork(block, powLimit) if err != nil { return err } From 79beb22aef5e72bebd924bc3c64dc2d64c8c2ff9 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Mon, 14 Apr 2014 07:59:30 -0500 Subject: [PATCH 135/190] Export CoinbaseMaturity as a const. The unexported variable is still kept so that tests may modify it. ok @davecgh --- validate.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/validate.go b/validate.go index a30a8ca7..d2738798 100644 --- a/validate.go +++ b/validate.go @@ -45,14 +45,17 @@ const ( // baseSubsidy is the starting subsidy amount for mined blocks. This // value is halved every SubsidyHalvingInterval blocks. baseSubsidy = 50 * btcutil.SatoshiPerBitcoin + + // CoinbaseMaturity is the number of blocks required before newly + // mined bitcoins (coinbase transactions) can be spent. + CoinbaseMaturity = 100 ) var ( - // coinbaseMaturity is the number of blocks required before newly - // mined bitcoins (coinbase transactions) can be spent. This is a - // variable as opposed to a constant because the tests need the ability - // to modify it. - coinbaseMaturity int64 = 100 + // coinbaseMaturity is the internal variable used for validating the + // spending of coinbase outputs. A variable rather than the exported + // constant is used because the tests need the ability to modify it. + coinbaseMaturity int64 = CoinbaseMaturity // zeroHash is the zero value for a btcwire.ShaHash and is defined as // a package level variable to avoid the need to create a new instance From 0cdaefd4cca34f40d90553606295e3bbd6196481 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 22 May 2014 13:29:39 -0400 Subject: [PATCH 136/190] export HashMerkleBranches ok @davecgh --- merkle.go | 10 +++++----- test_coverage.txt | 37 +++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/merkle.go b/merkle.go index f74ef2a3..4bb4dd51 100644 --- a/merkle.go +++ b/merkle.go @@ -24,10 +24,10 @@ func nextPowerOfTwo(n int) int { return 1 << exponent // 2^exponent } -// hashMerkleBranches takes two hashes, treated as the left and right tree +// HashMerkleBranches takes two hashes, treated as the left and right tree // nodes, and returns the hash of their concatenation. This is a helper -// function used to during generatation of a merkle tree. -func hashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire.ShaHash { +// function used to aid in the generation of a merkle tree. +func HashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire.ShaHash { // Concatenate the left and right nodes. var sha [btcwire.HashSize * 2]byte copy(sha[:btcwire.HashSize], left.Bytes()) @@ -92,13 +92,13 @@ func BuildMerkleTreeStore(transactions []*btcutil.Tx) []*btcwire.ShaHash { // When there is no right child, the parent is generated by // hashing the concatenation of the left child with itself. case merkles[i+1] == nil: - newSha := hashMerkleBranches(merkles[i], merkles[i]) + newSha := HashMerkleBranches(merkles[i], merkles[i]) merkles[offset] = newSha // The normal case sets the parent node to the double sha256 // of the concatentation of the left and right children. default: - newSha := hashMerkleBranches(merkles[i], merkles[i+1]) + newSha := HashMerkleBranches(merkles[i], merkles[i+1]) merkles[offset] = newSha } offset++ diff --git a/test_coverage.txt b/test_coverage.txt index a160aa2c..b601e8de 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,31 +1,31 @@ github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) -github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) github.com/conformal/btcchain/difficulty.go BigToCompact 100.00% (16/16) +github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) github.com/conformal/btcchain/txlookup.go disconnectTransactions 100.00% (13/13) github.com/conformal/btcchain/difficulty.go CompactToBig 100.00% (12/12) github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/merkle.go hashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) -github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) +github.com/conformal/btcchain/merkle.go HashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) -github.com/conformal/btcchain/chain.go New 100.00% (2/2) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/chain.go New 100.00% (2/2) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) github.com/conformal/btcchain/validate.go CalcBlockSubsidy 100.00% (1/1) github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) @@ -33,12 +33,12 @@ github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% github.com/conformal/btcchain/scriptval.go txValidator.Validate 88.46% (23/26) github.com/conformal/btcchain/scriptval.go checkBlockScripts 88.24% (15/17) github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.96% (20/23) +github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 85.71% (12/14) github.com/conformal/btcchain/validate.go IsCoinBase 85.71% (6/7) -github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) +github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.29% (29/34) github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) -github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) @@ -57,12 +57,12 @@ github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 59.26% (16/27) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 53.85% (14/26) -github.com/conformal/btcchain/validate.go checkProofOfWork 53.33% (8/15) +github.com/conformal/btcchain/validate.go CheckProofOfWork 53.33% (8/15) github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 52.27% (23/44) github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 51.28% (40/78) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) -github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) @@ -72,25 +72,26 @@ github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) github.com/conformal/btcchain/validate.go CountP2SHSigOps 0.00% (0/26) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) -github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) +github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/10) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) -github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) +github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) -github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) +github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 56.57% (706/1248) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) +github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 56.50% (704/1246) From d4082e4f24fa58fd910b6e2bf23f6ba64e06d1c9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 23 May 2014 13:44:23 -0500 Subject: [PATCH 137/190] Add checkpoint at block height 300255. --- checkpoints.go | 1 + 1 file changed, 1 insertion(+) diff --git a/checkpoints.go b/checkpoints.go index ade891d9..696dbdb0 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -59,6 +59,7 @@ var checkpointDataMainNet = checkpointData{ {250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, {267300, newShaHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, {279000, newShaHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, + {300255, newShaHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")}, }, checkpointsByHeight: nil, // Automatically generated in init. } From 4579cfb71b79ce14d26b7aac67d4a67bbefd2dad Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 26 May 2014 10:27:50 -0500 Subject: [PATCH 138/190] Refactor several network-specific params to btcnet. This commit refactors the code to make use of the btcnet package for network-specific parameters instead of switching on the specific network. For example, the percentage of the network that needs to run version 2 blocks is different between testnet and mainnet. Previously the code was using a switch to choose these values. With this refactor, those parameters are part of the network parameters provided when creating a new chain instance. Another example is checkpoints, which have been moved to btcnet so they can be specified by the caller instead of hard coded into this package. As a result, the checkpoints for the standard networks are now specified in the btcnet package. This makes it easier to add new networks such as a testnet4 should it become needed. It also allows callers to define their own custom network parameters without having to modify the code of the package to add new switch cases for the custom network. --- accept.go | 38 +++++----------- blocklocator.go | 4 +- chain.go | 71 +++++++++++++++++------------- checkpoints.go | 111 ++++++----------------------------------------- common_test.go | 3 +- difficulty.go | 52 ++++++++-------------- doc.go | 12 ++--- params.go | 101 ------------------------------------------ process.go | 2 +- validate.go | 15 ++++--- validate_test.go | 3 +- 11 files changed, 106 insertions(+), 306 deletions(-) delete mode 100644 params.go diff --git a/accept.go b/accept.go index e3087fff..a10035e0 100644 --- a/accept.go +++ b/accept.go @@ -7,7 +7,6 @@ package btcchain import ( "fmt" "github.com/conformal/btcutil" - "github.com/conformal/btcwire" ) // maybeAcceptBlock potentially accepts a block into the memory block chain. @@ -109,21 +108,12 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error if !fastAdd { // Reject version 1 blocks once a majority of the network has - // upgraded. - // Rules: - // 95% (950 / 1000) for main network - // 75% (75 / 100) for the test network - // This is part of BIP_0034. + // upgraded. This is part of BIP0034. if blockHeader.Version == 1 { - minRequired := uint64(950) - numToCheck := uint64(1000) - if b.btcnet == btcwire.TestNet3 || b.btcnet == - btcwire.TestNet { - minRequired = 75 - numToCheck = 100 - } - if b.isMajorityVersion(2, prevNode, minRequired, - numToCheck) { + if b.isMajorityVersion(2, prevNode, + b.netParams.BlockV1RejectNumRequired, + b.netParams.BlockV1RejectNumToCheck) { + str := "new blocks with version %d are no longer valid" str = fmt.Sprintf(str, blockHeader.Version) return RuleError(str) @@ -132,21 +122,13 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error // Ensure coinbase starts with serialized block heights for // blocks whose version is the serializedHeightVersion or - // newer once a majority of the network has upgraded. - // Rules: - // 75% (750 / 1000) for main network - // 51% (51 / 100) for the test network - // This is part of BIP_0034. + // newer once a majority of the network has upgraded. This is + // part of BIP0034. if blockHeader.Version >= serializedHeightVersion { - minRequired := uint64(750) - numToCheck := uint64(1000) - if b.btcnet == btcwire.TestNet3 || b.btcnet == - btcwire.TestNet { - minRequired = 51 - numToCheck = 100 - } if b.isMajorityVersion(serializedHeightVersion, - prevNode, minRequired, numToCheck) { + prevNode, + b.netParams.CoinbaseBlockHeightNumRequired, + b.netParams.CoinbaseBlockHeightNumToCheck) { expectedHeight := int64(0) if prevNode != nil { diff --git a/blocklocator.go b/blocklocator.go index 5a1dd150..136236cb 100644 --- a/blocklocator.go +++ b/blocklocator.go @@ -41,7 +41,7 @@ func (b *BlockChain) BlockLocatorFromHash(hash *btcwire.ShaHash) BlockLocator { locator = append(locator, hash) // Nothing more to do if a locator for the genesis hash was requested. - if hash.IsEqual(b.chainParams().GenesisHash) { + if hash.IsEqual(b.netParams.GenesisHash) { return locator } @@ -124,7 +124,7 @@ func (b *BlockChain) BlockLocatorFromHash(hash *btcwire.ShaHash) BlockLocator { } // Append the appropriate genesis block. - locator = append(locator, b.chainParams().GenesisHash) + locator = append(locator, b.netParams.GenesisHash) return locator } diff --git a/chain.go b/chain.go index a587ac24..f78506a9 100644 --- a/chain.go +++ b/chain.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "github.com/conformal/btcdb" + "github.com/conformal/btcnet" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math/big" @@ -140,22 +141,23 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { // follow all rules, orphan handling, checkpoint handling, and best chain // selection with reorganization. type BlockChain struct { - db btcdb.Db - btcnet btcwire.BitcoinNet - notifications NotificationCallback - root *blockNode - bestChain *blockNode - index map[btcwire.ShaHash]*blockNode - depNodes map[btcwire.ShaHash][]*blockNode - orphans map[btcwire.ShaHash]*orphanBlock - prevOrphans map[btcwire.ShaHash][]*orphanBlock - oldestOrphan *orphanBlock - orphanLock sync.RWMutex - blockCache map[btcwire.ShaHash]*btcutil.Block - noVerify bool - noCheckpoints bool - nextCheckpoint *Checkpoint - checkpointBlock *btcutil.Block + db btcdb.Db + netParams *btcnet.Params + checkpointsByHeight map[int64]*btcnet.Checkpoint + notifications NotificationCallback + root *blockNode + bestChain *blockNode + index map[btcwire.ShaHash]*blockNode + depNodes map[btcwire.ShaHash][]*blockNode + orphans map[btcwire.ShaHash]*orphanBlock + prevOrphans map[btcwire.ShaHash][]*orphanBlock + oldestOrphan *orphanBlock + orphanLock sync.RWMutex + blockCache map[btcwire.ShaHash]*btcutil.Block + noVerify bool + noCheckpoints bool + nextCheckpoint *btcnet.Checkpoint + checkpointBlock *btcutil.Block } // DisableVerify provides a mechanism to disable transaction script validation @@ -500,7 +502,7 @@ func (b *BlockChain) getPrevNodeFromNode(node *blockNode) (*blockNode, error) { } // Genesis block. - if node.hash.IsEqual(b.chainParams().GenesisHash) { + if node.hash.IsEqual(b.netParams.GenesisHash) { return nil, nil } @@ -633,7 +635,7 @@ func (b *BlockChain) isMajorityVersion(minVer uint32, startNode *blockNode, numR func (b *BlockChain) calcPastMedianTime(startNode *blockNode) (time.Time, error) { // Genesis block. if startNode == nil { - return b.chainParams().GenesisBlock.Header.Timestamp, nil + return b.netParams.GenesisBlock.Header.Timestamp, nil } // Create a slice of the previous few block timestamps used to calculate @@ -1015,18 +1017,29 @@ func (b *BlockChain) IsCurrent() bool { // Notification and NotificationType for details on the types and contents of // notifications. The provided callback can be nil if the caller is not // interested in receiving notifications. -func New(db btcdb.Db, btcnet btcwire.BitcoinNet, c NotificationCallback) *BlockChain { +func New(db btcdb.Db, params *btcnet.Params, c NotificationCallback) *BlockChain { + // Generate a checkpoint by height map from the provided checkpoints. + var checkpointsByHeight map[int64]*btcnet.Checkpoint + if len(params.Checkpoints) > 0 { + checkpointsByHeight = make(map[int64]*btcnet.Checkpoint) + for i := range params.Checkpoints { + checkpoint := ¶ms.Checkpoints[i] + checkpointsByHeight[checkpoint.Height] = checkpoint + } + } + b := BlockChain{ - db: db, - btcnet: btcnet, - notifications: c, - root: nil, - bestChain: nil, - index: make(map[btcwire.ShaHash]*blockNode), - depNodes: make(map[btcwire.ShaHash][]*blockNode), - orphans: make(map[btcwire.ShaHash]*orphanBlock), - prevOrphans: make(map[btcwire.ShaHash][]*orphanBlock), - blockCache: make(map[btcwire.ShaHash]*btcutil.Block), + db: db, + netParams: params, + checkpointsByHeight: checkpointsByHeight, + notifications: c, + root: nil, + bestChain: nil, + index: make(map[btcwire.ShaHash]*blockNode), + depNodes: make(map[btcwire.ShaHash][]*blockNode), + orphans: make(map[btcwire.ShaHash]*orphanBlock), + prevOrphans: make(map[btcwire.ShaHash][]*orphanBlock), + blockCache: make(map[btcwire.ShaHash]*btcutil.Block), } return &b } diff --git a/checkpoints.go b/checkpoints.go index 696dbdb0..0b6dbc2a 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -6,6 +6,7 @@ package btcchain import ( "fmt" + "github.com/conformal/btcnet" "github.com/conformal/btcscript" "github.com/conformal/btcutil" "github.com/conformal/btcwire" @@ -15,64 +16,6 @@ import ( // best block chain that a good checkpoint candidate must be. const CheckpointConfirmations = 2016 -// Checkpoint identifies a known good point in the block chain. Using -// checkpoints allows a few optimizations for old blocks during initial download -// and also prevents forks from old blocks. -// -// Each checkpoint is selected by the core developers based upon several -// factors. See the documentation for IsCheckpointCandidate for details -// on the selection criteria. -// -// As alluded to above, this package provides an IsCheckpointCandidate function -// which programatically identifies a block as a checkpoint candidate. The idea -// is that candidates are reviewed by a developer to make the final decision and -// then manually added to the list of checkpoints. -type Checkpoint struct { - Height int64 - Hash *btcwire.ShaHash -} - -// checkpointData groups checkpoints and other pertinent checkpoint data into -// a single type. -type checkpointData struct { - // Checkpoints ordered from oldest to newest. - checkpoints []Checkpoint - - // A map that will be automatically generated with the heights from - // the checkpoints as keys. - checkpointsByHeight map[int64]*Checkpoint -} - -// checkpointDataMainNet contains checkpoint data for the main network. -var checkpointDataMainNet = checkpointData{ - checkpoints: []Checkpoint{ - {11111, newShaHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, - {33333, newShaHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, - {74000, newShaHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, - {105000, newShaHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, - {134444, newShaHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, - {168000, newShaHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, - {193000, newShaHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, - {210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, - {216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, - {225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, - {250000, newShaHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, - {267300, newShaHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")}, - {279000, newShaHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, - {300255, newShaHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")}, - }, - checkpointsByHeight: nil, // Automatically generated in init. -} - -// checkpointDataTestNet3 contains checkpoint data for the test network (version -// 3). -var checkpointDataTestNet3 = checkpointData{ - checkpoints: []Checkpoint{ - {546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, - }, - checkpointsByHeight: nil, // Automatically generated in init. -} - // newShaHashFromStr converts the passed big-endian hex string into a // btcwire.ShaHash. It only differs from the one available in btcwire in that // it ignores the error since it will only (and must only) be called with @@ -89,38 +32,26 @@ func (b *BlockChain) DisableCheckpoints(disable bool) { b.noCheckpoints = disable } -// checkpointData returns the appropriate checkpoint data set depending on the -// network configured for the block chain. -func (b *BlockChain) checkpointData() *checkpointData { - switch b.btcnet { - case btcwire.TestNet3: - return &checkpointDataTestNet3 - case btcwire.MainNet: - return &checkpointDataMainNet - } - return nil -} - // Checkpoints returns a slice of checkpoints (regardless of whether they are // already known). When checkpoints are disabled or there are no checkpoints // for the active network, it will return nil. -func (b *BlockChain) Checkpoints() []Checkpoint { - if b.noCheckpoints || b.checkpointData() == nil { +func (b *BlockChain) Checkpoints() []btcnet.Checkpoint { + if b.noCheckpoints || len(b.netParams.Checkpoints) == 0 { return nil } - return b.checkpointData().checkpoints + return b.netParams.Checkpoints } // LatestCheckpoint returns the most recent checkpoint (regardless of whether it // is already known). When checkpoints are disabled or there are no checkpoints // for the active network, it will return nil. -func (b *BlockChain) LatestCheckpoint() *Checkpoint { - if b.noCheckpoints || b.checkpointData() == nil { +func (b *BlockChain) LatestCheckpoint() *btcnet.Checkpoint { + if b.noCheckpoints || len(b.netParams.Checkpoints) == 0 { return nil } - checkpoints := b.checkpointData().checkpoints + checkpoints := b.netParams.Checkpoints return &checkpoints[len(checkpoints)-1] } @@ -128,12 +59,12 @@ func (b *BlockChain) LatestCheckpoint() *Checkpoint { // match the hard-coded checkpoint data. It also returns true if there is no // checkpoint data for the passed block height. func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool { - if b.noCheckpoints || b.checkpointData() == nil { + if b.noCheckpoints || len(b.netParams.Checkpoints) == 0 { return true } // Nothing to check if there is no checkpoint data for the block height. - checkpoint, exists := b.checkpointData().checkpointsByHeight[height] + checkpoint, exists := b.checkpointsByHeight[height] if !exists { return true } @@ -152,12 +83,12 @@ func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool // associated block. It returns nil if a checkpoint can't be found (this should // really only happen for blocks before the first checkpoint). func (b *BlockChain) findPreviousCheckpoint() (*btcutil.Block, error) { - if b.noCheckpoints || b.checkpointData() == nil { + if b.noCheckpoints || len(b.netParams.Checkpoints) == 0 { return nil, nil } // No checkpoints. - checkpoints := b.checkpointData().checkpoints + checkpoints := b.netParams.Checkpoints numCheckpoints := len(checkpoints) if numCheckpoints == 0 { return nil, nil @@ -275,6 +206,9 @@ func isNonstandardTransaction(tx *btcutil.Tx) bool { // (due to the median time allowance this is not always the case) // - The block must not contain any strange transaction such as those with // nonstandard scripts +// +// The intent is that candidates are reviewed by a developer to make the final +// decision and then manually added to the list of checkpoints for a network. func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { // Checkpoints must be enabled. if b.noCheckpoints { @@ -339,20 +273,3 @@ func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { return true, nil } - -// init is called on package load. -func init() { - // Generate the checkpoint by height maps from the checkpoint data - // when the package loads. - checkpointInitializeList := []*checkpointData{ - &checkpointDataMainNet, - &checkpointDataTestNet3, - } - for _, data := range checkpointInitializeList { - data.checkpointsByHeight = make(map[int64]*Checkpoint) - for i := range data.checkpoints { - checkpoint := &data.checkpoints[i] - data.checkpointsByHeight[checkpoint.Height] = checkpoint - } - } -} diff --git a/common_test.go b/common_test.go index d84d9f93..b98592b1 100644 --- a/common_test.go +++ b/common_test.go @@ -10,6 +10,7 @@ import ( "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" _ "github.com/conformal/btcdb/memdb" + "github.com/conformal/btcnet" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "os" @@ -110,6 +111,6 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { return nil, nil, err } - chain := btcchain.New(db, btcwire.MainNet, nil) + chain := btcchain.New(db, btcnet.MainNetParams, nil) return chain, teardown, nil } diff --git a/difficulty.go b/difficulty.go index 99168aea..08a110ef 100644 --- a/difficulty.go +++ b/difficulty.go @@ -193,19 +193,12 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) durationVal := int64(duration) adjustmentFactor := big.NewInt(retargetAdjustmentFactor) - // Choose the correct proof of work limit for the active network. - powLimit := b.chainParams().PowLimit - powLimitBits := b.chainParams().PowLimitBits - // The test network rules allow minimum difficulty blocks after more // than twice the desired amount of time needed to generate a block has // elapsed. - switch b.btcnet { - case btcwire.TestNet: - fallthrough - case btcwire.TestNet3: + if b.netParams.ResetMinDifficulty { if durationVal > int64(targetSpacing)*2 { - return powLimitBits + return b.netParams.PowLimitBits } } @@ -214,14 +207,14 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) // the number of retargets for the duration and starting difficulty // multiplied by the max adjustment factor. newTarget := CompactToBig(bits) - for durationVal > 0 && newTarget.Cmp(powLimit) < 0 { + for durationVal > 0 && newTarget.Cmp(b.netParams.PowLimit) < 0 { newTarget.Mul(newTarget, adjustmentFactor) durationVal -= maxRetargetTimespan } // Limit new value to the proof of work limit. - if newTarget.Cmp(powLimit) > 0 { - newTarget.Set(powLimit) + if newTarget.Cmp(b.netParams.PowLimit) > 0 { + newTarget.Set(b.netParams.PowLimit) } return BigToCompact(newTarget) @@ -232,9 +225,10 @@ func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) { // Search backwards through the chain for the last block without // the special rule applied. - powLimitBits := b.chainParams().PowLimitBits iterNode := startNode - for iterNode != nil && iterNode.height%BlocksPerRetarget != 0 && iterNode.bits == powLimitBits { + for iterNode != nil && iterNode.height%BlocksPerRetarget != 0 && + iterNode.bits == b.netParams.PowLimitBits { + // Get the previous block node. This function is used over // simply accessing iterNode.parent directly as it will // dynamically create previous block nodes as needed. This @@ -250,7 +244,7 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er // Return the found difficulty or the minimum difficulty if no // appropriate block was found. - lastBits := powLimitBits + lastBits := b.netParams.PowLimitBits if iterNode != nil { lastBits = iterNode.bits } @@ -263,32 +257,24 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er // the exported version uses the current best chain as the previous block node // while this function accepts any block node. func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTime time.Time) (uint32, error) { - // Choose the correct proof of work limit for the active network. - powLimit := b.chainParams().PowLimit - powLimitBits := b.chainParams().PowLimitBits - // Genesis block. if lastNode == nil { - return powLimitBits, nil + return b.netParams.PowLimitBits, nil } // Return the previous block's difficulty requirements if this block // is not at a difficulty retarget interval. if (lastNode.height+1)%BlocksPerRetarget != 0 { - // The difficulty rules differ between networks. - switch b.btcnet { // The test network rules allow minimum difficulty blocks after // more than twice the desired amount of time needed to generate // a block has elapsed. - case btcwire.TestNet: - fallthrough - case btcwire.TestNet3: + if b.netParams.ResetMinDifficulty { // Return minimum difficulty when more than twice the // desired amount of time needed to generate a block has // elapsed. allowMinTime := lastNode.timestamp.Add(targetSpacing * 2) if newBlockTime.After(allowMinTime) { - return powLimitBits, nil + return b.netParams.PowLimitBits, nil } // The block was mined within the desired timeframe, so @@ -299,15 +285,11 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim return 0, err } return prevBits, nil + } // For the main network (or any unrecognized networks), simply - // return the previous block's difficulty. - case btcwire.MainNet: - fallthrough - default: - // Return the previous block's difficulty requirements. - return lastNode.bits, nil - } + // return the previous block's difficulty requirements. + return lastNode.bits, nil } // Get the block node at the previous retarget (targetTimespan days @@ -350,8 +332,8 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTim newTarget.Div(newTarget, big.NewInt(int64(targetTimespan))) // Limit new value to the proof of work limit. - if newTarget.Cmp(powLimit) > 0 { - newTarget.Set(powLimit) + if newTarget.Cmp(b.netParams.PowLimit) > 0 { + newTarget.Set(b.netParams.PowLimit) } // Log new target difficulty and return it. The new target logging is diff --git a/doc.go b/doc.go index 33a27b80..cbe2f9a7 100644 --- a/doc.go +++ b/doc.go @@ -73,8 +73,8 @@ intentionally causes an error by attempting to process a duplicate block. "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" + "github.com/conformal/btcnet" "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "os" ) @@ -85,20 +85,20 @@ intentionally causes an error by attempting to process a duplicate block. // calls to os.Remove would not be used either, but again, we want // a complete working example here, so we make sure to remove the // database. - dbName := "example.db" - _ = os.Remove(dbName) + dbName := "exampledb" + _ = os.RemoveAll(dbName) db, err := btcdb.CreateDB("leveldb", dbName) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } - defer os.Remove(dbName) // Ignore error. + defer os.RemoveAll(dbName) // Ignore error. defer db.Close() // Insert the main network genesis block. This is part of the initial // database setup. Like above, this typically would not be needed when // opening an existing database. - genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) + genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock) _, err = db.InsertBlock(genesisBlock) if err != nil { fmt.Printf("Failed to insert genesis block: %v\n", err) @@ -107,7 +107,7 @@ intentionally causes an error by attempting to process a duplicate block. // Create a new BlockChain instance using the underlying database for // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, btcwire.MainNet, nil) + chain := btcchain.New(db, btcnet.MainNetParams, nil) // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already diff --git a/params.go b/params.go deleted file mode 100644 index 1ce1fec2..00000000 --- a/params.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2013-2014 Conformal Systems LLC. -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package btcchain - -import ( - "github.com/conformal/btcwire" - "math/big" -) - -// Params houses parameters unique to various bitcoin networks such as the main -// network and test networks. See ChainParams. -type Params struct { - // GenesisBlock is the genesis block for the specific network. - GenesisBlock *btcwire.MsgBlock - - // GenesisHash is the genesis block hash for the specific network. - GenesisHash *btcwire.ShaHash - - // PowLimit is the highest proof of work value a bitcoin block can have - // for the specific network. - PowLimit *big.Int - - // PowLimitBits is the highest proof of work value a bitcoin block can - // have represented in compact form. See CompactToBig for more details - // on compact form. - PowLimitBits uint32 - - // SubsidyHalvingInterval is the interval of blocks at which the - // baseSubsidy is continually halved. Mathematically this is: - // baseSubsidy / 2^(height/SubsidyHalvingInterval) - SubsidyHalvingInterval int64 -} - -// mainPowLimit is the highest proof of work value a bitcoin block can have for -// the main network. It is the value 2^224 - 1. -var mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) - -// mainNetParams contains parameters specific to the main network -// (btcwire.MainNet). -var mainNetParams = Params{ - GenesisBlock: &btcwire.GenesisBlock, - GenesisHash: &btcwire.GenesisHash, - PowLimit: mainPowLimit, - PowLimitBits: BigToCompact(mainPowLimit), - SubsidyHalvingInterval: 210000, -} - -// regressionPowLimit is the highest proof of work value a bitcoin block can -// have for the regression test network. It is the value 2^255 - 1. -var regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne) - -// regressionParams contains parameters specific to the regression test network -// (btcwire.TestNet). -var regressionParams = Params{ - GenesisBlock: &btcwire.TestNetGenesisBlock, - GenesisHash: &btcwire.TestNetGenesisHash, - PowLimit: regressionPowLimit, - PowLimitBits: BigToCompact(regressionPowLimit), - SubsidyHalvingInterval: 150, -} - -// testNetPowLimit is the highest proof of work value a bitcoin block can have -// for the test network (version 3). It is the value 2^224 - 1. -var testNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne) - -// testNet3Params contains parameters specific to the test network (version 3) -// (btcwire.TestNet3). -var testNet3Params = Params{ - GenesisBlock: &btcwire.TestNet3GenesisBlock, - GenesisHash: &btcwire.TestNet3GenesisHash, - PowLimit: testNetPowLimit, - PowLimitBits: BigToCompact(testNetPowLimit), - SubsidyHalvingInterval: 210000, -} - -// chainParams returns chain parameters specific to the bitcoin network -// associated with the BlockChain instance. -func (b *BlockChain) chainParams() *Params { - return ChainParams(b.btcnet) -} - -// ChainParams returns chain parameters specific to the passed bitcoin network. -// It returns the parameters for btcwire.MainNet if the passed network is not -// supported. -func ChainParams(btcnet btcwire.BitcoinNet) *Params { - switch btcnet { - case btcwire.TestNet: - return ®ressionParams - - case btcwire.TestNet3: - return &testNet3Params - - // Return main net by default. - case btcwire.MainNet: - fallthrough - default: - return &mainNetParams - } -} diff --git a/process.go b/process.go index a9d26a8c..37d97f58 100644 --- a/process.go +++ b/process.go @@ -112,7 +112,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { } // Perform preliminary sanity checks on the block and its transactions. - err = CheckBlockSanity(block, b.chainParams().PowLimit) + err = CheckBlockSanity(block, b.netParams.PowLimit) if err != nil { return err } diff --git a/validate.go b/validate.go index d2738798..f59d3189 100644 --- a/validate.go +++ b/validate.go @@ -8,6 +8,7 @@ import ( "encoding/binary" "fmt" "github.com/conformal/btcdb" + "github.com/conformal/btcnet" "github.com/conformal/btcscript" "github.com/conformal/btcutil" "github.com/conformal/btcwire" @@ -165,10 +166,13 @@ func isBIP0030Node(node *blockNode) bool { // // At the target block generation rate for the main network, this is // approximately every 4 years. -func CalcBlockSubsidy(height int64, btcnet btcwire.BitcoinNet) int64 { +func CalcBlockSubsidy(height int64, netParams *btcnet.Params) int64 { + if netParams.SubsidyHalvingInterval == 0 { + return baseSubsidy + } + // Equivalent to: baseSubsidy / 2^(height/subsidyHalvingInterval) - return baseSubsidy >> - uint(height/ChainParams(btcnet).SubsidyHalvingInterval) + return baseSubsidy >> uint(height/int64(netParams.SubsidyHalvingInterval)) } // CheckTransactionSanity performs some preliminary checks on a transaction to @@ -728,7 +732,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // The coinbase for the Genesis block is not spendable, so just return // now. - if node.hash.IsEqual(b.chainParams().GenesisHash) && b.bestChain == nil { + if node.hash.IsEqual(b.netParams.GenesisHash) && b.bestChain == nil { return nil } @@ -836,7 +840,8 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er for _, txOut := range transactions[0].MsgTx().TxOut { totalSatoshiOut += txOut.Value } - expectedSatoshiOut := CalcBlockSubsidy(node.height, b.btcnet) + totalFees + expectedSatoshiOut := CalcBlockSubsidy(node.height, b.netParams) + + totalFees if totalSatoshiOut > expectedSatoshiOut { str := fmt.Sprintf("coinbase transaction for block pays %v "+ "which is more than expected value of %v", diff --git a/validate_test.go b/validate_test.go index 0157cedd..2710e061 100644 --- a/validate_test.go +++ b/validate_test.go @@ -6,6 +6,7 @@ package btcchain_test import ( "github.com/conformal/btcchain" + "github.com/conformal/btcnet" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "math" @@ -39,7 +40,7 @@ func TestCheckConnectBlock(t *testing.T) { } func TestCheckBlockSanity(t *testing.T) { - powLimit := btcchain.ChainParams(btcwire.MainNet).PowLimit + powLimit := btcnet.MainNetParams.PowLimit block := btcutil.NewBlock(&Block100000) err := btcchain.CheckBlockSanity(block, powLimit) if err != nil { From f37a5e76b5213538ce800385c4e7f2d8e38c191c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 27 May 2014 10:15:35 -0500 Subject: [PATCH 139/190] Update tests for recent API changes. --- common_test.go | 2 +- test_coverage.txt | 54 ++++++++++++++++++++++------------------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/common_test.go b/common_test.go index b98592b1..1cfed1ed 100644 --- a/common_test.go +++ b/common_test.go @@ -111,6 +111,6 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { return nil, nil, err } - chain := btcchain.New(db, btcnet.MainNetParams, nil) + chain := btcchain.New(db, &btcnet.MainNetParams, nil) return chain, teardown, nil } diff --git a/test_coverage.txt b/test_coverage.txt index b601e8de..08f15eeb 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,32 +1,28 @@ github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) -github.com/conformal/btcchain/difficulty.go BigToCompact 100.00% (16/16) github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) github.com/conformal/btcchain/txlookup.go disconnectTransactions 100.00% (13/13) github.com/conformal/btcchain/difficulty.go CompactToBig 100.00% (12/12) github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) +github.com/conformal/btcchain/chain.go New 100.00% (8/8) github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) -github.com/conformal/btcchain/checkpoints.go init 100.00% (6/6) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/merkle.go HashMerkleBranches 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) -github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) +github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/chain.go New 100.00% (2/2) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) -github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) +github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/params.go BlockChain.chainParams 100.00% (1/1) -github.com/conformal/btcchain/validate.go CalcBlockSubsidy 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) @@ -46,52 +42,52 @@ github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 77.27% (17/22) github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 75.00% (18/24) +github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/validate.go isTransactionSpent 75.00% (3/4) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 71.15% (37/52) github.com/conformal/btcchain/validate.go CheckBlockSanity 67.44% (29/43) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) +github.com/conformal/btcchain/validate.go CalcBlockSubsidy 66.67% (2/3) github.com/conformal/btcchain/validate.go CheckTransactionInputs 65.12% (28/43) github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) -github.com/conformal/btcchain/params.go ChainParams 60.00% (3/5) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 59.26% (16/27) -github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 53.85% (14/26) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 54.41% (37/68) github.com/conformal/btcchain/validate.go CheckProofOfWork 53.33% (8/15) github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 52.27% (23/44) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 51.28% (40/78) +github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 52.00% (13/25) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) -github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) +github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 17.07% (7/41) +github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 11.11% (4/36) github.com/conformal/btcchain/checkpoints.go BlockChain.findPreviousCheckpoint 4.88% (2/41) github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) github.com/conformal/btcchain/validate.go CountP2SHSigOps 0.00% (0/26) -github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/15) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) -github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/12) +github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/12) +github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/11) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/10) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) -github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) +github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/checkpoints.go BlockChain.checkpointData 0.00% (0/4) +github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) -github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) -github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 56.50% (704/1246) +github.com/conformal/btcchain ------------------------------------- 56.65% (690/1218) From b0b090009a7037c05b4c74899aa57b11cc5e3349 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 28 May 2014 00:55:22 -0500 Subject: [PATCH 140/190] Update README.md for btcnet changes. The sample code in doc.go was updated for the recent btcnet changes, however the sample code in the README.md was not. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f80ed381..67d9711b 100644 --- a/README.md +++ b/README.md @@ -83,8 +83,8 @@ intentionally causes an error by attempting to process a duplicate block. "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" + "github.com/conformal/btcnet" "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "os" ) @@ -95,20 +95,20 @@ intentionally causes an error by attempting to process a duplicate block. // calls to os.Remove would not be used either, but again, we want // a complete working example here, so we make sure to remove the // database. - dbName := "example.db" - _ = os.Remove(dbName) + dbName := "exampledb" + _ = os.RemoveAll(dbName) db, err := btcdb.CreateDB("leveldb", dbName) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } - defer os.Remove(dbName) // Ignore error. + defer os.RemoveAll(dbName) // Ignore error. defer db.Close() // Insert the main network genesis block. This is part of the initial // database setup. Like above, this typically would not be needed when // opening an existing database. - genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) + genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock) _, err = db.InsertBlock(genesisBlock) if err != nil { fmt.Printf("Failed to insert genesis block: %v\n", err) @@ -117,7 +117,7 @@ intentionally causes an error by attempting to process a duplicate block. // Create a new BlockChain instance using the underlying database for // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, btcwire.MainNet, nil) + chain := btcchain.New(db, &btcnet.MainNetParams, nil) // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already From 87bef61b3058e028088359f8557f755e483b70de Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 28 May 2014 00:56:57 -0500 Subject: [PATCH 141/190] Update tests to use btcnet genesis params. --- chain_test.go | 3 ++- common_test.go | 3 +-- validate_test.go | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/chain_test.go b/chain_test.go index 37659a02..2f600f1e 100644 --- a/chain_test.go +++ b/chain_test.go @@ -6,6 +6,7 @@ package btcchain_test import ( "github.com/conformal/btcchain" + "github.com/conformal/btcnet" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "testing" @@ -65,7 +66,7 @@ func TestHaveBlock(t *testing.T) { want bool }{ // Genesis block should be present (in the main chain). - {hash: btcwire.GenesisHash.String(), want: true}, + {hash: btcnet.MainNetParams.GenesisHash.String(), want: true}, // Block 3a should be present (on a side chain). {hash: "00000000474284d20067a4d33f6a02284e6ef70764a3a26d6a5b9df52ef663dd", want: true}, diff --git a/common_test.go b/common_test.go index 1cfed1ed..eceb51b5 100644 --- a/common_test.go +++ b/common_test.go @@ -12,7 +12,6 @@ import ( _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "os" "path/filepath" ) @@ -103,7 +102,7 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { // Insert the main network genesis block. This is part of the initial // database setup. - genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock) + genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock) _, err := db.InsertBlock(genesisBlock) if err != nil { teardown() diff --git a/validate_test.go b/validate_test.go index 2710e061..596c35c9 100644 --- a/validate_test.go +++ b/validate_test.go @@ -33,7 +33,8 @@ func TestCheckConnectBlock(t *testing.T) { // The genesis block should fail to connect since it's already // inserted. - err = chain.CheckConnectBlock(btcutil.NewBlock(&btcwire.GenesisBlock)) + genesisBlock := btcnet.MainNetParams.GenesisBlock + err = chain.CheckConnectBlock(btcutil.NewBlock(genesisBlock)) if err == nil { t.Errorf("CheckConnectBlock: Did not received expected error") } From 6e0aab52df3e3495939fbe6112d2fc5eb161792e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 24 Jun 2014 17:10:53 -0500 Subject: [PATCH 142/190] Improve the RuleError type to include error codes. This commit changes the RuleError type to a struct which consists of an error code and human-readable description. From a usage perspective, existing code should not break since type asserting an error to a RuleError still works in the same manner. The difference is the caller can now take that type asserted RuleError and access the .ErrorCode field on it to programmatically identify the specific rule that was violated. ok @jrick --- accept.go | 15 ++-- doc.go | 4 +- error.go | 218 +++++++++++++++++++++++++++++++++++++++++++++++ process.go | 19 +---- validate.go | 87 ++++++++++--------- validate_test.go | 30 +++++-- 6 files changed, 303 insertions(+), 70 deletions(-) create mode 100644 error.go diff --git a/accept.go b/accept.go index a10035e0..645d7ea7 100644 --- a/accept.go +++ b/accept.go @@ -47,7 +47,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error if blockDifficulty != expectedDifficulty { str := "block difficulty of %d is not the expected value of %d" str = fmt.Sprintf(str, blockDifficulty, expectedDifficulty) - return RuleError(str) + return ruleError(ErrUnexpectedDifficulty, str) } // Ensure the timestamp for the block header is after the @@ -61,7 +61,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error str := "block timestamp of %v is not after expected %v" str = fmt.Sprintf(str, blockHeader.Timestamp, medianTime) - return RuleError(str) + return ruleError(ErrTimeTooOld, str) } // Ensure all transactions in the block are finalized. @@ -70,7 +70,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error blockHeader.Timestamp) { str := fmt.Sprintf("block contains "+ "unfinalized transaction %v", tx.Sha()) - return RuleError(str) + return ruleError(ErrUnfinalizedTx, str) } } @@ -88,7 +88,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error // known good point. str := fmt.Sprintf("block at height %d does not match "+ "checkpoint hash", blockHeight) - return RuleError(str) + return ruleError(ErrBadCheckpoint, str) } // Find the previous checkpoint and prevent blocks which fork the main @@ -103,7 +103,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error str := fmt.Sprintf("block at height %d forks the main chain "+ "before the previous checkpoint at height %d", blockHeight, checkpointBlock.Height()) - return RuleError(str) + return ruleError(ErrForkTooOld, str) } if !fastAdd { @@ -114,9 +114,10 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error b.netParams.BlockV1RejectNumRequired, b.netParams.BlockV1RejectNumToCheck) { - str := "new blocks with version %d are no longer valid" + str := "new blocks with version %d are no " + + "longer valid" str = fmt.Sprintf(str, blockHeader.Version) - return RuleError(str) + return ruleError(ErrBlockVersionTooOld, str) } } diff --git a/doc.go b/doc.go index cbe2f9a7..68a7422a 100644 --- a/doc.go +++ b/doc.go @@ -124,7 +124,9 @@ Errors Errors returned by this package are either the raw errors provided by underlying calls or of type btcchain.RuleError. This allows the caller to differentiate between unexpected errors, such as database errors, versus errors due to rule -violations through type assertions. +violations through type assertions. In addition, callers can programmatically +determine the specific rule violation by examining the ErrorCode field of the +type asserted btcchain.RuleError. Bitcoin Improvement Proposals diff --git a/error.go b/error.go new file mode 100644 index 00000000..26071c97 --- /dev/null +++ b/error.go @@ -0,0 +1,218 @@ +// Copyright (c) 2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "fmt" +) + +// ErrorCode identifies a kind of error. +type ErrorCode int + +// These constants are used to identify a specific RuleError. +const ( + // ErrDuplicateBlock indicates a block with the same hash already + // exists. + ErrDuplicateBlock ErrorCode = iota + + // ErrBlockVersionTooOld indicates the block version is too old and is + // no longer accepted since the majority of the network has upgraded + // to a newer version. + ErrBlockVersionTooOld + + // ErrInvalidTime indicates the time in the passed block has a precision + // that is more than one second. The chain consensus rules require + // timestamps to have a maximum precision of one second. + ErrInvalidTime + + // ErrTimeTooOld indicates the time is either before the median time of + // the last several blocks per the chain consensus rules or prior to the + // most recent checkpoint. + ErrTimeTooOld + + // ErrTimeTooNew indicates the time is too far in the future as compared + // the current time. + ErrTimeTooNew + + // ErrDifficultyTooLow indicates the difficulty for the block is lower + // than the difficulty required by the most recent checkpoint. + ErrDifficultyTooLow + + // ErrUnexpectedDifficulty indicates specified bits do not align with + // the expected value either because it doesn't match the calculated + // valued based on difficulty regarted rules or it is out of the valid + // range. + ErrUnexpectedDifficulty + + // ErrHighHash indicates the block does not hash to a value which is + // lower than the required target difficultly. + ErrHighHash + + // ErrBadMerkleRoot indicates the calculated merkle root does not match + // the expected value. + ErrBadMerkleRoot + + // ErrBadCheckpoint indicates a block that is expected to be at a + // checkpoint height does not match the expected one. + ErrBadCheckpoint + + // ErrForkTooOld indicates a block is attempted to fork the block chain + // before the most recent checkpoint. + ErrForkTooOld + + // ErrNoTransactions indicates the block does not have a least one + // transaction. A valid block must have at least the coinbase + // transaction. + ErrNoTransactions + + // ErrNoTxInputs indicates a transaction does not have any inputs. A + // valid transaction must have at least one input. + ErrNoTxInputs + + // ErrNoTxOutputs indicates a transaction does not have any outputs. A + // valid transaction must have at least one output. + ErrNoTxOutputs + + // ErrBadTxOutValue indicates an output value for a transaction is + // invalid in some way such as being out of range. + ErrBadTxOutValue + + // ErrDuplicateTxInputs indicates a transaction references the same + // input more than once. + ErrDuplicateTxInputs + + // ErrBadTxInput indicates a transaction input is invalid in some way + // such as referencing a previous transaction outpoint which is out of + // range or not referencing one at all. + ErrBadTxInput + + // ErrMissingTx indicates a transaction referenced by an input is + // missing. + ErrMissingTx + + // ErrUnfinalizedTx indicates a transaction has not been finalized. + // A valid block may only contain finalized transactions. + ErrUnfinalizedTx + + // ErrDuplicateTx indicates a block contains an identical transaction + // (or at least two transactions which hash to the same value). A + // valid block may only contain unique transactions. + ErrDuplicateTx + + // ErrOverwriteTx indicates a block contains a transaction that has + // the same hash as a previous transaction which has not been fully + // spent. + ErrOverwriteTx + + // ErrImmatureSpend indicates a transaction is attempting to spend a + // coinbase that has not yet reached the required maturity. + ErrImmatureSpend + + // ErrDoubleSpend indicates a transaction is attempting to spend coins + // that have already been spent. + ErrDoubleSpend + + // ErrSpendTooHigh indicates a transaction is attempting to spend more + // value than the sum of all of its inputs. + ErrSpendTooHigh + + // ErrBadFees indicates the total fees for a block are invalid due to + // exceeding the maximum possible value. + ErrBadFees + + // ErrTooManySigOps indicates the total number of signature operations + // for a transaction or block exceed the maximum allowed limits. + ErrTooManySigOps + + // ErrFirstTxNotCoinbase indicates the first transaction in a block + // is not a coinbase transaction. + ErrFirstTxNotCoinbase + + // ErrMultipleCoinbases indicates a block contains more than one + // coinbase transaction. + ErrMultipleCoinbases + + // ErrBadCoinbaseScriptLen indicates the length of the signature script + // for a coinbase transaction is not within the valid range. + ErrBadCoinbaseScriptLen + + // ErrBadCoinbaseValue indicates the amount of a coinbase value does + // not match the expected value of the subsidy plus the sum of all fees. + ErrBadCoinbaseValue + + // ErrMissingCoinbaseHeight indicates the coinbase transaction for a + // block does not start with the serialized block block height as + // required for version 2 and higher blocks. + ErrMissingCoinbaseHeight + + // ErrBadCoinbaseHeight indicates the serialized block height in the + // coinbase transaction for version 2 and higher blocks does not match + // the expected value. + ErrBadCoinbaseHeight +) + +// Map of ErrorCode values back to their constant names for pretty printing. +var errorCodeStrings = map[ErrorCode]string{ + ErrDuplicateBlock: "ErrDuplicateBlock", + ErrBlockVersionTooOld: "ErrBlockVersionTooOld", + ErrInvalidTime: "ErrInvalidTime", + ErrTimeTooOld: "ErrTimeTooOld", + ErrTimeTooNew: "ErrTimeTooNew", + ErrDifficultyTooLow: "ErrDifficultyTooLow", + ErrUnexpectedDifficulty: "ErrUnexpectedDifficulty", + ErrHighHash: "ErrHighHash", + ErrBadMerkleRoot: "ErrBadMerkleRoot", + ErrBadCheckpoint: "ErrBadCheckpoint", + ErrForkTooOld: "ErrForkTooOld", + ErrNoTransactions: "ErrNoTransactions", + ErrNoTxInputs: "ErrNoTxInputs", + ErrNoTxOutputs: "ErrNoTxOutputs", + ErrBadTxOutValue: "ErrBadTxOutValue", + ErrDuplicateTxInputs: "ErrDuplicateTxInputs", + ErrBadTxInput: "ErrBadTxInput", + ErrMissingTx: "ErrMissingTx", + ErrUnfinalizedTx: "ErrUnfinalizedTx", + ErrDuplicateTx: "ErrDuplicateTx", + ErrOverwriteTx: "ErrOverwriteTx", + ErrImmatureSpend: "ErrImmatureSpend", + ErrDoubleSpend: "ErrDoubleSpend", + ErrSpendTooHigh: "ErrSpendTooHigh", + ErrBadFees: "ErrBadFees", + ErrTooManySigOps: "ErrTooManySigOps", + ErrFirstTxNotCoinbase: "ErrFirstTxNotCoinbase", + ErrMultipleCoinbases: "ErrMultipleCoinbases", + ErrBadCoinbaseScriptLen: "ErrBadCoinbaseScriptLen", + ErrBadCoinbaseValue: "ErrBadCoinbaseValue", + ErrMissingCoinbaseHeight: "ErrMissingCoinbaseHeight", + ErrBadCoinbaseHeight: "ErrBadCoinbaseHeight", +} + +// String returns the ErrorCode as a human-readable name. +func (e ErrorCode) String() string { + if s := errorCodeStrings[e]; s != "" { + return s + } + return fmt.Sprintf("Unknown ErrorCode (%d)", int(e)) +} + +// RuleError identifies a rule violation. It is used to indicate that +// processing of a block or transaction failed due to one of the many validation +// rules. The caller can use type assertions to determine if a failure was +// specifically due to a rule violation and access the ErrorCode field to +// ascertain the specific reason for the rule violation. +type RuleError struct { + ErrorCode ErrorCode // Describes the kind of error + Description string // Human readable description of the issue +} + +// Error satisfies the error interface and prints human-readable errors. +func (e RuleError) Error() string { + return e.Description +} + +// ruleError creates an RuleError given a set of arguments. +func ruleError(c ErrorCode, desc string) RuleError { + return RuleError{ErrorCode: c, Description: desc} +} diff --git a/process.go b/process.go index 37d97f58..e1fb7192 100644 --- a/process.go +++ b/process.go @@ -10,17 +10,6 @@ import ( "github.com/conformal/btcwire" ) -// RuleError identifies a rule violation. It is used to indicate that -// processing of a block or transaction failed due to one of the many validation -// rules. The caller can use type assertions to determine if a failure was -// specifically due to a rule violation. -type RuleError string - -// Error satisfies the error interface to print human-readable errors. -func (e RuleError) Error() string { - return string(e) -} - // blockExists determines whether a block with the given hash exists either in // the main chain or any side chains. func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { @@ -102,13 +91,13 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { // The block must not already exist in the main chain or side chains. if b.blockExists(blockHash) { str := fmt.Sprintf("already have block %v", blockHash) - return RuleError(str) + return ruleError(ErrDuplicateBlock, str) } // The block must not already exist as an orphan. if _, exists := b.orphans[*blockHash]; exists { str := fmt.Sprintf("already have block (orphan) %v", blockHash) - return RuleError(str) + return ruleError(ErrDuplicateBlock, str) } // Perform preliminary sanity checks on the block and its transactions. @@ -136,7 +125,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { str := fmt.Sprintf("block %v has timestamp %v before "+ "last checkpoint timestamp %v", blockHash, blockHeader.Timestamp, checkpointTime) - return RuleError(str) + return ruleError(ErrTimeTooOld, str) } if !fastAdd { // Even though the checks prior to now have already ensured the @@ -153,7 +142,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { str := fmt.Sprintf("block target difficulty of %064x "+ "is too low when compared to the previous "+ "checkpoint", currentTarget) - return RuleError(str) + return ruleError(ErrDifficultyTooLow, str) } } } diff --git a/validate.go b/validate.go index f59d3189..c50c095e 100644 --- a/validate.go +++ b/validate.go @@ -181,12 +181,12 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // A transaction must have at least one input. msgTx := tx.MsgTx() if len(msgTx.TxIn) == 0 { - return RuleError("transaction has no inputs") + return ruleError(ErrNoTxInputs, "transaction has no inputs") } // A transaction must have at least one output. if len(msgTx.TxOut) == 0 { - return RuleError("transaction has no outputs") + return ruleError(ErrNoTxOutputs, "transaction has no outputs") } // NOTE: bitcoind does size limits checking here, but the size limits @@ -206,13 +206,13 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { if satoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ "value of %v", satoshi) - return RuleError(str) + return ruleError(ErrBadTxOutValue, str) } if satoshi > btcutil.MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", satoshi, btcutil.MaxSatoshi) - return RuleError(str) + return ruleError(ErrBadTxOutValue, str) } // TODO(davec): No need to check < 0 here as satoshi is @@ -222,14 +222,14 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { if totalSatoshi < 0 { str := fmt.Sprintf("total value of all transaction "+ "outputs has negative value of %v", totalSatoshi) - return RuleError(str) + return ruleError(ErrBadTxOutValue, str) } if totalSatoshi > btcutil.MaxSatoshi { str := fmt.Sprintf("total value of all transaction "+ "outputs is %v which is higher than max "+ "allowed value of %v", totalSatoshi, btcutil.MaxSatoshi) - return RuleError(str) + return ruleError(ErrBadTxOutValue, str) } } @@ -237,7 +237,8 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { existingTxOut := make(map[btcwire.OutPoint]bool) for _, txIn := range msgTx.TxIn { if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists { - return RuleError("transaction contains duplicate outpoint") + return ruleError(ErrDuplicateTxInputs, "transaction "+ + "contains duplicate inputs") } existingTxOut[txIn.PreviousOutpoint] = true } @@ -249,7 +250,7 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { str := fmt.Sprintf("coinbase transaction script length "+ "of %d is out of range (min: %d, max: %d)", slen, MinCoinbaseScriptLen, MaxCoinbaseScriptLen) - return RuleError(str) + return ruleError(ErrBadCoinbaseScriptLen, str) } } else { // Previous transaction outputs referenced by the inputs to this @@ -257,8 +258,9 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { for _, txIn := range msgTx.TxIn { prevOut := &txIn.PreviousOutpoint if isNullOutpoint(prevOut) { - return RuleError("transaction input refers to " + - "previous output that is null") + return ruleError(ErrBadTxInput, "transaction "+ + "input refers to previous output that "+ + "is null") } } } @@ -275,14 +277,14 @@ func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { if target.Sign() <= 0 { str := fmt.Sprintf("block target difficulty of %064x is too low", target) - return RuleError(str) + return ruleError(ErrUnexpectedDifficulty, str) } // The target difficulty must be less than the maximum allowed. if target.Cmp(powLimit) > 0 { str := fmt.Sprintf("block target difficulty of %064x is "+ "higher than max of %064x", target, powLimit) - return RuleError(str) + return ruleError(ErrUnexpectedDifficulty, str) } // The block hash must be less than the claimed target. @@ -294,7 +296,7 @@ func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { if hashNum.Cmp(target) > 0 { str := fmt.Sprintf("block hash of %064x is higher than "+ "expected max of %064x", hashNum, target) - return RuleError(str) + return ruleError(ErrHighHash, str) } return nil @@ -347,7 +349,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e str := fmt.Sprintf("unable to find input transaction "+ "%v referenced from transaction %v", txInHash, tx.Sha()) - return 0, RuleError(str) + return 0, ruleError(ErrMissingTx, str) } originMsgTx := originTx.Tx.MsgTx() @@ -358,7 +360,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", originTxIndex, txInHash, tx.Sha()) - return 0, RuleError(str) + return 0, ruleError(ErrBadTxInput, str) } // We're only interested in pay-to-script-hash types, so skip @@ -383,7 +385,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e "output index %d in transaction %v contains "+ "too many signature operations - overflow", originTxIndex, txInHash) - return 0, RuleError(str) + return 0, ruleError(ErrTooManySigOps, str) } } @@ -415,25 +417,27 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { if !header.Timestamp.Equal(time.Unix(header.Timestamp.Unix(), 0)) { str := fmt.Sprintf("block timestamp of %v has a higher "+ "precision than one second", header.Timestamp) - return RuleError(str) + return ruleError(ErrInvalidTime, str) } // Ensure the block time is not more than 2 hours in the future. if header.Timestamp.After(time.Now().Add(time.Hour * 2)) { str := fmt.Sprintf("block timestamp of %v is too far in the "+ "future", header.Timestamp) - return RuleError(str) + return ruleError(ErrTimeTooNew, str) } // A block must have at least one transaction. transactions := block.Transactions() if len(transactions) == 0 { - return RuleError("block does not contain any transactions") + return ruleError(ErrNoTransactions, "block does not contain "+ + "any transactions") } // The first transaction in a block must be a coinbase. if !IsCoinBase(transactions[0]) { - return RuleError("first transaction in block is not a coinbase") + return ruleError(ErrFirstTxNotCoinbase, "first transaction in "+ + "block is not a coinbase") } // A block must not have more than one coinbase. @@ -441,7 +445,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { if IsCoinBase(tx) { str := fmt.Sprintf("block contains second coinbase at "+ "index %d", i) - return RuleError(str) + return ruleError(ErrMultipleCoinbases, str) } } @@ -466,7 +470,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { str := fmt.Sprintf("block merkle root is invalid - block "+ "header indicates %v, but calculated value is %v", header.MerkleRoot, calculatedMerkleRoot) - return RuleError(str) + return ruleError(ErrBadMerkleRoot, str) } // Check for duplicate transactions. This check will be fairly quick @@ -478,7 +482,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { if _, exists := existingTxHashes[*hash]; exists { str := fmt.Sprintf("block contains duplicate "+ "transaction %v", hash) - return RuleError(str) + return ruleError(ErrDuplicateTx, str) } existingTxHashes[*hash] = true } @@ -495,7 +499,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { str := fmt.Sprintf("block contains too many signature "+ "operations - got %v, max %v", totalSigOps, MaxSigOpsPerBlock) - return RuleError(str) + return ruleError(ErrTooManySigOps, str) } } @@ -511,7 +515,7 @@ func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { "version %d or greater must start with the " + "length of the serialized block height" str = fmt.Sprintf(str, serializedHeightVersion) - return RuleError(str) + return ruleError(ErrMissingCoinbaseHeight, str) } serializedLen := int(sigScript[0]) @@ -520,7 +524,7 @@ func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { "version %d or greater must start with the " + "serialized block height" str = fmt.Sprintf(str, serializedLen) - return RuleError(str) + return ruleError(ErrMissingCoinbaseHeight, str) } serializedHeightBytes := make([]byte, 8, 8) @@ -530,7 +534,7 @@ func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { str := fmt.Sprintf("the coinbase signature script serialized "+ "block height is %d when %d was expected", serializedHeight, wantHeight) - return RuleError(str) + return ruleError(ErrBadCoinbaseHeight, str) } return nil @@ -584,7 +588,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { "transaction %v at block height %d "+ "that is not fully spent", txD.Hash, txD.BlockHeight) - return RuleError(str) + return ruleError(ErrOverwriteTx, str) } // Some other unexpected error occurred. Return it now. @@ -619,7 +623,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input transaction "+ "%v for transaction %v", txInHash, txHash) - return 0, RuleError(str) + return 0, ruleError(ErrMissingTx, str) } // Ensure the transaction is not spending coins which have not @@ -633,22 +637,23 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in "height %v before required maturity "+ "of %v blocks", txInHash, originHeight, txHeight, coinbaseMaturity) - return 0, RuleError(str) + return 0, ruleError(ErrImmatureSpend, str) } } // Ensure the transaction is not double spending coins. originTxIndex := txIn.PreviousOutpoint.Index if originTxIndex >= uint32(len(originTx.Spent)) { - return 0, fmt.Errorf("out of bounds input index %d in "+ + str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", originTxIndex, txInHash, txHash) + return 0, ruleError(ErrBadTxInput, str) } if originTx.Spent[originTxIndex] { str := fmt.Sprintf("transaction %v tried to double "+ "spend coins from transaction %v", txHash, txInHash) - return 0, RuleError(str) + return 0, ruleError(ErrDoubleSpend, str) } // Ensure the transaction amounts are in range. Each of the @@ -661,13 +666,13 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in if originTxSatoshi < 0 { str := fmt.Sprintf("transaction output has negative "+ "value of %v", originTxSatoshi) - return 0, RuleError(str) + return 0, ruleError(ErrBadTxOutValue, str) } if originTxSatoshi > btcutil.MaxSatoshi { str := fmt.Sprintf("transaction output value of %v is "+ "higher than max allowed value of %v", originTxSatoshi, btcutil.MaxSatoshi) - return 0, RuleError(str) + return 0, ruleError(ErrBadTxOutValue, str) } // The total of all outputs must not be more than the max @@ -681,7 +686,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in "inputs is %v which is higher than max "+ "allowed value of %v", totalSatoshiIn, btcutil.MaxSatoshi) - return 0, RuleError(str) + return 0, ruleError(ErrBadTxOutValue, str) } // Mark the referenced output as spent. @@ -701,7 +706,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in str := fmt.Sprintf("total value of all transaction inputs for "+ "transaction %v is %v which is less than the amount "+ "spent of %v", txHash, totalSatoshiIn, totalSatoshiOut) - return 0, RuleError(str) + return 0, ruleError(ErrSpendTooHigh, str) } // NOTE: bitcoind checks if the transaction fees are < 0 here, but that @@ -725,7 +730,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in // checks performed by this function. func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) error { // If the side chain blocks end up in the database, a call to - // checkBlockSanity should be done here in case a previous version + // CheckBlockSanity should be done here in case a previous version // allowed a block that is no longer valid. However, since the // implementation only currently uses memory for the side chain blocks, // it isn't currently necessary. @@ -803,7 +808,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er str := fmt.Sprintf("block contains too many "+ "signature operations - got %v, max %v", totalSigOps, MaxSigOpsPerBlock) - return RuleError(str) + return ruleError(ErrTooManySigOps, str) } } @@ -826,8 +831,8 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er lastTotalFees := totalFees totalFees += txFee if totalFees < lastTotalFees { - return RuleError("total fees for block overflows " + - "accumulator") + return ruleError(ErrBadFees, "total fees for block "+ + "overflows accumulator") } } @@ -846,7 +851,7 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er str := fmt.Sprintf("coinbase transaction for block pays %v "+ "which is more than expected value of %v", totalSatoshiOut, expectedSatoshiOut) - return RuleError(str) + return ruleError(ErrBadCoinbaseValue, str) } // Don't run scripts if this node is before the latest known good diff --git a/validate_test.go b/validate_test.go index 596c35c9..d96c584b 100644 --- a/validate_test.go +++ b/validate_test.go @@ -68,28 +68,35 @@ func TestCheckSerializedHeight(t *testing.T) { coinbaseTx.Version = 2 coinbaseTx.AddTxIn(btcwire.NewTxIn(coinbaseOutpoint, nil)) - // + // Expected rule errors. + missingHeightError := btcchain.RuleError{ + ErrorCode: btcchain.ErrMissingCoinbaseHeight, + } + badHeightError := btcchain.RuleError{ + ErrorCode: btcchain.ErrBadCoinbaseHeight, + } + tests := []struct { sigScript []byte // Serialized data wantHeight int64 // Expected height err error // Expected error type }{ // No serialized height length. - {[]byte{}, 0, btcchain.RuleError("")}, + {[]byte{}, 0, missingHeightError}, // Serialized height length with no height bytes. - {[]byte{0x02}, 0, btcchain.RuleError("")}, + {[]byte{0x02}, 0, missingHeightError}, // Serialized height length with too few height bytes. - {[]byte{0x02, 0x4a}, 0, btcchain.RuleError("")}, + {[]byte{0x02, 0x4a}, 0, missingHeightError}, // Serialized height that needs 2 bytes to encode. {[]byte{0x02, 0x4a, 0x52}, 21066, nil}, // Serialized height that needs 2 bytes to encode, but backwards // endianness. - {[]byte{0x02, 0x4a, 0x52}, 19026, btcchain.RuleError("")}, + {[]byte{0x02, 0x4a, 0x52}, 19026, badHeightError}, // Serialized height that needs 3 bytes to encode. {[]byte{0x03, 0x40, 0x0d, 0x03}, 200000, nil}, // Serialized height that needs 3 bytes to encode, but backwards // endianness. - {[]byte{0x03, 0x40, 0x0d, 0x03}, 1074594560, btcchain.RuleError("")}, + {[]byte{0x03, 0x40, 0x0d, 0x03}, 1074594560, badHeightError}, } t.Logf("Running %d tests", len(tests)) @@ -104,6 +111,17 @@ func TestCheckSerializedHeight(t *testing.T) { "got: %v <%T>, want: %T", i, err, err, test.err) continue } + + if rerr, ok := err.(btcchain.RuleError); ok { + trerr := test.err.(btcchain.RuleError) + if rerr.ErrorCode != trerr.ErrorCode { + t.Errorf("checkSerializedHeight #%d wrong "+ + "error code got: %v, want: %v", i, + rerr.ErrorCode, trerr.ErrorCode) + continue + } + } + } } From 0550bbbdc5ea39f8c5e8490580dc03f0e7d9121d Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 24 Jun 2014 17:47:57 -0500 Subject: [PATCH 143/190] Add tests for new RuleError and ErrorCode types. --- error_test.go | 90 +++++++++++++++++++++++++++++++++++++++++++++++ test_coverage.txt | 44 ++++++++++++----------- 2 files changed, 113 insertions(+), 21 deletions(-) create mode 100644 error_test.go diff --git a/error_test.go b/error_test.go new file mode 100644 index 00000000..d1801d8f --- /dev/null +++ b/error_test.go @@ -0,0 +1,90 @@ +// Copyright (c) 2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "github.com/conformal/btcchain" + "testing" +) + +// TestErrorCodeStringer tests the stringized output for the ErrorCode type. +func TestErrorCodeStringer(t *testing.T) { + tests := []struct { + in btcchain.ErrorCode + want string + }{ + {btcchain.ErrDuplicateBlock, "ErrDuplicateBlock"}, + {btcchain.ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, + {btcchain.ErrInvalidTime, "ErrInvalidTime"}, + {btcchain.ErrTimeTooOld, "ErrTimeTooOld"}, + {btcchain.ErrTimeTooNew, "ErrTimeTooNew"}, + {btcchain.ErrDifficultyTooLow, "ErrDifficultyTooLow"}, + {btcchain.ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, + {btcchain.ErrHighHash, "ErrHighHash"}, + {btcchain.ErrBadMerkleRoot, "ErrBadMerkleRoot"}, + {btcchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, + {btcchain.ErrForkTooOld, "ErrForkTooOld"}, + {btcchain.ErrNoTransactions, "ErrNoTransactions"}, + {btcchain.ErrNoTxInputs, "ErrNoTxInputs"}, + {btcchain.ErrNoTxOutputs, "ErrNoTxOutputs"}, + {btcchain.ErrBadTxOutValue, "ErrBadTxOutValue"}, + {btcchain.ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, + {btcchain.ErrBadTxInput, "ErrBadTxInput"}, + {btcchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, + {btcchain.ErrMissingTx, "ErrMissingTx"}, + {btcchain.ErrUnfinalizedTx, "ErrUnfinalizedTx"}, + {btcchain.ErrDuplicateTx, "ErrDuplicateTx"}, + {btcchain.ErrOverwriteTx, "ErrOverwriteTx"}, + {btcchain.ErrImmatureSpend, "ErrImmatureSpend"}, + {btcchain.ErrDoubleSpend, "ErrDoubleSpend"}, + {btcchain.ErrSpendTooHigh, "ErrSpendTooHigh"}, + {btcchain.ErrBadFees, "ErrBadFees"}, + {btcchain.ErrTooManySigOps, "ErrTooManySigOps"}, + {btcchain.ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, + {btcchain.ErrMultipleCoinbases, "ErrMultipleCoinbases"}, + {btcchain.ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, + {btcchain.ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, + {btcchain.ErrMissingCoinbaseHeight, "ErrMissingCoinbaseHeight"}, + {btcchain.ErrBadCoinbaseHeight, "ErrBadCoinbaseHeight"}, + {0xffff, "Unknown ErrorCode (65535)"}, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + result := test.in.String() + if result != test.want { + t.Errorf("String #%d\n got: %s want: %s", i, result, + test.want) + continue + } + } +} + +// TestRuleError tests the error output for the RuleError type. +func TestRuleError(t *testing.T) { + tests := []struct { + in btcchain.RuleError + want string + }{ + { + btcchain.RuleError{Description: "duplicate block"}, + "duplicate block", + }, + { + btcchain.RuleError{Description: "human-readable error"}, + "human-readable error", + }, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + result := test.in.Error() + if result != test.want { + t.Errorf("Error #%d\n got: %s want: %s", i, result, + test.want) + continue + } + } +} diff --git a/test_coverage.txt b/test_coverage.txt index 08f15eeb..03540b43 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -7,22 +7,25 @@ github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) github.com/conformal/btcchain/chain.go New 100.00% (8/8) github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) github.com/conformal/btcchain/merkle.go HashMerkleBranches 100.00% (5/5) -github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) -github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) +github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) +github.com/conformal/btcchain/error.go ErrorCode.String 100.00% (3/3) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/error.go RuleError.Error 100.00% (1/1) github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) -github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) +github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) +github.com/conformal/btcchain/error.go ruleError 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) @@ -31,8 +34,8 @@ github.com/conformal/btcchain/scriptval.go checkBlockScripts 88.24% (15/17) github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.96% (20/23) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 85.71% (12/14) github.com/conformal/btcchain/validate.go IsCoinBase 85.71% (6/7) -github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.29% (29/34) +github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) @@ -46,9 +49,9 @@ github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/validate.go isTransactionSpent 75.00% (3/4) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 71.15% (37/52) github.com/conformal/btcchain/validate.go CheckBlockSanity 67.44% (29/43) -github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) github.com/conformal/btcchain/validate.go CalcBlockSubsidy 66.67% (2/3) -github.com/conformal/btcchain/validate.go CheckTransactionInputs 65.12% (28/43) +github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) +github.com/conformal/btcchain/validate.go CheckTransactionInputs 63.64% (28/44) github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) @@ -70,24 +73,23 @@ github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate github.com/conformal/btcchain/validate.go CountP2SHSigOps 0.00% (0/26) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/12) +github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/11) github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) -github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/10) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) -github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) +github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) +github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) -github.com/conformal/btcchain/process.go RuleError.Error 0.00% (0/1) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 56.65% (690/1218) +github.com/conformal/btcchain ------------------------------------- 56.83% (695/1223) From 415ac4596a109c288611195bce8be9bc0e50f355 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 25 Jun 2014 15:47:24 -0500 Subject: [PATCH 144/190] Make orphan ntfns to a return val on ProcessBlock. This commit changes the way that orphan blocks are identified by adding a new boolean return value on ProcessBlock and removing the notification for NTOrphanBlock. This allows the calling code to identify orphan blocks immediately instead of having to setup a seperate callback handler and implementing some type of state tracking. This, in turn, allows cleaner code for handling them. In addition, the tests have been updated for the new function signature and also now check that each block is or is not an orphan as expected which makes the tests more robust. ok @jrick --- chain_test.go | 15 +++++++++++++-- doc.go | 2 +- notifications.go | 10 +--------- process.go | 30 ++++++++++++++++-------------- reorganization_test.go | 7 ++++++- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/chain_test.go b/chain_test.go index 2f600f1e..c99c0ba2 100644 --- a/chain_test.go +++ b/chain_test.go @@ -48,18 +48,29 @@ func TestHaveBlock(t *testing.T) { btcchain.TstSetCoinbaseMaturity(1) for i := 1; i < len(blocks); i++ { - err = chain.ProcessBlock(blocks[i], false) + isOrphan, err := chain.ProcessBlock(blocks[i], false) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return } + if isOrphan { + t.Errorf("ProcessBlock incorrectly returned block %v "+ + "is an orphan\n", i) + return + } } // Insert an orphan block. - if err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), false); err != nil { + isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), false) + if err != nil { t.Errorf("Unable to process block: %v", err) return } + if !isOrphan { + t.Errorf("ProcessBlock indicated block is an not orphan when " + + "it should be\n") + return + } tests := []struct { hash string diff --git a/doc.go b/doc.go index 68a7422a..052db9e4 100644 --- a/doc.go +++ b/doc.go @@ -112,7 +112,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - err = chain.ProcessBlock(genesisBlock, false) + _, err = chain.ProcessBlock(genesisBlock, false) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/notifications.go b/notifications.go index 813ffa35..73b63b36 100644 --- a/notifications.go +++ b/notifications.go @@ -17,16 +17,10 @@ type NotificationCallback func(*Notification) // Constants for the type of a notification message. const ( - // NTOrphanBlock indicates an orphan block was processed and the - // associated block hash should be passed to the GetOrphanRoot function - // to find the root of all known orphans which should then be used to - // request the missing blocks. - NTOrphanBlock NotificationType = iota - // NTBlockAccepted indicates the associated block was accepted into // the block chain. Note that this does not necessarily mean it was // added to the main chain. For that, use NTBlockConnected. - NTBlockAccepted + NTBlockAccepted NotificationType = iota // NTBlockConnected indicates the associated block was connected to the // main chain. @@ -40,7 +34,6 @@ const ( // notificationTypeStrings is a map of notification types back to their constant // names for pretty printing. var notificationTypeStrings = map[NotificationType]string{ - NTOrphanBlock: "NTOrphanBlock", NTBlockAccepted: "NTBlockAccepted", NTBlockConnected: "NTBlockConnected", NTBlockDisconnected: "NTBlockDisconnected", @@ -57,7 +50,6 @@ func (n NotificationType) String() string { // Notification defines notification that is sent to the caller via the callback // function provided during the call to New and consists of a notification type // as well as associated data that depends on the type as follows: -// - NTOrphanBlock: *btcwire.ShaHash // - NTBlockAccepted: *btcutil.Block // - NTBlockConnected: *btcutil.Block // - NTBlockDisconnected: *btcutil.Block diff --git a/process.go b/process.go index e1fb7192..5e18f0b0 100644 --- a/process.go +++ b/process.go @@ -81,29 +81,33 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { // the block chain. It includes functionality such as rejecting duplicate // blocks, ensuring blocks follow all rules, orphan handling, and insertion into // the block chain along with best chain selection and reorganization. -func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { +// +// It returns a bool which indicates whether or not the block is an orphan and +// any errors that occurred during processing. The returned bool is only valid +// when the error is nil. +func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) (bool, error) { blockHash, err := block.Sha() if err != nil { - return err + return false, err } log.Tracef("Processing block %v", blockHash) // The block must not already exist in the main chain or side chains. if b.blockExists(blockHash) { str := fmt.Sprintf("already have block %v", blockHash) - return ruleError(ErrDuplicateBlock, str) + return false, ruleError(ErrDuplicateBlock, str) } // The block must not already exist as an orphan. if _, exists := b.orphans[*blockHash]; exists { str := fmt.Sprintf("already have block (orphan) %v", blockHash) - return ruleError(ErrDuplicateBlock, str) + return false, ruleError(ErrDuplicateBlock, str) } // Perform preliminary sanity checks on the block and its transactions. err = CheckBlockSanity(block, b.netParams.PowLimit) if err != nil { - return err + return false, err } // Find the previous checkpoint and perform some additional checks based @@ -115,7 +119,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { blockHeader := &block.MsgBlock().Header checkpointBlock, err := b.findPreviousCheckpoint() if err != nil { - return err + return false, err } if checkpointBlock != nil { // Ensure the block timestamp is after the checkpoint timestamp. @@ -125,7 +129,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { str := fmt.Sprintf("block %v has timestamp %v before "+ "last checkpoint timestamp %v", blockHash, blockHeader.Timestamp, checkpointTime) - return ruleError(ErrTimeTooOld, str) + return false, ruleError(ErrTimeTooOld, str) } if !fastAdd { // Even though the checks prior to now have already ensured the @@ -142,7 +146,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { str := fmt.Sprintf("block target difficulty of %064x "+ "is too low when compared to the previous "+ "checkpoint", currentTarget) - return ruleError(ErrDifficultyTooLow, str) + return false, ruleError(ErrDifficultyTooLow, str) } } } @@ -155,16 +159,14 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { prevHash) b.addOrphanBlock(block) - // Notify the caller so it can request missing blocks. - b.sendNotification(NTOrphanBlock, blockHash) - return nil + return true, nil } // The block has passed all context independent checks and appears sane // enough to potentially accept it into the block chain. err = b.maybeAcceptBlock(block, fastAdd) if err != nil { - return err + return false, err } // Accept any orphan blocks that depend on this block (they are no @@ -172,9 +174,9 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) error { // no more. err = b.processOrphans(blockHash) if err != nil { - return err + return false, err } log.Debugf("Accepted block %v", blockHash) - return nil + return false, nil } diff --git a/reorganization_test.go b/reorganization_test.go index df407725..7e7d400f 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -57,12 +57,17 @@ func TestReorganization(t *testing.T) { chain.DisableCheckpoints(true) btcchain.TstSetCoinbaseMaturity(1) + expectedOrphans := map[int]bool{5: true, 6: true} for i := 1; i < len(blocks); i++ { - err = chain.ProcessBlock(blocks[i], false) + isOrphan, err := chain.ProcessBlock(blocks[i], false) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return } + if isOrphan && !expectedOrphans[i] { + t.Errorf("ProcessBlock incorrectly returned block %v "+ + "is an orphan\n", i) + } } return From 7d84d801d7cd54c747e5e3904d25604eab401444 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 26 Jun 2014 16:10:10 -0500 Subject: [PATCH 145/190] Make golint happy. --- validate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validate.go b/validate.go index c50c095e..188ad511 100644 --- a/validate.go +++ b/validate.go @@ -56,7 +56,7 @@ var ( // coinbaseMaturity is the internal variable used for validating the // spending of coinbase outputs. A variable rather than the exported // constant is used because the tests need the ability to modify it. - coinbaseMaturity int64 = CoinbaseMaturity + coinbaseMaturity = int64(CoinbaseMaturity) // zeroHash is the zero value for a btcwire.ShaHash and is defined as // a package level variable to avoid the need to create a new instance From 67394ec45d5c16d4d4a664d979fb82bfc7b974d5 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 26 Jun 2014 15:50:13 -0500 Subject: [PATCH 146/190] Modify ProcessBlock to accept behavior flags. This commit change the ProcessBlock function to accept a new type named BehaviorFlags in place of the current fastAdd parameter. This has been done to pave the way for adding more control over the checks that are performed such as avoiding the proof of work checks which will be in an upcoming commit. A bitmask was chosen because it will allow the ProcessBlock API to remain a little more stable since new flag additions that change the behavior are only likely to be used by new code because adding flags does not change the existing behavior. ok @jrick --- accept.go | 12 +++++++----- chain.go | 11 ++++++++--- chain_test.go | 4 ++-- doc.go | 2 +- process.go | 31 +++++++++++++++++++++++++------ reorganization_test.go | 2 +- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/accept.go b/accept.go index 645d7ea7..10b6a222 100644 --- a/accept.go +++ b/accept.go @@ -13,10 +13,12 @@ import ( // It performs several validation checks which depend on its position within // the block chain before adding it. The block is expected to have already gone // through ProcessBlock before calling this function with it. -// The fastAdd argument modifies the behavior of the function by avoiding the -// somewhat expensive operation: BIP34 validation, it also passes the argument -// down to connectBestChain() -func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error { +// +// The flags modify the behavior of this function as follows: +// - BFFastAdd: The somewhat expensive BIP0034 validation is not performed. +func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) error { + fastAdd := flags&BFFastAdd == BFFastAdd + // Get a block node for the block previous to this one. Will be nil // if this is the genesis block. prevNode, err := b.getPrevNodeFromBlock(block) @@ -164,7 +166,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error // Connect the passed block to the chain while respecting proper chain // selection according to the chain with the most proof of work. This // also handles validation of the transaction scripts. - err = b.connectBestChain(newNode, block, fastAdd) + err = b.connectBestChain(newNode, block, flags) if err != nil { return err } diff --git a/chain.go b/chain.go index f78506a9..b9eb97ad 100644 --- a/chain.go +++ b/chain.go @@ -888,9 +888,13 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // chain. However, it may also be extending (or creating) a side chain (fork) // which may or may not end up becoming the main chain depending on which fork // cumulatively has the most proof of work. -// The fastAdd argument avoids the call to checkConnectBlock which does -// several expensive transaction validation operations. -func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fastAdd bool) error { +// +// The flags modify the behavior of this function as follows: +// - BFFastAdd: Avoids the call to checkConnectBlock which does several +// expensive transaction validation operations. +func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, flags BehaviorFlags) error { + fastAdd := flags&BFFastAdd == BFFastAdd + // We haven't selected a best chain yet or we are extending the main // (best) chain with a new block. This is the most common case. if b.bestChain == nil || node.parent.hash.IsEqual(b.bestChain.hash) { @@ -957,6 +961,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fas "which forks the chain at height %d/block %v", node.hash, fork.height, fork.hash) } + return nil } diff --git a/chain_test.go b/chain_test.go index c99c0ba2..17b53de9 100644 --- a/chain_test.go +++ b/chain_test.go @@ -48,7 +48,7 @@ func TestHaveBlock(t *testing.T) { btcchain.TstSetCoinbaseMaturity(1) for i := 1; i < len(blocks); i++ { - isOrphan, err := chain.ProcessBlock(blocks[i], false) + isOrphan, err := chain.ProcessBlock(blocks[i], btcchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return @@ -61,7 +61,7 @@ func TestHaveBlock(t *testing.T) { } // Insert an orphan block. - isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), false) + isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), btcchain.BFNone) if err != nil { t.Errorf("Unable to process block: %v", err) return diff --git a/doc.go b/doc.go index 052db9e4..24dbb603 100644 --- a/doc.go +++ b/doc.go @@ -112,7 +112,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - _, err = chain.ProcessBlock(genesisBlock, false) + _, err = chain.ProcessBlock(genesisBlock, btcchain.BFNone) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/process.go b/process.go index 5e18f0b0..bb5d452f 100644 --- a/process.go +++ b/process.go @@ -10,6 +10,21 @@ import ( "github.com/conformal/btcwire" ) +// BehaviorFlags is a bitmask defining tweaks to the normal behavior when +// performing chain processing and consensus rules checks. +type BehaviorFlags uint32 + +const ( + // BFFastAdd may be set to indicate that several checks can be avoided + // for the block since it is already known to fit into the chain due to + // already proving it correct links into the chain up to a known + // checkpoint. This is primarily used for headers-first mode. + BFFastAdd BehaviorFlags = 1 << iota + + // BFNone is a convenience value to specifically indicate no flags. + BFNone BehaviorFlags = 0 +) + // blockExists determines whether a block with the given hash exists either in // the main chain or any side chains. func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { @@ -26,7 +41,10 @@ func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { // block hash (they are no longer orphans if true) and potentially accepts them. // It repeats the process for the newly accepted blocks (to detect further // orphans which may no longer be orphans) until there are no more. -func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { +// +// The flags do not modify the behavior of this function directly, however they +// are needed to pass along to maybeAcceptBlock. +func (b *BlockChain) processOrphans(hash *btcwire.ShaHash, flags BehaviorFlags) error { // Start with processing at least the passed hash. Leave a little room // for additional orphan blocks that need to be processed without // needing to grow the array in the common case. @@ -63,7 +81,7 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { i-- // Potentially accept the block into the block chain. - err := b.maybeAcceptBlock(orphan.block, false) + err := b.maybeAcceptBlock(orphan.block, flags) if err != nil { return err } @@ -85,7 +103,9 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash) error { // It returns a bool which indicates whether or not the block is an orphan and // any errors that occurred during processing. The returned bool is only valid // when the error is nil. -func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) (bool, error) { +func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bool, error) { + fastAdd := flags&BFFastAdd == BFFastAdd + blockHash, err := block.Sha() if err != nil { return false, err @@ -154,7 +174,6 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) (bool, err // Handle orphan blocks. prevHash := &blockHeader.PrevBlock if !prevHash.IsEqual(zeroHash) && !b.blockExists(prevHash) { - // Add the orphan block to the orphan pool. log.Infof("Adding orphan block %v with parent %v", blockHash, prevHash) b.addOrphanBlock(block) @@ -164,7 +183,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) (bool, err // The block has passed all context independent checks and appears sane // enough to potentially accept it into the block chain. - err = b.maybeAcceptBlock(block, fastAdd) + err = b.maybeAcceptBlock(block, flags) if err != nil { return false, err } @@ -172,7 +191,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, fastAdd bool) (bool, err // Accept any orphan blocks that depend on this block (they are no // longer orphans) and repeat for those accepted blocks until there are // no more. - err = b.processOrphans(blockHash) + err = b.processOrphans(blockHash, flags) if err != nil { return false, err } diff --git a/reorganization_test.go b/reorganization_test.go index 7e7d400f..2bca2ff2 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -59,7 +59,7 @@ func TestReorganization(t *testing.T) { expectedOrphans := map[int]bool{5: true, 6: true} for i := 1; i < len(blocks); i++ { - isOrphan, err := chain.ProcessBlock(blocks[i], false) + isOrphan, err := chain.ProcessBlock(blocks[i], btcchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return From ad275b34a8d6e34f1fbd36eb2ed0e4e350e69322 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 26 Jun 2014 15:50:13 -0500 Subject: [PATCH 147/190] Add a new behavior flag to disable the pow check. This commit adds a new behavior flag, BFNoPoWCheck which allows the caller to indicate the check which ensures a block hashes to a value less than required target should not be performed. --- process.go | 7 ++++++- validate.go | 55 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/process.go b/process.go index bb5d452f..5d3d0b7e 100644 --- a/process.go +++ b/process.go @@ -21,6 +21,11 @@ const ( // checkpoint. This is primarily used for headers-first mode. BFFastAdd BehaviorFlags = 1 << iota + // BFNoPoWCheck may be set to indicate the proof of work check which + // ensures a block hashes to a value less than the required target will + // not be performed. + BFNoPoWCheck + // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 ) @@ -125,7 +130,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo } // Perform preliminary sanity checks on the block and its transactions. - err = CheckBlockSanity(block, b.netParams.PowLimit) + err = checkBlockSanity(block, b.netParams.PowLimit, flags) if err != nil { return false, err } diff --git a/validate.go b/validate.go index 188ad511..c253fd19 100644 --- a/validate.go +++ b/validate.go @@ -268,10 +268,15 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { return nil } -// CheckProofOfWork ensures the block header bits which indicate the target +// checkProofOfWork ensures the block header bits which indicate the target // difficulty is in min/max range and that the block hash is less than the // target difficulty as claimed. -func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { +// +// +// The flags modify the behavior of this function as follows: +// - BFNoPoWCheck: The check to ensure the block hash is less than the target +// difficulty is not performed. +func checkProofOfWork(block *btcutil.Block, powLimit *big.Int, flags BehaviorFlags) error { // The target difficulty must be larger than zero. target := CompactToBig(block.MsgBlock().Header.Bits) if target.Sign() <= 0 { @@ -287,21 +292,32 @@ func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { return ruleError(ErrUnexpectedDifficulty, str) } - // The block hash must be less than the claimed target. - blockHash, err := block.Sha() - if err != nil { - return err - } - hashNum := ShaHashToBig(blockHash) - if hashNum.Cmp(target) > 0 { - str := fmt.Sprintf("block hash of %064x is higher than "+ - "expected max of %064x", hashNum, target) - return ruleError(ErrHighHash, str) + // The block hash must be less than the claimed target unless the flag + // to avoid proof of work checks is set. + if flags&BFNoPoWCheck != BFNoPoWCheck { + // The block hash must be less than the claimed target. + blockHash, err := block.Sha() + if err != nil { + return err + } + hashNum := ShaHashToBig(blockHash) + if hashNum.Cmp(target) > 0 { + str := fmt.Sprintf("block hash of %064x is higher than "+ + "expected max of %064x", hashNum, target) + return ruleError(ErrHighHash, str) + } } return nil } +// CheckProofOfWork ensures the block header bits which indicate the target +// difficulty is in min/max range and that the block hash is less than the +// target difficulty as claimed. +func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { + return checkProofOfWork(block, powLimit, BFNone) +} + // CountSigOps returns the number of signature operations for all transaction // input and output scripts in the provided transaction. This uses the // quicker, but imprecise, signature operation counting mechanism from @@ -392,9 +408,12 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e return totalSigOps, nil } -// CheckBlockSanity performs some preliminary checks on a block to ensure it is +// checkBlockSanity performs some preliminary checks on a block to ensure it is // sane before continuing with block processing. These checks are context free. -func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { +// +// The flags do not modify the behavior of this function directly, however they +// are needed to pass along to checkProofOfWork. +func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFlags) error { // NOTE: bitcoind does size limits checking here, but the size limits // have already been checked by btcwire for incoming blocks. Also, // btcwire checks the size limits on send too, so there is no need @@ -403,7 +422,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { // Ensure the proof of work bits in the block header is in min/max range // and the block hash is less than the target value described by the // bits. - err := CheckProofOfWork(block, powLimit) + err := checkProofOfWork(block, powLimit, flags) if err != nil { return err } @@ -506,6 +525,12 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { return nil } +// CheckBlockSanity performs some preliminary checks on a block to ensure it is +// sane before continuing with block processing. These checks are context free. +func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { + return checkBlockSanity(block, powLimit, BFNone) +} + // checkSerializedHeight checks if the signature script in the passed // transaction starts with the serialized block height of wantHeight. func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { From cf3ad14d4df79fec5f41f1f0d5672b216c5c8556 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 26 Jun 2014 20:31:19 -0500 Subject: [PATCH 148/190] Remove TODO that is complete. --- accept.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/accept.go b/accept.go index 10b6a222..f9cddb94 100644 --- a/accept.go +++ b/accept.go @@ -82,12 +82,6 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) // It's safe to ignore the error on Sha since it's already cached. blockHash, _ := block.Sha() if !b.verifyCheckpoint(blockHeight, blockHash) { - // TODO(davec): This should probably be a distinct error type - // (maybe CheckpointError). Since this error shouldn't happen - // unless the peer is connected to a rogue network serving up an - // alternate chain, the caller would likely need to react by - // disconnecting peers and rolling back the chain to the last - // known good point. str := fmt.Sprintf("block at height %d does not match "+ "checkpoint hash", blockHeight) return ruleError(ErrBadCheckpoint, str) From a22da99f91ec1823ccb7c91a730416a96f7b744b Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 26 Jun 2014 23:29:57 -0500 Subject: [PATCH 149/190] Convert script errors to RuleErrors. This commit modifies the error return type for errors during script validation to use the RuleError so they are consistent with the rest of the errors. This also helps the calling code differentiate blocks rejected due to script parsing and validation errors as opposed to internal issues such as inability to read from the disk. To accomplish this, two new two new RuleErrors, ErrScriptMalformed and ErrScriptValidation, have been added. Also, the errors for script parsing issues and script validation errors have been improved to include both transaction hashes and indexes involved in the validation effort. Previously script parsing issues had almost no additional information as to which transaction input/outputs the failing script came from. --- error.go | 13 +++++++++++++ error_test.go | 2 ++ scriptval.go | 35 +++++++++++++++++++++++------------ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/error.go b/error.go index 26071c97..94a5e8ae 100644 --- a/error.go +++ b/error.go @@ -151,6 +151,17 @@ const ( // coinbase transaction for version 2 and higher blocks does not match // the expected value. ErrBadCoinbaseHeight + + // ErrScriptMalformed indicates a transaction script is malformed in + // some way. For example, it might be longer than the maximum allowed + // length or fail to parse. + ErrScriptMalformed + + // ErrScriptValidation indicates the result of executing transaction + // script failed. The error covers any failure when executing scripts + // such signature verification failures and execution past the end of + // the stack. + ErrScriptValidation ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -187,6 +198,8 @@ var errorCodeStrings = map[ErrorCode]string{ ErrBadCoinbaseValue: "ErrBadCoinbaseValue", ErrMissingCoinbaseHeight: "ErrMissingCoinbaseHeight", ErrBadCoinbaseHeight: "ErrBadCoinbaseHeight", + ErrScriptMalformed: "ErrScriptMalformed", + ErrScriptValidation: "ErrScriptValidation", } // String returns the ErrorCode as a human-readable name. diff --git a/error_test.go b/error_test.go index d1801d8f..37bfade8 100644 --- a/error_test.go +++ b/error_test.go @@ -48,6 +48,8 @@ func TestErrorCodeStringer(t *testing.T) { {btcchain.ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, {btcchain.ErrMissingCoinbaseHeight, "ErrMissingCoinbaseHeight"}, {btcchain.ErrBadCoinbaseHeight, "ErrBadCoinbaseHeight"}, + {btcchain.ErrScriptMalformed, "ErrScriptMalformed"}, + {btcchain.ErrScriptValidation, "ErrScriptValidation"}, {0xffff, "Unknown ErrorCode (65535)"}, } diff --git a/scriptval.go b/scriptval.go index f3badf19..1e300eba 100644 --- a/scriptval.go +++ b/scriptval.go @@ -51,15 +51,15 @@ out: select { case txVI := <-v.validateChan: // Ensure the referenced input transaction is available. - //txIn := txVI.tx.MsgTx().TxIn[txVI.txInIdx] txIn := txVI.txIn - txInHash := &txIn.PreviousOutpoint.Hash - originTx, exists := v.txStore[*txInHash] + originTxHash := &txIn.PreviousOutpoint.Hash + originTx, exists := v.txStore[*originTxHash] if !exists || originTx.Err != nil || originTx.Tx == nil { - err := fmt.Errorf("unable to find input "+ + str := fmt.Sprintf("unable to find input "+ "transaction %v referenced from "+ - "transaction %v", txInHash, + "transaction %v", originTxHash, txVI.tx.Sha()) + err := ruleError(ErrMissingTx, str) v.sendResult(err) break out } @@ -69,10 +69,12 @@ out: // is available. originTxIndex := txIn.PreviousOutpoint.Index if originTxIndex >= uint32(len(originMsgTx.TxOut)) { - err := fmt.Errorf("out of bounds "+ + str := fmt.Sprintf("out of bounds "+ "input index %d in transaction %v "+ "referenced from transaction %v", - originTxIndex, txInHash, txVI.tx.Sha()) + originTxIndex, originTxHash, + txVI.tx.Sha()) + err := ruleError(ErrBadTxInput, str) v.sendResult(err) break out } @@ -83,17 +85,26 @@ out: engine, err := btcscript.NewScript(sigScript, pkScript, txVI.txInIndex, txVI.tx.MsgTx(), v.flags) if err != nil { + str := fmt.Sprintf("failed to parse input "+ + "%s:%d which references output %s:%d - "+ + "%v (input script bytes %x, prev output "+ + "script bytes %x)", txVI.tx.Sha(), + txVI.txInIndex, originTxHash, + originTxIndex, err, sigScript, pkScript) + err := ruleError(ErrScriptMalformed, str) v.sendResult(err) break out } // Execute the script pair. if err := engine.Execute(); err != nil { - err := fmt.Errorf("validate of input "+ - "%d from transaction %s failed: %v "+ - "(input script bytes %x, prev output "+ - "script bytes %x)", txVI.txInIndex, - txInHash, err, sigScript, pkScript) + str := fmt.Sprintf("failed to validate input "+ + "%s:%d which references output %s:%d - "+ + "%v (input script bytes %x, prev output "+ + "script bytes %x)", txVI.tx.Sha(), + txVI.txInIndex, originTxHash, + originTxIndex, err, sigScript, pkScript) + err := ruleError(ErrScriptValidation, str) v.sendResult(err) break out } From ae51c3e6e0f2ff5cc274c2b3e3ec33d4fce49ede Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 27 Jun 2014 00:01:33 -0500 Subject: [PATCH 150/190] Update test coverage report. --- test_coverage.txt | 56 ++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/test_coverage.txt b/test_coverage.txt index 03540b43..b07d42c5 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -6,37 +6,38 @@ github.com/conformal/btcchain/difficulty.go CompactToBig 100.00% (12/12) github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) github.com/conformal/btcchain/chain.go New 100.00% (8/8) github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) -github.com/conformal/btcchain/merkle.go HashMerkleBranches 100.00% (5/5) -github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) +github.com/conformal/btcchain/merkle.go HashMerkleBranches 100.00% (5/5) +github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) +github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) -github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) +github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) github.com/conformal/btcchain/error.go ErrorCode.String 100.00% (3/3) github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/error.go RuleError.Error 100.00% (1/1) -github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/log.go init 100.00% (1/1) github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) -github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) -github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/error.go ruleError 100.00% (1/1) github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) +github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) +github.com/conformal/btcchain/error.go ruleError 100.00% (1/1) +github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) +github.com/conformal/btcchain/validate.go CheckBlockSanity 100.00% (1/1) +github.com/conformal/btcchain/error.go RuleError.Error 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) +github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) github.com/conformal/btcchain/scriptval.go txValidator.Validate 88.46% (23/26) -github.com/conformal/btcchain/scriptval.go checkBlockScripts 88.24% (15/17) github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.96% (20/23) +github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.71% (30/35) github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 85.71% (12/14) github.com/conformal/btcchain/validate.go IsCoinBase 85.71% (6/7) -github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.29% (29/34) github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) +github.com/conformal/btcchain/scriptval.go checkBlockScripts 83.33% (15/18) github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) @@ -48,21 +49,21 @@ github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 75 github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) github.com/conformal/btcchain/validate.go isTransactionSpent 75.00% (3/4) github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 71.15% (37/52) -github.com/conformal/btcchain/validate.go CheckBlockSanity 67.44% (29/43) +github.com/conformal/btcchain/validate.go checkBlockSanity 67.44% (29/43) github.com/conformal/btcchain/validate.go CalcBlockSubsidy 66.67% (2/3) github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) github.com/conformal/btcchain/validate.go CheckTransactionInputs 63.64% (28/44) github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) -github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 59.26% (16/27) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 54.41% (37/68) -github.com/conformal/btcchain/validate.go CheckProofOfWork 53.33% (8/15) +github.com/conformal/btcchain/validate.go checkProofOfWork 56.25% (9/16) +github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 55.07% (38/69) github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 52.27% (23/44) github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 52.00% (13/25) +github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 50.00% (16/32) github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) -github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) +github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) @@ -73,23 +74,24 @@ github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate github.com/conformal/btcchain/validate.go CountP2SHSigOps 0.00% (0/26) github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/12) +github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/11) -github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/10) github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 56.83% (695/1223) +github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) +github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) +github.com/conformal/btcchain/validate.go CheckProofOfWork 0.00% (0/1) +github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) +github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) +github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) +github.com/conformal/btcchain ------------------------------------- 56.65% (699/1234) From dbca1d59c3dc48088654eaddbadfe038f245ccad Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sun, 29 Jun 2014 15:11:13 -0500 Subject: [PATCH 151/190] Add a new behavior flag to provide a dry run. This commit adds a new behavior flag, BFDryRun which allows the caller to indicate all checks should be performed against the block as normal except it will not modify any state. This is useful to test that a block is valid without actually modifying the current chain or memory state. This commit also adds a few additional checks which were elided before since they are implicitly handled by btcwire. However, with the ability to propose blocks which didn't necessarily come through the btcwire path, these checks need to be enforced in the chain code as well. As a part of adding the checks, three new error codes named ErrBlockTooBig, ErrTooManyTransactions, and ErrTxTooBig have been introduced. Closes #5. --- accept.go | 17 +++++++++++----- chain.go | 54 +++++++++++++++++++++++++++++++++++++++++++++------ error.go | 15 ++++++++++++++ error_test.go | 3 +++ process.go | 32 ++++++++++++++++++++---------- txlookup.go | 6 ++++++ validate.go | 47 ++++++++++++++++++++++++++++++-------------- 7 files changed, 138 insertions(+), 36 deletions(-) diff --git a/accept.go b/accept.go index f9cddb94..fc488767 100644 --- a/accept.go +++ b/accept.go @@ -16,8 +16,11 @@ import ( // // The flags modify the behavior of this function as follows: // - BFFastAdd: The somewhat expensive BIP0034 validation is not performed. +// - BFDryRun: The memory chain index will not be pruned and no accept +// notification will be sent since the block is not being accepted. func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) error { fastAdd := flags&BFFastAdd == BFFastAdd + dryRun := flags&BFDryRun == BFDryRun // Get a block node for the block previous to this one. Will be nil // if this is the genesis block. @@ -105,7 +108,7 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) if !fastAdd { // Reject version 1 blocks once a majority of the network has // upgraded. This is part of BIP0034. - if blockHeader.Version == 1 { + if blockHeader.Version < 2 { if b.isMajorityVersion(2, prevNode, b.netParams.BlockV1RejectNumRequired, b.netParams.BlockV1RejectNumToCheck) { @@ -143,9 +146,11 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) // Prune block nodes which are no longer needed before creating // a new node. - err = b.pruneBlockNodes() - if err != nil { - return err + if !dryRun { + err = b.pruneBlockNodes() + if err != nil { + return err + } } // Create a new block node for the block and add it to the in-memory @@ -168,7 +173,9 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, flags BehaviorFlags) // Notify the caller that the new block was accepted into the block // chain. The caller would typically want to react by relaying the // inventory to other peers. - b.sendNotification(NTBlockAccepted, block) + if !dryRun { + b.sendNotification(NTBlockAccepted, block) + } return nil } diff --git a/chain.go b/chain.go index b9eb97ad..312c6b10 100644 --- a/chain.go +++ b/chain.go @@ -69,7 +69,7 @@ type blockNode struct { inMainChain bool // Some fields from block headers to aid in best chain selection. - version uint32 + version int32 bits uint32 timestamp time.Time } @@ -605,7 +605,7 @@ func (b *BlockChain) pruneBlockNodes() error { // isMajorityVersion determines if a previous number of blocks in the chain // starting with startNode are at least the minimum passed version. -func (b *BlockChain) isMajorityVersion(minVer uint32, startNode *blockNode, numRequired, numToCheck uint64) bool { +func (b *BlockChain) isMajorityVersion(minVer int32, startNode *blockNode, numRequired, numToCheck uint64) bool { numFound := uint64(0) iterNode := startNode for i := uint64(0); i < numToCheck && iterNode != nil; i++ { @@ -811,7 +811,11 @@ func (b *BlockChain) disconnectBlock(node *blockNode, block *btcutil.Block) erro // disconnected must be in reverse order (think of popping them off // the end of the chain) and nodes the are being attached must be in forwards // order (think pushing them onto the end of the chain). -func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error { +// +// The flags modify the behavior of this function as follows: +// - BFDryRun: Only the checks which ensure the reorganize can be completed +// successfully are performed. The chain is not reorganized. +func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List, flags BehaviorFlags) error { // Ensure all of the needed side chain blocks are in the cache. for e := attachNodes.Front(); e != nil; e = e.Next() { n := e.Value.(*blockNode) @@ -842,6 +846,12 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error } } + // Skip disconnecting and connecting the blocks when running with the + // dry run flag set. + if flags&BFDryRun == BFDryRun { + return nil + } + // Disconnect blocks from the main chain. for e := detachNodes.Front(); e != nil; e = e.Next() { n := e.Value.(*blockNode) @@ -892,8 +902,12 @@ func (b *BlockChain) reorganizeChain(detachNodes, attachNodes *list.List) error // The flags modify the behavior of this function as follows: // - BFFastAdd: Avoids the call to checkConnectBlock which does several // expensive transaction validation operations. +// - BFDryRun: Prevents the block from being connected and avoids modifying the +// state of the memory chain index. Also, any log messages related to +// modifying the state are avoided. func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, flags BehaviorFlags) error { fastAdd := flags&BFFastAdd == BFFastAdd + dryRun := flags&BFDryRun == BFDryRun // We haven't selected a best chain yet or we are extending the main // (best) chain with a new block. This is the most common case. @@ -910,6 +924,11 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla } } + // Don't connect the block if performing a dry run. + if dryRun { + return nil + } + // Connect the block to the main chain. err := b.connectBlock(node, block) if err != nil { @@ -932,7 +951,9 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // become the main chain, but in either case we need the block stored // for future processing, so add the block to the side chain holding // cache. - log.Debugf("Adding block %v to side chain cache", node.hash) + if !dryRun { + log.Debugf("Adding block %v to side chain cache", node.hash) + } b.blockCache[*node.hash] = block b.index[*node.hash] = node @@ -940,9 +961,27 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla node.inMainChain = false node.parent.children = append(node.parent.children, node) + // Remove the block from the side chain cache and disconnect it from the + // parent node when the function returns when running in dry run mode. + if dryRun { + defer func() { + children := node.parent.children + children = removeChildNode(children, node) + node.parent.children = children + + delete(b.index, *node.hash) + delete(b.blockCache, *node.hash) + }() + } + // We're extending (or creating) a side chain, but the cumulative // work for this new side chain is not enough to make it the new chain. if node.workSum.Cmp(b.bestChain.workSum) <= 0 { + // Skip Logging info when the dry run flag is set. + if dryRun { + return nil + } + // Find the fork point. fork := node for ; fork.parent != nil; fork = fork.parent { @@ -975,8 +1014,11 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla detachNodes, attachNodes := b.getReorganizeNodes(node) // Reorganize the chain. - log.Infof("REORGANIZE: Block %v is causing a reorganize.", node.hash) - err := b.reorganizeChain(detachNodes, attachNodes) + if !dryRun { + log.Infof("REORGANIZE: Block %v is causing a reorganize.", + node.hash) + } + err := b.reorganizeChain(detachNodes, attachNodes, flags) if err != nil { return err } diff --git a/error.go b/error.go index 94a5e8ae..974d33c9 100644 --- a/error.go +++ b/error.go @@ -17,6 +17,10 @@ const ( // exists. ErrDuplicateBlock ErrorCode = iota + // ErrBlockTooBig indicates the serialized block size exceeds the + // maximum allowed size. + ErrBlockTooBig + // ErrBlockVersionTooOld indicates the block version is too old and is // no longer accepted since the majority of the network has upgraded // to a newer version. @@ -67,6 +71,10 @@ const ( // transaction. ErrNoTransactions + // ErrTooManyTransactions indicates the block has more transactions than + // are allowed. + ErrTooManyTransactions + // ErrNoTxInputs indicates a transaction does not have any inputs. A // valid transaction must have at least one input. ErrNoTxInputs @@ -75,6 +83,10 @@ const ( // valid transaction must have at least one output. ErrNoTxOutputs + // ErrTxTooBig indicates a transaction exceeds the maximum allowed size + // when serialized. + ErrTxTooBig + // ErrBadTxOutValue indicates an output value for a transaction is // invalid in some way such as being out of range. ErrBadTxOutValue @@ -167,6 +179,7 @@ const ( // Map of ErrorCode values back to their constant names for pretty printing. var errorCodeStrings = map[ErrorCode]string{ ErrDuplicateBlock: "ErrDuplicateBlock", + ErrBlockTooBig: "ErrBlockTooBig", ErrBlockVersionTooOld: "ErrBlockVersionTooOld", ErrInvalidTime: "ErrInvalidTime", ErrTimeTooOld: "ErrTimeTooOld", @@ -178,8 +191,10 @@ var errorCodeStrings = map[ErrorCode]string{ ErrBadCheckpoint: "ErrBadCheckpoint", ErrForkTooOld: "ErrForkTooOld", ErrNoTransactions: "ErrNoTransactions", + ErrTooManyTransactions: "ErrTooManyTransactions", ErrNoTxInputs: "ErrNoTxInputs", ErrNoTxOutputs: "ErrNoTxOutputs", + ErrTxTooBig: "ErrTxTooBig", ErrBadTxOutValue: "ErrBadTxOutValue", ErrDuplicateTxInputs: "ErrDuplicateTxInputs", ErrBadTxInput: "ErrBadTxInput", diff --git a/error_test.go b/error_test.go index 37bfade8..cee2ea06 100644 --- a/error_test.go +++ b/error_test.go @@ -16,6 +16,7 @@ func TestErrorCodeStringer(t *testing.T) { want string }{ {btcchain.ErrDuplicateBlock, "ErrDuplicateBlock"}, + {btcchain.ErrBlockTooBig, "ErrBlockTooBig"}, {btcchain.ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, {btcchain.ErrInvalidTime, "ErrInvalidTime"}, {btcchain.ErrTimeTooOld, "ErrTimeTooOld"}, @@ -27,8 +28,10 @@ func TestErrorCodeStringer(t *testing.T) { {btcchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, {btcchain.ErrForkTooOld, "ErrForkTooOld"}, {btcchain.ErrNoTransactions, "ErrNoTransactions"}, + {btcchain.ErrTooManyTransactions, "ErrTooManyTransactions"}, {btcchain.ErrNoTxInputs, "ErrNoTxInputs"}, {btcchain.ErrNoTxOutputs, "ErrNoTxOutputs"}, + {btcchain.ErrTxTooBig, "ErrTxTooBig"}, {btcchain.ErrBadTxOutValue, "ErrBadTxOutValue"}, {btcchain.ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, {btcchain.ErrBadTxInput, "ErrBadTxInput"}, diff --git a/process.go b/process.go index 5d3d0b7e..540701dd 100644 --- a/process.go +++ b/process.go @@ -26,6 +26,11 @@ const ( // not be performed. BFNoPoWCheck + // BFDryRun may be set to indicate the block should not modify the chain + // or memory chain index. This is useful to test that a block is valid + // without modifying the current state. + BFDryRun + // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 ) @@ -110,6 +115,7 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash, flags BehaviorFlags) // when the error is nil. func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bool, error) { fastAdd := flags&BFFastAdd == BFFastAdd + dryRun := flags&BFDryRun == BFDryRun blockHash, err := block.Sha() if err != nil { @@ -179,9 +185,11 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo // Handle orphan blocks. prevHash := &blockHeader.PrevBlock if !prevHash.IsEqual(zeroHash) && !b.blockExists(prevHash) { - log.Infof("Adding orphan block %v with parent %v", blockHash, - prevHash) - b.addOrphanBlock(block) + if !dryRun { + log.Infof("Adding orphan block %v with parent %v", + blockHash, prevHash) + b.addOrphanBlock(block) + } return true, nil } @@ -193,14 +201,18 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo return false, err } - // Accept any orphan blocks that depend on this block (they are no - // longer orphans) and repeat for those accepted blocks until there are - // no more. - err = b.processOrphans(blockHash, flags) - if err != nil { - return false, err + // Don't process any orphans or log when the dry run flag is set. + if !dryRun { + // Accept any orphan blocks that depend on this block (they are + // no longer orphans) and repeat for those accepted blocks until + // there are no more. + err := b.processOrphans(blockHash, flags) + if err != nil { + return false, err + } + + log.Debugf("Accepted block %v", blockHash) } - log.Debugf("Accepted block %v", blockHash) return false, nil } diff --git a/txlookup.go b/txlookup.go index b2773414..de6036ef 100644 --- a/txlookup.go +++ b/txlookup.go @@ -49,6 +49,9 @@ func connectTransactions(txStore TxStore, block *btcutil.Block) error { originHash := &txIn.PreviousOutpoint.Hash originIndex := txIn.PreviousOutpoint.Index if originTx, exists := txStore[*originHash]; exists { + if originIndex > uint32(len(originTx.Spent)) { + continue + } originTx.Spent[originIndex] = true } } @@ -82,6 +85,9 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { originIndex := txIn.PreviousOutpoint.Index originTx, exists := txStore[*originHash] if exists && originTx.Tx != nil && originTx.Err == nil { + if originIndex > uint32(len(originTx.Spent)) { + continue + } originTx.Spent[originIndex] = false } } diff --git a/validate.go b/validate.go index c253fd19..127e4672 100644 --- a/validate.go +++ b/validate.go @@ -189,10 +189,14 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { return ruleError(ErrNoTxOutputs, "transaction has no outputs") } - // NOTE: bitcoind does size limits checking here, but the size limits - // have already been checked by btcwire for incoming transactions. - // Also, btcwire checks the size limits on send too, so there is no need - // to double check it here. + // A transaction must not exceed the maximum allowed block payload when + // serialized. + serializedTxSize := tx.MsgTx().SerializeSize() + if serializedTxSize > btcwire.MaxBlockPayload { + str := fmt.Sprintf("serialized transaction is too big - got "+ + "%d, max %d", serializedTxSize, btcwire.MaxBlockPayload) + return ruleError(ErrTxTooBig, str) + } // Ensure the transaction amounts are in range. Each transaction // output must not be negative or more than the max allowed per @@ -414,10 +418,29 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e // The flags do not modify the behavior of this function directly, however they // are needed to pass along to checkProofOfWork. func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFlags) error { - // NOTE: bitcoind does size limits checking here, but the size limits - // have already been checked by btcwire for incoming blocks. Also, - // btcwire checks the size limits on send too, so there is no need - // to double check it here. + // A block must have at least one transaction. + msgBlock := block.MsgBlock() + numTx := len(msgBlock.Transactions) + if numTx == 0 { + return ruleError(ErrNoTransactions, "block does not contain "+ + "any transactions") + } + + // A block must not have more transactions than the max block payload. + if numTx > btcwire.MaxBlockPayload { + str := fmt.Sprintf("block contains too many transactions - "+ + "got %d, max %d", numTx, btcwire.MaxBlockPayload) + return ruleError(ErrTooManyTransactions, str) + } + + // A block must not exceed the maximum allowed block payload when + // serialized. + serializedSize := msgBlock.SerializeSize() + if serializedSize > btcwire.MaxBlockPayload { + str := fmt.Sprintf("serialized block is too big - got %d, "+ + "max %d", serializedSize, btcwire.MaxBlockPayload) + return ruleError(ErrBlockTooBig, str) + } // Ensure the proof of work bits in the block header is in min/max range // and the block hash is less than the target value described by the @@ -446,14 +469,8 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFla return ruleError(ErrTimeTooNew, str) } - // A block must have at least one transaction. - transactions := block.Transactions() - if len(transactions) == 0 { - return ruleError(ErrNoTransactions, "block does not contain "+ - "any transactions") - } - // The first transaction in a block must be a coinbase. + transactions := block.Transactions() if !IsCoinBase(transactions[0]) { return ruleError(ErrFirstTxNotCoinbase, "first transaction in "+ "block is not a coinbase") From 933cdf50e8f7539c51e7c9c545fa43a5a87ffdce Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 30 Jun 2014 10:27:44 -0500 Subject: [PATCH 152/190] Export constant for the maximum time offset. This commit creates and exports a new constant, MaxTimeOffsetSeconds, which is the maximum number of seconds a block timestamp is allowed to be ahead of the current time. Previously this value was hard coded into the consensus rule path, however it is useful better to have it defined as a constant and exported so other callers can access it. No consensus rules have been changed with this commit. --- validate.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/validate.go b/validate.go index 127e4672..ba6c9ef5 100644 --- a/validate.go +++ b/validate.go @@ -29,6 +29,11 @@ const ( // the lock time is a uint32, the max is sometime around 2106. lockTimeThreshold uint32 = 5e8 // Tue Nov 5 00:53:20 1985 UTC + // MaxTimeOffsetSeconds is the maximum number of seconds a block time + // is allowed to be ahead of the current time. This is currently 2 + // hours. + MaxTimeOffsetSeconds = 2 * 60 * 60 + // MinCoinbaseScriptLen is the minimum length a coinbase script can be. MinCoinbaseScriptLen = 2 @@ -462,8 +467,9 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFla return ruleError(ErrInvalidTime, str) } - // Ensure the block time is not more than 2 hours in the future. - if header.Timestamp.After(time.Now().Add(time.Hour * 2)) { + // Ensure the block time is not too far in the future. + maxTimestamp := time.Now().Add(time.Second * MaxTimeOffsetSeconds) + if header.Timestamp.After(maxTimestamp) { str := fmt.Sprintf("block timestamp of %v is too far in the "+ "future", header.Timestamp) return ruleError(ErrTimeTooNew, str) From e29f40274df668b52733ba419edb937dc5f6df05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Senart?= Date: Wed, 2 Jul 2014 17:56:22 +0200 Subject: [PATCH 153/190] Replace map[a]bool with map[a]struct{} The later uses no memory storage for values and provides the same functionality. --- reorganization_test.go | 4 ++-- txlookup.go | 14 +++++++------- validate.go | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/reorganization_test.go b/reorganization_test.go index 2bca2ff2..c041ea6f 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -57,14 +57,14 @@ func TestReorganization(t *testing.T) { chain.DisableCheckpoints(true) btcchain.TstSetCoinbaseMaturity(1) - expectedOrphans := map[int]bool{5: true, 6: true} + expectedOrphans := map[int]struct{}{5: struct{}{}, 6: struct{}{}} for i := 1; i < len(blocks); i++ { isOrphan, err := chain.ProcessBlock(blocks[i], btcchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return } - if isOrphan && !expectedOrphans[i] { + if _, ok := expectedOrphans[i]; !ok && isOrphan { t.Errorf("ProcessBlock incorrectly returned block %v "+ "is an orphan\n", i) } diff --git a/txlookup.go b/txlookup.go index de6036ef..c969ba7e 100644 --- a/txlookup.go +++ b/txlookup.go @@ -100,7 +100,7 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // transactions from the point of view of the end of the main chain. It takes // a flag which specifies whether or not fully spent transaction should be // included in the results. -func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool, includeSpent bool) TxStore { +func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]struct{}, includeSpent bool) TxStore { // Just return an empty store now if there are no requested hashes. txStore := make(TxStore) if len(txSet) == 0 { @@ -160,7 +160,7 @@ func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]bool, includeSpent // chain). Another scenario is where a transaction exists from the point of // view of the main chain, but doesn't exist in a side chain that branches // before the block that contains the transaction on the main chain. -func (b *BlockChain) fetchTxStore(node *blockNode, txSet map[btcwire.ShaHash]bool) (TxStore, error) { +func (b *BlockChain) fetchTxStore(node *blockNode, txSet map[btcwire.ShaHash]struct{}) (TxStore, error) { // Get the previous block node. This function is used over simply // accessing node.parent directly as it will dynamically create previous // block nodes as needed. This helps allow only the pieces of the chain @@ -245,7 +245,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // Loop through all of the transaction inputs (except for the coinbase // which has no inputs) collecting them into sets of what is needed and // what is already known (in-flight). - txNeededSet := make(map[btcwire.ShaHash]bool) + txNeededSet := make(map[btcwire.ShaHash]struct{}) txStore := make(TxStore) for i, tx := range transactions[1:] { for _, txIn := range tx.MsgTx().TxIn { @@ -274,7 +274,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc txD.Spent = make([]bool, len(originTx.MsgTx().TxOut)) txD.Err = nil } else { - txNeededSet[*originHash] = true + txNeededSet[*originHash] = struct{}{} } } } @@ -302,10 +302,10 @@ func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx) (TxStore, error) { // Create a set of needed transactions from the transactions referenced // by the inputs of the passed transaction. Also, add the passed // transaction itself as a way for the caller to detect duplicates. - txNeededSet := make(map[btcwire.ShaHash]bool) - txNeededSet[*tx.Sha()] = true + txNeededSet := make(map[btcwire.ShaHash]struct{}) + txNeededSet[*tx.Sha()] = struct{}{} for _, txIn := range tx.MsgTx().TxIn { - txNeededSet[txIn.PreviousOutpoint.Hash] = true + txNeededSet[txIn.PreviousOutpoint.Hash] = struct{}{} } // Request the input transactions from the point of view of the end of diff --git a/validate.go b/validate.go index ba6c9ef5..476448f7 100644 --- a/validate.go +++ b/validate.go @@ -243,13 +243,13 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { } // Check for duplicate transaction inputs. - existingTxOut := make(map[btcwire.OutPoint]bool) + existingTxOut := make(map[btcwire.OutPoint]struct{}) for _, txIn := range msgTx.TxIn { if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists { return ruleError(ErrDuplicateTxInputs, "transaction "+ "contains duplicate inputs") } - existingTxOut[txIn.PreviousOutpoint] = true + existingTxOut[txIn.PreviousOutpoint] = struct{}{} } // Coinbase script length must be between min and max length. @@ -518,7 +518,7 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFla // Check for duplicate transactions. This check will be fairly quick // since the transaction hashes are already cached due to building the // merkle tree above. - existingTxHashes := make(map[btcwire.ShaHash]bool) + existingTxHashes := make(map[btcwire.ShaHash]struct{}) for _, tx := range transactions { hash := tx.Sha() if _, exists := existingTxHashes[*hash]; exists { @@ -526,7 +526,7 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFla "transaction %v", hash) return ruleError(ErrDuplicateTx, str) } - existingTxHashes[*hash] = true + existingTxHashes[*hash] = struct{}{} } // The number of signature operations must be less than the maximum @@ -611,9 +611,9 @@ func isTransactionSpent(txD *TxData) bool { func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { // Attempt to fetch duplicate transactions for all of the transactions // in this block from the point of view of the parent node. - fetchSet := make(map[btcwire.ShaHash]bool) + fetchSet := make(map[btcwire.ShaHash]struct{}) for _, tx := range block.Transactions() { - fetchSet[*tx.Sha()] = true + fetchSet[*tx.Sha()] = struct{}{} } txResults, err := b.fetchTxStore(node, fetchSet) if err != nil { From 73ed07bd8552aa72629c62cd0e12f802a4bf06f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Senart?= Date: Wed, 2 Jul 2014 18:00:47 +0200 Subject: [PATCH 154/190] Use chan struct{} for semaphores With semaphores we don't actually care about the value passed in. It makes sense to use a 0 bytes type in these cases. There is also the added benefit of compiler optimisations for this specific use case as described here: https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub --- scriptval.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scriptval.go b/scriptval.go index 1e300eba..f931c88f 100644 --- a/scriptval.go +++ b/scriptval.go @@ -25,7 +25,7 @@ type txValidateItem struct { // function that is intended to be in run multiple goroutines. type txValidator struct { validateChan chan *txValidateItem - quitChan chan bool + quitChan chan struct{} resultChan chan error txStore TxStore flags btcscript.ScriptFlags @@ -181,7 +181,7 @@ func (v *txValidator) Validate(items []*txValidateItem) error { func newTxValidator(txStore TxStore, flags btcscript.ScriptFlags) *txValidator { return &txValidator{ validateChan: make(chan *txValidateItem), - quitChan: make(chan bool), + quitChan: make(chan struct{}), resultChan: make(chan error), txStore: txStore, flags: flags, From 4772d4a1a444ee224091790f74464707ed07820f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Senart?= Date: Wed, 2 Jul 2014 18:04:59 +0200 Subject: [PATCH 155/190] goimports -w . --- accept.go | 1 + chain.go | 9 +++++---- chain_test.go | 3 ++- checkpoints.go | 1 + common_test.go | 5 +++-- difficulty.go | 3 ++- difficulty_test.go | 3 ++- error_test.go | 3 ++- internal_test.go | 3 ++- log.go | 3 ++- merkle.go | 3 ++- merkle_test.go | 3 ++- process.go | 1 + reorganization_test.go | 7 ++++--- scriptval.go | 5 +++-- timesorter_test.go | 3 ++- txlookup.go | 1 + validate.go | 7 ++++--- validate_test.go | 9 +++++---- 19 files changed, 46 insertions(+), 27 deletions(-) diff --git a/accept.go b/accept.go index fc488767..b94ae48d 100644 --- a/accept.go +++ b/accept.go @@ -6,6 +6,7 @@ package btcchain import ( "fmt" + "github.com/conformal/btcutil" ) diff --git a/chain.go b/chain.go index 312c6b10..ffe05ac8 100644 --- a/chain.go +++ b/chain.go @@ -8,14 +8,15 @@ import ( "container/list" "errors" "fmt" - "github.com/conformal/btcdb" - "github.com/conformal/btcnet" - "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "math/big" "sort" "sync" "time" + + "github.com/conformal/btcdb" + "github.com/conformal/btcnet" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" ) const ( diff --git a/chain_test.go b/chain_test.go index 17b53de9..562eb733 100644 --- a/chain_test.go +++ b/chain_test.go @@ -5,11 +5,12 @@ package btcchain_test import ( + "testing" + "github.com/conformal/btcchain" "github.com/conformal/btcnet" "github.com/conformal/btcutil" "github.com/conformal/btcwire" - "testing" ) // TestHaveBlock tests the HaveBlock API to ensure proper functionality. diff --git a/checkpoints.go b/checkpoints.go index 0b6dbc2a..6d02d621 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -6,6 +6,7 @@ package btcchain import ( "fmt" + "github.com/conformal/btcnet" "github.com/conformal/btcscript" "github.com/conformal/btcutil" diff --git a/common_test.go b/common_test.go index eceb51b5..882d6a36 100644 --- a/common_test.go +++ b/common_test.go @@ -6,14 +6,15 @@ package btcchain_test import ( "fmt" + "os" + "path/filepath" + "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" "github.com/conformal/btcutil" - "os" - "path/filepath" ) // testDbType is the database backend type to use for the tests. diff --git a/difficulty.go b/difficulty.go index 08a110ef..b09c108b 100644 --- a/difficulty.go +++ b/difficulty.go @@ -6,9 +6,10 @@ package btcchain import ( "fmt" - "github.com/conformal/btcwire" "math/big" "time" + + "github.com/conformal/btcwire" ) const ( diff --git a/difficulty_test.go b/difficulty_test.go index b29271f2..19aa278a 100644 --- a/difficulty_test.go +++ b/difficulty_test.go @@ -5,9 +5,10 @@ package btcchain_test import ( - "github.com/conformal/btcchain" "math/big" "testing" + + "github.com/conformal/btcchain" ) func TestBigToCompact(t *testing.T) { diff --git a/error_test.go b/error_test.go index cee2ea06..20f6f58c 100644 --- a/error_test.go +++ b/error_test.go @@ -5,8 +5,9 @@ package btcchain_test import ( - "github.com/conformal/btcchain" "testing" + + "github.com/conformal/btcchain" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. diff --git a/internal_test.go b/internal_test.go index 840c0c5e..ac11ca53 100644 --- a/internal_test.go +++ b/internal_test.go @@ -12,8 +12,9 @@ interface. The functions are only exported while the tests are being run. package btcchain import ( - "github.com/conformal/btcutil" "time" + + "github.com/conformal/btcutil" ) // TstSetCoinbaseMaturity makes the ability to set the coinbase maturity diff --git a/log.go b/log.go index 22a60ebd..4998869c 100644 --- a/log.go +++ b/log.go @@ -6,8 +6,9 @@ package btcchain import ( "errors" - "github.com/conformal/btclog" "io" + + "github.com/conformal/btclog" ) // log is a logger that is initialized with no output filters. This diff --git a/merkle.go b/merkle.go index 4bb4dd51..1ac7a5fd 100644 --- a/merkle.go +++ b/merkle.go @@ -5,9 +5,10 @@ package btcchain import ( + "math" + "github.com/conformal/btcutil" "github.com/conformal/btcwire" - "math" ) // nextPowerOfTwo returns the next highest power of two from a given number if diff --git a/merkle_test.go b/merkle_test.go index 01a9af77..fad68b2f 100644 --- a/merkle_test.go +++ b/merkle_test.go @@ -5,9 +5,10 @@ package btcchain_test import ( + "testing" + "github.com/conformal/btcchain" "github.com/conformal/btcutil" - "testing" ) // TestMerkle tests the BuildMerkleTreeStore API. diff --git a/process.go b/process.go index 540701dd..4017a552 100644 --- a/process.go +++ b/process.go @@ -6,6 +6,7 @@ package btcchain import ( "fmt" + "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/reorganization_test.go b/reorganization_test.go index c041ea6f..d6baa87b 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -7,14 +7,15 @@ package btcchain_test import ( "compress/bzip2" "encoding/binary" - "github.com/conformal/btcchain" - "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "io" "os" "path/filepath" "strings" "testing" + + "github.com/conformal/btcchain" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" ) // TestReorganization loads a set of test blocks which force a chain diff --git a/scriptval.go b/scriptval.go index f931c88f..e958c650 100644 --- a/scriptval.go +++ b/scriptval.go @@ -6,11 +6,12 @@ package btcchain import ( "fmt" + "math" + "runtime" + "github.com/conformal/btcscript" "github.com/conformal/btcutil" "github.com/conformal/btcwire" - "math" - "runtime" ) // txValidateItem holds a transaction along with which input to validate. diff --git a/timesorter_test.go b/timesorter_test.go index bd4b2fe0..db2f9e24 100644 --- a/timesorter_test.go +++ b/timesorter_test.go @@ -5,11 +5,12 @@ package btcchain_test import ( - "github.com/conformal/btcchain" "reflect" "sort" "testing" "time" + + "github.com/conformal/btcchain" ) // TestTimeSorter tests the timeSorter implementation. diff --git a/txlookup.go b/txlookup.go index c969ba7e..fc9c24b7 100644 --- a/txlookup.go +++ b/txlookup.go @@ -6,6 +6,7 @@ package btcchain import ( "fmt" + "github.com/conformal/btcdb" "github.com/conformal/btcutil" "github.com/conformal/btcwire" diff --git a/validate.go b/validate.go index 476448f7..e7a4b659 100644 --- a/validate.go +++ b/validate.go @@ -7,14 +7,15 @@ package btcchain import ( "encoding/binary" "fmt" + "math" + "math/big" + "time" + "github.com/conformal/btcdb" "github.com/conformal/btcnet" "github.com/conformal/btcscript" "github.com/conformal/btcutil" "github.com/conformal/btcwire" - "math" - "math/big" - "time" ) const ( diff --git a/validate_test.go b/validate_test.go index d96c584b..98c75a2f 100644 --- a/validate_test.go +++ b/validate_test.go @@ -5,14 +5,15 @@ package btcchain_test import ( - "github.com/conformal/btcchain" - "github.com/conformal/btcnet" - "github.com/conformal/btcutil" - "github.com/conformal/btcwire" "math" "reflect" "testing" "time" + + "github.com/conformal/btcchain" + "github.com/conformal/btcnet" + "github.com/conformal/btcutil" + "github.com/conformal/btcwire" ) // TestCheckConnectBlock tests the CheckConnectBlock function to ensure it From 73228aaebe3312d7a5cbe000f40c4a749e72e195 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 7 Jul 2014 11:42:28 -0500 Subject: [PATCH 156/190] Update for recent btcdb API changes. Since the underlying database driver can now return an error when looking up if blocks and transactions exist, the HaveBlock function now includes an error return to allow any underlying errors to be exposed. --- chain.go | 8 ++++++-- chain_test.go | 6 +++++- checkpoints.go | 13 +++++++++++-- process.go | 28 +++++++++++++++++++--------- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/chain.go b/chain.go index ffe05ac8..0b979dcc 100644 --- a/chain.go +++ b/chain.go @@ -175,8 +175,12 @@ func (b *BlockChain) DisableVerify(disable bool) { // be like part of the main chain, on a side chain, or in the orphan pool. // // This function is NOT safe for concurrent access. -func (b *BlockChain) HaveBlock(hash *btcwire.ShaHash) bool { - return b.IsKnownOrphan(hash) || b.blockExists(hash) +func (b *BlockChain) HaveBlock(hash *btcwire.ShaHash) (bool, error) { + exists, err := b.blockExists(hash) + if err != nil { + return false, err + } + return b.IsKnownOrphan(hash) || exists, nil } // IsKnownOrphan returns whether the passed hash is currently a known orphan. diff --git a/chain_test.go b/chain_test.go index 562eb733..b1e4d72e 100644 --- a/chain_test.go +++ b/chain_test.go @@ -97,7 +97,11 @@ func TestHaveBlock(t *testing.T) { continue } - result := chain.HaveBlock(hash) + result, err := chain.HaveBlock(hash) + if err != nil { + t.Errorf("HaveBlock #%d unexpected error: %v", i, err) + return + } if result != test.want { t.Errorf("HaveBlock #%d got %v want %v", i, result, test.want) diff --git a/checkpoints.go b/checkpoints.go index 6d02d621..17417f11 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -103,7 +103,12 @@ func (b *BlockChain) findPreviousCheckpoint() (*btcutil.Block, error) { // that we already have. checkpointIndex := -1 for i := numCheckpoints - 1; i >= 0; i-- { - if b.db.ExistsSha(checkpoints[i].Hash) { + exists, err := b.db.ExistsSha(checkpoints[i].Hash) + if err != nil { + return nil, err + } + + if exists { checkpointIndex = i break } @@ -222,7 +227,11 @@ func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) { } // A checkpoint must be in the main chain. - if !b.db.ExistsSha(blockHash) { + exists, err := b.db.ExistsSha(blockHash) + if err != nil { + return false, err + } + if !exists { return false, nil } diff --git a/process.go b/process.go index 4017a552..e86103b1 100644 --- a/process.go +++ b/process.go @@ -38,10 +38,10 @@ const ( // blockExists determines whether a block with the given hash exists either in // the main chain or any side chains. -func (b *BlockChain) blockExists(hash *btcwire.ShaHash) bool { +func (b *BlockChain) blockExists(hash *btcwire.ShaHash) (bool, error) { // Check memory chain first (could be main chain or side chain blocks). if _, ok := b.index[*hash]; ok { - return true + return true, nil } // Check in database (rest of main chain not in memory). @@ -125,7 +125,11 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo log.Tracef("Processing block %v", blockHash) // The block must not already exist in the main chain or side chains. - if b.blockExists(blockHash) { + exists, err := b.blockExists(blockHash) + if err != nil { + return false, err + } + if exists { str := fmt.Sprintf("already have block %v", blockHash) return false, ruleError(ErrDuplicateBlock, str) } @@ -185,14 +189,20 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo // Handle orphan blocks. prevHash := &blockHeader.PrevBlock - if !prevHash.IsEqual(zeroHash) && !b.blockExists(prevHash) { - if !dryRun { - log.Infof("Adding orphan block %v with parent %v", - blockHash, prevHash) - b.addOrphanBlock(block) + if !prevHash.IsEqual(zeroHash) { + prevHashExists, err := b.blockExists(prevHash) + if err != nil { + return false, err } + if !prevHashExists { + if !dryRun { + log.Infof("Adding orphan block %v with parent %v", + blockHash, prevHash) + b.addOrphanBlock(block) + } - return true, nil + return true, nil + } } // The block has passed all context independent checks and appears sane From 5a4242cb03fd791c5c7deb502be56ed1ba9831aa Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 7 Jul 2014 22:52:04 -0500 Subject: [PATCH 157/190] Update doc.go and README.md examples to use memdb. Since the code is only intended to be example code, there is no reason to use a database which actually writes to disk. --- README.md | 18 ++++++------------ doc.go | 18 ++++++------------ 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 67d9711b..46cba450 100644 --- a/README.md +++ b/README.md @@ -82,27 +82,21 @@ intentionally causes an error by attempting to process a duplicate block. "fmt" "github.com/conformal/btcchain" "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/ldb" + _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" "github.com/conformal/btcutil" - "os" ) func main() { // Create a new database to store the accepted blocks into. Typically - // this would be opening an existing database, but we create a new db - // here so this is a complete working example. Also, typically the - // calls to os.Remove would not be used either, but again, we want - // a complete working example here, so we make sure to remove the - // database. - dbName := "exampledb" - _ = os.RemoveAll(dbName) - db, err := btcdb.CreateDB("leveldb", dbName) + // this would be opening an existing database and would not use memdb + // which is a memory-only database backend, but we create a new db + // here so this is a complete working example. + db, err := btcdb.CreateDB("memdb") if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } - defer os.RemoveAll(dbName) // Ignore error. defer db.Close() // Insert the main network genesis block. This is part of the initial @@ -122,7 +116,7 @@ intentionally causes an error by attempting to process a duplicate block. // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - err = chain.ProcessBlock(genesisBlock, false) + _, err = chain.ProcessBlock(genesisBlock, btcchain.BFNone) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/doc.go b/doc.go index 24dbb603..4db9322d 100644 --- a/doc.go +++ b/doc.go @@ -72,27 +72,21 @@ intentionally causes an error by attempting to process a duplicate block. "fmt" "github.com/conformal/btcchain" "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/ldb" + _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" "github.com/conformal/btcutil" - "os" ) func main() { // Create a new database to store the accepted blocks into. Typically - // this would be opening an existing database, but we create a new db - // here so this is a complete working example. Also, typically the - // calls to os.Remove would not be used either, but again, we want - // a complete working example here, so we make sure to remove the - // database. - dbName := "exampledb" - _ = os.RemoveAll(dbName) - db, err := btcdb.CreateDB("leveldb", dbName) + // this would be opening an existing database and would not use memdb + // which is a memory-only database backend, but we create a new db + // here so this is a complete working example. + db, err := btcdb.CreateDB("memdb") if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } - defer os.RemoveAll(dbName) // Ignore error. defer db.Close() // Insert the main network genesis block. This is part of the initial @@ -107,7 +101,7 @@ intentionally causes an error by attempting to process a duplicate block. // Create a new BlockChain instance using the underlying database for // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, btcnet.MainNetParams, nil) + chain := btcchain.New(db, &btcnet.MainNetParams, nil) // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already From 7e875e7952388f63ab13c93b7452e6c015d9a2b1 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 7 Jul 2014 23:00:13 -0500 Subject: [PATCH 158/190] Add godoc reference badge to README.md. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 46cba450..53ebef6b 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ handle processing of blocks into the bitcoin block chain. ## Documentation +[![GoDoc](https://godoc.org/github.com/conformal/btcchain?status.png)] +(http://godoc.org/github.com/conformal/btcchain) + Full `go doc` style documentation for the project can be viewed online without installing this package by using the GoDoc site here: http://godoc.org/github.com/conformal/btcchain From 94845326b5ccd208ef357a6958f23ff3572f46d8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 8 Jul 2014 01:41:39 -0500 Subject: [PATCH 159/190] Use testable example and update doc.go README.md. This commit moves the ProcessBlock example to a test file so it integrates nicely with Go's example tooling. This allows the example output to be tested as a part of running the normal Go tests to help ensure it doesn't get out of date with the code. It is also nice to have the example in one place rather than repeating it in doc.go and README.md. Links and information about the example have been incldued in doc.go and README.md in place of the example. --- README.md | 59 ++++++------------------------------------------- doc.go | 56 +++++----------------------------------------- example_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 102 deletions(-) create mode 100644 example_test.go diff --git a/README.md b/README.md index 53ebef6b..180afa8c 100644 --- a/README.md +++ b/README.md @@ -73,59 +73,14 @@ is by no means exhaustive: coins - Insert the block into the block database -## Block Processing Example +## Examples -The following example program demonstrates processing a block. This example -intentionally causes an error by attempting to process a duplicate block. - -```Go - package main - - import ( - "fmt" - "github.com/conformal/btcchain" - "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/memdb" - "github.com/conformal/btcnet" - "github.com/conformal/btcutil" - ) - - func main() { - // Create a new database to store the accepted blocks into. Typically - // this would be opening an existing database and would not use memdb - // which is a memory-only database backend, but we create a new db - // here so this is a complete working example. - db, err := btcdb.CreateDB("memdb") - if err != nil { - fmt.Printf("Failed to create database: %v\n", err) - return - } - defer db.Close() - - // Insert the main network genesis block. This is part of the initial - // database setup. Like above, this typically would not be needed when - // opening an existing database. - genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock) - _, err = db.InsertBlock(genesisBlock) - if err != nil { - fmt.Printf("Failed to insert genesis block: %v\n", err) - return - } - - // Create a new BlockChain instance using the underlying database for - // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, &btcnet.MainNetParams, nil) - - // Process a block. For this example, we are going to intentionally - // cause an error by trying to process the genesis block which already - // exists. - _, err = chain.ProcessBlock(genesisBlock, btcchain.BFNone) - if err != nil { - fmt.Printf("Failed to process block: %v\n", err) - return - } - } -``` +* [ProcessBlock Example] + (http://godoc.org/github.com/conformal/btcchain#example-ProcessBlock) + Demonstrates how to create a new chain instance and use ProcessBlock to + attempt to attempt add a block to the chain. This example intentionally + attempts to insert a duplicate genesis block to illustrate how an invalid + block is handled. ## TODO diff --git a/doc.go b/doc.go index 4db9322d..f9909cb4 100644 --- a/doc.go +++ b/doc.go @@ -61,57 +61,13 @@ is by no means exhaustive: coins - Insert the block into the block database -Block Processing Example +Examples -The following example program demonstrates processing a block. This example -intentionally causes an error by attempting to process a duplicate block. - - package main - - import ( - "fmt" - "github.com/conformal/btcchain" - "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/memdb" - "github.com/conformal/btcnet" - "github.com/conformal/btcutil" - ) - - func main() { - // Create a new database to store the accepted blocks into. Typically - // this would be opening an existing database and would not use memdb - // which is a memory-only database backend, but we create a new db - // here so this is a complete working example. - db, err := btcdb.CreateDB("memdb") - if err != nil { - fmt.Printf("Failed to create database: %v\n", err) - return - } - defer db.Close() - - // Insert the main network genesis block. This is part of the initial - // database setup. Like above, this typically would not be needed when - // opening an existing database. - genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock) - _, err = db.InsertBlock(genesisBlock) - if err != nil { - fmt.Printf("Failed to insert genesis block: %v\n", err) - return - } - - // Create a new BlockChain instance using the underlying database for - // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, &btcnet.MainNetParams, nil) - - // Process a block. For this example, we are going to intentionally - // cause an error by trying to process the genesis block which already - // exists. - _, err = chain.ProcessBlock(genesisBlock, btcchain.BFNone) - if err != nil { - fmt.Printf("Failed to process block: %v\n", err) - return - } - } + - ProcessBlock Example + Demonstrates how to create a new chain instance and use ProcessBlock to + attempt to attempt add a block to the chain. This example intentionally + attempts to insert a duplicate genesis block to illustrate how an invalid + block is handled. Errors diff --git a/example_test.go b/example_test.go new file mode 100644 index 00000000..b5a0d8e1 --- /dev/null +++ b/example_test.go @@ -0,0 +1,59 @@ +// Copyright (c) 2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "fmt" + "github.com/conformal/btcchain" + "github.com/conformal/btcdb" + _ "github.com/conformal/btcdb/memdb" + "github.com/conformal/btcnet" + "github.com/conformal/btcutil" +) + +// This example demonstrates how to create a new chain instance and use +// ProcessBlock to attempt to attempt add a block to the chain. As the package +// overview documentation describes, this includes all of the Bitcoin consensus +// rules. This example intentionally attempts to insert a duplicate genesis +// block to illustrate how an invalid block is handled. +func ExampleProcessBlock() { + // Create a new database to store the accepted blocks into. Typically + // this would be opening an existing database and would not use memdb + // which is a memory-only database backend, but we create a new db + // here so this is a complete working example. + db, err := btcdb.CreateDB("memdb") + if err != nil { + fmt.Printf("Failed to create database: %v\n", err) + return + } + defer db.Close() + + // Insert the main network genesis block. This is part of the initial + // database setup. Like above, this typically would not be needed when + // opening an existing database. + genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock) + _, err = db.InsertBlock(genesisBlock) + if err != nil { + fmt.Printf("Failed to insert genesis block: %v\n", err) + return + } + + // Create a new BlockChain instance using the underlying database for + // the main bitcoin network and ignore notifications. + chain := btcchain.New(db, &btcnet.MainNetParams, nil) + + // Process a block. For this example, we are going to intentionally + // cause an error by trying to process the genesis block which already + // exists. + isOrphan, err := chain.ProcessBlock(genesisBlock, btcchain.BFNone) + if err != nil { + fmt.Printf("Failed to process block: %v\n", err) + return + } + fmt.Println("Block accepted. Is it an orphan?: %v", isOrphan) + + // Output: + // Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f +} From 62c14b70014cc78127ac90c7d952d1498fe82859 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 8 Jul 2014 01:49:48 -0500 Subject: [PATCH 160/190] Name new example so it shows up properly on godoc. --- README.md | 2 +- example_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 180afa8c..d4ea306d 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ is by no means exhaustive: ## Examples * [ProcessBlock Example] - (http://godoc.org/github.com/conformal/btcchain#example-ProcessBlock) + (http://godoc.org/github.com/conformal/btcchain#example-BlockChain-ProcessBlock) Demonstrates how to create a new chain instance and use ProcessBlock to attempt to attempt add a block to the chain. This example intentionally attempts to insert a duplicate genesis block to illustrate how an invalid diff --git a/example_test.go b/example_test.go index b5a0d8e1..3f88bf78 100644 --- a/example_test.go +++ b/example_test.go @@ -18,7 +18,7 @@ import ( // overview documentation describes, this includes all of the Bitcoin consensus // rules. This example intentionally attempts to insert a duplicate genesis // block to illustrate how an invalid block is handled. -func ExampleProcessBlock() { +func ExampleBlockChain_ProcessBlock() { // Create a new database to store the accepted blocks into. Typically // this would be opening an existing database and would not use memdb // which is a memory-only database backend, but we create a new db From 1a2baa3099511003a53fc11407043182e93977c1 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 8 Jul 2014 02:15:41 -0500 Subject: [PATCH 161/190] Add CompactToBig example. --- README.md | 6 ++++++ doc.go | 8 -------- example_test.go | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d4ea306d..a67182df 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,12 @@ is by no means exhaustive: attempts to insert a duplicate genesis block to illustrate how an invalid block is handled. +* [CompactToBig Example] + (http://godoc.org/github.com/conformal/btcchain#example-CompactToBig) + Demonstrates how to convert the "bits" in a block header which represent the + target difficulty to a big integer and display it using the typical hex + notation. + ## TODO - Increase test coverage diff --git a/doc.go b/doc.go index f9909cb4..75a29f8f 100644 --- a/doc.go +++ b/doc.go @@ -61,14 +61,6 @@ is by no means exhaustive: coins - Insert the block into the block database -Examples - - - ProcessBlock Example - Demonstrates how to create a new chain instance and use ProcessBlock to - attempt to attempt add a block to the chain. This example intentionally - attempts to insert a duplicate genesis block to illustrate how an invalid - block is handled. - Errors Errors returned by this package are either the raw errors provided by underlying diff --git a/example_test.go b/example_test.go index 3f88bf78..0ee7a583 100644 --- a/example_test.go +++ b/example_test.go @@ -57,3 +57,18 @@ func ExampleBlockChain_ProcessBlock() { // Output: // Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f } + +// This example demonstrates how to convert the "bits" in a block header which +// represent the target difficulty to a big integer and display it using the +// typical hex notation.. +func ExampleCompactToBig() { + // Convert the bits from block 300000 in the main block chain. + bits := uint32(419465580) + targetDifficulty := btcchain.CompactToBig(bits) + + // Display it in hex. + fmt.Printf("%064x\n", targetDifficulty.Bytes()) + + // Output: + // 0000000000000000896c00000000000000000000000000000000000000000000 +} From 01fa7fa069e22a851e0377ff786ef947275e265c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 8 Jul 2014 07:57:22 -0500 Subject: [PATCH 162/190] Add BigToCompact example. --- README.md | 11 ++++++++--- example_test.go | 26 +++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a67182df..8bc2af0d 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,14 @@ is by no means exhaustive: * [CompactToBig Example] (http://godoc.org/github.com/conformal/btcchain#example-CompactToBig) - Demonstrates how to convert the "bits" in a block header which represent the - target difficulty to a big integer and display it using the typical hex - notation. + Demonstrates how to convert the compact "bits" in a block header which + represent the target difficulty to a big integer and display it using the + typical hex notation. + +* [BigToCompact Example] + (http://godoc.org/github.com/conformal/btcchain#example-BigToCompact) + Demonstrates how to convert how to convert a target difficulty into the + compact "bits" in a block header which represent that target difficulty. ## TODO diff --git a/example_test.go b/example_test.go index 0ee7a583..ac1b3f8e 100644 --- a/example_test.go +++ b/example_test.go @@ -11,6 +11,7 @@ import ( _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" "github.com/conformal/btcutil" + "math/big" ) // This example demonstrates how to create a new chain instance and use @@ -58,9 +59,9 @@ func ExampleBlockChain_ProcessBlock() { // Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f } -// This example demonstrates how to convert the "bits" in a block header which -// represent the target difficulty to a big integer and display it using the -// typical hex notation.. +// This example demonstrates how to convert the compact "bits" in a block header +// which represent the target difficulty to a big integer and display it using +// the typical hex notation. func ExampleCompactToBig() { // Convert the bits from block 300000 in the main block chain. bits := uint32(419465580) @@ -72,3 +73,22 @@ func ExampleCompactToBig() { // Output: // 0000000000000000896c00000000000000000000000000000000000000000000 } + +// This example demonstrates how to convert a target difficulty into the compact +// "bits" in a block header which represent that target difficulty . +func ExampleBigToCompact() { + // Convert the target difficulty from block 300000 in the main block + // chain to compact form. + t := "0000000000000000896c00000000000000000000000000000000000000000000" + targetDifficulty, success := new(big.Int).SetString(t, 16) + if !success { + fmt.Println("invalid target difficulty") + return + } + bits := btcchain.BigToCompact(targetDifficulty) + + fmt.Println(bits) + + // Output: + // 419465580 +} From cc315d045e0e7664ecc34b377fe9a21115b2b9d6 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 8 Jul 2014 10:32:29 -0500 Subject: [PATCH 163/190] Use a more specific license adjective in README.md. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bc2af0d..e6b62a56 100644 --- a/README.md +++ b/README.md @@ -119,4 +119,6 @@ signature perform the following: ## License -Package btcchain is licensed under the liberal ISC License. + +Package btcchain is licensed under the [copyfree](http://copyfree.org) ISC +License. From ff4d01765f6e853ad826d36a87424312797bc331 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 11 Jul 2014 09:36:53 -0500 Subject: [PATCH 164/190] Split time too old error into two distinct errors. This commit splits the two rule validation errors related to the timestamp being too old into two distince errors rather than grouping them under the same one. Thus there is now a new ErrCheckpointTimeTooNew in addition to the existing ErrTimeTooNew error. This allows the caller to detect the when a block is rejected due to a time-related checkpoint failure whereas before the combined error did not. --- error.go | 7 ++++++- error_test.go | 1 + process.go | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/error.go b/error.go index 974d33c9..31853c59 100644 --- a/error.go +++ b/error.go @@ -62,10 +62,14 @@ const ( // checkpoint height does not match the expected one. ErrBadCheckpoint - // ErrForkTooOld indicates a block is attempted to fork the block chain + // ErrForkTooOld indicates a block is attempting to fork the block chain // before the most recent checkpoint. ErrForkTooOld + // ErrCheckpointTimeTooOld indicates a block has a timestamp before the + // most recent checkpoint. + ErrCheckpointTimeTooOld + // ErrNoTransactions indicates the block does not have a least one // transaction. A valid block must have at least the coinbase // transaction. @@ -190,6 +194,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrBadMerkleRoot: "ErrBadMerkleRoot", ErrBadCheckpoint: "ErrBadCheckpoint", ErrForkTooOld: "ErrForkTooOld", + ErrCheckpointTimeTooOld: "ErrCheckpointTimeTooOld", ErrNoTransactions: "ErrNoTransactions", ErrTooManyTransactions: "ErrTooManyTransactions", ErrNoTxInputs: "ErrNoTxInputs", diff --git a/error_test.go b/error_test.go index 20f6f58c..4f7b3398 100644 --- a/error_test.go +++ b/error_test.go @@ -28,6 +28,7 @@ func TestErrorCodeStringer(t *testing.T) { {btcchain.ErrBadMerkleRoot, "ErrBadMerkleRoot"}, {btcchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, {btcchain.ErrForkTooOld, "ErrForkTooOld"}, + {btcchain.ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, {btcchain.ErrNoTransactions, "ErrNoTransactions"}, {btcchain.ErrTooManyTransactions, "ErrTooManyTransactions"}, {btcchain.ErrNoTxInputs, "ErrNoTxInputs"}, diff --git a/process.go b/process.go index e86103b1..55927afd 100644 --- a/process.go +++ b/process.go @@ -165,7 +165,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo str := fmt.Sprintf("block %v has timestamp %v before "+ "last checkpoint timestamp %v", blockHash, blockHeader.Timestamp, checkpointTime) - return false, ruleError(ErrTimeTooOld, str) + return false, ruleError(ErrCheckpointTimeTooOld, str) } if !fastAdd { // Even though the checks prior to now have already ensured the From c3abafc7eb86f90f17daa064782f4e5faad10ce3 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 28 Aug 2014 10:23:46 -0400 Subject: [PATCH 165/190] Println -> Printf when using formatting directives. This makes go vet happy. --- example_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example_test.go b/example_test.go index ac1b3f8e..d23c9476 100644 --- a/example_test.go +++ b/example_test.go @@ -53,7 +53,7 @@ func ExampleBlockChain_ProcessBlock() { fmt.Printf("Failed to process block: %v\n", err) return } - fmt.Println("Block accepted. Is it an orphan?: %v", isOrphan) + fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan) // Output: // Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f From 351a2a5f5eb0ef12acf101fe7635e2f4076b88ed Mon Sep 17 00:00:00 2001 From: "John C. Vernaleo" Date: Tue, 16 Sep 2014 08:21:34 -0400 Subject: [PATCH 166/190] Add vet, lint, and 1.2 builds to travis. --- .travis.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 59c603be..0e3948e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,15 @@ language: go go: + - 1.2 - release - tip -install: go get -d -t -v ./... +install: + - go get -d -t -v ./... + - go get -v code.google.com/p/go.tools/cmd/vet + - go get -v github.com/GeertJohan/fgt + - go get -v github.com/golang/lint/golint +script: + - export PATH=$PATH:$HOME/gopath/bin + - go vet + - fgt golint . + - go test -v From f5f03e8172ab3ebbb9934142ef757833c0d62300 Mon Sep 17 00:00:00 2001 From: "John C. Vernaleo" Date: Tue, 16 Sep 2014 15:08:53 -0400 Subject: [PATCH 167/190] Match error names to btcdb updates. --- txlookup.go | 6 +++--- validate.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/txlookup.go b/txlookup.go index fc9c24b7..2df1499a 100644 --- a/txlookup.go +++ b/txlookup.go @@ -77,7 +77,7 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { txD.Tx = nil txD.BlockHeight = 0 txD.Spent = nil - txD.Err = btcdb.TxShaMissing + txD.Err = btcdb.ErrTxShaMissing } // Unspend the origin transaction output. @@ -114,7 +114,7 @@ func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]struct{}, includeSp txList := make([]*btcwire.ShaHash, 0, len(txSet)) for hash := range txSet { hashCopy := hash - txStore[hash] = &TxData{Hash: &hashCopy, Err: btcdb.TxShaMissing} + txStore[hash] = &TxData{Hash: &hashCopy, Err: btcdb.ErrTxShaMissing} txList = append(txList, &hashCopy) } @@ -253,7 +253,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // Add an entry to the transaction store for the needed // transaction with it set to missing by default. originHash := &txIn.PreviousOutpoint.Hash - txD := &TxData{Hash: originHash, Err: btcdb.TxShaMissing} + txD := &TxData{Hash: originHash, Err: btcdb.ErrTxShaMissing} txStore[*originHash] = txD // It is acceptable for a transaction input to reference diff --git a/validate.go b/validate.go index e7a4b659..ae10d683 100644 --- a/validate.go +++ b/validate.go @@ -626,7 +626,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { switch txD.Err { // A duplicate transaction was not found. This is the most // common case. - case btcdb.TxShaMissing: + case btcdb.ErrTxShaMissing: continue // A duplicate transaction was found. This is only allowed if From f60e503308bfb41b6fa84e4d2d3f6a56b8e539f6 Mon Sep 17 00:00:00 2001 From: Jonathan Gillham Date: Wed, 1 Oct 2014 13:53:47 +0100 Subject: [PATCH 168/190] Changed TxIn.PreviousOutpoint to TxIn.PreviousOutPoint after btcwire API change. --- scriptval.go | 8 ++++---- txlookup.go | 12 ++++++------ validate.go | 16 ++++++++-------- validate_test.go | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/scriptval.go b/scriptval.go index e958c650..a7f972f5 100644 --- a/scriptval.go +++ b/scriptval.go @@ -53,7 +53,7 @@ out: case txVI := <-v.validateChan: // Ensure the referenced input transaction is available. txIn := txVI.txIn - originTxHash := &txIn.PreviousOutpoint.Hash + originTxHash := &txIn.PreviousOutPoint.Hash originTx, exists := v.txStore[*originTxHash] if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input "+ @@ -68,7 +68,7 @@ out: // Ensure the output index in the referenced transaction // is available. - originTxIndex := txIn.PreviousOutpoint.Index + originTxIndex := txIn.PreviousOutPoint.Index if originTxIndex >= uint32(len(originMsgTx.TxOut)) { str := fmt.Sprintf("out of bounds "+ "input index %d in transaction %v "+ @@ -198,7 +198,7 @@ func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript txValItems := make([]*txValidateItem, 0, len(txIns)) for txInIdx, txIn := range txIns { // Skip coinbases. - if txIn.PreviousOutpoint.Index == math.MaxUint32 { + if txIn.PreviousOutPoint.Index == math.MaxUint32 { continue } @@ -240,7 +240,7 @@ func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { for _, tx := range block.Transactions() { for txInIdx, txIn := range tx.MsgTx().TxIn { // Skip coinbases. - if txIn.PreviousOutpoint.Index == math.MaxUint32 { + if txIn.PreviousOutPoint.Index == math.MaxUint32 { continue } diff --git a/txlookup.go b/txlookup.go index 2df1499a..107c3ed8 100644 --- a/txlookup.go +++ b/txlookup.go @@ -47,8 +47,8 @@ func connectTransactions(txStore TxStore, block *btcutil.Block) error { // Spend the origin transaction output. for _, txIn := range msgTx.TxIn { - originHash := &txIn.PreviousOutpoint.Hash - originIndex := txIn.PreviousOutpoint.Index + originHash := &txIn.PreviousOutPoint.Hash + originIndex := txIn.PreviousOutPoint.Index if originTx, exists := txStore[*originHash]; exists { if originIndex > uint32(len(originTx.Spent)) { continue @@ -82,8 +82,8 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // Unspend the origin transaction output. for _, txIn := range tx.MsgTx().TxIn { - originHash := &txIn.PreviousOutpoint.Hash - originIndex := txIn.PreviousOutpoint.Index + originHash := &txIn.PreviousOutPoint.Hash + originIndex := txIn.PreviousOutPoint.Index originTx, exists := txStore[*originHash] if exists && originTx.Tx != nil && originTx.Err == nil { if originIndex > uint32(len(originTx.Spent)) { @@ -252,7 +252,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc for _, txIn := range tx.MsgTx().TxIn { // Add an entry to the transaction store for the needed // transaction with it set to missing by default. - originHash := &txIn.PreviousOutpoint.Hash + originHash := &txIn.PreviousOutPoint.Hash txD := &TxData{Hash: originHash, Err: btcdb.ErrTxShaMissing} txStore[*originHash] = txD @@ -306,7 +306,7 @@ func (b *BlockChain) FetchTransactionStore(tx *btcutil.Tx) (TxStore, error) { txNeededSet := make(map[btcwire.ShaHash]struct{}) txNeededSet[*tx.Sha()] = struct{}{} for _, txIn := range tx.MsgTx().TxIn { - txNeededSet[txIn.PreviousOutpoint.Hash] = struct{}{} + txNeededSet[txIn.PreviousOutPoint.Hash] = struct{}{} } // Request the input transactions from the point of view of the end of diff --git a/validate.go b/validate.go index ae10d683..5f4bccc1 100644 --- a/validate.go +++ b/validate.go @@ -104,7 +104,7 @@ func IsCoinBase(tx *btcutil.Tx) bool { // The previous output of a coin base must have a max value index and // a zero hash. - prevOut := msgTx.TxIn[0].PreviousOutpoint + prevOut := msgTx.TxIn[0].PreviousOutPoint if prevOut.Index != math.MaxUint32 || !prevOut.Hash.IsEqual(zeroHash) { return false } @@ -246,11 +246,11 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // Check for duplicate transaction inputs. existingTxOut := make(map[btcwire.OutPoint]struct{}) for _, txIn := range msgTx.TxIn { - if _, exists := existingTxOut[txIn.PreviousOutpoint]; exists { + if _, exists := existingTxOut[txIn.PreviousOutPoint]; exists { return ruleError(ErrDuplicateTxInputs, "transaction "+ "contains duplicate inputs") } - existingTxOut[txIn.PreviousOutpoint] = struct{}{} + existingTxOut[txIn.PreviousOutPoint] = struct{}{} } // Coinbase script length must be between min and max length. @@ -266,7 +266,7 @@ func CheckTransactionSanity(tx *btcutil.Tx) error { // Previous transaction outputs referenced by the inputs to this // transaction must not be null. for _, txIn := range msgTx.TxIn { - prevOut := &txIn.PreviousOutpoint + prevOut := &txIn.PreviousOutPoint if isNullOutpoint(prevOut) { return ruleError(ErrBadTxInput, "transaction "+ "input refers to previous output that "+ @@ -369,7 +369,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e totalSigOps := 0 for _, txIn := range msgTx.TxIn { // Ensure the referenced input transaction is available. - txInHash := &txIn.PreviousOutpoint.Hash + txInHash := &txIn.PreviousOutPoint.Hash originTx, exists := txStore[*txInHash] if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input transaction "+ @@ -381,7 +381,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e // Ensure the output index in the referenced transaction is // available. - originTxIndex := txIn.PreviousOutpoint.Index + originTxIndex := txIn.PreviousOutPoint.Index if originTxIndex >= uint32(len(originMsgTx.TxOut)) { str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", @@ -667,7 +667,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in var totalSatoshiIn int64 for _, txIn := range tx.MsgTx().TxIn { // Ensure the input is available. - txInHash := &txIn.PreviousOutpoint.Hash + txInHash := &txIn.PreviousOutPoint.Hash originTx, exists := txStore[*txInHash] if !exists || originTx.Err != nil || originTx.Tx == nil { str := fmt.Sprintf("unable to find input transaction "+ @@ -691,7 +691,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in } // Ensure the transaction is not double spending coins. - originTxIndex := txIn.PreviousOutpoint.Index + originTxIndex := txIn.PreviousOutPoint.Index if originTxIndex >= uint32(len(originTx.Spent)) { str := fmt.Sprintf("out of bounds input index %d in "+ "transaction %v referenced from transaction %v", diff --git a/validate_test.go b/validate_test.go index 98c75a2f..7aa7f1e2 100644 --- a/validate_test.go +++ b/validate_test.go @@ -152,7 +152,7 @@ var Block100000 = btcwire.MsgBlock{ Version: 1, TxIn: []*btcwire.TxIn{ { - PreviousOutpoint: btcwire.OutPoint{ + PreviousOutPoint: btcwire.OutPoint{ Hash: btcwire.ShaHash{}, Index: 0xffffffff, }, @@ -186,7 +186,7 @@ var Block100000 = btcwire.MsgBlock{ Version: 1, TxIn: []*btcwire.TxIn{ { - PreviousOutpoint: btcwire.OutPoint{ + PreviousOutPoint: btcwire.OutPoint{ Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. 0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60, 0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac, @@ -255,7 +255,7 @@ var Block100000 = btcwire.MsgBlock{ Version: 1, TxIn: []*btcwire.TxIn{ { - PreviousOutpoint: btcwire.OutPoint{ + PreviousOutPoint: btcwire.OutPoint{ Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. 0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d, 0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27, @@ -323,7 +323,7 @@ var Block100000 = btcwire.MsgBlock{ Version: 1, TxIn: []*btcwire.TxIn{ { - PreviousOutpoint: btcwire.OutPoint{ + PreviousOutPoint: btcwire.OutPoint{ Hash: btcwire.ShaHash([32]byte{ // Make go vet happy. 0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73, 0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac, From df065eee1903cead496672d968a44bb7d585e078 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 3 Oct 2014 15:29:25 -0500 Subject: [PATCH 169/190] Provide a new median time source API. This commit provides a new interface, MedianTimeSource, along with a concrete implementation which allows improved accuracy of time by making use of the median network time as calculated from multiple time samples. The time samples are to be provided by callers and are intended to come from remote clients. The calculations performed in this implementation exactly mirror those in Bitcoin Core because time calculations are part of the consensus rules and hence need to match exactly. --- chain.go | 6 +- chain_test.go | 7 +- example_test.go | 8 +- mediantime.go | 217 +++++++++++++++++++++++++++++++++++++++++ process.go | 4 +- reorganization_test.go | 3 +- validate.go | 9 +- validate_test.go | 7 +- 8 files changed, 246 insertions(+), 15 deletions(-) create mode 100644 mediantime.go diff --git a/chain.go b/chain.go index 0b979dcc..9066a2d6 100644 --- a/chain.go +++ b/chain.go @@ -1038,7 +1038,7 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *btcutil.Block, fla // - Latest block has a timestamp newer than 24 hours ago // // This function is NOT safe for concurrent access. -func (b *BlockChain) IsCurrent() bool { +func (b *BlockChain) IsCurrent(timeSource MedianTimeSource) bool { // Not current if there isn't a main (best) chain yet. if b.bestChain == nil { return false @@ -1053,8 +1053,8 @@ func (b *BlockChain) IsCurrent() bool { // Not current if the latest best block has a timestamp before 24 hours // ago. - now := time.Now() - if b.bestChain.timestamp.Before(now.Add(-24 * time.Hour)) { + minus24Hours := timeSource.AdjustedTime().Add(-24 * time.Hour) + if b.bestChain.timestamp.Before(minus24Hours) { return false } diff --git a/chain_test.go b/chain_test.go index b1e4d72e..22f0d01b 100644 --- a/chain_test.go +++ b/chain_test.go @@ -48,8 +48,10 @@ func TestHaveBlock(t *testing.T) { chain.DisableCheckpoints(true) btcchain.TstSetCoinbaseMaturity(1) + timeSource := btcchain.NewMedianTime() for i := 1; i < len(blocks); i++ { - isOrphan, err := chain.ProcessBlock(blocks[i], btcchain.BFNone) + isOrphan, err := chain.ProcessBlock(blocks[i], timeSource, + btcchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return @@ -62,7 +64,8 @@ func TestHaveBlock(t *testing.T) { } // Insert an orphan block. - isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), btcchain.BFNone) + isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), + timeSource, btcchain.BFNone) if err != nil { t.Errorf("Unable to process block: %v", err) return diff --git a/example_test.go b/example_test.go index d23c9476..08f62991 100644 --- a/example_test.go +++ b/example_test.go @@ -45,10 +45,16 @@ func ExampleBlockChain_ProcessBlock() { // the main bitcoin network and ignore notifications. chain := btcchain.New(db, &btcnet.MainNetParams, nil) + // Create a new median time source that is required by the upcoming + // call to ProcessBlock. Ordinarily this would also add time values + // obtained from other peers on the network so the local time is + // adjusted to be in agreement with other peers. + timeSource := btcchain.NewMedianTime() + // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - isOrphan, err := chain.ProcessBlock(genesisBlock, btcchain.BFNone) + isOrphan, err := chain.ProcessBlock(genesisBlock, timeSource, btcchain.BFNone) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return diff --git a/mediantime.go b/mediantime.go new file mode 100644 index 00000000..b11fcd34 --- /dev/null +++ b/mediantime.go @@ -0,0 +1,217 @@ +// Copyright (c) 2013-2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain + +import ( + "math" + "sort" + "sync" + "time" +) + +const ( + // maxAllowedOffsetSeconds is the maximum number of seconds in either + // direction that local clock will be adjusted. When the median time + // of the network is outside of this range, no offset will be applied. + maxAllowedOffsetSecs = 70 * 60 // 1 hour 10 minutes + + // similarTimeSecs is the number of seconds in either direction from the + // local clock that is used to determine that it is likley wrong and + // hence to show a warning. + similarTimeSecs = 5 * 60 // 5 minutes +) + +var ( + // maxMedianTimeEntries is the maximum number of entries allowed in the + // median time data. This is a variable as opposed to a constant so the + // test code can modify it. + maxMedianTimeEntries = 200 +) + +// MedianTimeSource provides a mechanism to add several time samples which are +// used to determine a median time which is then used as an offset to the local +// clock. +type MedianTimeSource interface { + // AdjustedTime returns the current time adjusted by the median time + // offset as calculated from the time samples added by AddTimeSample. + AdjustedTime() time.Time + + // AddTimeSample adds a time sample that is used when determining the + // median time of the added samples. + AddTimeSample(id string, timeVal time.Time) + + // Offset returns the number of seconds to adjust the local clock based + // upon the median of the time samples added by AddTimeData. + Offset() time.Duration +} + +// int64Sorter implements sort.Interface to allow a slice of 64-bit integers to +// be sorted. +type int64Sorter []int64 + +// Len returns the number of 64-bit integers in the slice. It is part of the +// sort.Interface implementation. +func (s int64Sorter) Len() int { + return len(s) +} + +// Swap swaps the 64-bit integers at the passed indices. It is part of the +// sort.Interface implementation. +func (s int64Sorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less returns whether the 64-bit integer with index i should sort before the +// 64-bit integer with index j. It is part of the sort.Interface +// implementation. +func (s int64Sorter) Less(i, j int) bool { + return s[i] < s[j] +} + +// medianTime provides an implementation of the MedianTimeSource interface. +// It is limited to maxMedianTimeEntries includes the same buggy behavior as +// the time offset mechanism in Bitcoin Core. This is necessary because it is +// used in the consensus code. +type medianTime struct { + mtx sync.Mutex + knownIDs map[string]struct{} + offsets []int64 + offsetSecs int64 + invalidTimeChecked bool +} + +// Ensure the medianTime type implements the MedianTimeSource interface. +var _ MedianTimeSource = (*medianTime)(nil) + +// AdjustedTime returns the current time adjusted by the median time offset as +// calculated from the time samples added by AddTimeSample. +// +// This function is safe for concurrent access and is part of the +// MedianTimeSource interface implementation. +func (m *medianTime) AdjustedTime() time.Time { + m.mtx.Lock() + defer m.mtx.Unlock() + + // Limit the adjusted time to 1 second precision. + now := time.Unix(time.Now().Unix(), 0) + return now.Add(time.Duration(m.offsetSecs) * time.Second) +} + +// AddTimeSample adds a time sample that is used when determining the median +// time of the added samples. +// +// This function is safe for concurrent access and is part of the +// MedianTimeSource interface implementation. +func (m *medianTime) AddTimeSample(sourceID string, timeVal time.Time) { + m.mtx.Lock() + defer m.mtx.Unlock() + + // Don't add time data from the same source. + if _, exists := m.knownIDs[sourceID]; exists { + return + } + m.knownIDs[sourceID] = struct{}{} + + // Truncate the provided offset to seconds and append it to the slice + // of offsets while respecting the maximum number of allowed entries by + // replacing the oldest entry with the new entry once the maximum number + // of entries is reached. + offsetSecs := int64(time.Now().Sub(timeVal).Seconds()) + numOffsets := len(m.offsets) + if numOffsets == maxMedianTimeEntries && maxMedianTimeEntries > 0 { + m.offsets = m.offsets[1:] + numOffsets-- + } + m.offsets = append(m.offsets, offsetSecs) + numOffsets++ + + // Sort the offsets so the median can be obtained as needed later. + sortedOffsets := make([]int64, numOffsets) + copy(sortedOffsets, m.offsets) + sort.Sort(int64Sorter(sortedOffsets)) + + offsetDuration := time.Duration(offsetSecs) * time.Second + log.Debugf("Added time sample of %v (total: %v)", offsetDuration, + numOffsets) + + // NOTE: The following code intentionally has a bug to mirror the + // buggy behavior in Bitcoin Core since the median time is used in the + // consensus rules. + // + // In particular, the offset is only updated when the number of entries + // is odd, but the max number of entries is 200, an even number. Thus, + // the offset will never be updated again once the max number of entries + // is reached. + + // The median offset is only updated when there are enough offsets and + // the number of offsets is odd so the middle value is the true median. + // Thus, there is nothing to do when those conditions are not met. + if numOffsets < 5 || numOffsets&0x01 != 1 { + return + } + + // At this point the number of offsets in the list is odd, so the + // middle value of the sorted offsets is the median. + median := sortedOffsets[numOffsets/2] + + // Set the new offset when the median offset is within the allowed + // offset range. + if math.Abs(float64(median)) < maxAllowedOffsetSecs { + m.offsetSecs = median + } else { + // The median offset of all added time data is larger than the + // maximum allowed offset, so don't use an offset. This + // effectively limits how far the local clock can be skewed. + m.offsetSecs = 0 + + if !m.invalidTimeChecked { + m.invalidTimeChecked = true + + // Find if any time samples have a time that is close + // to the local time. + var remoteHasCloseTime bool + for _, offset := range sortedOffsets { + if math.Abs(float64(offset)) < similarTimeSecs { + remoteHasCloseTime = true + break + } + } + + // Warn if none of the time samples are close. + if !remoteHasCloseTime { + log.Warnf("Please check your date and time " + + "are correct! btcd will not work " + + "properly with an invalid time") + } + } + } + + medianDuration := time.Duration(m.offsetSecs) * time.Second + log.Debugf("New time offset: %v", medianDuration) +} + +// Offset returns the number of seconds to adjust the local clock based upon the +// median of the time samples added by AddTimeData. +// +// This function is safe for concurrent access and is part of the +// MedianTimeSource interface implementation. +func (m *medianTime) Offset() time.Duration { + m.mtx.Lock() + defer m.mtx.Unlock() + + return time.Duration(m.offsetSecs) * time.Second +} + +// NewMedianTime returns a new instance of concurrency-safe implementation of +// the MedianTimeSource interface. The returned implementation contains the +// rules necessary for proper time handling in the chain consensus rules and +// expects the time samples to be added from the timestamp field of the version +// message received from remote peers that successfully connect and negotiate. +func NewMedianTime() MedianTimeSource { + return &medianTime{ + knownIDs: make(map[string]struct{}), + offsets: make([]int64, 0, maxMedianTimeEntries), + } +} diff --git a/process.go b/process.go index 55927afd..d6162590 100644 --- a/process.go +++ b/process.go @@ -114,7 +114,7 @@ func (b *BlockChain) processOrphans(hash *btcwire.ShaHash, flags BehaviorFlags) // It returns a bool which indicates whether or not the block is an orphan and // any errors that occurred during processing. The returned bool is only valid // when the error is nil. -func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bool, error) { +func (b *BlockChain) ProcessBlock(block *btcutil.Block, timeSource MedianTimeSource, flags BehaviorFlags) (bool, error) { fastAdd := flags&BFFastAdd == BFFastAdd dryRun := flags&BFDryRun == BFDryRun @@ -141,7 +141,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo } // Perform preliminary sanity checks on the block and its transactions. - err = checkBlockSanity(block, b.netParams.PowLimit, flags) + err = checkBlockSanity(block, b.netParams.PowLimit, timeSource, flags) if err != nil { return false, err } diff --git a/reorganization_test.go b/reorganization_test.go index d6baa87b..1acaf23b 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -58,9 +58,10 @@ func TestReorganization(t *testing.T) { chain.DisableCheckpoints(true) btcchain.TstSetCoinbaseMaturity(1) + timeSource := btcchain.NewMedianTime() expectedOrphans := map[int]struct{}{5: struct{}{}, 6: struct{}{}} for i := 1; i < len(blocks); i++ { - isOrphan, err := chain.ProcessBlock(blocks[i], btcchain.BFNone) + isOrphan, err := chain.ProcessBlock(blocks[i], timeSource, btcchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return diff --git a/validate.go b/validate.go index 5f4bccc1..04cb1787 100644 --- a/validate.go +++ b/validate.go @@ -423,7 +423,7 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e // // The flags do not modify the behavior of this function directly, however they // are needed to pass along to checkProofOfWork. -func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFlags) error { +func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource MedianTimeSource, flags BehaviorFlags) error { // A block must have at least one transaction. msgBlock := block.MsgBlock() numTx := len(msgBlock.Transactions) @@ -469,7 +469,8 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFla } // Ensure the block time is not too far in the future. - maxTimestamp := time.Now().Add(time.Second * MaxTimeOffsetSeconds) + maxTimestamp := timeSource.AdjustedTime().Add(time.Second * + MaxTimeOffsetSeconds) if header.Timestamp.After(maxTimestamp) { str := fmt.Sprintf("block timestamp of %v is too far in the "+ "future", header.Timestamp) @@ -551,8 +552,8 @@ func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFla // CheckBlockSanity performs some preliminary checks on a block to ensure it is // sane before continuing with block processing. These checks are context free. -func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error { - return checkBlockSanity(block, powLimit, BFNone) +func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource MedianTimeSource) error { + return checkBlockSanity(block, powLimit, timeSource, BFNone) } // checkSerializedHeight checks if the signature script in the passed diff --git a/validate_test.go b/validate_test.go index 7aa7f1e2..aa91333b 100644 --- a/validate_test.go +++ b/validate_test.go @@ -41,10 +41,13 @@ func TestCheckConnectBlock(t *testing.T) { } } +// TestCheckBlockSanity tests the CheckBlockSanity function to ensure it works +// as expected. func TestCheckBlockSanity(t *testing.T) { powLimit := btcnet.MainNetParams.PowLimit block := btcutil.NewBlock(&Block100000) - err := btcchain.CheckBlockSanity(block, powLimit) + timeSource := btcchain.NewMedianTime() + err := btcchain.CheckBlockSanity(block, powLimit, timeSource) if err != nil { t.Errorf("CheckBlockSanity: %v", err) } @@ -53,7 +56,7 @@ func TestCheckBlockSanity(t *testing.T) { // second fails. timestamp := block.MsgBlock().Header.Timestamp block.MsgBlock().Header.Timestamp = timestamp.Add(time.Nanosecond) - err = btcchain.CheckBlockSanity(block, powLimit) + err = btcchain.CheckBlockSanity(block, powLimit, timeSource) if err == nil { t.Errorf("CheckBlockSanity: error is nil when it shouldn't be") } From 208d4d79d7b732d651a1682424c7402503933615 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 10 Oct 2014 01:11:39 -0500 Subject: [PATCH 170/190] Add 100% test coverage for new median time code. --- internal_test.go | 6 +++ mediantime_test.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 mediantime_test.go diff --git a/internal_test.go b/internal_test.go index ac11ca53..d18369cf 100644 --- a/internal_test.go +++ b/internal_test.go @@ -34,3 +34,9 @@ func TstTimeSorter(times []time.Time) timeSorter { func TstCheckSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { return checkSerializedHeight(coinbaseTx, wantHeight) } + +// TstSetMaxMedianTimeEntries makes the ability to set the maximum number of +// median tiem entries available to the test package. +func TstSetMaxMedianTimeEntries(val int) { + maxMedianTimeEntries = val +} diff --git a/mediantime_test.go b/mediantime_test.go new file mode 100644 index 00000000..6a4254c5 --- /dev/null +++ b/mediantime_test.go @@ -0,0 +1,96 @@ +// Copyright (c) 2013-2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "strconv" + "testing" + "time" + + "github.com/conformal/btcchain" +) + +// TestMedianTime tests the medianTime implementation. +func TestMedianTime(t *testing.T) { + tests := []struct { + in []int64 + wantOffset int64 + useDupID bool + }{ + // Not enough samples must result in an offset of 0. + {in: []int64{1}, wantOffset: 0}, + {in: []int64{1, 2}, wantOffset: 0}, + {in: []int64{1, 2, 3}, wantOffset: 0}, + {in: []int64{1, 2, 3, 4}, wantOffset: 0}, + + // Various number of entries. The expected offset is only + // updated on odd number of elements. + {in: []int64{-13, 57, -4, -23, -12}, wantOffset: 12}, + {in: []int64{55, -13, 61, -52, 39, 55}, wantOffset: -39}, + {in: []int64{-62, -58, -30, -62, 51, -30, 15}, wantOffset: 30}, + {in: []int64{29, -47, 39, 54, 42, 41, 8, -33}, wantOffset: -39}, + {in: []int64{37, 54, 9, -21, -56, -36, 5, -11, -39}, wantOffset: 11}, + {in: []int64{57, -28, 25, -39, 9, 63, -16, 19, -60, 25}, wantOffset: -9}, + {in: []int64{-5, -4, -3, -2, -1}, wantOffset: 3, useDupID: true}, + + // The offset stops being updated once the max number of entries + // has been reached. This is actually a bug from Bitcoin Core, + // but since the time is ultimately used as a part of the + // consensus rules, it must be mirrored. + {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52}, wantOffset: -17}, + {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52, 45}, wantOffset: -17}, + {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52, 45, 4}, wantOffset: -17}, + + // Offsets that are too far away from the local time should + // be ignored. + {in: []int64{-4201, 4202, -4203, 4204, -4205}, wantOffset: 0}, + + // Excerise the condition where the median offset is greater + // than the max allowed adjustment, but there is at least one + // sample that is close enough to the current time to avoid + // triggering a warning about an invalid local clock. + {in: []int64{4201, 4202, 4203, 4204, -299}, wantOffset: 0}, + } + + // Modify the max number of allowed median time entries for these tests. + btcchain.TstSetMaxMedianTimeEntries(10) + defer btcchain.TstSetMaxMedianTimeEntries(200) + + for i, test := range tests { + filter := btcchain.NewMedianTime() + for j, offset := range test.in { + id := strconv.Itoa(j) + tOffset := time.Now().Add(time.Duration(offset) * + time.Second) + filter.AddTimeSample(id, tOffset) + + // Ensure the duplicate IDs are ignored. + if test.useDupID { + // Modify the offsets to ensure the final median + // would be different if the duplicate is added. + tOffset = tOffset.Add(time.Duration(offset) * + time.Second) + filter.AddTimeSample(id, tOffset) + } + } + + gotOffset := filter.Offset() + wantOffset := time.Duration(test.wantOffset) * time.Second + if gotOffset != wantOffset { + t.Errorf("Offset #%d: unexpected offset -- got %v, "+ + "want %v", i, gotOffset, wantOffset) + continue + } + + adjustedTime := time.Unix(filter.AdjustedTime().Unix(), 0) + wantTime := time.Now().Add(filter.Offset()) + wantTime = time.Unix(wantTime.Unix(), 0) + if !adjustedTime.Equal(wantTime) { + t.Errorf("AdjustedTime #%d: unexpected result -- got %v, "+ + "want %v", i, adjustedTime, wantTime) + continue + } + } +} From e1c622c4cfd1bf2e27448a0f0940407d35022343 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 11 Oct 2014 13:30:08 -0500 Subject: [PATCH 171/190] Modify the time sorter tests to make golint happy. This commit changes the internal testing mechanism from returning the unexported timeSorter type directly to insted returning sort.Interface. This has been done because the latest version of golint complains about return unexported types. --- internal_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal_test.go b/internal_test.go index d18369cf..a7bd88c2 100644 --- a/internal_test.go +++ b/internal_test.go @@ -12,6 +12,7 @@ interface. The functions are only exported while the tests are being run. package btcchain import ( + "sort" "time" "github.com/conformal/btcutil" @@ -25,7 +26,7 @@ func TstSetCoinbaseMaturity(maturity int64) { // TstTimeSorter makes the internal timeSorter type available to the test // package. -func TstTimeSorter(times []time.Time) timeSorter { +func TstTimeSorter(times []time.Time) sort.Interface { return timeSorter(times) } From b4c55aee281e90baad00ee210f330d06ccb04093 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 11 Oct 2014 14:49:35 -0500 Subject: [PATCH 172/190] Update new time tests to prevent false positives. The new median time tests perform a comparsion of the adjusted time returned from the median time source to the expected value. However, since time is always moving, it is possible the current time between the call to the adjusted time function and the current time taken in the tests for comparison just after the call differ by a second due to a boundary condition. So, this commit modifies the tests to allow for this condition. --- mediantime_test.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/mediantime_test.go b/mediantime_test.go index 6a4254c5..98e720c7 100644 --- a/mediantime_test.go +++ b/mediantime_test.go @@ -84,12 +84,17 @@ func TestMedianTime(t *testing.T) { continue } - adjustedTime := time.Unix(filter.AdjustedTime().Unix(), 0) - wantTime := time.Now().Add(filter.Offset()) - wantTime = time.Unix(wantTime.Unix(), 0) - if !adjustedTime.Equal(wantTime) { + // Since it is possible that the time.Now call in AdjustedTime + // and the time.Now call here in the tests will be off by one + // second, allow a fudge factor to compensate. + adjustedTime := filter.AdjustedTime() + now := time.Unix(time.Now().Unix(), 0) + wantTime := now.Add(filter.Offset()) + wantTime2 := now.Add(filter.Offset() - time.Second) + if !adjustedTime.Equal(wantTime) && !adjustedTime.Equal(wantTime2) { t.Errorf("AdjustedTime #%d: unexpected result -- got %v, "+ - "want %v", i, adjustedTime, wantTime) + "want %v or %v", i, adjustedTime, wantTime, + wantTime2) continue } } From 6af93023744264c2d49de0d21588604c62d0b60c Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 11 Oct 2014 18:03:14 -0500 Subject: [PATCH 173/190] More false positive prevention in new time tests. This commit extends the same logic in the previous commit to the comparison of offsets returned from the median time source in the tests. In particular it modifies the tests to allow for the offsets to differ by a second due to a boundary condition to prevent false positives. --- mediantime.go | 3 ++- mediantime_test.go | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mediantime.go b/mediantime.go index b11fcd34..1026edc9 100644 --- a/mediantime.go +++ b/mediantime.go @@ -118,7 +118,8 @@ func (m *medianTime) AddTimeSample(sourceID string, timeVal time.Time) { // of offsets while respecting the maximum number of allowed entries by // replacing the oldest entry with the new entry once the maximum number // of entries is reached. - offsetSecs := int64(time.Now().Sub(timeVal).Seconds()) + now := time.Unix(time.Now().Unix(), 0) + offsetSecs := int64(now.Sub(timeVal).Seconds()) numOffsets := len(m.offsets) if numOffsets == maxMedianTimeEntries && maxMedianTimeEntries > 0 { m.offsets = m.offsets[1:] diff --git a/mediantime_test.go b/mediantime_test.go index 98e720c7..d191c9c9 100644 --- a/mediantime_test.go +++ b/mediantime_test.go @@ -62,8 +62,8 @@ func TestMedianTime(t *testing.T) { filter := btcchain.NewMedianTime() for j, offset := range test.in { id := strconv.Itoa(j) - tOffset := time.Now().Add(time.Duration(offset) * - time.Second) + now := time.Unix(time.Now().Unix(), 0) + tOffset := now.Add(time.Duration(offset) * time.Second) filter.AddTimeSample(id, tOffset) // Ensure the duplicate IDs are ignored. @@ -76,11 +76,16 @@ func TestMedianTime(t *testing.T) { } } + // Since it is possible that the time.Now call in AddTimeSample + // and the time.Now calls here in the tests will be off by one + // second, allow a fudge factor to compensate. gotOffset := filter.Offset() wantOffset := time.Duration(test.wantOffset) * time.Second - if gotOffset != wantOffset { + wantOffset2 := time.Duration(test.wantOffset-1) * time.Second + if gotOffset != wantOffset && gotOffset != wantOffset2 { t.Errorf("Offset #%d: unexpected offset -- got %v, "+ - "want %v", i, gotOffset, wantOffset) + "want %v or %v", i, gotOffset, wantOffset, + wantOffset2) continue } From 8945620a8494f69764777638c314291a02b9ecfa Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Tue, 6 Jan 2015 19:20:25 -0500 Subject: [PATCH 174/190] Improve double spend error strings. The error message now includes both the previous tx hash and output index, rather than simply the transaction with the already spent output. --- validate.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/validate.go b/validate.go index 04cb1787..af9f52e0 100644 --- a/validate.go +++ b/validate.go @@ -701,8 +701,7 @@ func CheckTransactionInputs(tx *btcutil.Tx, txHeight int64, txStore TxStore) (in } if originTx.Spent[originTxIndex] { str := fmt.Sprintf("transaction %v tried to double "+ - "spend coins from transaction %v", txHash, - txInHash) + "spend output %v", txHash, txIn.PreviousOutPoint) return 0, ruleError(ErrDoubleSpend, str) } From d58ea754f338d2cb917f7b0d2d140884ab51758e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 8 Jan 2015 05:08:11 -0600 Subject: [PATCH 175/190] Add test and infrastructure for block scripts. This commit adds a test for checking known good block scripts in a block are valid. As a part of this, it adds the infastructure needed to load a saved transaction store from a file which contains all of the input transactions needed. It also contains some changes from running goimports as well as some other cleanup. --- common_test.go | 110 ++++++++++++++++++++++++++++++++++++ example_test.go | 3 +- internal_test.go | 10 ++-- mediantime.go | 2 +- mediantime_test.go | 20 +++---- scriptval.go | 1 - scriptval_test.go | 43 ++++++++++++++ testdata/277647.dat.bz2 | Bin 0 -> 115673 bytes testdata/277647.txstore.bz2 | Bin 0 -> 1374217 bytes validate.go | 4 +- validate_test.go | 1 - 11 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 scriptval_test.go create mode 100644 testdata/277647.dat.bz2 create mode 100644 testdata/277647.txstore.bz2 diff --git a/common_test.go b/common_test.go index 882d6a36..1010f185 100644 --- a/common_test.go +++ b/common_test.go @@ -5,9 +5,13 @@ package btcchain_test import ( + "compress/bzip2" + "encoding/binary" "fmt" + "io" "os" "path/filepath" + "strings" "github.com/conformal/btcchain" "github.com/conformal/btcdb" @@ -15,6 +19,7 @@ import ( _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" "github.com/conformal/btcutil" + "github.com/conformal/btcwire" ) // testDbType is the database backend type to use for the tests. @@ -114,3 +119,108 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { chain := btcchain.New(db, &btcnet.MainNetParams, nil) return chain, teardown, nil } + +// loadTxStore returns a transaction store loaded from a file. +func loadTxStore(filename string) (btcchain.TxStore, error) { + // The txstore file format is: + // + // + // + // All num and length fields are little-endian uint32s. The spent bits + // field is padded to a byte boundary. + + filename = filepath.Join("testdata/", filename) + fi, err := os.Open(filename) + if err != nil { + return nil, err + } + + // Choose read based on whether the file is compressed or not. + var r io.Reader + if strings.HasSuffix(filename, ".bz2") { + r = bzip2.NewReader(fi) + } else { + r = fi + } + defer fi.Close() + + // Num of transaction store objects. + var numItems uint32 + if err := binary.Read(r, binary.LittleEndian, &numItems); err != nil { + return nil, err + } + + txStore := make(btcchain.TxStore) + var uintBuf uint32 + for height := uint32(0); height < numItems; height++ { + txD := btcchain.TxData{} + + // Serialized transaction length. + err = binary.Read(r, binary.LittleEndian, &uintBuf) + if err != nil { + return nil, err + } + serializedTxLen := uintBuf + if serializedTxLen > btcwire.MaxBlockPayload { + return nil, fmt.Errorf("Read serialized transaction "+ + "length of %d is larger max allowed %d", + serializedTxLen, btcwire.MaxBlockPayload) + } + + // Transaction. + var msgTx btcwire.MsgTx + err = msgTx.Deserialize(r) + if err != nil { + return nil, err + } + txD.Tx = btcutil.NewTx(&msgTx) + + // Transaction hash. + txHash, err := msgTx.TxSha() + if err != nil { + return nil, err + } + txD.Hash = &txHash + + // Block height the transaction came from. + err = binary.Read(r, binary.LittleEndian, &uintBuf) + if err != nil { + return nil, err + } + txD.BlockHeight = int64(uintBuf) + + // Num spent bits. + err = binary.Read(r, binary.LittleEndian, &uintBuf) + if err != nil { + return nil, err + } + numSpentBits := uintBuf + numSpentBytes := numSpentBits / 8 + if numSpentBits%8 != 0 { + numSpentBytes++ + } + + // Packed spent bytes. + spentBytes := make([]byte, numSpentBytes) + _, err = io.ReadFull(r, spentBytes) + if err != nil { + return nil, err + } + + // Populate spent data based on spent bits. + txD.Spent = make([]bool, numSpentBits) + for byteNum, spentByte := range spentBytes { + for bit := 0; bit < 8; bit++ { + if uint32((byteNum*8)+bit) < numSpentBits { + if spentByte&(1< 0 { m.offsets = m.offsets[1:] diff --git a/mediantime_test.go b/mediantime_test.go index d191c9c9..1b714007 100644 --- a/mediantime_test.go +++ b/mediantime_test.go @@ -27,21 +27,21 @@ func TestMedianTime(t *testing.T) { // Various number of entries. The expected offset is only // updated on odd number of elements. - {in: []int64{-13, 57, -4, -23, -12}, wantOffset: 12}, - {in: []int64{55, -13, 61, -52, 39, 55}, wantOffset: -39}, - {in: []int64{-62, -58, -30, -62, 51, -30, 15}, wantOffset: 30}, - {in: []int64{29, -47, 39, 54, 42, 41, 8, -33}, wantOffset: -39}, - {in: []int64{37, 54, 9, -21, -56, -36, 5, -11, -39}, wantOffset: 11}, - {in: []int64{57, -28, 25, -39, 9, 63, -16, 19, -60, 25}, wantOffset: -9}, - {in: []int64{-5, -4, -3, -2, -1}, wantOffset: 3, useDupID: true}, + {in: []int64{-13, 57, -4, -23, -12}, wantOffset: -12}, + {in: []int64{55, -13, 61, -52, 39, 55}, wantOffset: 39}, + {in: []int64{-62, -58, -30, -62, 51, -30, 15}, wantOffset: -30}, + {in: []int64{29, -47, 39, 54, 42, 41, 8, -33}, wantOffset: 39}, + {in: []int64{37, 54, 9, -21, -56, -36, 5, -11, -39}, wantOffset: -11}, + {in: []int64{57, -28, 25, -39, 9, 63, -16, 19, -60, 25}, wantOffset: 9}, + {in: []int64{-5, -4, -3, -2, -1}, wantOffset: -3, useDupID: true}, // The offset stops being updated once the max number of entries // has been reached. This is actually a bug from Bitcoin Core, // but since the time is ultimately used as a part of the // consensus rules, it must be mirrored. - {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52}, wantOffset: -17}, - {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52, 45}, wantOffset: -17}, - {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52, 45, 4}, wantOffset: -17}, + {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52}, wantOffset: 17}, + {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52, 45}, wantOffset: 17}, + {in: []int64{-67, 67, -50, 24, 63, 17, 58, -14, 5, -32, -52, 45, 4}, wantOffset: 17}, // Offsets that are too far away from the local time should // be ignored. diff --git a/scriptval.go b/scriptval.go index a7f972f5..5980948e 100644 --- a/scriptval.go +++ b/scriptval.go @@ -217,7 +217,6 @@ func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript } return nil - } // checkBlockScripts executes and validates the scripts for all transactions in diff --git a/scriptval_test.go b/scriptval_test.go new file mode 100644 index 00000000..558d6194 --- /dev/null +++ b/scriptval_test.go @@ -0,0 +1,43 @@ +// Copyright (c) 2013-2015 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcchain_test + +import ( + "fmt" + "runtime" + "testing" + + "github.com/conformal/btcchain" +) + +// TestCheckBlockScripts ensures that validating the all of the scripts in a +// known-good block doesn't return an error. +func TestCheckBlockScripts(t *testing.T) { + runtime.GOMAXPROCS(runtime.NumCPU()) + + testBlockNum := 277647 + blockDataFile := fmt.Sprintf("%d.dat.bz2", testBlockNum) + blocks, err := loadBlocks(blockDataFile) + if err != nil { + t.Errorf("Error loading file: %v\n", err) + return + } + if len(blocks) > 1 { + t.Errorf("The test block file must only have one block in it") + } + + txStoreDataFile := fmt.Sprintf("%d.txstore.bz2", testBlockNum) + txStore, err := loadTxStore(txStoreDataFile) + if err != nil { + t.Errorf("Error loading txstore: %v\n", err) + return + } + + if err := btcchain.TstCheckBlockScripts(blocks[0], txStore); err != nil { + t.Errorf("Transaction script validation failed: %v\n", + err) + return + } +} diff --git a/testdata/277647.dat.bz2 b/testdata/277647.dat.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..598420a65ab8b2801d2d917147fb58e53ee6014a GIT binary patch literal 115673 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ℑEjb(mj%6b&GABb zmhjeY4ZJHK-}BdQegozFsp3i0h&qpd&tSWFhx&z>3Y{0vLHRAt@8KnpQWp{0bwh&# zL*=|B&D_B>r~Ca76kNRo#Ot_`vSkz>%|PT^;_){7Q&mb* zI>u=eB0bqmt^?Lf<(8`lo!<%A;odaoyLCvZCkJHKk@i*}R2oo#T;s^9#K%Mq-43KuoNqP@)6SR)f@MQo`suJ}w8w^`(ajv43 zk-ph9&Sq!yY^$--y9iBVxHSj+=9GucU`-3@?jqyfjL(XA*|K>ti*j#v)!C zGqpA{C(HUD7wRgvPiH#NYNL^9ooTFbkAn6_!TFPY?w;(e>~TsG<5dqhZEyD;9+dX2&Sj0@f^2ieLE1J_*u?uK0&@oDoiU(= z9q);o?>FGQM7;gW=D)H&bbkdzY3DsjL1J*GeiPi$HMmru%Cs9q60oZP)$f|{005Ug z9z7ul%yJJ63q!7>Cg^6~xU;X(RyW%XeP|7*C_E0qvsWQOo#~{ez&dy*pP|)(y#N zFdOxY$YMX7w`rwZG$h$=1e15CDk0l!=H&9|zh9p|uE-A+Y}}=~5IEAm2xjNSKwLcK zrOjj@fFM=fxMS2UFR?xq$d)O3nA1^-KH!L)W{~TaX?)z&SK3 z;KNb0g)rKsIC{Vq{D-Gwp>}pJUm>jWWreiOsuSZZ`VM^lPUc$`|B9Ba{s&o3@s3E zjl~lIBF_WoZV|oRO-=ePNpfOaH6i)`#vbb5GJgEt*HEFR{&^Pxd*yvmTH@&1^zLThYFMC z=p7qJuq+TC5t!a%hBTnN;{0OAO1JDXK#y5gdRIe$vkqZ6QQv7)0S}c-ZebKv13K}N z>Hcktw>`1@Nwcr~%O>pegp{dp#5Ap+4Nj(-IcNd`j%{}-0fAgFq`b1^XU+(h0_0uN&;M)AKDGCV=kY+DJZa z2FCe(ufMdJRAqDea9Mp~fb6+a;Os07(@sWqtD28tE2!P?(G z&q`%k38j(H%#Ch{Wl}v1RPEB5NpMSk$cZ~Q1pp1+z{~9a zsPh%_B$OV^^)J^m@`py05apd||F^N%I{$$p8J0e6W5`;(J;O{W$9!0V9L;hrqE##} zOwMe@rnPJXB)^Gk4ci~2E;!0)7aqw1`WDVvfRozjl< z%)-drfB+Zy zt~c@xTqhv=l3t|aHicDM6P^ngbq$e%xUjV-zLORz?X6bMfXt3)&sb6&Tak5m07Pc^ zRdLcsI|!}I~Gp?~7zp&;AO8@}BHSXET z0U4H2p&DRI8i8wY@!cV?{BA(|Q8HMY$hDP_&+=hfPNxFd4Wrdeo+Q8%>;M6X^Kwy9 zPsw8)*n!_QtnT9Be0OyzEBO$(r)NE@+5YxCcj6XYApkvFMJ-aEL{73OI{$BuJPi~}VXsV=A$BOqP>}{>mRHBKK za)&bg8%du)F%t)RotZ8zdp&><`jtZNsJcfpyTPj)rMwmyOY@s!Pw@3yu4v%yZ}Qc7T@EHrQ04Qbk5bR?@oVT$a5CMr9o#1 z_hG!bg6IAIp=u=%K8_pq89(fOEO=v-jpD2{Z@!fDwQGxb$&TrqfVPz2b4pdl#nd4k zcV2F`S1v6k=U*h?s{}377kBP@sACj2-~AG$^X>ouQRVStuoa5<9Ak4_Xt#17{rdb(l*w}`BN+@_TT5MZaT{PP8#_$cH&jL%EY1B z)g8~iTncPr#dGpjqMt5mCFE-fIH59|QicU7@+uqHOod_{U@;V$zr6mK6+`&?U% zI=l2>01m?-iXj~1wdVR=67 z(Ut5$2>9!Z#@t0w`kct;d4YyLPxZ-Eoj|eb`NYn4>0y^J-$6p)05ORc0(VArpD&jT zTvq(F{;2CijPj@VspfS9jTmNNHT+T$geLT1 zEZjU2s{#41&!r*7}%;R}C3+faj}@SYJYS`UV+14~ehsExU~OezbO9PSyu=dLjT zK{Qx5gteJ4QYT+S9IO2}kFXN-T;B*|e1M|l*_~6jmP;GNg8gr@nA=GD2Dns$Sv7$XBArB3|blxSjvVKXaEp*tp=iH*UfZ1moDq@4(3I-?6q6EDVj) ztKmlDxc3y)TVWA=T^mPdR2PK3UjyV}YIXe~aS%8wCfZHjh_?KQ#5EGoD(Tx8o)H~v zHk~3dqiF<}+z|0(vUS9E$MpHM` z!-H4JG&U^>pov|<0e_k&Dvzg2wxZ{PzmxCILiPw$*YI`~*Nnv%^?w$mbn#7vpJ>B- zHs~CXe(vO|y#x_ zQm3~>9i{)#=6ykG%+v$=yABv9#82ASULy7(V%p8kf1Gj+;yjSRV74D5SF(^Yf?E%9 zkBd0~qM}*t%o#4>F|f`RPPq-ck5v!=APv;rOjV*H+Ffl1p0A4+)f&r5k zTO)VJ#g{I)HMN9g23x3|CRetiK_C6F{G2Y#cxBj^fl77)S>cHYnD%e*Z3$RK-fTYR znWRKG{;trOGJClc*o!2K-B-F3>CKy1cUU9*^D}S?V=D?$GOOTDF2uIs^;Y@0?f*QyWO0SGmUplAOM}= zmY*wh43K~#?4%+_z=8qgqM7elju>n?el_!7pMO&(!o4 zZhv^&YyT@kH3>YH{G1v&p&24&IIDi^c`hY+*_ot%*2_19aZaUbgX8|qy|g-__iw+!Kq*$caN&IGmFmy^J4M&B|5;3QyGsT(-wQc@V(I@)Mk*`Z84{Aep|gcGeXhpfs_ ztZ)@gtWS6YulhZ&_uZOi7H0)qaG-a9-(b+6_%*_3y%Kn+Hx}-OAe=SdK}T8tZ3&1! zp3#ncjdzsa93SUeRuC1ku^{A?6L(4=_QD`&J5ZCk+5y8FgJ`Ng^_BpV5-ikPZ)X&F z=EPAeFkHd7B(YarX04TaH0Nz{#>2XN+eyf>Fe zmBGk3*#FKQfkli}$tFu>CYK(0eOI>{Jt4=e&)*b;tZdj$DimtFDg#pQU)eO@Tr5DO zWw>W6e#QPV5@2@+RdF`2Wc_V09vwdf{~0|7Y^gJ2>KsjZm+&$g0uKjERDMOmx6A+l zCr~~4jUst96)zEaLeQ}e+}K9_$Itl;6IMM~l~8H^64hM)U0e^c!X{gzgR3=+!^4l$ z$}Nl_QjTlZkG0HSy41i2>(A_VUltj)Yd&W+TNh14XpkqZyh(Lm0oi;0#=u|vIo+1i zlSNh5OGC4oZQNr>?%KVH{=TN*v5$wYmgaAQjAe!Yk)rm7fzi=jOHEYGJzN&+SD{g= znaAk=(t0tmT-tk2w6nCg=8v34*0O6<8k=`v>o2LT`MEzG?HdR!WM&c;a$X*9ecE$0 zbID;YAMZJ#KZvgBck-NmPOE2{R@E&1vzyas0R z7~dPYtE=K){`0n%G{*7oWNT_v>N#(11dSDNBpdGBBNMC;XEZH!#1J8+>|{_=SC!tP z3ynWKZmbz!7y!8_$=)iTIY7Vu+Qh)Q^DK<2NF<0L2oTu%>d6;JDnp3+G7=Z`8J23| zxXGKa8GLSM5pGM)_5vC%N&j9tl?t((-($f6HQCr4NJ@CBchkWacJi=rJLgTfoX@6h zR}Gq}f6EFb)M!9SOiIcGduG?zOWean#6=qvwxV=Kj*+3k!{j^rxDbShsp{GiB1(n3 zIuJ;}01ur+t6d&Eoi?-&vZbTuUqXDJ@cL0j%=PBW1=+CRBBWOQS_hJ`75%S>GA0Mo z1;YIS(^_e1gWD?2Tn_LB{+Ytx03~hsFIzUy=NvC+%do11}Hwka9 zM@_K9$zdF1!9iwTR)=UMKmbhW5aE2>UQ$ElpOh3ADHJ8;>QCHK)KBkh|EtXZTOs2g z)ZDGgHFghZQF+;BF)MU>5Vu>*{N~G%|I|m}jThf+l(_Z7zoJfY^*JRrS07?xcEuFWPKzMVZJqu(AHtrf>)b!LI4mD z-<#w$s*~}Sa#Up2Aqos1@dDW=;*~6Jz)8fkeb{G}>apbMX_WgZQXCuZ!f32_00Z*; z?x#fYY?dgOrjf1*POa4qR42Du2~}Gn7|C(re@m*Q(=4+{3c{UEDO^A~$DMfHx;`WV z*BX=y=mPJ|woET~mzRa=0~J=<;OiL|$K_}>1*9>dZKc`2h7{8PnEWyvgBnyCIve+R z003lRiQXr4S6e#LL7QArz0~TT6uVgKXR}Tf{WrY$e!xFd6~CIl9#t=)^8IPL(Od5l zP%#XXK=aOl$k6{z(o>n(Sw+M|T9;O~=S^*b`Ky)?7(6!n3S^?5rkwsW=1F^Uicf@O z4S98ie9X=j|KEkX%By?jAYQ)n+ovi4f|d#I7A@S10?aVPKh~gv6!EO?znXa^RsC&v zMFD_qD<82m)am0l`%C1g!ivh7W+!dt!Jy4VkUz1^d!_q(+aKF$wQBSy}?x3~QpKqwN=%bT;}57c5VG>HEZww>!#6HQ9=B zlScP8g+S(~;*0V7?apiW${Q;33~#)6<|`d)2sooJC++ppsBb5MYdJ5@yGcI%WX&!t z%nBpMf2!+Csp!L3FIOOu12i$b$?16td%B_d9klCAa$N9k{oPm!40ai6dc*_&X zUGkMo#NJb~r$U*|&I9PNscoe6eh>>CJj%TA+X+klR>Qp87>3#7;J^$w}+6Epr?? zk~-{eUEh3n2l9IumY0(=(#ZB#KT3M)U7Vx=KywT&RnWbrWN2DR$v0k=t zS?lR6wHiTQ(|mVoj5Mz1x*yG>_J)@}iiDh*na9;&KZ^6EfC2)pVjX0`63F^Pw_=f0 zgRn^HJ3;C2$@gVFoI6_t_YlndR0ygjJyZx`ThK2*(zCi`wzITUdF=qRY8>mkAYmJ<8sYPg(N+U3Y5u;erB7P~`QI&gaIDA*8b*&fjD4taiVafgEAU>Ex6wDwG1{tiZ zseuhWZ2j2+={jKC#}$FJY8~XkLb@VKY18a4G1@c@+GeK}-W^JB{jRWc?4v};;7l7B zevH@Zk2zWxc*KUftH+s_D(s0OJ!CqRY=6q;J@FT68JaQOQ_KIP^B%m+E&0FfxwCQ% z_pK_XExLp#07{b!r362>x)-{%3nRy&6T&3yA3YC^_cj4Nv^O^AC4d87h7nEK3O;APFa@*443FV}#jk$>3sV=u!X>589wK{YUych5KUtQFQ!s$&<99`lMgKboRt`ygYdF z&4i*9X))^HWl#4GEoUhW#sZ;0J$3l4%NZ4XOJPr3)U8RdWD478%8SIh>m79M7C#AS?S6!`Z;H3J$JEKym_Lsg;c7`0}Q+Xw2 zq^gsvbt=g?JRfKowr#U5$A0|JWlM3naaH-dSr2=f)7rUF>!`Idb#eh>^t1s3*<#cJb$aJ_!q8vXdXL(+sF2kea~W zSK;ih)ZZ+*v!37~OCy>kn&)o+6x#Bdaq_FYKbyhB8sD$c*I9S;+DRmk45}oJdLRHP zsDMDU1V{)V14B^Tdsx_J1Zn)J^5P55j7Rj^yPvfYyqwazw7o>(wASVMRHQ2xd=aM>0wP4?W4Yvn>iZ*WVe6NA9_B7rl%p)Ql@T!&2`IGFe)VKNYOtiMQ zJa+j&FXV_f|GvGj4)4d-#C{P}A0J7G82NZC+tYqr?8-_nv?A3GEI>?;ZYB$k>WDYN zMbb5mASJvmX*f?0)`;pFNVVb1dr@mKhOBaG(dhunf>fiQe}ekav&q~HmQ=`4^lDJ# zlY4@~(C&xb`OKH~F+sL0JsKITJ{M$5Y>R*ZAc6=11O~G#bjvc`ud=L^*lOo`Vwn{*dnT(9cL`Go;x?m-`7$>1WM8+l0Bt30R!H5StJj@ z1^DWK{n;ZR(IK>P?iC^q4drRN*C+ast~f^+bNIpdev?pxwu=3i=KQ^Mz*xDguYk?i z;uSj)%U!J|lecD`KKIX>T|X}dC3c#P+T1PS_9ygIlB4+ACerG!4+j$v$)`=<{kPx}ej-K8z zas>#|kHW(bJcKAhO>?va5#ir$;o@OraR3z~2?+{^2W!d}i4+fXRRK)_vi{SZ3;=G< z-=v|B@4iy_5z_ezGlCAGCumwdRCP1i>_{V7S3g~UgQMZ~qfm8~Cwh5mRi>BV&V|8I z70Ra{Q@OMX{Igd+biBU)EKIEPQ&4@E9aoFv!qZ&al>=)~%|oTC(WLwRT1&gmIyC@z!GWyk zdtB6UT)d>3EPe1{K~N7H3MYadbVx=TJ?tt_Bus$)4uM3Xc_EcLPCh8>NX=5Ibr~1I z9~4g{q;Bz=n-4p{n^Z{|*V!`CzGRemrpbJ<^O2%vE6_%Q$2Be_A)ds*K`B7+;>X0E zCeYEb9@du=C*?--W15Layi2|+6S?IMUE;6Znz>*g%%7_u)9Ab&8_I?O;t-*zil0={ Sb|MzP@pmLsg$V^hK!kv~;xIn| literal 0 HcmV?d00001 diff --git a/testdata/277647.txstore.bz2 b/testdata/277647.txstore.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..e3e389647cb5f228caf324ae23b2a2834bbe1c90 GIT binary patch literal 1374217 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

7>!9{#2nOb2Ar6z-f(0&xBpYV@5Fe= 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�ev0v>GNqDH^UH_T-6BS7Ndi_@-`D5kQa~N2k_1 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%0A~l^pnTf16(+Hj!OpL{6+v(Mt7@V~l^QO;Y!V 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 z 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%0D5AL-C#zdQ=ZfODEnU?^`2qJ2l2h5^_Je<&g; zA>q~k7lD4DrKIW{VE6c~8Nl_QQVsIDRW63z8ZhiUOuE=wRt2{tSWfIyg~TGdOs24i zkY;{C4Tn{h_D%~(ULVNKhHxW(4&-DmKGz8^Wvz9eE{hxn?Rdjf@q8wENb<&ykJ)hr z2Cg_x|N0yZ+?jHtyBU;v3rz|g(Woqqn0lWEOmo-`W+Xp;Vp^?>xF6Mw)PLB=i$uRz zI+-^SIglgw(ruN^nQTbx^pW} z_N#7K#C3#>&(yBR)}(fF+B|o8EPWMfGu?;-o*AJ{2!TU(4n@&$Z`xIF!%KJB1HDD^ zaF1fy1A+A36Pvui)2;k08sXt_!5+WQHT5@aKs-IWGJ~rJiVI!<;$kl`{DApY~EnrXu+ zfGB}aj0MA|+Ulhz^&57%jpF1te7Z(jz?1DU)(OohPEyBW(-ZsuyX)Ysz^SWq`>ScH zj+t8&NroA0tSo2L5=SN@na8lC3K4CZqHi%^S3f5I>;gh~osPnW7o(k;#=Qr;pGXho zgfjUP%V5EwW=xmo^z!SH27dtTIO!6?iB0gwYqJc9@TG$!I_C;k1|7Xbp=~Mf;E(;8 zqjd8fOFo${>E4CJp3m7xvIP|g>L~41uUol5bZ93!+?>8q(}e8zP6uF@;N+FRAFhIi zYGJ6HN^-((47#i*(Y)$*j-lL7=k z{i;Vv0T>)z15c1u3r#+lvgPh*OrUPI@~)U}2B)s~yMOqwe--`k`u86Cci@U7eF@o}u*9a${|?I8f> zjed~xfPDo~Mgeu(DWD=*X{??;wT;?z8<$Lr-9IZ0*NJD419jQsbQyVwpniW~M$7H8 zq~7_<2rCy&umz-_7|@_4pK4OGykh1}CqYT*Kc7>XO_vVD+b$2dzeuYW8_2 zIJGhQ!Ee2-XCdxve549Fnbc8eaRLZ`$qGx0?)X;CSd-_rexb$D>$tA!KDOIaaI&Q; zJ3~>(fggL~$^2(dX@2vL6+jrGxw1tPf@n@EOqAbRH!sqko3yP>7R!nq25AF}27$VY zm&r-B0l3Ruv&|uxHK~YL&to;oTyVbO{B1}jpW5Hs@DB-j$&9CNI9I@c9YrDZktCyL z?Nv~ng+atADJxenbVc-8Z^0Amy>kDy=Lw^lThI1i0^A;OtC%)>PGj(yrBAXl- zz-RhOfX~tcgxZs4=GjF2D{A|>$D;MwWhaodO7CE19TOL!UhHnO-FEzo{}Gv4}j z!;KL0qMMC!@U~?vlNgraQn%R4Q*sw~zn#l$1k^dM*z`|RO97dwYvLXv6mGs4s}qcQf(%iV^H+8j)Q;{R~$DyPO>og-^o@=C7I*w6NSAKJ~y z>?j=wBKh(BZ2>YA%fjKLN=cNtEGAgc8#w;T3Ovogg)%n^HpbyI6sm1&VqLnA?*;+w zuGM^$$fDyR7>{I3+!K}$KtUc#Rxm9-&g#Oy1X`70nfyebQug=W&b9u*-JZ+rfUyFvY}E2pF>|gkWDQ*cB)N@Dqo;d zuIDU)Mw~DW;}{Lr95mX4Z9faorX!Z^oPZ?p`Cy3o1LnW zmRZ`gp-sCj{%$hO>i%CRkMHhU`;DP5qfg)K7nZmuu-7#RYY2z%e!N)44%kJMHTkUl zaT^X($TyyS_tBmYv5=qXvmwoMIa{hog-6Tm_Z2gDhkVa+J*^(-E22z$52@?Pc&?@6NsxcE$cLl zeKH>#9U)c53LU^FvzD^-Rwj^}^Xn;JI>Z@#hCK`s2&4r~X8PhutGK2VhFZEzgj9B1 zq;lubH$0l9BZw~(mlcce%fj$9tB*|TEdX3bGc%zwJM(5jIAa{<-ph88CbyOX_0wc? zo%gGeeQH!KIJ*+@3T2iS&A-?zY<7qm2^cbk166T~$nQhM4i~ljMB$n$ln}O|`%sF* zh+<)$yNeGL9}lM2AT;2JDkt?h)A4C8Z?Kf>>`7`NzTLCLY4ca_l1%NK7Fose@SDzQC!8Hve0VWOz@QowOXAFdQv8>m82h`q5Rg(n7NXw{9 zjlK`WHpnj}{4f^k#u0V{T_KS|a+f>W)90V|UL*eCs2m7_HsFH_tMhK3%1(osza?>1qd8N5&(rb3sWxz5BvGXGxBgKr-7u^Znm7sU5=PefzuedSMDfxvmf(z0=eu-;iteYbTM_>9(sp0y`oN@v&4-Q zDp{1Z;hH=S8bR>n-v?#Ow!!`Rn+}uf-4O z48Y^E$H4VpV4v!cszpu$bRD#mb_>F+WIrN`Slc* zPpRPrtVt9+A8Q~L6tb+)QKEjA6QNvsZrqlf>K5!7>4(y!5#`5(4pzRXwt?XkMY0iQ z3dvTo1?9*lEuWlH?;w=V;XTWSF}(hBYdwPhC!5#;7>VCP$T^POZZHLQ57WdT6jKe| ziG1N6KZjfT-;5=8jBB}oD;4YIeFo&2<@yk%V$LVypeYI9Ldt5#A!Cw$6Rhjh*7Jzw zvz(=b2;r+ztiF(cfVItNgB-* zs+7ojV_f)6Te9>D5O?O@ihA?oe#0KN_`>1b3eE;Q^LbctWASzPVRAbs$*X`>NMZwy zA`NXw7|Z^CM>JZT`E=)JgeNzKYhu~|9WYWpJi=m6XygG;gc3qz1hrsClZ40XaehGid%?U zq{kiptYmI$Iyb)CLgI!fSwdKtLY5p7HGB@NXX#hwNPAt$M}OdBEx^DM#;YXS&_w3= z1jzl(i*IxZP~+#x@%6@ZL@aKeK>HKhU?XE|m5IxB(NhyV3KAHgX}dQnKr%CDr_^;> zna(bj#2Z{<9IPevv7S4R`F3J#;!~{WB1#5;4i>}Qu=*VuRv_65o|Yr^KU^f;`ibZB zpJ<%3J=^p^ee7P?ZBO0sn9J>$ZQVynMBTL_GI?d29~sSd(bM0Gs0QP7uR4o9oYd6W z-Wz=I7(UD3tMMFEDY-)7vSERLg|%HWSeO1mi1Nrar<&yRU79N$YlMqin)W4lR%;u5 z)~e9YGq0E*cP%I6m=89sj11G2rYE1*{%{v3RS(gNwxcnt7{7uIhxZ;VDQ02p9s5OiBp!1fO!CF0A)hIDzFXu=EX8RX+=z_k@ zOXBw8^bc(QeT&jto!IsgxD0Yz_^W4iqHW>QV9T}!9EFiDl?5>hKz2%hVCO(d(V*k6 zhlcbE>o60S;0ODO_xBMe>82%4Cf6^;bv&rBVM5z0knFv2_9X~v{{!n*(LzMeN2A0x z0PP+`|P!mdu;(2oQq^M2Fi=5LyUfIWoT)S{Q^cO_ie<}sP} z0Cr==4;6|%c>&_1efQ;MT0u-_CuUC| zm$Y3d3Gs3u&aSVmJj7r~P{{R}U~NMyC)L;~H4o8nJ)WfQ7&4dkK)8UjExUBI6~-4S z{M!`0n#7o*4lQ&gA-PWn_KF7UpZQ#itkx&xXQXjlvjE+Xf3ysfWvQjvKc4NB=sm_E ztZ4N$Wq(t*z#Ygf@C*w)O_y3v=R%y$dDVTL6FC>1x zxJj@d7^MI$1!|~yG4f9Cp1txs85@vDNW9E{aoil}z~hg9gh(L#8bPX!+i zT#XKH(D!7+ePae?NCcOWw{+~`($)dm+U0%;vY%nPd1dNwOBLC_UVBAT)1^0R6Tx>` zV?%K}wZk_W8j_eKq9t8iP z;fH6v&c_BamF4bxC(GFNvW}s$K)&>3*^#@Sl(O~SB+JCb`P}vVW$~{d?CbTHU#%y5 z;A9%aw$WnAhMpTkzH>@ah%W<5&^$WGx1)TkS*-4*Er)j1XgN4sphYu{w49Fz3b`6Y zlxpzWo9X?HsNNJ%s)vd&IAw1N9lL2Vw|)(JU9Tnb5UNQRf4axor!9^$(El?fzD18S zYOt;>8oioT1;=XKEhg?SoY&o}x1XTXUbMJLD8HTIz@lPNY+u`o`1T$L|+={EM-~Zo11aB z17Bp?Fwf&{=XfI4T>BjDz)$FDaLCI8t2-xvCCLC!K(N1hPg2%dUoL{V(Fer3yc}g= zz{72Lgd((wGFQH3?*b6NgnNLom+_iGvV4EsX)K?@SKZJFttJJ~n# zV=bHXL?d||&-FtuX<)FC9l=p_<*A_pcuKU_hx0LXK>l>vR#)XIgEL*~OLZqBFpdOWEVab^SItD?KfbtHrr? zs-K}zn-;|vHnAY+c$i##bzRV=DCgETa@%O+48!|J|mAkChE_^xsC? zVR>|QcD%@wF;=f@#70l*`zX%j-hu|^<`Ions#zVY-TK?OxCSWpg+Gop`u2KwP+H%Z zx_!8?Ac4gDKvuECs2yEicsq2WaerFZ03r7EM;5#`S`SfoORd8Lf9+7mWOi#Kw(G-1 ztYi6fp2%8@SDufh#P32NA8@?M1DApvCPKt$ec;5KpsE7zceZq-a*JCKVW-8LYl>O> zE@EIi-)~=0`oF9elv^lPKLVreH#{%>fU8CB-fmrild2D0BrsF+9xhGT&<#PFh*yjU=^yc?6Cx(p=mk23V!Yn7(b z9vNnU)`wU+{4H<2+}V0MvTCWe)L3k|K~Qz$w^(AhlM%hjV2d?*aP8x*xuwhegt)>X z%U6x#pm4+EKVhT~ zMcv|RN0d$TjuQ~zb%E=$X>MjQL1bSUq$CsC7g$c!g1pjh;0FDkBaefAD!2cd8lw<(x8rcU z$KIG|h*X`hSuBa&?P$Jv#)D6sX{WMe0;5KFK58N>a?UDX(k#yO^7n?~CzLt3xGwC>6XYgW2vAX<1a>PaJT5JBV)= zO0Ew;&QkI`EQRpY6V`PZz*`}=32V4(Ga@r7I7`@a1F@uNCyDhJbiJc2HoV+5l-_4H zE1DZsCxCdk#~%H&+0bI)p0CtbsaAylvb~kp!qY~_S_k{Jo2Qh4LXQp||6*atW`SX? z2RI3^s=v2D@NEzEmN?p7bRO1LmuB3%mrxQ7KOQR}7^7(Mtx(dDxp`^(VNfZZuLaf| zNHxj;V_#$(E@j_RL4>3b(|^~s5Wt^Lizg9y1&1Fv2k@N-`(mGb2GhkAx0Oni0&i{D zV#nhKQEu*W3o4$8n7kq8F?b6A_^pW_GIQ7KAkb*5yP=>9i9(iiwT?J;v1I@FZW&%T zgLn_va!mI(4~ZKp+qJatKa#9N&SVe;s^2g^P;yt?oUDav;VYXUG_P3ybEFx}gFNZx z0)KJs&NV|g1#uNVxWlbJgjJwLO6W>82FvfQo!s*Hjen;)mUeQH>C698@`u*6)89Vu ziR|2h>w^Oh1ASz^$REa?lb5*pL$XRe5;o+;BV#r)keB);Hk{mZ6oQRU|P3rMs-&Y-_Nywh*6te8q&R9A8#ESPvhLGxV@ zj7BAdvXqSPl9#Tqy>7j(S)KLFyq$Wl$E=x`mp4WE@>)+4vysVr77$kL=zR90v_HS9 zG~8|Tg)Co&xuuCkuCe@zsg2k67hh*F$JxQhwJ$NvxR8I=UQU~i_qs4OuykRx0rUlM zjI#Z9GhAuXwEl$v9;8c)W7GL}gY9hy9Ec2#e|;m+ba=Cjv|V|^Vo$WXlKqVVBBh#?Z+lk)t6TAXlO6l?s)1dwh*4fuX<9 zgPEE03%0v;VRU3l)zvGMO~0MD2~E9e!O>rc-|cqK1p-Qc*=xXAA_3uUUnz3U3E*LT z`iDDBA}u1@`^A~SZ0GcOLp`aCsA>uTu|d}sHMer!5YHCcrCaO}J+WOqX!W(?W7R*z zTg85Xg2~0|slhB`Qnx?{%fv3Py%_jZnlE31^c}YpsIC67JcaZ*e(sJaQ#_UyM(rH_ z>6%_z@A2%ntGw5Qlk00@2ueh^m0T{>7X%u%#F zLp$OOn9!Vy7AytVsK)jpQ)ItYDM79@6vONCY$2w=%L7383$hKWi8#>zd8yd-Ib~+R z$M0d{wzyvKcXLM~s$@|~(0HJsvDIyjPQn^!;65Gw0Q9&t$b8|V7C{}q`!*UQ2)iX| zy#Ky9-2dU+@4vES#7$ykN$`^UYHcDt&-a4HbOpGnML@a9=>snN7+aRi$hjT4kWwLS ziEMD5M5wQ61t<;x@s^+x>HOJtw-fVLHVM@Lcc?$ScyoyqIVEhrA_0t;*Z>`doAGqI zs)i?ow+!UerU%n2u>>Mo_^gK*IIc+3w?C-RI24{I*Zy@-YkOP@@}5i^f;_SKha~bn zU$9Y(3#4f`0O;>J(D&Q(0jjbF$j=2pl19oHLjQN`dr&G}*-4va`4GQr(W9aVJVH*~ z!x7km7a+|=DdE=g4?e8Tjm#gAHq_#e#dj2?73}&E0hq^;6PsAgGJ?B&vCXRYlDZG5 zc1D;bavnNu?exe=e`B{)U2;gm+vBb8q1zbnZmzrZ*=3X24Z-&eV0;8cKAkkgUlXa) zpZzm&NOhL^?&B)=oNk?o8o0=0MZsA8sDw<;+*m`mRu|Wg+~i4?w=CNn}-P7B5zkP zPkgQ;$7us(Mx><%W>}ky7!ckOc28y74(9VKBq{#*jxDWAjFhF=qCl_?B@w_V^`Znx3C0Rh!0zxu%{H>^I8-Hz@zK zhO<%?KgAB7iFr_%UD`0KR9uRZqBIkcC#a)hPg6>~l@%+OfuJT@@(eH@3@)vo5tZ_R z3C)Pq@38sp$5H3RMj#HR7Z z;Xy^($_V}_;Yu{|ewo004@9PCR{YX;Q$_Y<1(V+eC3?dLePa#`@hcxyvqBG6--P04 z`y&De2gaBOtZKcpt3LbF@+QH#GNc73`3k<~mHz!FDcl>;G7IwVX+88C%ndm`yiF}^ z4zI&3(pQGA=oG=+_FWhI3Od#LgA}OqIWe%U&xRdzYvTAZ(XLA;j*5?gr`zFzJG^dX ztV!dR+z3h-PMcYo0unq5x)=#b4vuUj!Z4rk4QihbOK9#4SaTu*h?Oir5B|wZwn1~U zUa&whR)b>=Jk`~1C$9P9P#ld|$Z@R+Qkx;ClqW!$I*gV(_kRz?W8wAn&yh*ZS|G}VlKMmsbCl<+AT&Lqh##m`q zgNCi>s5zZ$^Ajpm-+)*}G4q%=H?Yoxt>?AU%`Le*NyDHkDS^Ry!z4VCSI*{JnRVpQ z?}qr09svDb0g#4u2l0nAIau4Rd=SLo{!$2vKqYBf_&V6oF>vqXMS+>&l93=U_};$5 zRpLgEm&j_nBikN@ItW5~o1#_8=WA}qtK(h=RxjBBm*C7O48u{u6Ze1OJ>`5L*Ac4* z<(-OpXu(2JtCvM1A19>6! zD;2+7v@ygMdk=f_fMRNp@iZS3e#tzcvI5c1E)5VLjb`uxgQoZj4BVJXEw0PUZ%dXH ziD06Q?qHlls4JcTUpk|;Q?p5-1@(0S{a09GL^uQSn02Hw)ugLL0H!$>j66n_#C7F%U4_F^a7>%Ymx`>YU^v${(pL)jC^5+b+_c&S2^^c z)`I>$V6_bjmzxpYd#KGy)WI}jDJcL(e>L7vbmE2BPkEJ2zc%qEtWEwC*$OH>#Pzoy zblUvDJpfbzz1x-ySQmf79%xZLL6=>ZQLG7Jl$dY4S?p9A)F^jqI7*;i|zf63ze24tdziD>%#`eVhT?zUEx4GO3wph7EefF53q2U)uMK2(>-6n zQZ(3L8i%E-+eetR58hZ6W!!{%2-V^od7G|iwKKdZVAsF%4Gi-ATYhmZpNQp00=BDM z3T%gkP&wDzkFXW5k4}|^(<5=M28L*!z%CSbGp?g27JJ|O_A_j+cl@^v4nb6AuHCM`7rqy^4g=Xf7x?@shV)O**s9$+SLhu|BUOCzTuhC|GAxVE{ z;Rxl66@VVC79lWgpjs9{@b(k1SJHmpBR=kpx<5XcK0@LQ74(29WUo_R z>C>ASKl+8WDBBw?2r1ya ziG5ovlvx@l&>|ookKHY2ulT6N!*FmhS*Y9q9tJ@myW^u2-a+&xl7!)qZHc^{0f%Yq zT%hu|OHjahzNcdstc#JtoRGd{uR74NUL4w)$?LY3VAAHr{DDjvwVnPxx?+5>d?v{H z#0Y#{W8k&wzLFX{ou{uxaHyQ555#bP$Z)Rej00{{kF7ggG~2k) zLVOl1|G{OYf75pu`9=M_nOK9P>H+v=>lQ4*icSTVG@dLO;O{;0$=lF$y-g82d^_b7 z@$AZu^s>1UmeuV<#pgbki^i2S2G|bx#I53qc*s0aL4EVoojf}4`FBH4S1Z_1IvM~Zl(n8{!Lf6cpdCuz1b)AS`&N^msfvYoCOC0VDo5L z0^afu;n{mejefdyJqPm#(&WUvhgPh}t%i14=^B>|;8ApS1i*X=;>WbJkmkCG=gOb( zGFd*qUMXT5arYWi(jRGlgR5$sRf>f^8D_P6gO-?RFkymcp>O+n7jz$==@dQQ3eVnl zIrbXx&wq^Fv#o$^;#=G@ZtE!fhgY3-JEvV$b}$6Z&}8t9#)hG@y>a$4uhKVfcJ}vc zcBNC-A*A(PO9#W7rqQ4Me0MBSsc}_w8~>gA9RRUjIB6mL-5j^s2 zPCw@wJ2?_hV4mH;oBr_QRMiC~@~_)cR|rX#9@jmsZ!*~dr4#|(9kteNBG}w{tgNHG z^=Nlc#RB^4Z>#efsQnCSWC@%Q@-qC-o>VGz-R-R`bw_iis^vmdfbfaH9I0<&b}bau zBgwyJw2kYYAKZ+d0T#fjN0%po`3*%UL-^N2qo2Wy=UX++F0#W*8y2V2vek`kwrAK7 zDVkO8#FixU##%<}0h-3i`fgx9oz&!ISPG!$KQi$W=A(V1K||YSmG?eRM~5EY*i=c z+!-mmQF7a5ttVq|&xXuAGs=a>500eEv``0~3_nq+U02H4&kYR^0P^C?s)~)`+%=dy z1*{DrVFNG32zS&kcas_!pMd+|D86vI;{S|dlVIg|jJM{O>IR^e-YFhB*PM)x{#LZS zlbJMRudkER%+>>SI<)x40{{tt-Y`>FIiz;T(F753om#ef6sevSIy&y6?vV%7A12Cs zx5dk6T|eQA@!s$2vlsD8<0Zn_2uX(kDkDXrq?BqiT{hGAI&f?l{;VxB3_F(5UU_Mk z=@pv_QP+w;O8-~JZav|tsT;W1$ks`;io!|TO2+3q*Z)x0iV>W`&Q=ia$-8Nmu3){Z z1hsd_U)1DTKS!ug_=)lL>WUWTE``*J_mj zOHV&3x{v40eT?ja7joYpOA8wF(wP-42G;Y-pjc}jHZz@MZ8t4)zU%QxAa;n}=nq!2ou z{dIU+b%(E86ET$jt&7+Arkr%kvv{`(ktpx^hr*rd?*kkcL~vUIc#IdB*HDDzq5g4u z@5-a)HX{Vc9?9N7M(EP8LF6zxdjb3(=GYtPboIU)M4bnrhQ8->Ka4@fb`QY6lRFS> zc`h_?+{05bYH!Rn!!$}*m8Kl_0OYhIajS4bS0^vF?}ZUAVtrZZth!Y z0*V|Tco8|w3l*9NpTqF9@8ztX&^!s{wR{+W_AiCS-K-Lt0O9Rn)en{@k9I4VIdG)Y z@LbbCu!~FHyx0N?(wfp+sn`Bw) zG~lxy4$RjY#mpQWEXEOy`fSXz#H83)=+34XYUpT4N{J~bsZe^x4sfj5Lh8RuN5}FGD`t@(C zy`TlJ@YZ)p(CzsJi z^5LN_OS#77y6~&zY9_}_3MHj(WwFPRYqr%P1}X%4!m*5VXCE}o=-0=aup6w*iQU)9 z$oOXPJ(xB#oNa}4#x00&8{)hZ1Ml$)mG~*!d1*%V-gX{stWH4=IFZE^vH(~)>U#~drGzM?5wN-4{pv^YQr^n$1p4_q$o|D%3 zy;P0%kQH)l*w`{Qxxer?XSYWQw+(7<9LEO|-s3ZFruR={b3xe@$ zUX*h)oF)X*^be2(E#GbOW>1A)w+$JGruyol2I0jb;F-Q|fC}&?N!I2W?_pr}xPWum ztcr0r>{W&=;G_wIgIWA=z_v3hKJwyA_QVuqSbM^8>qm_DFHw%zhI#|Z0Y7L$Zyi&V z$3~B@T2ch4Fl>huG;FHGnwGyP9jmDju1cwtVUq8I^xo~$$oh(VgIfNB=*s4yCA17MY?ewl>7!x8y|l=e?lvlI2d2M6vP#%lt;s2v8*y4WLr7Hkd-g@8fLR za`B0;*sJwd2lHQh)g7^e9nDxK*sd;~n0$vur_Nt?qR#v;pKuiCQAwUg{wDiLC8>g+ zjFAp}Y2>nP7v9*Cdqfs|nPc}$Jhy@=ra#`MbqLLhjOfT?zLyd?p6MNRe4(J~0AfTgtzEus*Ys}!YK#m7XaN&-XLay5_z1QR4cob_tO58GRN2!%8h!~>#FMZ8mPEgB|K2T zRqcBFE~VkNMF4^bM{+(I4PXwXn_C9yN5;OBX;pRvZ$0YUtGQOEN4Qq5-C)p@?`Moz zF5O^WVQ;ivL02z(dAjw~H30H%nu@fo9TI#+@$tndF;f7z>C*Y)0dEI|c;7AV|BThK zdCgNutrlRvb+CMvbfXy$5?|c64A+6Cjx)QboT>lbRlG{8R{y`UJ+;|aK9^!Jp49Wt zM?DBCXsyLm(+7HF+H5PwdYXLpJo@JN?pI^=JF2)$mq zv)v94f4&1#OSnDONwX45aKS+iBAhB3?(+wgjy1>!8;c&e34wQojn&%n+AUyo$EU+B zm#h=>(j1Y0h^=kvnex0*&XgFOk{!kcILLm%uw59~T9Vl7&J`Gky01A@0p%L0y5X@5ls%VI7CU_5zF+l*+46nx5BT_+eu-f$&!W(VUL z8T(9-cfwD0MX?+V^3s#{N& z%0Ji-;&~SM$_8D*mrLzWhso1zV#9|A3jH4TGMOweSB_rK zK1Vm6x;8zl2|@y+V8#i44L_x@nA8tn zK=R(5nu4F?0*A?}V#3DxOF*&*yRsS0_&xmYKo7&p_OQO!Q3^x=PxehC$Q3Z;ytI5- zfzDv`*%<)93=xa?{4fk@W9?)Gk5EWlfn=2G43)z2GE$F;cw9{6dzUAJ)D+ESJTRqUks&;=}JcY@dOq?htEzwZfclU4kU;ORn1Zwc*Y z$efI5H6O<5kRex80y#647J#;IG_MgW$G#8@5D0*DXmUi`Q944JA67>hxmajW`1qI3 z8+o9|*CnAIZ{=jT_`E|p85}oAZk#|D#9pZiz}IfE7t0$V@+324Vg|E%o6GN#^&O9l zt;*7}rO=szSqLH>_q4rp4>RfArn22uctj?0iT zxFmeSavlx?>vVUDXioHqVB}Vbt&VOjbP(W`!V2abZ`m*#TRIW3vUhLShedjMUN;Oe zZq`?9^ci?$w-`K3I4w*v{O3OGl2H&Hh>^L)1A>Cl1`TVxU`;82XhW`gBTk=Pe&uQg z%WtcZ*lCs}5%^XP#z?!RQT7IyFMn6H zpplZ_lKOuge8o#beZcwim5NUFFr{ZNXB_f>$xVpbX}Bn@4sl2SjK$91Z1^l$WW~oY zf%6P$%iCwe#JkZR3xHX{Z<%`o9<6pV7ocUMthSIH#mf5{%8HP1T!M3JM*a4#V7)r( zA)`+qX)1|9iTPI1vMG5f%}!^7Q5`X^)(;mwwyZvc>&Ps% z-YC6h&oCLQX5Oya1I#FaX`K7A4laA-Hi_s{*5JKIVXWfqi5(mIe`zI$sq^Sa*xR5! zgN^(G`VHT;AZ#hRYbgSs%#d>N!g0(CG%RG6LEJR%)mgM=!UvIvn5MMJ9X(75e4r(# zlY=W{eT}|k8i#OsOSQ1VV|!)*J#v0_{96$lPwFC{R_q6yz9(Vvd@I42k*8#6xO{UAFvC5|HiJ(S3=I4>%9G!p8U6YSWWC`_wuU69WS=De ze;yuRorhpholU~bf!T)j>CZISX{dYrcZaiC8WhRU=m4n()mu4!Q^uHpmWj*~0xzA~ zvJvrZv^zq2I+q)n2rq#jB2uX@iP#Iy?l?*PexrWDEvL!?fZyBtxX>E$E+gse_M~c7 zS?y%{c@l8|{K=5EI6XDJaQoi@b@o`T=@EAemp^$wA8E|np*hxmiS!M$i5-aiDpWgMm(xq*`w-!4)YE23WAWbpbTzv`t7UoeI2w=MIy6rj`!ZjP=un7Y>uf0#j&)sk=^vC?bm5!88#SRspTGU1 z4?^ec;i4OD^*QHLM|lz)M3&1q@GLwq4d|y(1LKaI>hgk_ zxC)=u^k_WN_d_LLV`2k}8Sxr{!FRLm>xpeZ*s)r$XI93dx5^H)SuUT6-^GU|?>mqY zwbf*5P3uuLVs5t=ZLqwGpd&z{a@8F$~F*TijM?J5{b3$FYkC(JjM$1EF_uh8E# zFzLLr?3an=&(}Z|uHAdi6O{j97rV+$;UtN%FJg4P#@8K}v79**pl~%?jWd@Y)`Ha5# zc=X^W!Ey&9&eW2Wi&u}b@|AtjhS36V5*`wBcL&KiE{dEc*qivmT>Cs3Ol@Pu%jlV=&q^lfVfKM6zk-$R)YAU z$8ji&P+I~HVObnPi7v2Hg5qya`DGw1kjk$~|{V&Gk2B*a- z(4fcVw#3G>6LA&{GJg*st;)5Csvo_(urX|)T$6}D=YVohDaWZ$8^rfsrGhWf^mEEs+yI;K2b9ov7uk< zBRRvHpt(=NOFG^dl}7rluK|)8ji0fouTWBp1aaBjXe={|q0Pv{70 zDP{th9U5uuqxn9YY|n=s`K^>@EL>vPJJ^0!t^6o;Vk5;1dhD|hd-}UFj33^bufXrZ z_}jm;BuztrmI?&I2=jO&YOebcNZ8Hzszhdy&w6wOwf0p>qyqBSRiUoLJAMI- z&G&VtH_C#6x=@|Z3=K#=nXoAU*8AB2_n_{x|LRbF+dbo(Bt@_+Yh}O=$TRC$tM>n9 zpVKq)1&m!m$P5R#8+-0RoJ5VO482ta0!B2!Q*w<7mi4?$>(A$oA@zn;|V zEiNZ5kyT~4>~h_Ld#&qa#mdP7&b{+PD53_2Zz5NhNB-% zdz&nUdf_LOz;i!8E`qWo{BDhFGI{Bv|3^2ffwozq#mXk-+L^Q}Fej$W^|$x1w1r~K z{~f3PV@0W_YOUILyBemzvu1fhVLezMKLPy>7;js5&JSCvY5!mTBrlermw{B2>?TQg zUv4Z6Fff>5j*pI6vgxuHYLRx^N{3geqsAi2mZi1128bS&N4d_2Ll(p{>fKN}N%r8b zk>%fcxnA6uVGqe)<{Ny9mNvRL0jNPRS=n;Q=^QgXs1e z`8M*Y;uDOJP(81n*vs+H6?8g0;IsrIc(LnLep0S?SyzK(@n6MM?hcW+@mipNi9Eul z2xzYPGTQJ&9r4R>kQUNId$qcD}N(Pds9Y87|dUm%{X~6gMa4{-0kS5<|4b9-< zu(Zh;;nDPkz<3J8uy0)k+qqRs*Erb>x{q2(m<2#H8bfZIBQj`#MADu>jHr~_--fbQ za`lgik6OW10o(_43)ttljEPEf4VY(*M<#%kGsI@5|xd}z6GO9j)|oZx!2O2g0j)`3qHgyS+-){>-)wz4U>I4vA-EEH)>7hGh`+-k{z zxug`@NH-^pW!emUcVBO(N;&axi@eh{ZsE&n8SU3FKAH0#d1e3sZd`5}p#0xiA(i+qz|tKVREbhcYa9c^f(!S;zOiIJ+@`zVZN4}I%-Gld|1Vy zVZNN-aqhleuA|<)jRQzH`E^i`uLrrV3B4&WOJ>R7D4Xk5p8rO^ES2^*I3&B!C>;U( z>&qc46ZWagag`m}n|eY0@WM#8#rhUmGv;vvGpaNov^h{`YA$S6?fc6GMsj`9oqPvK zD*do@7TBRO*y0<3npN27+|xtT^7*)dvF59NXXJf5r_CCnh0ME%o(Te?z*m<47R=Ny~EjaeWy70U}@nNn%xeESc z?7_a=QkO`0fSFIV$05?-CoWUHyKl)`P~Iq&6KQcveDcZ0+pQ!%BK#Q(*RR^{W#mw=xO>~)Y2Q?>IA}Yin zYb_|Gn9FgtsH=;IDa>4`YDyqe=d-_`UL1WetOi*to-A9J!PGI6s+b0}G)nkEm;`!2 zch_c_G81hC_qnexpGXZh{Xa4}F9#^tx((^ZYW4wIjM=Wp_euNu2?3f@fa0e(bt{cH zl6aJ0#aLrk3wC)49n@qn??-3*@%tM|A*z;AB@V9Ps2QF$_Tdf9*#wyH4wcC>*X&PF zL!z8VE8Mr`mDAU9Q@(M4)mOhM4vUcwgAWfKA0C=R{rpo4*i#BS>b)()X5oE3SKt}< zX>C_i-%v7f)}pc(nhgRLei;+vj!=Qpi1|aO2GnWHYFn@D%fa0b*guabP^{BSHK*MN z=@}Z~Yl|(AwL$z0EaC{R)Zz21NBjRv?Z>XAhpyKKU^EgrDKKZ#oR83+I=ZHl zJuo^V5gG8fXri^={Km-A@CE7a*WZKR-1`ed+6wc3HMw%7+~`YaA|EZM-*5`7-%@1h@bS_M6F&)jTyW1Q7owF=*KX;BlD%YDrIf< z(Qf4g2&5O#T{Je`ZKMs}5vY1-4ijXbWxGK!+Htqj0o0T+W#U1uz{T-l{9l4%xZyqT zQ8u~_)_*l3Uyd!pn@vWNwz%1;Nb7OOO-B6vmt>Hy-T#`4?tVQYafAN$wV1EWv4x$K z;^;Oag+bA1(%p$L!xN4+e8AgQMX4+lfs`GH?V8tW{j&TDb`QDENVDaCnwHFO4XL2|E5Y2TP8`D6mO1<%^mUot5~RbE zAG36E+V{5p9GcFH_xbs`y}Og}Y}nqrbk_k|6NLYXShLGz9EQHiyF%4e57(v-7>d;A z0oOnQ%ESbNe?63lR%h`yL6a@8BmPFACe)ViOmF}V7%X|p4ogZ=Ka%m+m)8wjCVa`x!6^MQnegSES6DvKftG3`%(w+ zM0dUW4F&}0DWz#C8e4$J@3_X5Cxf6TIu&r(GJcqQd%gv5(&_=wnpNuD`4w?TkBLEf zQ>5{XQ@XrAei|q`4KHkcy1v%UYe`_6>=IoBSU(`5epo#QYSY{f-WK{S2!J#1hVGOP z4bCj@u`?mI9EP*;PMo3qMWp&NB;tXF)ar@!tq5nG@6$EAT?od`Z6gKl`CK@oXR@TC zYP?CCm=8&5iswehBvwWQHktmfP09sbG#y6>l9l3@KK!0!ohmf$?3mtdsY{v_NQ8FN zBRXgMl+ahuqmf0wgqHqFCEqZ`MzFB>HI^+9Hh&zgvV(a`3HXhZ7~#1g`s1pBooNA$ zg=GBIwC9FtelTkw+P=wYZ4cxq^)FP&oJe-@zcE5bfU)8O7AOkRS%G`aq=NZFy5Mqo z&OxlJHB|i?)GMuN#RxsOu^nxBWlP&^3vKxnS~%-X9rG9($`vM7vI_q`6H^uy0ORtImJmOQ z{|9j+xgy&r2PJy#L@mYT=95XCZzj_LshF*B%@>Itk=FBT_rH>R0B&QU3|Yf>Eax!? zceZxlVTk2q%U&4;UaT7c1DvC0;kQAQ<+|so7!QXU@KS^8{RUOd^v%vHC8yW(e!h*- zTO>LOC8_iGWpYW2GxhsC(u zTdn_NO+dEyb zow&ST@FAa2@v(bKY+oYx-d&h9)++%0;}>UB3U-Hb3~@fDEEepQ6fzyb_mbc| zYQd{kCu7f%JZV4W9mj(&+19wFI-A9qqMko@<#O=Ki1fZyXjSGbHe<$?Vw*xyrmiP*UDlqp0*zz#@)5?QS6ZNBCH8l8^1mU3@gQY}qm+ zh?$Bz@N_s3SZ;PQV~@OkLENiZm79GvB*PFe7t_i#l&06@iCtk_I-K!q`dy;g6?MGg1huyDleRAV$Q5Cd_yCKOx>(s{QD##<%luMBqP)z-lvi>92-%q^p{-xfyLP(I;wrPi+Vy<2;$gRs(+mdVgrMazfL#+Ink zjWYH=vtR~%nE*9Fz|#$X-Ak6Rjpzm|tV7Oqou6EL&Y(;IB@~jiUDmp8I}raYE0aB5 zPUqvjk%n)7!O}M&vi2lPvCAfmAcm)?;G8k9{w5Qf7C0d6-TR5k>Tw8YKy%DB&>GC! z%1Ap7H2x0RF1Zdkn)Ex5;aU_(p9Dr=du{HVSFCWLleiBaJZ0gG&^Bn%(s{6`_WGi9ptFTx>qPr+*NgSZMnMJ>{zl(;QSm7> zOT}!;Qvx{VRR2QGU)tA|`^MfL%Ux)YGk(Go6ImRC$e)Efy}%L!u+74xtcewPJYg-0 z)I$Hy2d**sekiFD*nN~*;7|ohmuD|<{ATn)D-mEzxgSvcVbQ3phiHZjvsujHl-V5F(Je<|@ukzHep)wKNPU$xK}iIcbczXJ>m%?WHk17ga5z-smAPY0 z(ssd=4CMFZ&?-RGNc z$2%DcH_UJct_JH&EO?k*rpib2tOc&%4CkY(TRl$+p6TYKe4wvmX@IluOhMGcLs7r= z2&hcseq4&prKIA2#b~wBU2CVE;6)}+EJ!6_6zny$%r4{}{!P>t(HVkiA7CkAWaAFz zR32?EUpH=CveNqd+ju3SZC8WZO7S01_`z+8hV#H!!(`{x4$gtbF0?99PeiUGovqVk zalLVL_zyz7(eespb$#N@8#nw>CGr=jOi>$@CDd4m?D{s+4g&Yg3;sCoCZ$nbeG}hO zd7UAdGhlbi)CFja}c#0hAvwwy*6;ael^xlU6 zC>kpeco^y=&iW>M%x!^_x-R4}UdL-ZJKh3?4oTUf*!)fQZLl(ve*R5z0X_!`f?D-k znj(Up?VEb=yQ!WC$oXJ2(@0Kyrhp7{zHT9tiH;j2XzyqvM1+z=9xp#U4fiL4?PT94 z|GmUh&ujjZo?Y5Nfr?*P=fCa@+7#8WIfJpUQiCp2AxD8PwyZ#v^8N{(q;$@1J!K9+ zPxxb?sQ`;JF1&?0Wb$%O{gHQn=02hGejwgr|KDe@3%7hz`Ig~Rk zA29lGr@;-c9FTV}@{Yt>wBhs{yrLbArk}CVSJFrO1yE=jJ%!`G&?*Yg_-i%g^pPQ5 z=!KtXwRXicM@m~|t?M7kDhhSTj5z)zy+L#y3(N+29xR?5Hv!KHzJAaTNO|i%xC!CF z{nVSB0>v*iU077TS63^NSCyM=8sR#xlkj73AwcbtSEIt4n|~Xd6&JXpj!>=v!Im^?>?X)gRy9DbWx95}_Cj_X zT^K)qh58L1bRVC8IOz^o?~K|rNZS5C+X~n{$%#st7LUk#1FxD7-HgiW4b(l0cnlEx zP_I9(V@pLqN!4ow{g4qL)2@bGHk(r<1~!g_m$IA&jNSEfQ34PyaXEC=^=noSBse2n zF%Xn}2ZOE~ej5Nhd*IbWT2fY&SJh7y=dgAdju)Do_knkQB2itTbe_nA&W@NZSbvvr zg_B?d7QZjB#rsz7hvkswzW<&-U&Xt3KGuP-*^Y6yef3=StyevW?biJ99{P)YeE2dA zTRh_B{Hq3QNeQTx{0cb>llj`tw+qzR!K7MPUyP@W6_{*H*bo!@zHNm>q!h#^%e;P8 z7oUX?W>}UY_W$6~>KVyZq5EiucbX&WIk(%KjZMR@0Z>>5C0pc8W;dSp9lHWhp~TOa z|Hh!@!b^$UnvCFCp!XXm0y$H#BEl}C)>;B3Kf^gG4)h^*Y~U*>89x-W$A}#k-z#{e zei?GXM@n^J#b;WvKgZQ2+9P9-O@KqxhF=xtdkZ~X@YWZ#n@cXXSF}7APTdOwrU40W zJSy_DnVlxg$KHYRw*K;8?#0OK&Vhjk!%f-fvGGn>8sTUt6Z|Ks?A=AlOyGg<6o!Ig zne~oHzMyeHL7H4DQ5Ilr?_Ht#^%QfS5@+G1V3acFR1V@{b4CjTZOr*&lMK(|#V#M3Ve?Hkb$s?G)t z&(x>kn)Y>;_WSRZ8W>(nJoKEg-HCB>ZQL5$|{L>z%r^+8FDUR;TUcx2kgMC5>h4kpAbqBnwyXoTfvD z6w<*Out`y32CEOxr`v)4JrR4spj4%Yp|vhwNsu%oDqnw&88f`5sFP|mUD|2RmrZey0f zt(r!3?`@PDp~GPU9~ZWvb0+g6Womu~;8RP~72{Udk_}TcIik3RKb5}Isko`q&S8^> z!AP^>XxTf2RuKiYjzM=FJR1DyN?0;B(nHF`UH52tA0F zxhy6YkfnM_x>12&Dph_WO)c9qbS~3CUdZsK1n6i7?Tb?iu#*W6jCQ0D$`-r~k{bg7 z*J2p7vMT+|ou(ZfjToyIU&uI#Io4pA?-;cM2~iA>jY8>L+mFu4CPT=8 zs=N+sKwR*hGPZ%s7F<3Oh4S+d%Q_2!*Z};X@h$;77E~Lr1s!VzV|3oaJ5NKB{>KOa(?OFV#_#AKnhC-?6kNcJ6}Oy;sdio^ z&?M50m=z%p6i?=6(LrX-Hjs(i2cI8$5kYveLz>g`uCTZ7bQDxdUuc(BS*LM7sb^(P@My3!KzJGmg5QEGVKo z>9#d5;HMcjmX4ZCgwD|5zg^30#zYM_wh8UIt}P971$1tmAco;e1Jp{!aoB}M&jS%< zP`1=G3GSwz&sAf+bVSicy|O*G*~Ro41LtbpIp_N+6oQ%@>{;eX%_7Of7oZ{YJ>T19 z_se^2QsFzLwi0+Y`k&$Vn@EQ&RCk@ozKKy&pc*DG8t&cy#MVmVa*PP2%ol`gdgX4+ z-Tdf!hiC}>z^HfL=}&F|=1H=kK_tjzAD7x7zfD7F+86q)DWG^#;Wk%Nd5Q+C5g7_m>VB?I}@cZlHunW|_=Q?f*n z1=-29tvnxtXyd{p;xKTT{tiH|rlhM-9skp0V6rJb){2 z#O6$Ilhe9*8wwC7*pkWe%!A)|dkQxr7@smBBiR#c@t~m0z5^ja(A)HD$xBlGZF}5p zAR5qiH*4=|3%%C}>Y`l9cR5)NWlxX<%undxXo<6#OO~2oP`SMxrz~55vZGti_0u>Y zDC!oEwkJONeI}xn33<+gifLJ4Ym<23ao*CjKuhmDL9rlsIkbx`8m__2r;xx++2Yk^ zfPv66BDn*owvemF=0VvLg-IpJ4~3nP2+YS}>p@tD6=d|@x1ir-LkKr>i)|e(?xWC} zFHKYOi_gY>H&-D=4q|^lOk==mdn?*4D5{rDs6Ip2LDU@3KBge zaaQ+()l9Qjx(${*Ss+F(G<0^7SsI_P6KVs3$n;F3`&$_+t>wWy&c-O7mNB_>^v4ZU zo6QKv01mRa8t%9Cb}~cf9uGs1f0#3uSXL7fkWgM>NiWlE8#?eAD~<6|`m6gUh18LO zC&CAuE^rn{nL2%2I-5bY7_5eveVi2NB-~< z+eYQ~@$=wb#l?eV7|J&YZ#81o3aOc&8PGoMsqxkxoS;4LP0h_A;GNs1PVY>{ZPb`w zn2RjGs}vh~A~hHS(Pb}L90+hMYZ4M8lXaE4_gcF->dsD1S9|<4sa2fne-k}o%zRgp z$r4|~R=abbCC4$=Ny|m>otcx{03S0+J{`e0*bqL4P6K3hr2Alz5`Y#Ak+MIyHH|oYcjA-*C?8w+m;X`PY?t z3H~R7If$g;E9gfa{!m4O0>IzHB`0#-#hlz4q3b20y+)=`PA+O~D2PM1G@Ok%^@ehw zIbU{g{s%u__D2a%9ez`#vV~8QKi0fIl8LQfjhQk)=ey|aS#U61K!4`R&lZmPxzckM z2OytHwT5n@1|oQvpeDO~$a_Q!cd544k>V+@k;rEk!0Z)d9f4>IbK=-;&;BXeo<&DfS6l&X>ROC+AU&K-TeGx1Tp(3EPd<>bPKBbRaei!1Fa1KR*N;w^EI9^CV=*>#xPCu#;*B zyS4PeV$k3OUXaMykKB-8FT6(feP)7p(|=v-O?Bfo7flkBEdT_ zva1RlG1nhg35tj8v~=@_k?$R{w($jl++CGfOWi8Giw| z^=`YE`{sL7NP&|cTM~ z;AE8;Mg7O@UBn&`#stq)XZ0j)$=(8ywEajnKz$}3JbY7Ys*5r+tz+b_nXQfNSOd)+ z$}Wh0adERv19;t{dilWd^b7oAlh#nC@@Quexm;CrB1PD5;YC<2M{Ik88+V;Mm0L5h zlOB$n#FDS~ry3j7$x%Kb>Ai$cRf3vx@^4{fR-D@@E)(CvQerB_%k1Pr!JUetReW4} zdRO1N=|6#}g9kS0_YK(&XF|@HxR+BRHJK1!s8bF#mkour_``4a9?qv|xZl!t8B!%t z*wlJ~ugH($7O%7@>961Bmy36W_Ofe|_BC5nY~dhl2PP$O@-p1*QxFG+eNJzw#du^T!vys*$Dpu$yfdRs{*Mix(fd z)U>YCPU5vM_2+#ukGt@GTAtS|Ds|awT~$w9?PzTMw@36_+U*JE9Gc``nyR&D0W{N9 zKY7*md`D?|N~)%N@VVtpneBx6SwGeXb*FEhhhwkwB;~%ZGrE)g`yc3X1MZh&M*@*7 z#Ffu3YaX?cxKYQ$T{(TMCg{;6!=m4T#2@&gYFX!K3e&HOwqMY2UA zI*%E%^Qa6jggh_oo{eM#W8n!rRro{0p5rxnzuP!3UX5V9A*3SasPlc&9Dz6nB0JLW>a+q=M(-8=y^#&!Fu2$1m0;u{1v> zy$$E&CE)Q}cICrS=>`=JCe(L({G**HOslqE6`%6!oO!PN-pp^bOQyZ2n+Z-|Fhg{xdqRp z1~Gl)ir^MW|FZWi;QZ}5g;z%x-3Ce!m0}ZY7}WU1e4*+Y)bG)uwQvqu9#6OpQ>#rN zF&d82CWq~03&4qCBQ1*x#G=*iyqaf(Ua{$C54;~kH-FCl8)@G9SqPc7hu492%AUSW zCW0QPiC7%5bqR_pLV32#3(j)AlTE{#?n0&6eBWh%<=3x z`9#8a^`Jj)GXSPqFMRdh4QBc#C=S364zwiZ?<0)n(GTV(*wl=woSK^^gi{;7y!)#R zgT#~IP^*Le3#*LM;7=c0hCWxRcJob+SnGb%(J0%Cy8X#S%F`-D#i~ny=3b=yFp5_P zyA0pJP!-@kXRxeVxJ?`i(8Ttto+v%K8)UhxLFM6O&}Q3SMcjm(C&7N|ED=Eeyu9Iu z3x4%)-fQ zVOOlg=Ts2tP(~K(&h>@P$TiHlM^5(Za2~-jSA@(4_do5k1I7SaEXy(yY0kH~hpIZ$ znrFlmXZQWg4E%G5t2F7*Vdnvvl1rNX==*d3Kk0_*NeGt_`i9ff_i2}&2NW+Zyz2O! zOGc_-moXEud!*Va_|Kih>&&|awk*R~&4a%O<;NG#1!zGe)eW>KZfd^*BD(!_GBhw0vqdNf-aKkAQ`F}RT+zd{4OwH`aSzJe=Xx zVxhKm%iN1!LDo$Et!`c=uLQ#MKjQNe{(2=tDVMI&K1}-|&#VQ@Ajd{3=66!y3h?qT zW;J#Hn#|=XoYX0zw(qR&kUrmi2V+qUS%)+y5xx$y)aUM8B%hP{rdEqiMQ=HJuxUpF z*hh1zU=GRqWDwB;_sS*!jkDA!>q2BIh!!otRIWA??c^2zJcR#7K;)`!)+O6Sx+@B}njXwVuJ|JAJyH=w&H)v*8shhODSi+pX zHr_JK-9*9dWGcAzSdTZ#3}t);Q$nm6Sgu>dWjDDTecA9SxKFvUod}#Ci(@dJbN(g~ zhDitgXa_)@(vdSdW?BCpm*2c5r%CI^U&sbooA%wLkO(I_<^zimDgaho`{CM@og+;w zfE&q=H;R7i;--??!XXgP7tyjJKTR@E9lvHwk*_8a{&Q}@e$X~b<&TdU{TxZRn9ik= zZeEnA*<#1#3;$uX*gr;Q*#CfomfzP(ozC}acd5&-^#C+0Vz6;8u_<0Ynf;8wdy&;u zZZc_P0q6306slZtQM#OgT>if^t2(XsWGR}_N{N-2Pg+So9CcYa49`ZrD3&;8pp=)L9~ufnHiZZ zm(8;YG*zV0;)K|eZvh%BRRhp80SVyzO=42s7fa$cX*3B?{W4D3R|V;_o)oc^$n!TSRP^Xt39J*i8i^GmCyoic z0o(T0>6gFnI_;Aj3(lfrW=2UaMx%?l2PeYX{9kKq!SRudTloK8Il|+n9lyJE&qO9k z`(*a9@{s`)GPv$Y!%gf~FYovzHr@04X};}&q@}=u~+brXy!PazA19vH?xgK0k zOUdmz!6YAFY2+H6wTseF0ro65YYEUsNV<3}8NBt{KZWAKxP-k_KFF&JONT@^vrYJT z6y`VYIh$9Jl~n6j)7H@)7h|_u%xj(W3?0z6_xB*)l|YEex9_!BL^IVoW8cMc?gv~w z3~8}+D=4F8^C{lkdP9I#&+ZZH`&!GTgB1t8Lfze`D#|a#c`K4VIg64ukq!d!T2^(2 z7(I^GE-LV3c{t>?lJAkAVW9lBG1UzQ$9MybF`OvtS0Nw^HdQrI2f#jV^3>(A?L`xN ze&Pz4FhfTO@7>zkGr(uSsJ11$)%Q`^kn7cf0p968M3{F1ZT9}g^n0exzU$V5TKFph z@<{J>X-pldr;C~v*FyaS5;xt*q;n-E=V@~KO9ob%1ZHVuM)ubP4#%RP;S3j}8_y0x zPG65C#IVTitHe~!kJGoMA7gUwyCu*5<)U^_$vTQIG+zdI5oFI%imc$pN@A=S%iOk} z+LdrRi8j0jmU6g1C%!qObY&~+7ulzrR%t3Ivle|BmAg;yN}fe+p7z)qHo0Y+K<#uC zsxd^hE#5C;M$~!ifc*9WW22jt3=g)%uX@1V0<1+=oE3)G!vmWaH~x_+)>9yN-S+z` z>w)^Md+jRwXTS|0a-~usC+$uP&I>S=a3&8DozwcoA>KSllB zNr4pSEQ_%iW6aFbulzjWT!Y>VZ<)YKi;jBL z1k2t`op;AgP&^dt}KIX*#b4$Ox)l3}xZUWq5 zBB}gi4?z`o$s8L1AOM4`QQ-sn&67qW>v069Zsch4z$*cfd{7|CtW28Pf-@ z#wB|Taje9Cf~a+Q8jq z9$7rOYEXF8K^N~v40!H=@_Nk?yN2aqwPBUhy(OY>5Baa6q(-!GG&UV_TDJqAAq1&= zc1EohpbQhKDlghOe&jdgW-fPCc;14l$-rW$p-5N%yw8j!`?0_zyR0Cp8Y+PtM z*>aaW4Ml$FKH>V=gRnB$-#3@3b9k*=6>onnFcfL2gx}&cyZVm2W*?sW`F`?o_EGD^x&uBz9MjH) zQy(!=tjNiO$lC1gmj4r1{Z;fSFAEUyII@||2!BDs*~Cib=+mvt9Lpd(GT;-f2-z=n zBf6E}2pF+(0)HGcE7N{=znChZLId1eoP35!bo%|w@0++6`2m=mV*`7QZ!C)6Cu%<< z&T;s7V2=IyXs44LgR%ZLG3>=r*HEVMDrd6n= zy$dzj#&y@NV==Ls-dBO0Td{kY#?xLE$jZ5=e%0*Y28_c7G+K+;!&Tj}tHRx$D>&%B z?o;gtY$yHw{5Z`(^Sm$DI|e7i#o*5ezgJ3w2ys$YS(d&5M_7epGzn^gZEMYZeBf5?78bO~PSJAEnO zPzrYw_!{8cimMf0j=k9Xjf?nNii%#xg|-OyJReYsU3#@%&PpDOqA<&fpk%$_5p_e0 zy8FIY_3$=zl6u!f(MY8x+~e&FJNbkvL#?!Q%?2R5+iGZZ3!KqxsOy;V(5|!DPkjzU zV~0_=_(8^Dg|q?89}g6mDgD6+{ASVH9>u{0s2&eyR2l=zrskf5Yjz6^!B8)wfDHw5WX@Ks~Xk$u}uEE)iNVfWc(_QwlL@N@WZHaHT2<<(wz z6~~ZlM@rzFz0+UAvzzsk?d7kx+4H1nRFHX(_~%9Lu=j;E{cUw9;gd>d?5r$h&AKcl z?YH9U70?;ZoFFm(^=uW|V6e+pk-w)Lbb3H_K2!jA_lf_&5_y?Gd^~_O4JrRhLV!51 zx((@|^jl|9uBSSmYs`96qu>ay^+vV-3;0$dvTYz@_NQB1@s_uZOU;Y^qz=TmSs=<7 z%V4n^3Ci(3#rTDXU>ZIEK@F+r%sq&T$7w^K-nH<-%Dx=U0w7BJ#ui}7IEo?prf4|* zzV{8keoCLKuFR9OSH70Bb&k0RDXM8deNw~=J!1cQUkR^GeWxFh0q?J&4D(wL8QHYBeJcbo`pQ z|DlWT=_s{=Z+Wg3Ok#0n1TA0uU3ZL<*T@+f4{A8v>m>l>Fx^9JOGt~oBJ2sK&W42X zJr2=NpJ3AlSN58)a1Q0nRQBG|<(R>!Ytv#k%;fU2d zi1KLeJX6AwfS=$9WUcbSkXeL3ICuP7Vp)8>d@o=B2cjN*!HM>fE%PRT9jiWN#SHJ@ zON=7+r8B8v^unASjj-SL^xQ1V2qNo{5OX7PhXUH>Tjba8 zh5y>mg4@5gy9i!(V(Xi0KWEti#6-N+``@X ziyP~wXvPyp;HbKC$~Ul;E)XuTg*GGGPAJb4IMDMLlogWz)RfxEd!ckT)jkU z&3Ov?KpW*9YN{~LwT#?AdF}+-6P=Zd`GX8H&ijyb)vD@WN|zoPWkxRyps4|bjnTP= zw(|#Po8Ycq%Co|9a_-Pp;FFH0ax$*qf58}rKk{uaWb^j)-hVv{`(VT%#7)UkCG?=_ z0QLFy0z!T)q+uqch^t>o;|8RIr(&;n`2)XA8 zmloj-e)kPUS2zfUN^a6lkicd1QW|)%%S&I`B=5XzF34TGb?1JlVd19Y~ecI*~fZ6ErHb}O6W@>R&Rik7%BoM9L9n+Dd# z+lJb> z#k9jU$J+70?KX5DNzJe5GkUvXCN(hr{Z$VZu7-3p{A9ap5)h&qh~`;0Qu!Ne&HnV# zek;gcyPi&0%QaaxraX{&g$eg;GI-kDhh(e0dt_;}KE#~YYPEsX;ODBKGwPt){M$L~ zMk9K!!;w@1rI85_wM{^9|C-xkB;H?7f?O*1zFx4oqm2#lnso*f{&S;Jq5gNQuVPtK z)h<4J9^eo;-^%1_G#l`Ae^f37ls>yW)K*mi>C~51BmP#`b`N$<*1b8o(W{0+yiQ@q zNO-Q9l0#F}~;;U|0w4i9A_b45Bj|ve|mHI3&v+vw0hHLEy z2C5W~%7`lH?8APVCQ&-%yCD|6**zuzo(kJf4l|4n=}U$uRLrth!I9+Ii{2KCG^nq= z-|xWP1vOf_u5%zYdH2aSbYr29CVN^RL6Ua{d&xB2_h$nwlj5!;@xlX&(t|T?k(3C| zhqOi9?96=4NRovNXf{-}*)4i0gj9MXBE760fhL7XbVDG~vas0o;z8C)INYsKn!4ma z(-~F5O+WSrPttZqWEULwJ)KYkj;@)o zCpT^1g=mTSxY9{giIhW-0powt|&2nprvr3#j~^Za1zGtGs5iF1qk) z;MebLc@yq6)qxIheOoQ-Qn&xpZ!+-hglN*HCozk@`4n=x+6mhnLWZwA2Icp`C!5ww zmw(GshFvs%qsaP22^IOWK9ZcAkiLbYsI7XKG(&O#asX%cGzuIVUiuuMTnDj&^h7M+ zjW7vzO11t9@b6z?q=pS1PU4#A>$=Kw*8>|YE9ju*_bBHzp41E7@yxS{{ptd-Jg^$+ft%WXLRdP@kUCa~E$S-Ek}bRRZA+LgV`>g) zl`EmJBNgGZs;mWSscrP()Ct+Tn@PT~3UC<%^(P6aqMx_}eps~h%lP+Wd6>C*cS@oH zS3oCu17%$nj8)9B?x$XGIvowa%L8h9KuokHe3RUM(L?n+uz7xES z25l2PF)e_H7^`^&Y;mqt@f3TGMC*n08yqRcR<#PgPqskAa-`M^jqH{zxT^RTNgFSq zL(zG z2HnLy&)d4eErIu>q7#65Uo0X?kKsEF&Ke{P8q<2a-U+<7NaOK!<-nL4F38SGHnU zl-WDBUZLhZY#~?P>rcODT00|V~E;K{Y>HLIj_R{5i1Z&b$ zVgvvfkBtI&XmtBI?~};k*9djD{MCyF{r;MWw{3YxQ<@jR{JQ#J@O$jM!(?vp)rHuO z((oE?cSq-i`V70EmWq^$Gz+5hN9t*IiAp7L27n0i7=}8f;b%xPym}}?_C%y0yQez-AS~ZghW*#E z2^Ams9KB&5GIC(*8Q)a;{muLH2mS1FBD9jCHB--MCbL|9qUk_boh>LC_qKk5vqE;6Mh6HlatT9Em}TV+sIC2d z+WR@scMAY|VEj4FhZcaGH|XXCf;r_U(NVCWeuSh3vyN%t#j-|Lt4~=F*-BbC;n7%d ztt!j^oFB@#=95FF(JvgkBls+n{ASywp}lQ$6dF9Q2O6^nu>9wdvEAd1s@rFJKkT)K zm39NEv#gA)jCJCZZQ%+&HAgyqfIADDh*EIk2jZ3HB7~uqC)Rx+C~xP%;}_nx+Cnyw zG2C)#G&fbSm@K)k?lnq;?%_j4mz_GZJXU<{vm%;Z8KmwMTCW_xz6Gph2am}9Or0<_ zRqFEMt_$t;{N(9YkMilqKEL$CrHB6q*TkIFXuEqy_zObjemjZZ;XfTS*5mElwcntO ze^I1f63AB89yNd+J{{tnkT)2u=2!L|Fzv6rW!sXsId>(WpL+vB)Qti~{Ei+XvXT6L zY2FIiuclKJBEhW;8bdaOO-932f_QW#`!7uR^l2S0Eg;hDJ-;`c&QfIwi~J2DQeJE9 zO?4{Z@Cyl$EVVm)*hM8D&S}}eTAL>!IM*cGE0C!uHD_77mW{A+@3xPPNdEQ%+kDzw|H?9!62vQSr~~<6Ectm1 z(X?EAvsdfUf`_CLG~55n_^$VZ=F5-vvtio3(8Gr|BU+Y_U_drl`y|X3*q5dJ7BtJax}s76<(5I{464Qp=90dVh(; zosq}d0Vl`sW&wi-v6>}n?tM+M@E9y~?qE4rRUfC}LH zbOfp1M7GIwDgA51jbDgP=xDQEO%tTTW}E zaxDD`Iqka6Ex*`cGM4}Cs3CD33J2bSxyp^m zFBj{gdOXO^QmTVZgz)}BPI_G10SS?(y=}!^R(Qs+nnWU@mCFt_Gla>Seh3jd@$e1m z{@_2!EO2*lwthcJ3gqO_;m!|Qx-;FX=N@$2Jn;piR=>O4eG;G7OfbMP!R<^NIMk3-*mZk; z)UI4wjjA?3^E9_C39Uziw+PWG`5|`IuYOuZGQ)*6cp8kOi5uO%D5je2i+3oepoQUb z^Xr&D@`id?Qfv_gVWM>IU*H7ail@gCmZlsj@vvd{X3 zN}qk9hK5{&mj~hL=(~#m$>>HW_3!ply4;80rqx3!aX&yQfbJ$;=)716psXElY0vh}lfX6?l}BJ=z+0PZE)N-;g{YI?`CRd&`doyM z5S>&8DIQwMPALbukLYQ@NLrm&@q^d~`Ol1T|2dyiU^p6;XBNJ&moxFe-b?)kDdnlP zUszU_^XZSYjwtP?ACPc+HsRluvs8 zxO3}8%h#c#4XhP3*cdFWM&&0)HMYRjfvo2{#eTrGBi>FMqqs+LnJk&d$qP^w@iF2# z>oNBhVsX;5`vs?hMz0B_+o!VrOA%T4)NrxoM`{TfSH+HG4Dh&91swnza(L1zfOG-Y zS=rIv1pJNYdd%1(0Xu{m7526;jM38##zXr>;btq(<~gqVa4E$AETPdr1GtrZ81P@> zp{CoTT**X6i0j@otnl?xBef0!Cj6OjRvWjDiQ^4swF^bQTr=Ty^Tml^bLrTT($xXp z%Rz${uR4tc$8s?(0msMcrG?cEIB+Wxp!*wc64)}e;FR*mvVN1De{nmM44BIB+xW`F zufL?dRGhS0j`Eh#Gjk0=M_KJR52}0Un0YS)U~ie;FoxA8E&8s(RY7NU5EAQS@u zuLYOX$*`}HiaEKM9s z^0h;LYr>NNm0X+V=wn;p>W+&oNT}?%dLQ&KU!9IVsdrxO8q~i3T>BUYb#hl5H8J!i zcvK;GkgJWt^_FTwQ`%0X_-d`a-LA}{tJiR zm5Z?kZEpGJ#cpRK%fBM}JWLsThwQt zY3CWSt_KRObemOYwXxNvS#3#OY$34cxbID0|5(~}eUgWm zQ>Kk7(2iU-Nwl>KccpIZAcI6k$LnNituJvIsQzh%txw`_DwT^su{(=6QSjn3uXZoO z;A#9%-_}k%>v8Gjltai=g6D>U_0*9w)Bid--=^F$X6sqd304naP{ zgNMqn$X|^89&>pUjewWnQs2q&Q$zfd*Rm6GKvP8b2dst`%_)DfHI`1Jf~5-5wBCi= z)N+e_ytqw^@^c#bLKwFX*ug{QJ(m7DWry2z`bdNP41Sbp9jNF|ncdWCtqb;7$Ig^9eVZo@|veX7R{o)_=9*!{W}`oU2jEYo})4qLjnF^MJ4?9njQEW(4H4X=wnX zb+n-;l=mzoI$Mi>3BimD%$J%}kBk2mya?1C=K^OyX(sgj?XW=Zn{quKVNkr!4`bOd z%svzY-H&Vy-8y3<*6;nJdHDzoC^& zvEGE8itQb}u8Wh+=!66^Sf2hMs?|A_e2N}nwjpB+NjHzkz+WV^vnVTif*_3&Fp7<^ zFUT^HmY70wGp)?V;%msUnsbmwcpz@4K7#U}qeLtlY7knT?zJ$$q61U#UPkRjP8|RXFZ-IaTqHL)kjLTxf1?cq|c& z)mh;9v;(7gvL(S3Z!*EeoDz8q+ptk^^Xw$^Ga=Cg5I~?1?Ho;?r?MX1$7-0OuoK~# zFl5TlNsTFu9dgHEc>8(f@oyd=;hIr~m)luDI*FH>jdlu-R~FlyI@Je3c!1{DwZe9i zuqA5NifTjG4d{8%f;mtdP~K?O!D_SL>0x~FQxfNP3VT=z#J|Oq5I`VM3Q}H%PNtc5 z9xV4A!_@ZG%eSY$l1(hWoD%9qZEv)hvEpV=4QtD%PSr3!(n$~HwQaFwC0yMX3ENST zwiBRx@}t+-+~@}GgjJ4%S`#vG&X?1_Uzohx*Z2hGCGgEEUvaxKEv)n;;s;Pzr^gV6*AY&CPR~T}4qYzrIaa zFrd(wUdt@foq}v%Qi7*ZVe=pa&*$`-p@{;Ki*=b99Msf}cC; z?m@wG9>M<|sdEZ(d2=MvFAzI?9qy9}1wy?7%#(-+Wp(!S1JJL&XJ#j3>&tRWoSLwEuBAEymxa3m2` zlI4QI=!wzMKDpE_hfNwPyh=wvnujy#&tFe0sRtxr3}NflZ9V=vy<0u`Zkc)P?C3q; zp^R>zsO$znIxyI)m6==VF?+2ql$qjPlR1Ff8@_z@bYOdAfede`0~^)I!*({Af`2it z`Ea$2(=*9FrJp0U;P^E*e=G1`f4T3MAUCv{KK4eA&D>jOA;Glw9?zTP3Dy=`-Fiz%8dVJAJPq*5#fl2V(|9Z|tt=1x)2;Uh zCvbUKNo^a)Fr2raZ=}^7L}wgi`#ucz!>%pIUwc%b?@$bG%a1cE4%z*s?xdX6@Qx3U zvQC#PKsbX&4-k1vs+BXd)8!zw2lHewA0uZfRf&8Duq`|Vt?|9Sim2n&2$a2nr|6}j z*kyUpAo%PTT5`1C;IQtgwCyR?=uM}Ll;23?*@kz3TWO7Z&gf+-K57G|0&y>EEctM5 z9~X2TZngA=1MNX*JHqQh(qrifw5SX%;CD>#ZTU&^=zGtltYSg(cg8`YYlVDb{6}83@?@|?^eA;=nJbqA%n#pYl2il6QCR@ zU0`@=8@^GOE;*G}b#%K73$m8!C?~mOpnstc0G%#7z!-1I(re$aHgkuoSNhdtwBOO- zjbFma2JR+qUp+=B0&_=B`YGY!lTpy3u-50l^FM2YsI5qt)hA)f1S~L9)5Z9~IM%TV z<*j9P`x&bb5VcODEPFR?ak{0o<3fe63siEryDP9>iNfXd3pcx2c{%D)Xkb-nZU+`Ap!^R2&Yy z!*@=46v7r$o(90uv|z}g$AKl&0#5ZC2Bb<{R(B+Opzp0sR8wCc;PgZC8maOJXoY`t zH{@m-X%opM%M_i&D)jRgSr>C1P^8eawTXm1KT^f~VJmp4@+3&~SIJbR(uQoc+y+g- zT$t2&V$m9M@-maUN5FCpscU04t8+(?D(AK>?M`GHDAELB$TJ+13e z{Q0875H*_4|Anmf@S-ve-GA1AHEC-CN^CE@XNV};VEX!+Lk`ipT@a?VmPT&8?x1af zR3*R%bS+w;(eP>mN;LjI-wh`El@|Pux~r;D?(z^2ry85q>8qu*?vw6)vxlmkjC>ED zw~>n(b2!@bd>k<~?0wr80}m?75`~-!uGA~90ulP=YzS3NiB|7bFLw@oLn|ka9;Vxc z55sWHIWReJbm4`mgE&48$%)lD13gU{X6iq&M^L#T<8@Z->}jLiYC+&^#F95vuZ1S# zL=1Mv$9{84Lzjm>sdn~%jjZRR055Cfcsd49RDbp$Q&75gO#$q9@i|%{gUG*PqJ_Y# z-)etm@(l}?1nr?ri_}?|BDLCj>oha4YH<|xA16*bp$#N!+Jr1Sq z{a0zvW<%eVnn+649wbw01z7h&7QH_!TVq;17+3-0K39@+1iwezhT zHnD&7o>uE&^_WpdYtIPhf=QFXykv!ugdouBF|O&z>I}QL=U4`1IWpp+1O5dczKj+I zmZP%!1H3ITq`$m-MH;&7(Huc1hYP%WyWQL`2|lI$3t}#>`7wM2AQ_2S&%9ObWabLK znS{-7GcXQcipp10xZ+ej5vkYG>db4WyWk=O?kzKFL9y6=0@)7Az7~|G?~*{QmENj= z?5WJ~R|56!)hz(_-B~Bq^8)6Nz5vRl7?HSQ)^YdH3ke{=ESB*KznI~7oUHzyFHI-z7gDl}~fM)8|1Np=h9TD+q~vkbSRwMqi8?2K_i zx`Zfl*&;0R;u77^5_rT#_{AnrkB&DfIV~BdcHIMfeGHe-I7*KQkJzUWK9M+6Cbf5R z3yisi(103&MH3he)mTXFVnNFnzqkyH!1zCarcg%C^xUzQ);pZ0ut#TmxLa97ix(R` z&`Ur}Pnhbf>inA&J?m1aUW6@5&TVE8WbvA7nm;9$=@v!}Gj~eGST`mOZdUHwj?1Xk zO`7MdPkHHV3M@^5tUo`{1D*GuNjjcStCRYBUN(Eg={kRQe@j0a)F_Zw?{vfbu5&Jf zk;hX<%4jGdJt=*2ofr9NG} zHQ@e+lU5335KF@W^;#u-VFRn>K0%5Ng#6$wOHo3LFX;PtR7?={uiJ{=PPL2!3=ADl z=vsLqh@B;dn`Oe)FF#dSy4P^aSk*lxL z81Xj=Wa@$@P#04jyZ*mP!09Iejr}%dktU;><|bENUq6UIjfI7tj|n_0@6U!y-ctt`4{-Yho18cFu4t7J7YeEw;e6rQ_0; z5MFoY52z{N);apZn|!+PY02|}(@U*_tW##vcR=hBE3FpVN~Vw(+bOi00&t#U)a-39 z;wGA5oC|;!L*Xzf9BL9%Oy!hxXLiXH!nij@E)CdSguKDpa*X_3MMMd+P61l9$l8LP zYlE`W);XnIjnmu`(-yanX!KXMH=dZ(mw#Tp&l4T#qVYn+o~7tBOjul>FP}u2Pjgrz zGF%)q?q9?GC7w&J6<@P#KND^yAn}z(85gEh)LWz z9cv$>GcDuAC*dB`@Y50rLh)aM4cXw&0cT!teh+T(#4a{9&&a)8Q;O~`_Nk4Bft;V%Wny}No2uQ46;`Qu;Lhq5gB1!_dt zi*c>kBMkg47`C4%0ZMgI+vKHn43;Oe6S8M%u^H@^-%sfVHdeI6SA(l%eHFD}rvC}^ zfzeig&gpqWr~nr&Yx921FYl2cesyKg%ZExo94JY(s)}UQ`sGaxpLg5ia;RS^<-8r5 z`azIQYH3t_ac0UooWeHy!CD0*A810T4$e3?9(2yvT0zgj*DY?r-=*t*^VFH%ft@A( z(Uw>j;+XN%)RXz(b@p*j+ldY{HzQpr>mD|~YsOB8#uy3aQ3G$igFQn(`^P=g3TC7( zw3YGp=NC!&Pq(gP-Z6Vs_|h(GA0xQv#w%7c1mN5W_UdA*%L9{LemN~&DfPX%wfj8W zBe+}4SwEsGEwlLWB>2F(gIk7;9BzvF7!tDGaew^9&w&qfG&n#>7OuXC5mW&Z?CS8RUvS__pJS&rVgR^3NEhMAu^w9e6*YA+3V=P zkG=e1|5S1>tXHvn`Axf=&C3?-V=l{o_WY_RQow7LJlbrCZ;)wEX45`7uEO<&X92Ne zrPVdbPlY`XLZ3~=liQ}2SpWP^#pCM-TFQr%JPzVwp#?Mz{;Tmn#DZiVtoY3aslDrk zDL?a{u$V!~Y^XW_`TKg9FSglhGSj34B!tFXq!l&dRllHtnj)e4jk2LM9dyNQwjt_J zViwJyezvb--u^eS@ey#1K1r{?>%-{atSetgeEn2q`op?8JB_l640^%+VOIGb0(AA? ziYcKI2Ww`tj@fky_h)oy@0F8)V#_VrdYd0lL>)vjahe=>uztw@H?d1l2N63NxlTJ0 zAbUCCD8&}UOGz+?sGpqvO5qUw>+RRt`8E;> z_c4QWm+8mLQz?3=GBmbD&mO#|k{fsPpwsy70q3>Wd}}V~bo={gd9KlEP<2oez1;KU6w;YDJRJZ__1-W@K{2&XJ7;C@R@vqiO>_x zII0IGrcSH}=8o}b;`$K@eamNmE?L%kvqf$@*4QReFl#4T5+X!=KnZ=7Vw+CIY;rlI zv2*wf#}fy_Y!}=~m5jMK@L_=U)p!wRN#lJsdO~NTCi4LMI4+5VbDO_(iq)!@h?T&$ z4TuDSJ{Gr%6u(j!KaqL`PyHSFLf6uvXT-HZMIli>d7kqCCWQB<+FSOWF7 z`o6%)4HJ(?J+#j+66J*JStgzUxosh@2T#$|49d!~>p?Ki)H$8^1z9QK+U#LQQAX8G zUM;_QvC##tF2evQtls@#DrWwY945Yc=y+JNi%yHMo$-#9fj0%egUTzutq2F}=#~iY zcMS-!e47}izwMJ&DM+3)(tN+rSdF5g6XIfH{^(D%(PK#0g2X$rdNp4N&F`I7j28)V z#&Jb)t&#~!%=VM9n9{1l4a&SakMgA2o5F=Br4AT!-+{!dPenxf`G-0w<;%)S~hBO6^Ph8j#=JOjb36lS9KD z+2i<9tKmL)O0}78F`5CeuKE*`wfYQ`DikSK*2ez#^YbK}gYI?mRy*0&(Q&vv_Xk3}PL9J-s(da_#&t(` zF{Z}q^Fg9aRH|f{jwq51%#IOd^?xIz3Fjw}w*GG1m~{V0Fb*QtqNl`T z7|MPPZ5p`6=y$QXV9KbxpN-)oOS*AW(V-18Sy%oC`K(m}-{9ZZoFQ<47ZNbC61Dq( zL*!aa&|Jk`S840GeCA^M2U<5#9YwuvK708>MwOBit!a#H+HoC99kjty3ejGNBR8S3 z=V5dg**YDUeLxOQcsp53Hwv|wne3sV!_j%tlr&%oGF(YND>C5@d4#2Z6W!Nye-M?n za1&8@CDqSwSbVj0;*6wSn~YeqzFdxK+(DGx((4PV;5unAu52FbuXKT!RP&=>!v2wV zr~Cp~3D&^WeX-PFaUZmNUI%mPw)X!TW^FeQ;|&n+6TI|&UQLbq&6!Vs+WhCMHpPsU z*xH5nv0}&W{T$8RaT0uLy3*@qhr0Z9U4-;-8vPfpbKMd1f!Kl54&Fv@wi^#rD1)*s zz-oM94Bc)@Df#dy28AmarA5V=JYm<^Hb()acDJZuh7}_5biu`~eKi~FH0rU!vYPPj zV}&rf75R5p&1j_2j0<&V-eQ-#?LH^4tBCvK=_5W3sh8S+1-IF@xu?i3Co9^r6|?(b z5)j-_fz8&~;asn4#x>g7*)-{P%NfD*@p9hKW|~Aqhb^SyQGc94=Ty zVpq;G<-iJ`3NDtH6_yveZPI$S{xsmXYyqQ;{UQN|Be?e~&%5avpi~n`%(yN2+p+ne zH$us9r>%|5A>!nG7`)xn-n)UcGXmnj_zx@|car+9k{Tgqs5QM?Drl$Pq@YpRDG8!k zuxtS?h#5rm9{$vG0a7Zp(`-F|oPHlohrrB(J+a|*&ceS zedo(6<0>Z{SfacO{WUqEQH`{phH2DL*|_|#j9zu<8BN-(Svn4R)L>^x|6>4`d4$F9 zHdfN`p5*E4Qh9_s(6#b*o<4H~;Ws6C1vU~~ILB77@)_Rw5u`TI?1Sa50WpUTHReTD zc94`Le&z>Y7QToVgZ{4Q1Ii~NPF3xGOSv;{PQ^3C`5@kLC%1-T7sE=*BWKs;3RNr(nf)g4PO%Hb z9`rQh4i9Y3*GGAd>L#;Z1~Y>pc!TbxF*5t{d*ban+AFDR#LN=PjC*$S%+5>bQnbwi zApdMQoO1~-h}@u;slKe<(4|D7ng9AcET?`EN_?T>R}U<)dub62)z?lrZWQT1Aj(a~ z>kg7bQI)RvxmM8oFPLIV#<|I?Tc~w%u(bFSJ>)>SIeCaveoU_iD$1q|o!CHuI$;y~ zZv2Z1B*H)g5BQZvB999ML94;E{blmFLj7KTFkzj3V+ExMlQBSKj=KEwgauF<_g$y)^TB!kP@hCA6jE;o2b1YcurnC@*JGE2A>{lZ6z? z36x>5Oo_K@i7?Q;v2w-F{F$UT$Ogf^BhPAn3_jQzoNNOm=^UbQ_bRnfPcB+9bDWld zP~vXw&f2w$Hek#}2=t7uNb*=2)Xt!pxn%;J-H5D|L*M6Wy=Z((;LaU@7?fm$dWHs| zz%D*L5MooTEV*bzMB&SZ(G-XqbCEM&EI}4%wy?Ext_w!HTMfD~4mN4(B~Z-|MZf-L zai(78Zu#b!W|vC4Ddg6j&=y3?fid;MGr12ACi?IU6m|jou4qcM80MgQi`yfAOj^Q0 z4O0&*-Ys-tqA4FpF-m)Sp?%0E*WG6+^`NIxtenCrlpOQiEffn?58?C-{JU{{OaOGR za>AGp#^qoGd^kgOzIjIcMPe%jDfjEiO0b;cIJmPM*lzd+o^I3Qm*+%=c6Q&MO;m|N|QCWur>GgXl6 z#Mtrj&LJ%9t@`FMp9bCp63I#psH1R*Hemsr&wy<3v$22TQY)AP&qa|A&tnVUY>?a} zxs0@CvUR?-=jan2&o&{rie()Mm22d0D*7&;`1I{Og`0GG7OvyEp4zT%&Qk5}zVI&K z+2=V6P}%UWJp;s_{eHVH7=X%W^DGPT81Jgiqv__f*O9=(#Th-BHcy1vJ~I}X>`e+W zvN5&nY}<#O`4f%cfV&3g2GPCZ@lg5+^59<^(huZI|B9a00#-Ck()!f>O13R@jOi*v ze=yuKFJ5~~+e5mOc(cXGO$30}Fb9xTHcvl2l6Xs~*S~0VW*~*eeW@av?pv>D$1*C2 zu}!L>q03tvBUo>~(d27Y+?=uigEbXkaA{KLOt5VOSiuBbzbP}c3@w`oS5h5-W%Emu z{N33>_-+z1CK&QgmDw@h>x*xHuM0HgK^PJTaBKcYuqq8_t4<(>ESTPk?Bh!k`NUt3 zePEycfUArj#@4Z6g41q$lW2-jLFq11!Gq7COxlvOR_K;ENT@Q_KP$PavU}FufG`q4 z-an`Z#T`m025Z?25!`e&`J{xrlE3#3AjM}0xJ%mF0*LP>3G`LrHRFFXLY@fs$l15s z$UWRvG~LfC(KS1rn8+I|H?kDwYbv)F>xP98w1s+lJ6H4W)TI9(>G&xnjmIy5yl|CpQgE+fAN|W z@s98?Y{h|BkuwGHzUy$D`@lC)@z2-xlOx}yHL@bh=9^#%E(n>4PJN8LpQcFtFi#4C zyWT$|S-~A~Owq*B&(i0IDz^EqFwJ#&79gfY`s6RDARdvN%pdEv!UJ>LjK6W{-a?ja z4+D-379<~5ZD6^FS-7UaX4&b|bYu+}N_8dH$W|9UxJS6BNYnP4J>l3^O`=XH=_TXT zy@{aIR#)+w14`@r+_bLBZbo{sgfF>R4t@Cho+j8gdchHRtHB9s)MZJ*nKls_dz)Vt4WPs^!a+EuubV1&s8xue}EP(jz z{=QL~Fk{R#1kh;{2nqgA|D0vFNutIKPo?hC50??O*w$<0@)755V?b5+;X`47j7|7$ z65bmtw_w&1^aKFF@m9u;s1y!od>)`-?N$*=`&N+pL0)K5CGG{|04l)WJ zV$XXSWLRg5jEl^3tIYJDwrL~Q!TR0k+^yP^5QP}DW`oKM?Xr_kAB6r0=J|_=VSldx z{Ci0+OsMbi)*8UcsKFsw65b@6{5&A~HOX8YUhpV@qydfyI>YX_k{bL`)PPCkC9bs% z{p2~4ErT);_42|;Ar8STf?04|M%9X_a~C50tb8dT#kFHhh{cChj2d;MIGeThTsJLP zXj5u;HYtSd-@+^T>YMr1NEypVUPwXefVy+v}&I|9G$%=nvg7%M^e|{JvWks0vf{V4>SM=J{PjU8W#yFXC_><2B z*za8h@e9%ivIhn9g<8zppJ^zm z*Za=}rX=icG`n14O*x3<3dW%3X0lA0Ld`*3eO~CX?jq`}n;>>N z%Hm{oM5?`$wY5LLGqSgExGsvGxoF+W?d6D-b>*bksy2M-UeN>5T3|K6x&dbo zcuBYcG#@}ZxzbVhuyIVDvTey+l*We+){Rd}NS#u=d4$0+U9zT5pM;(76R+u!*cD%) z@|o@01rB1rkGZ9Pj2QT1eX6nAHQ09+0gG^OO9R2VqVp1!-#SVbk}&nXpgd&lRkO;p zw&BYOFsIe=EtA}MSnXC>;qmSsWCYilr52y7JKmC{3yec zGJ*BsOfB)&@=EnXqa>$S0RM1nz%vIPQcFHKfxVkDKh*fBj{kpvo) zzdL5g>e{G6nK}bEwaT|4DD=BmllbF0#cWdy_b{-1YE=j-QM`*L!-5(y`XW5O@cB6mUA2C#UOHTY~i#sPREGg|kUcCzYq zR(BIfjKCwolo%zEuRLd5pwzP~8j_#LZf@TLU=y2~X+^*($%;^rV&?6el^LQxO)nAU zNc>xecgf~DLK*12f+?BOo74w30P4mq#sr$w<^$lEEHwmr0EBH^Fu?FLC#9#F-AMUK}8s6dt%70Y^ZwOR+o z(HRX`as9vG<~-vo9UYMW+cDAqG*{|2pW3r%*_bcE)Xsz1L+Wkfb^+4XM*%VqhHv_{ z2B9Og^F0hY)w!f63b$vRZ&UHW4pgXh>2`tYg8uWLw`cui-%03U128U843%HRJBG`K zPTzBpT-V;s;ofnmOv{j=o$Y0pcq-SWvi`fJ{1h|NN=mbdctZTH)kYM$ ztuJs9k3?^I%h2C-s{{2V<@kGM`bJ9T>pH>RBe-V3^hAWPYX?cf8wlL_Z@On_xesb= zV9*3sN$v<`_i9PY%sBo+S+Sx?%vH~)oKF6nXq3tzZby8{?cYeZv#J*l*eZEY>3CzZ z&*Jef@(1t}!RN^&77)*@KzqSA?qddj)39qt)W7Ubck@oQ&?m|+?^$QZ)z|&zZ@@ac zk?m`j1yGkmy7B&w=0U&C`xm+;!||6nu1@$I#Lx(~ka?TP^ySiCEu((;OSV`%SefGg zadVcSR=tGPoagju4#@x~CROdbX)GGa#l;6tqNdDZiTUg{x3P611B<9>+oQEvp-M*( z8e%^Sj=FGZaiPlDM2mAlrzM3~g)*1_KYvO`&bu=0xP7!U*5cmMsx)aV);+6^8L-i| zN@=V-nWy?ay}o$}^_ru&`YW+E$qPQstc|a-x&?n_iSE_r^|*u&XV44X2g}+W9IhfX z93yw%Wu+6Xl6@@0KhEn0ep9f>MJ~qyWjO5!O0MJfn*DAL12V<>-*kAn1m)6w zB%vZYRSRJ%|H~f9Devu|Ig{cw)Qo&|&TT%77XT=_K+}rsSU%EW$-h^+dvgQ07Y_;0 z9e~+`)U|^Cvf$)t`G3P#Ts5zSv{UUH0bD#!w8Ge~!m~p2rKul2vn|sFs z9mqTq#p%froP+;DEU|$nTFeXd3H)<&1UP{JZC8lm38(rc4P#Vky#?AMo?o8Mp^yvO zSKxI&LDA^t0LfTN_2;zwPvvkC1o;<+m=BxLJb{H_1+u?5hz&k|hpq+N!`f1@H1v5W zZa|uksjLNH%6P3{(F{l5a^ZFZaMGE3?Y0AP!@t?~hI^1LQDdor{TK`OnUSuHyR&A_ zcwU%chAe70dFYojzfs%VeBt@_hdOmSxFr5Hk!T2L3^)u0Uu2gI78lGb?Oe<@_D=<*2*}{Z9@1l)*CIX z=sO*iw~KM_@PD}~Sc(1(-A%kpviqa2Gzb)=4BgvH>q&W`T(_4#X5oPIrOb~iUhhkpB+@hr5d=@TH+o$UWYd=RuL~{j`tdvuoJk}%D4o4J) zLX%<(<_V_xs)lr>II=F3zA||jOo=a7AmaN|5ac_7;`|S+1nqbXaXc~^Ja+;DXl;p&CRQ=|u%S;m^J_@U zv)n@gfw%{qsGFE4;Q*RdHH~vu@^b*Ghl)}q4gFLPZ6r`X=-*8lE%Ao1n_g%Y%ZgAT z+-I1#4uWk0lg+oYWZn9q5hyKMi_88OStl>QW1>#S^2tLDEFq4yn!h!;XW+H&>)RWo@W?(G~FI2E%pThbuOiY<72v6Z0=3i74ib;U-p6hB7e1@8kw}3iSww z9giPNUY16j{~_N95LX1NfmmHs;X(9xCJ9@Z-g8K7q6OLJJ&>Eub(CgkXTZ!oWhb$N z&d5G5yI5m1&<|R{Hm4^Uu@~MKwYUb4mX74X%>6HYC%NU}wFP!hDtKp_ zZ3Yg^n4X)uk?)L{-OeN#m0nLh%PHj0s(DQ`q%a+FQDlKn?L=QD!1JI~unq-=YF*_g zfAvmHTZy2gadk0fTsfgeM}r9``9t(h1-GS`s3ET2i+GMcUB|_K6%09g_dNJ%GMKA* z;FuMdO$&8PEx->oQkP`w{+FBX_A2U(Nz3i9(5zdR*nN@_DShD0NKW41E%hl~=Z~(~ zp42`jN9}2t8AcFofMM6;uqbEBz~&=#!DX`*DqeWE-{vP2qHrJ9F5;gJIfC|)A^6E& zy#bHo?mvV0oC{t=3BYl3EFhxBIVvF%m2{#^+q>i9OK*^9^h&6ZuRgd+!d`MY5&m)wQ=@O#|h9R68!4= zjHaJ{60yMA8XiBgB z-X9H7HI=i=4&vNvg?f6i@5&Pb!Lw}_hNzqp@+_tLNwD435o=Eoi%yYo&Gns+9uG z>K{wSW5p@V*$R8J%>;yf$)sPU5D8oCiLx@6^hojoD1$_f+!s(Q7o8S~T)7uZM5(q# zxQtW?7R8ieGOjwZetdl%>6!tO=th!?=pgZ_K~=6F_qWe7l7jKkv%&T}L8$%vLNu#j zmyPHm5xyfTwknr4qj{`R3a!;6-FXw?Un4M2opUGqR;sDS6L3s`Or_pkA5KL6!D_K3 ziC;+M=Sw^PhVyx;&I)P8j;*75vFX>Fk0|T)L)HCPObBq$+e2D?Y{0}9sxKh`aTJLBI;Mj&&&k$-H4UG;&goId1P&DFFPAB9gh#MGhi>zv z#q6sg)w;YzvFyvTYwtXV21TyhstF4%+vIFh7@yUuxlxos-a0*lqpfTOXetq^@ z1j09L1yoC#Yu&<>UxqU&EdN?1pwh~%HxZRYIG7@3(4Com$ z(Mhwc&5!vP-L0lru!|SR#tzeSpa7>jAQ0M=>>se;r2#23 zP=qEzwp>jm6W}kz#p8%D&g7-%`C@c3|12?WG3k>JV?(+2hl6NIK6T_t_>YOUUMsWB zfO4{{&B})e+0iw@VxvPeih}Jq>UIYMJcS)+UenB_{ST+vBlj1;x^*$(&tnCfeW3b* z$eh#y#;<@KqY_BKk->gZ{(hU{Q7i-}p6@cQ2DGNR!NA zNfr(m2J4KD6?s&AhDe*pTLn({m>C``E#uHExFgzjy2dX0idf%y2exp!cv_1g;nLW*3+S~^!3O&v$-@9c}t!iLNIZFKWAuur9j3An4?1BsX223kBd zkUVQ@@;apD@?^A^5XGq*K5fkzp=C+|Pg(NWOZN})-AlP+q4Q!>fB1z5Y*8%L5u<); zcmUS6pD~*z5vm9mpdg#B{6?5L@j1So>8aeXCy|1|IVJI0!1aRd_9F-l9bsRurVGwo zEqMImRojd=<7g2(eaJY`$7G7b-r{Y@oZsat0PGtkPn*mYf*Tu9dT;R>*HP{gYyjf% zx~l&m!-{llXdLbJG*eU78gQRL9Wr!!J9u%5cziADJ4BLM}`B5dTHHm8b={vi8SpTY_VddYR>y72)ee!~XHA068{MpjK*x)$n zF%6{G6PN*|i(S}>@{<||9!J0VI+iduh|IYgj{d$Qms@m(Y!{sxV}htLY2Wwo*e%R; z%x10Id*Sx2EPS6to0fkmXWpEj44BgiOlGE4YzBcX&Az`$oVhsCcseWc1vp13VM;m)W>K6Fn&! zzOEz&piy_&8K7<>undA;=gQ9gcv@@~ ze%pUkmX-XkLTpe@vMGr^BuI7a0iL!Dr^N zEj|R&6;_^W5y7!z79Wf(4+6Grn>n*+<#yDI1ABGZ3Y2cbtq9;{1HC%L`lm_ECZC_c zzZ~P}caB7*Sh1yH?4@4738Kt2fetwqlat?N5j`YfsXU% zL67DVv9H>PzPyXu2sOi@6w|NgWMkw&s3wyzb=w#e!ynE9>%9TLBb4Q}a|eGu<8De z$vDUmJ0c4d`V6XK#w)^-ZZG_q$XLF=&0Dr&siBmVWIJ;j0N%4p_$M4E*9G{Vig~$? zIP}Y8@?XPFp>)zTJKhr9{=>_opTJs~9G^K#v}*=1K1Gu2zgxDAGSr0o&k)^Li8Us# z(tLPIf5>`s%!e!fatf>4ax^!}i8{nyJf2!$-B2BR1cQD4r_cXmoEv&HBT%snezX^? z0Vnd`uQY(54rysq3VFpC!0vss!=b~RaaGu+XMEO1)V#r&oJ%gLJ``e#G`;}dgQ6y{ zTm*l{!~68h$GY}u;BnS%Kz-;y!}lg%_Ij)jyv>uKM)U0{wXQJuSM0VhPSJWO--af- zi=du`L&x>?bOrX)2K(6`QVvy$M&=+>`8n*DR8sClW=rN6hdm+uJug?x4# zb=)@tmM48+fA`lQw>#9)6`0N_8Fibu-=tejom&ry=#e5t28|U8M4pX@Req*dWxvDI zgEzn+6SRqQ!Jn$0K$VK_3R!Dp`mXyTDRd!@a5NkRLF3jdM#k&872hn-34wbC4?Rum zrfbsZfX)H70?o%Tu*9NF6#OOy_@SMGr%2cgI~OtxT@__;4?HH|HR7ZO*mw$E4Wd_G z#gFn2I!(^eL0d+|Za{EIN^5jO-`<+c3)|sweBOx{(VuMdqR^$2sEJ+?!B+7q})g=sQ!-eCaokbkqidAG~_eQ{TysMP&@@6+EJ_$+2i zACIp?lsNcVoZ|_i=Ji5~J**F@Y^yd2X1=T`W30hb_QK#MEwB|19fDqK^?}hi_c1woNdZ3*u9Qj>5tNi)N5Gz+VHM>aXMST!C_DH)QoM4`pZIPe&W} zRM8PZS3EW6-biryMQi?ELe#ji^sz__d$&_{O38Ux7br;Z1Si2j@;L zQ@C=VjQO;>kq6jWUVX$UG+PO5way;$cX4X8zi7j!fUZC~o@7`4K~!iN_9hrcb-JF- z#V=Ru$>E!8bb@d03qCUPSjC$0%aE)LFu=nHMyWpgbyD;5q*27ggFohnga#bGK2NhD z%Nu+Fpvf^0ARk72^LamVd3AiwW@r@@WXr%*@^(}%!NUlJZcp=F_n;T`fwH-*csO&% zlceed%kS{Q09UV-$ssA~no6$wlC=Qy@$JLR{M8tt6{x(pT=v+p!>8bURqNJ}BLzHo z2a3Snd~i8amtA5Zo+{aL{*>{#^ckj>+FhyY;{3mB(e?mlUaPXdo!8U#Ue9VPz`%H6 zQ+5!!i3?h7{9BaETC7v?;ar;2VG{WArCj47{zpzZHc%CEVCc-X(V3e(QlKcf}~7J(j&t@bD| zz+gds618GZ=m?&`7FK{wKm#pSY&a?X=}ML&XZ7KM&8QA*#uL6SG7Q>qakZnJc}d;4 z0VA}qVvYm6#^F)NghR2zg36`T6xc3q_V1q+YA=-OjTf?%>tcl}pfL-rQm+O$k6x(~ zi}og^q!nFkyh$w1$crk8Z5Wo~is9%7N$UqyDhl#IFCe47_o1U29 zJePu!I{4=mpkhBA_>n$RvBS6=4~%U=oAo=$fR{`&oEmtVkmUvK7&UoAr-ImVB&)qy zE}(sh^QzMejsCXW$`?!gmks%$c&c{CxB$Qov%K)Z6A$2o2QoHwMuD^GP7A=KV;DB= zE37CftHenZ4;4EYXnq+OR>tqD;#65Mu3bBFQDPO5JCEc;;E?S}=(a}Gvg8pIkakiy zaDPOxHhc-m)vs(RBg7dd?kao0K?`?H3o6c~5NShdEWGU}Gn=noZmDEMcx3vEaBk`} z<+rwj=4!S$sMZ#Tb*p&xvTSE#r^#7qv$PCE-+|ZGMtKKb;h2TdvJzV| zZ~qQR887uBW`?4H%n0$IQ&217ORL{K-hB5mByPN@br7r|MAd<^A#I47D$sG`Eu}n% z0aFEJ-2bRlqx1en${}X$qRobnKi$oFIt9*k%Vmrn7}^Y(TK2d5DBdiaIq%^?_6`Vs zNkroc^Jp4d#*icVkDa-F>wLSE3!a~{w;)|EfZwEH1=o+8AJ6x_U7#J?27bJqTB;W8 zhqL=8jG^G*BTJumBWVV@b^K+%pJY{?d)r1LBN2P!o6dC-=_>{3NE*|Z`dW&zJO2-&F9LU9GuQoyX|Lsu0 zwKxGr^~Jb;>(%^V@1XW^U8V9#Lfu%!rcNt5TN%2$U%ZcXoWZWVD_ilh@cW~H=Txra z&I-PR74(X|r(Zdaw#IO}QmFNv{0O0cumG+D5V?+00bxLx$-TA*ugW7b2Rt9OW6j6x zmlMaIgv;?v6m_5-u|vS!{Ioz;wsL^2vtSP^KWExH3 zBbVkEoHbn)e>%2rc^lR}A@TgXU<)_e!S!i>o*%X&2ksRv0IcP;%(#F&L< z$Xh?D1*Pb#{mo9f*fLd-5#-Uz?7;in@78`_@Z=Jx7)hNcX??dM_>Bhwj!8ZZ**F>A zhLE^a1X5-4zJNKPqun$rKTomD2`p(*(Kccq#}pP|rM2L; z(PIfi2zwfR;CZc!W2u)O1kljO*4Rbbv(oOg@Fnz^>fWpzVO{x&5T&A!(%Hf;l@PAj zL8;)>-MBNW=&BqXC{hy1{c|T@0r05tT}~V=w`X8Gt)6!MTe#V|p5xkZ_UVpe>`Ja< zsN>-@_?DWxS3TOHn$1OuFm8YMw|d^naZVi;EGTDq*X~4lN408|T-;3%y9>QHFPKq( zxykKsA03;MV&g2_w{vO28xQ#zn~lhy&q&&`%ebrC<@(=Fr*vw{DAi+@IG-hP&~(7c z6#Tg6A7jaZT?SsnU7+% z5Cx+L7ce-cAOK4iU`UR_)IQL8-B`{@nfe z09sTvgY0$Ot6lLEip!m8;ey|rC44diWSwdT)D5hFHDFIReKS1*D=M>->h~D~_XqnO zy<`S~ZuAI(XEGgB&Dh~-;W8eeH?9pHzPx=Uf02j(1xW+2h41A*#u&PYaR{eH|6;s z@`lq@$NOTJU>}m=%Y_Q%+nUk^f9L;2YS10B=$2MT3>WK2gJ=wdGF(wDCdW3J5wRv8 zePwn}y=f>Pzh3I87VNaLu=hg{n97OU@L8PjB_^buK{Zukln*2;_DCGdKH?+$YPbh0 zMR4>U_@In0IbTXsL6vO**m$ae#zn|3^X^}eJqDF}5x*uxFqj=R zhT=DI<_tv-#cbUipiP~p=?AqAqDc=u_@A*Xx=NUW8nATVpmo7}5I#dR_lW+`A^1Wl zCn_=E)GrrmXU^nb=WA>vp=wsGQ8{o!0buu90{xFa(V$(G$OEAQa@f<2NptWAUPs2d8!Auk{9e=7y!}!c=#G1dLh+(ch}n0ZKu{C23n59R*!pV zGop#4lyV^d1oJ_E=KDc{USJX!O|N4ksi}{#|05HwGD=VSJL8{wdbDfEUEySc zSUxzNpnZ`GmYR=x7UyKX6mzxZx5=7Q*d3_h(7X;x$s8k?a6Z!7#P)(Z^|OTKbZz2E zwLDY_7pKC4;t&U|lmUztA3Y&E$6UQQF$>Nf=3#dBjI-ZD&*9SZ&Bq@ImW))8C&Q9t zZOJl#iULX+-Jpw~Fc|9=LCYJ^cVNL`ak1K{0k{&^Z@irMFVIMJGg;o`ez*Cr$<6YT znz%bu0b<}+tG?S>JW?_$6P^A5aUb|T_cDFH8bwYY3%NA5 zdC(?a5CAnm%D;uFYC3~y(Ivi__o#4eSA(p49$6f^SSLG)zgEkcNodywd(XjgYJYqo zuak!-u=exV-YXLH0xAidq?Q2nNojfbSNC_diLD^?e*ndU@+}Gg({F8M%5aUq7ybBq)0t1KT|U&xcDmPoO10*{+?U`^)7LIQ)= zk|v`Ucq*fHWc95^6b>mb%6J9v7XPx6gz_&7X4FSdCgZ>7zxa6jrmO2|bZ0j;dSO7v z*RXPyy=Dzf7_>*uF`Jp+Y}pt4OEcNB_09Rp+uFAXLcLFDg_uW?vmK@q!LuO@2bPX` z`{&C8!S1-wKfU8~>ocu*vh1?|c?&BhIG5-nj2m&Y7YvB|X|<2}f^kfPZ$Sx%D_pm+ zs^~+|SMVb@iPJth2xr(B0lS7~T zU869Qx?dxu79qOOe5;-hBY+H5(%Bks0y6o%6ElsW4b!IeDA~xeT`rc;KSsM+mv*5_ z;)gB*b#FGQ?UkgXa1RxF{;a?-JJ_lXGV-uYuw3JBJD&VFMz%p zSTZHI+&86==*RTQ4G@AbB#@c;! zBdq5V=!vZh25Xcv0k?$jGCKpMZB~=;x`a`}j;~b_za_kC+wj-b#_1a1gwKOR!F#&F zh5Fss9b2Kvsy}jg#QHcDpYCM3!-VIAjD}<#9HRMzA|t5TfvJZlSpHbS!7{Mh3|V)h z=qLB?AYNl1Kg=#W8JOVOLd9R^pi`xJ{GeWl9P*oWh2UB}DSlS+KG1K4L7(?C zS6?0zx1cG-Gw48dM{+%F@uJL+lDO{@)uI?S&}~~};JTn{>)bpkHI2Yihg~c{Ic~@d z^ba>XULSXMRXkyl_b#z}qi5f4$^3^Xz8W`-b;gOC2hbxm@AC@>qr9NeHpQ`34TO3y zIV9{~QAnWu0kP0h0E`6l8j=$O#_NIwGi-j3>F0eu>GpJN3x!)r8>Nvg&VIsDG`NazDbG^E?ZzoanzA!xdqehUGI%Yy0cph<%+4Ik>I z)Q=kihk6L^|BW9qa@}oD?X2~V+~}-OD0!XS>)0PZ-!EveC~$g9c|tWvw1t4hfIK_> zO`spheLGT?4AIjB`M(~nZoImIV*~cyK&oZM1I{ag#hSJPF_!SMY`x{r-=$%d zW!pUO(09-IZ%X*R+`!WSG{Secv)($|Q=l*ga}lZ&Ex0u;nPAgfe4| znmya73cGr&`c}Cf+KXOx70aBqski)--?p@j_wS>Wjl2JS?&UsBdRKam+U6+k=Wle7 z&DbXG<^Ca)t9!i4&kyH>8Z~X3iD=-%%Q5}NZ3BG@veaS%gQU&qyW>#)=rEma;LA52 zMS@+~HyoJe7)%G@dwq}EnA!OD>{)6G*=`#gmf?-Zjjd<*Aejb}gmG|m$5KvheAXXr zO9}C~hYL4SEu8Cd514Pz!mH&N%XtA`& zmOZ!h3a}knCu9WI?p7>Fx2w6)6Mt};!4r&r3FM*PCjT2MUmE#H>F)2Za+;X`Z^}F! zzn3QCTl_GEtQCzA=wn>lAR9o@KM;~Ext%#)|KiJpXEQIWWNtvI^5#buJ)s66ODClU z5X96GV8aJag(~>qB=A=%WV=0azO1Na-X}i&UVFg7OfweosB-z#f#Hv!Io&RNZ^9cZ z{xdT)yF^y0@|&apq!3sTt_=KcTv5(0;ljYKO#@E^!TM7JCmN zJk9VKH|uIs>{9E2F&+XxnGgr66H-6D%D+_;gEm+iL8p%b3z`iNGFutC^k?lj?^%FW zFr;;p5%2+=C3m>HIuoa*@xM@m#qY9a2?1>+2Rft$tJzeh>4wz{{<6PZ)URfnoL6wJ zN2}K|*!?oKWIRgQ1x;bXh3|iKShs30pF)#JO+Es9`ZouiEtkqkeRqQ1)-!jB_PH9n ziky4`IltEgVw88jy@`eUgIZ@&6u%lj$xyO-WkTR7wL~s;5xaMRN}G@We?<0K9tCGv zdA;TE&sb5lj)C$cuSfoGj&nL=f3lb^5X}M$LxVwgwfA(lnS}ikFU#Piiss`iFN(-jN!6Z zBa7+>vaa<{)L(0a12nbDbDwr0s-;#61L_XphznRhSEl)BEU8uZe!^9DfMK10-2Eoa zluR;j9biX;)va;G5l8%37(2j)@%ZR{;Ap{rj(GBF8+$hNcf$ckE$B^VQU^dBEk0>^ zZ&e`{9hF4JA%pdYnuix20>nOJ8^Dk6WeO&?w>_^1(ay5w@*%Q-U4&<+kEDe#GsCKJd3i-0#o0>x}SgcF_E5zKAUFi1TahbXXVI zeUo``ycNwfcajIXP|}4pW+31}y03Myr2N_;-V0qO-QfRS;P5n_-iS#E>OZ|Xm-_GH zVl}4cS^~b}zTiQuc$&A{|1C=ZX99{LV%#J*dqUlrahzv^(Tfq8EC^qHnl(7hY~zQ0 zl#`O#{XlgVi$5d53md-;@tnb{$J!QRWsfSf_%Xu zdCHv0gV4qxBc@!}=;im})E&)`4kUb~CgkCUHb5B6lR&-roYb4} z__c5Ndw?xMH;5ii`dGX55-!TSp6@d=;r3`0D;(G}0r1WnZTel)8KI=w7EthIxota; zC!<%gT7NK71<2A7!#Ouvf?9yO2a$+#%J%FM#ps6@tM<`eGPM7q%hjRP>PMtWD-kPgWqZ2V#QG2+OL@RZ18RI0^Y+lt*EON>a>$- z0d!mrJD=?RJf%X(q7opklR&Hd^k&%#E?@=1C&2ekX-URBU@16{x`I($-8yzOe#TW; zaZd4LmYz+^{pMkXmAiC!FJM`J!^!BiP`Al#dcn@mvpjX=>`7qE>|P1ZViVLR1F33A zCbT?L<*TY2*Ho~|Wy}`igm5gb+C=~iWA?6Im2D6#Sj``z5#GHzn)?N?5+aNqI6}E6 zo5=>dLx~0F&TxReC~6e$T1I3G=H`E=9G>Tqzd<{SH!yDL9S+By`<7wi!fG_2$3r1k(u{!p@T0Irr6ukly)rC@ z?lJq$FLp`t5ex)Ih@7mpY?r6n5@0Qlahy2!FSZ*ETK0=FHPVEz+=Dao(fbWZ@wel0 zX^&eSHUkg~DzICOxBdCI@#Lc6dLS_YK#C9boIt~csCB0^(`FiNH=wfB@+FXB$e*Fd z*rc+ zP6KS3!9LFU)m*X%igMP2h3HWSpXxhou>M@7KAyGsZSv}Y8x0MkkC1H5&ubcZ{Ig}N zF1J=pHy^3Ugd;T@+S8e}@M7E#hU0@#{Gs5J1M3Y-3xI4!<1$M!DKuonQ2NQUR_v<^ zY)fSEKSP;M0hE@`0P}bFth|Wec|qL)gWv%OI68jc=~WmRl;kLp#?tlglZ3 zg;v zrlg%_@5BQLdU}ZK2wGt(ReO5ox50t-$*14~Grw{9ZHuh(}V}e?hA9zo5$&bveB%P>unnX> zZA^@eYyI>T9e1#W*+@t2=;ao>GfYJx**=Uc$i8GI9@K` zd68oXObBAIVA{`g3Y$cC+R_L3&#}t?ol%2|fm5>XB-%#F8s0{0<4nQ0L?VGP$Uln3 zS1Wb8*Ndf?k6bVtCaGXt{#l@7CnJ4X(*_cnStHgtD}@vsw+FxKC1~-!f2+1wLHUW^ zFt_Hq=(<2@9b|nuJ$$#Ya?R-TK_-JQKZx@-R`xi`D_?pRf`v-XE-|`jWx&YqKQ{Uj5&7J zBK6zGO!K&U=DBEGm`{HO#dJ)sLWtZ-EeP+sI5mr}rjH_%$Ea@TZ$ZMYn`%nbhiF(C zzLo}bK7FD6bgyP{fMm#a_LHTF^-i&(@o#PJIyorD3~(B z2R3wk{yvv5QkH8n1a+aXkt|cs%2N3xz#AFk2}cbexQS)be4yNLgZ<|?i(PPh3)IR< zboara4?S}=(zRcU>}pLJ>OlPY1y?m6AFIKtD&Lr|RnX0Bck@1rr9S#u*3RXmbPEil zrT9BZMbE_8$}$esCKi3Z+ATe1BZnHjU_Nn%;x|y=j@~ot8222A#1>*Lk~mGig1%JiIK@3t%V~WaD&Q{YLjjc=lTX&k*s_ zj^2hjOu3i=B2s#a&?f0vT8WFiq^|+}g6=dVb#9bgi;K;Da2Y%MoA@mLU#T_O5fx3( z0zjC-x!Qp=ja|VdAfFf?wC1T)XBwAm$($y69GjlFHke8>HBM*oXq?~*BXwca<95J7 zg5CPvK7iKD1sNDmoZiN-MGa!U53mcdeUJ>%ZRmi2dp}R7Nj_Ww^}AueVyDX z=~oSX4x28?&4*7`yZ4AzKXBpr?a7%KsKpEjN`f42l4JBWwGp7w&smU(;&nbYe1)011^CI3gEu5I)C2wG^DFzNHFP!mrB z@G^njr`TmuVaKhqoCRF!X)js|)-3LYT2Qy3iO8{Qan8RfrAYh4z>nmt+{-VxqgXIZ zo+K+D!9}$fQ^1~ujy)7>W;hz$RzOeEYTV>fGB9xdWb$kZW`~68^+{l@vytNi0n32e1<35#S%U%}Bj)kIR}DrqoyaS= zE58(rK1s@M<zI5V!uBuyQpWpVf*`aGjvE#nmW)(L-DBhlIKEl0@ zHDy;tP_?jCC0(AELxgzMjh$x<8OVG<1!Nc!(xm{O1xY=D-=FNCxoR= z8Y)_fDr)>HBC;xius_ZFIH+|eJm>#9$^))YzEh_KB$%Ow)(ag-%Tx1l))w>5tM@}A%h#pPkjV2W!aJ7@(6H1_WZ4b$5>^}UQo{!(c6Uhnbpmzz_=!!tjmc6l(1yCZ ze2*l?QY)!naK~7xMv9{w&k~u+tlK#r;3?4b%Z@MY2%#$4A$oTTs{O*T54$*9T27r? zWTDGByo6c;z-GFP1BEewTRbpG=%yRT^ndgYy&(7 zn2Za{z#2VMPm1JAWR>n#l#VT&&BeSuv7e0DvsP<&kjBCt{tIH+QN!Cl3f6&jKysCS zRgfgk6HOAL0+2izfPSB>u{BKb0pu#s#xY+7vNvFHDp6k(?AdfIbg_TmNHzRhzwXZl zH_^Mvn=h#n0QEqW1^?G%4p}!?MJ`|ud2Rtnf&H~URKO>Rol3Zl`#fgz$!P%h=zFd} zN=4rI(m+s)*_~-BkzJ@!U--QFM<^^EgQREArg&#t8(%K!FT^q3 zRZD}(2mb`mo?}E8U;P9bSkC$yFM{ok`&cEsF*M|&FXFb1Zur++eU`QBFDi534e=oD zY(UT|y8*N(Zv0Di`3tw1fMt1eh)!Nbzo9tIsEd{RqfQd=ro8u^s*Tu>d&d;nR zuKzNC4rbgqkM7|0q80AmV;tyhoY|%Fw}q;0ule@4+4i^&I75bw+s$VOn;4u0Kt_dQ z@3-xWZkf2))b8|W{WgARkmr4P{SK^TBu|0Nnux zQ{U&S1ZV!>NBt6}$979tJRHOO4`yME}1P{uFDG{SkW&-m+3tCZ06|Wr09L= z>J4e_9;}d$Vh!jKlT9gVb6-pgZO9YE{=Drnn~_1y#XUw-NiH3xD&er=6L7=FfoMbG zLI@9bt)KJr15KEouPuvREYpUc?P>~Y^Z(ApX?!6i=A8__qx*{vyVsN3Rj&F{qsJRs zbvuTNvEfhO>=Vr=zu#pvmuTE5L6(fjk;?s&yi~yAU=IQV(ipy`{!}hezovtca=c{U42S6|5)Slt+S%TjHfw!A*e0kNKZM3(QklwdApwc(t z-i9IAlt9Aw);D5{RxLE?#H#U0j3(pyA68zY>Ffs%GsEL|8-VQ>mTG&&#;v*Z1lDz3@|o8OwALc0bnhUwC{oJloWlaEdGKz z#}+2DHatX(HUubv2T5WMLYx_3=Qhvn)v-MOmjYJ0!_Y5kfG`O88U91o$LDM<<9+RoHz5_aoe@3Xv%5AomY$gW<5JnrJ-KBGaqq%=)ouSeAT z5g8SxKwNd-ua#bgmERRS;tT8knZyb8i@w4QEH?1c{iinh4tX~`rk0GKp+JmF3+rVu zKaF~xJ^|^8U|i8=u4Q#^LN3_4OX#s zshg>q&2M9B0CNMCyaCGBpX)!sTuuqdhAEvY5O;%ZfYtz7nv*X>r4f}KJC#wOedp2>m>UTB%nkF(=x(cVm``zlA z)o*3(tkM+VfABqTBkJ;hct87;+=g5YjUd|YV@lwe{%f0eITawLBmsl^E#=dQ(PINBUoOnSZE=o z?SB98>c28f5pH7hL$9h`XBa;!jwEOUo^mU|-3a+*VsXxT@L;HT{vJlVlMW1oeD;-2 zu--xY|0~Jt(G$R3J@u*`T;_64Gx_NBwKnV-6I|aICx2+b<-@_=lJ&4UW&FSKM;U`Y z8?I`gm*0!*I+Pc+?O4ZXh^yGWh=DPoJqiQI8<$(n3v?@Wyx5KSLsVk7m%a3wqndX| zj95&H7vO$8fZ-^gLO8Yub1j1>uXeyf5X|{kDIq~gRi8^YL}#)p;5c@_+PROaT47Pb zk*@iulWN@q-x|<86u{c#&eu=76$sGht$a1PU{hR#-D$W#k7x>*Shy=)U&Q}q6TFu- zZEuT-bBQ@vrE13UWDJPbig<5K>ke&EXBMC6qI{x!QQ0vLr;rM>ZKn|!(9z)l+DeG+ z$2e=T=OUth>rWql>0ci@^i#vF4aihD!GEu1R(@q3D+=C)!T+*M;V1WE-5=sFMKJWr ze!CeJlGx8z>?nVsc%23?XWm#g+=6sO$yGXia2ZwbZaS=)MSqf5QKL)&OE1d+c!7qz z1v@-UN^ZNs@e1-+Zm@Bzp+&;M%<2?oGP=h|RyS;htr|Bqz4A**F2^~S!^OM8aXTT{ zz5|L4q21HZtk8*0J3_a(211Dsm$n8JmSADm*MkUgkIuxDM!g_^r5(&C?5}3rH15ZXKZUF*>c6 zz_4I!0~<+;!e$6rt&i@qbL_B!U~D#Z0(pFdw2ce~HpyBaL*M@0;|HJn_p^Y_(I(hK;B!qz>J3trYstaicb{SnGQEo- zfyg{_ukc}=&Dk!=I&Ha}FYq)eiDN?9G!}GfFJ8;f0TL#!NW|G-tL;#Z=%${M5AD{Qx|sZLclnzv)hMWJWDZ0m{l%;3GaYo|0Jk- z!>{Pw>_Gkju@ zgR}agp9`PzKk5`HVd>bzHkQ^%7F8I#ep~d{o(vUc1+;GY)Y>{N&YJF%NY`se)eR=X zxC&2l4rFGHcT$VhIDvv7GGX3)I-Hu`^_x8R?d6?qxw~RA{Z{-J93jYj7(&0^6+9`{ zY`u%~OoNY-P+x@{JK)kWnV$w2aHSLN^?qadKKZehKyyI18uM$M{}}>$z7yOgjjKRl zWuRjTr)hv0sHAsWhDdQ@u19Ar7KzW-I|X5)e0VxQgcEV%6_YW=fcgl`dz%adc`}!3 zM=&}|DqOTTq+lJEPX*HaN74{r1`-6xG~eCeA{P|#a%!oNaYX|tnf#wa+imJQg8v8+ zO7S@w|~P zXOTerXYsu@7e}Ej4fvs27ltK1Sp*UXyO<@PvZ&3 z-(8_a+Db{@e0j@5%$58vhVuj@@)7EC%J3|GvCm2%rx2r#6gy#0BG#w~P; zLm*_{e>gUVkvP*Ctc37YmTj0TjB!{98KztOS#gsni>I-~kEV=-Rz|nqyeKXN)hP>I zVMOMlNDV7wBt8jjeVcTzR@cltDreMB+Ya87%vi(_iM<#b+zj@KmfZXnFgE=}I#x0v z{l(8HNuji>4epl*^W&^S5KAm55UW)g<;Oe9F3|9pwYnf~@xcfL-H%R~ZcOg9D*B1o z_?(IOz~Kpl50BG)HySR0nNRO@rgMvHBvp6K1q(lFFUsvl3bclb=b`MUk$+=_?2992 z?lo6Bi!>Oqat$c9LCF+Jfbg8XwCtJ_BRE%yuu&&k^Ca~`zjllP6Q?R&A)dM5OM{)xAGngV2&uUH@U zy(X|Mgbx+1vs50ic)0Q!NiYwA%492F_lIw(+vm_&pv9sf{z~_HvB;DF>Q!>=T}v+p@1y(5wPGf`3Yl2MhS%?FuyYA^~@@Ft)$p;VkO*HVC3~qZ-JpH9 zJhZ?ZLG+hRLKRfV<_JzpMD`zyRjR8gpB1X4OdmSMOIbHd%@&F9t)kn(aJ51C+v)u9 zJ~*~gdLLE4VN<5Xg;ra&{hW*SQPG8s;V+(VgK<83EC*Q}VMC#h3@f!6@am81^cWqj zl&5yWeAnRYW+XeS&p*&6`jXM9l>*fiGW~Ax>N8EZR?mqCItl2e*=y>*$BKUNF17=U zl=R%fC|pj%qQ#*f(Z%EuSlY(TVacke;j&CX#p8p+%!Mx09ud`UZ&!h;4F=cfn~!+5 z-m^H5^vKQrW!b$CH^I2bFV_+H(DR81_#7|ke3e7BxffXf zpfDgA8;qblqs_^ba)7<=D0AiIwz9F*oO*pQxeTtSypjl!*V$M{vceP`&E2#DGbHAp_Teesx zH5s(%Aj@a-*BfQ^dXg@6t65XqFH6ghtSop4UbfeIzS#uCCPranQ=iFWloga^tJ7pf zLx*HvfZRw6$_&1poBMdD(>_&Z{aPEC6afmBfKJXeo4aQDP0LS6arqn^;dX(L$L`!^ z^keb@p6X*K*rPA7+E2NX{jJJd=hX{;M+eKzWPNxOT%xacg01h$)q35GV5&8~ zKa#6ogfRtUD5|47G%)u+c=%pnI{`U&shR+FJ{L&pe{D2-KcQTw2jg-dtqgirl%B8% z>^uaLU#Xy8b4IRU{QumPpu?@p>jzNaY^<9HQ9$)CFI2cuU*B^aI_O+hkWiA?O9d#f zv?!^KN~#6G$MDY(S^$=)SZP+ryPb6Y=-rH}pTN(N7WbS5F<<^f@?d9a@xE8Ifr`d& zB;3%)4A3kOPYKo9jwvFkZjWS_U$M*D(l$GO${(Mj22dzFG84`M0W5@8ft-rb;1ep0 z4Ua|Q17ncV!oYv0Kg5ZFRAD`0lnb`|hvIEBo4y$R3i-`4QgI0?kWl2_ zXhaM`R; zyZttiXA|ImIJ?(TM=uY(khSjAp>J!mI8~Fx9Q{8M&9{g}Dp@P!K;MBJkzdH^idAs_ zb%Lvq7QxW}ukgyJbE_sms!tQQb zKW>XN&j(3k3>KS&{bl=Nxg|B13cD)Mi3C?2B*bAP&L>S9Y2EZ9m2ai32XsDY4KEAz zX#bg^c>|TA$luezLKutEp>L{AV%jb?Mb?fT!b@Fi)a!z!{uOi}1(&V3d3j;*-P9B@|u0JY9UMt`r@ve{sYt5gH-F4&06{6Da;=!apzuoL+H{QbZ)N1b@x(_1?N z))9FmS-SZ3V1L1&2RLZvD)}(D@uso;&K%=g_kLDVgB~m>u2q1l*#^ zeFAwIRpjCxPr4k>6H_cy^o=$T=R^iPlgvh@sgzxXjDG$KHqdo2l0R81U-5tJ(r{KE zw7R~w-i=7y&cEm|`dY`vCV{tN6`Yy>QebGo{{pG0zt=?$3@|QHb%)<5|8LfbNhz9h*iTQ5rZs)<6R6AAfg*E&fj~ z48B`dmO4S%l@3M@sgoNj-Q?C8=cRlf4(3x13sID*lUDd(IvWyw{!I<B!0t@!>wNcb{nD|>3645wW{jW)}`DXf|AxN0b`04EoIBMi8R-&Ws)9YO>U*}0_ zBLOlpZacKDN28u{p!5lx*Jvl6pmL#J6SIhkT8 z-ikaPt7eQAqEJ=6T9!TKE)R4-41dWL=>gi4YLkhOl~YNK(}W(=7Rjw@dv4@i=4^F^2Fc~pl#T| zh3Hpt@MJel_`az^Zo^H(CON2dWz|tlYtoE`mkNWhwa)hEtDKywBX|69 zKvCJDV5fmbFv4-lra$V|eW(urSxf@T zkMy|B^?9;D!nH#ao7w@g^7{qZ>WV$k%9+8++kYQ=&=)3?+u6_u#qMob)`6J^+o2`a z2U71*oY8D|K5#sb$cu(Xe|pT)D7rfrVOnY@W8yelXn8z$IMN37^B4_Myj1jIqNZ%~ ze4IC?6%*8b(ik|y?h}O4Q%)n-jCo7#6SC5 zg!|WRl3u9LWr8`GQogm1$^-G{t$`4!(I%qTCCv%_w$Vqb^6im%R5n8#Mr6oRmeWzj z>lhFnuJCe2SYqk>6RrSnsA;uok>K$}mhr5D8pvm4cRMd}bOF|Ut1}8ozQS|{n!f51 z#K-Lz|3beLrAl=*B|V1y*$I3EU)jjG`G8NBWvG~_t! zpKAlj6o~%h-v!b;>q*QO7bSoMBArChW~!gzZ~PvWggmepagQBtPXZb~YbcZ9i^5OQ zt7UE#o53v7#B6YNNCO{e4xBPIp@!&m#n`F+b@RKds>fK*vn9gaEwFhL2pyH4*q0cc zD#f>Y0}6hdj8THX2X^{anSn@PUT z^QYr=1G*g8nfs-`AxZJ4m3pW9jUJWAb62tLJg$;!D?8a~l3E3Skrv!;w1dXB1~R=B z8LT1K>g)z@F}`FzFJ24m?Fq;?ef>#C+Wbh>HfUvd8E}0H9 z)aGJt3$%Ni_eyG8^?EvAaw@H0$I^)SpmL{)=q){>F!r2{`*+n-T%?=SO4q&lKPV<3 zHtEVcwB){-cnlg_9@g2}O@2!C$|l77_@9Go!xk{G|2zx}1NgOtiN(hPKjv-JZ5Z2n zWuq)+SBv2Ok1xX3QU#qGoM?Eqki_Plm_y59dmoaqey#pj;gG4aJY;OlvDlX(izc;Q zar*VUN#en)WVkdf;5d>8Y z9l1LY8tR)Qmp#P!M`64jFJgq-ao524ah47Mbe3!p_2kPgUjY0}Q1>QUbki@|Fw%2) z_B0dfyF>jV1v|b!ZV1n^odzupFe`P~uRq=&YGZ)wfurX(1LvW9WWH<9TB%*e4ogj(3?m0cR2R}{9>a4@s?lp&(PYum(fnnCLB+ADW0KIi-@)#nnhkr$A_@y z!MD9^!>Dyt#8DLxUSknGprU&6bl>1F@ds zGanE*dBR`l63+lgOmkd`oGktjcKPj|fU-?iQA4>S4bb|zl)q`OOr?)^+C!C%#6H4#E|*7im4@7{iWWdQCO`BR$#9eO=Eq1IqB5?$aG?J-u@ z;Z~#NuJk4a!}N*Cf83;+MB6(av}qS>rA3VW@C}M<`Q&8}Y;*nbm3QU?f*g#?N#U`t z(oq#a_#iN&I*Ho^be9IFt{SUB&0W1@)EHAP&jse?+!;(>^+5jwtVlGlEWOZc0~*}p z#(^ICrS}{jH8wbqiPVBvm-F4(4`I;{24QafU4^!R034*HnFJ5GTF{@u1)&JdU|ZRV ziGP2{ffch|E1(mF@pWnU?HEdM9yQS`^FVwox%_nzf=uj_H4?ajwP*{^RA-s>9*0Dg zAUFPyDq6eyIG#z?$_dgU2Q5)haW*o&A#G9%aGSM(ywl;0M37ay`dvUt`>I`3k{^!Z zi8{7ngKRT>XMW8Uf1V)eVMkw1g`(lsGhnL|Gv3nQgWZ!azavlK%TWR)!B)jr+~{dU zA}(87wb5$@)<)QX?LGM1#cD2HJz$-o1SPXB@5t_l_pe%$z8M(u@)E$jd_pKk270{= zwo`99&XNFy+68wze^|yhD6H2*M-TsQ>df++?Kr0i)qIduRh|y{KvkAzZPiLcdWH7l%L&wwFyt($0_Os z`ThGGkJ>mj??zD9Y6pCO3pY;IpQ)0@U(@;t<@w`3q^qx$h6#XK0{zTfKf@hTu8toq z@Wy-f)K`ZDxo*i!y7!)&jxTv|1w6DS&H{@RWK?)&PdI1(*orW2n)Mm@?o+4}D;|Xp z^9f%5*0=)3Pc)Ui5?API^j)FO2P!_#9+`Y2g`c>wBN!cK)@1Wy3O+`hWj&-k!KR|m zG*HiMW|qe+5Qu|{=1 z!tm{`%$TP@ikOU=GP0gLYg_QCT72l=qZ&-=FMc{G7t6Ce&QD#a3cz!*bhl*C2VYsm ze%Imml|i?A!^Qh&q?>9#p44}PyfHwpXU09QwibU1?pD+^@H;Y@%mz(#n*X6OrW5kB z-}BpXweXsGuF~ZaeYYVab;AX|XVsj4liE#<`dGLf#b`6w+sUiu$@bU%#lEmQtY=_2 ze9j4?pDn90WIG#WgezFErbq6xG^z{oXUgxzBLs1mjH zA+I3>1Q|begS8@k>&4KL&nVyB^jaimW!%v$Q~DYq;B@-c)WFD^bBVj0-)A1^<^_Q0 z{R7c$vfz%6B8D0 zbcZh&C=gsotw6rg;X)pSeN$K^T>N!z@=Ufl+16B(n{3=8HA`RnH(mbFLCl&+t8fjRbh|C3INGg6YN z5bBj*u)*>aDXs-kx-|vk8|5|45sd7OSue`eG>HdjtG=}OfjSTj^@ZPLj(WUqC)oK8 zgR|h%slAKRm;Rh}Qq%wSnWsd;q!=dB37{k;soi})+BxMFNEu;Hfuubn%82Vo+$N}7 zLUFvfG3*Msl|BXAnoarFGk8uCE^7IOJL5+UrK;8X>w8npAat2B^QWg9ETdf9Qfd4q z6RxAaxYA@4Gx)J9EGt==_-R$T>&@*Cm%r+pbx4v*PsCyoD92Z0IV2c7&=N;ii6Zsq z_%FOXyt`tx?HnRdwvw;EL{LH4R+1p&RC%D^acb(|OchH}J)_p3yEKixWxa-6P7p9& zA?R04P9MOlQ;!Ze#-cR7jCj#5P$&X6R3x{t!+>&r(m^s*^rpLIoq$Ae+l{*GRryj_ zg5r-Gj0Q^E8`|v-Lb2&76e+K<5uf5?+DQegXTtHml%kDXTHkkD``p;U)Glv2bWN={ zdc_Yc_YqPgGm-m|&LH{taaHh`T98NWJhh2DKlCX_8E*lfq2faxeUrA{^YUHdR(=>& zwL&x7(EYXAHr>YxLC`0iPph1v9Fx#6#0$rmBl&Jh8_KEnw}4FN9$^rs`A&icSz9lk zHnRg;*8y!pn-3kUYC&ASmQC#{#6H9Cw1TN3P!&DlmOa@QA6s{&gFm#tC7Y4?&-BL% zBhQ=Pj6M5a=;Z=6#mIPs9<|CGY_5^gYUbZ~bL9v(#(j4>_$xMx7ARu+ zd3&)V3DipkoFmbL4Xf$LW0csd&iCK*UhXbKvd|>+4OZ}62uILSz5niVpD}}9x1#!y z$AHu`J>+s%6wMiRnnbL4D96gE_QW1gCsc6AP9)Z@k_+2lAaMeTT42<)Re$>;@qLPT zT|AAVjDjUlUBgxutQ_cE^G&$Xco!z`36H;r)~EqhA^i1-6*J2>SS{?#mi(AOHo#*} zpb55U#2f4`w%#G5WcsQ@K(24_D0PnL1VnsG6Sp3i=K`=OQEbB-Gt0Qa=x@p1Z+oQ$ z*EvYcJ<>5a+{eiW@H4!uVCjr~cs2))>SG4Btj{YkPG&U)nguY`u~KWfYcL@zCr;PH z{zd9V_UK&JVDkKfKdyD+UU4y8ikP8S-A(g1lh~+;x%26VX2R&x$Vg~h+XS6YO`jfc zv4`9sq4!c3BV0c-?bC@xL8D$RMv=G(BJ$gn3SJrUR^x-?!(Qz7^UZ`d!yQ#AXIA8x zff(6*8 zbWFH*L|`6?BzriYX5-i9;GpJdhd#@PkvZ5{SPyd!AIUoXBWzzgZ0^A<{a0g6uu8i5 ztSZqK)859pdVA$YkZiOyNjo+l6kELCA>PRECyvCZ8g&kYLgLsY3`H}V7q)lQ9U*V$ znXnE}ET@SkD;ae@o<}RnDeYo5o+G?{kHN}lq+>?J86GDUYl^?P;qgJ<;9AJC*s@Rj zw%Q|_ZRk;Gfm1i4zUV8_w;d0Aox7`Pj&`>x`U+>@vFN_@jW6h2$trhLHe>DKEngt? zOYE>Q!Z=X+a_nW6ZxX8*9_0=-srT?UK9BT4U9iMyp$PxB>H`z-no{HCeB|XaI3dC_ zDfnaW@XCl{HvYgm1~nnzovD?IX(8e@ob0I#qu;MLfVuOAm}2q8%@qk1(X#bw&`m^P z%E&C(csaN-6oLY3C&^%HB4MOpqh4~!5*@Nn3ie-V;LcI>Cae*z^HMID#&a4aOKYRc z($v8x{g~8${9sstd?Gw?T%B=sROgvaAe5OTjicILz7TnEf9_hwwc1j1tdH*v2nAf} z_C5;voFw)a05Vq|8lv)D-KtLd;;1xa`C20tY-E_gGTg>2;8fC$~cG z*LPXEUEqapVdy}1ChH?LfBIsFueD7jmW?JKD9!9sY8FqeugFcG;pcTUzg#PR^lo>U zE&uRfIH}iN4RrHK&eE^muK^7L^tD@rA^J(9XWdaWLWB8Ups9wF70L&uwqx~HsE6ss&pV1}>UVdhy z-@o&21N8>tkb#sd9n6PDA!6VFIq7YV2!}IKu;KH%=>_~FSx0mJ{l%VCBJQd`uPk0SPC^ zg4cyLk~%x-0{h5EyVRU%8xRwrp~zPPxUpFrmoXDPmEht`Q=VBm6GEl(qT z8&K8oVGDMF8o~~E5LF;XaW{kLZ?!EcE_FmC{`#_VHMF2<^Du=Gw^NXV zHiOMJZO6lS<)~Pato#C~fKv((erygy$m9AtpQjn{&v8qIF&i;~Uxcw_Vl5M+_DvK; z34cg`NAN9w1U6TZh?!JbZDHWp5S3lO(KF=6ltcRgW{_yseF-hD#oF zw(Y5)oL)@3W%#J0-WMwu2?BIUy{5f2%O|QYO;`20(=1C&J6#veR97Y zt-fUlB`a=1zLsu(X>hWOl0yW^oH>YVI{j2Th;;nA7R+Nv8=l`p0Y2pI{=L#na# zk5}W1w4|vdRd%cU?c`=eHy`|FQ%P%8tb6uy- zU*NH)l_*j%8SVYrjVN`^u+f*>`|S0jK(M$FGQNZZK{R$qR!YdmPY+4cNk1+YIuor!p2$tfbF9j2;TaX3aX zQYI{emPVQOQEj7nKy6`P!$!jn4P12zyzE7>IbXKy&K`}VCn{)9ndUv^gU)+qo}@$? zGmyp+ArMMlMu17Xt1zFvw*Cuh$jwXF2#Yvj_VR20J{H7O0=4$5Xb(;*m6mlL1H0b2 zY%KtYvAljPO-*uZDnS5)tzPqEK(UlZ5D7*~+cJ#6% z5H=u!Lh;a?O34ilcb;D6EEyh4a|>dqh1Pq(^Y=iX(1eup9x53Kgmop!TJI<$(E`EwdTcB+qJAaUt zi&PRqLS?OZM80{+tP%6?^spqvilygtvIlXhw3%hMaewq(Id@dxtTBvpkziV&%Sx8J zo$rnNR4rr`N94yy*+$EOK4;BTe|zCH1x(`o;sr7m4|Ae2$&s_&V*VZ*)ueav?bi3Z zMU6{-MxEE8nU%5a%!$zK7$NN1!_TGc zmK3z)!b#D3$~%BOph>c_LobV`myRB?a&RkC0JOK)@*KW`VB~nc18+ZSB}Kp**C*nU zmHxc5Z(-i+#(Zxy9^geEOsdqf9ez5lMhq#uj z`4&q7s5jia7l6A{$n3{u|@S}+zt6T z6`^Bmjw$GZfAY&J>!GWY*-y1Mkn~Od36G^RrGY_pAbAL0Hr=vT+8!<5YG(+6CIOF>U3B3B)kPy@1@xZK zD=`RHO)LwfU{g2}8KTNpaD;Zw+_&%6(&|c@&kdjPBj9u(^PE7@#@Nc>9P74P#` zwd#xPppWKt_y%Wz@0J&G{{4?vO=O{l0l58q&tl$%p9BikZ9ZV$b$)Lj-o0Pz+h|Os zb>4TWiDqqNFVQL0@ZT8Wt{kzTTz34_&&R;UvcuUxrwUzLSxdu`5!eO|%3-K5$ND>+ zcuQL2xG>!2fU^R3x89dYK#XIwxjdtyA&zS7xev;~I8_5zL$O?3K>V@N<@cd01i!%V z3&NXN&SG<=w*3V%rURoK-`Fnbl{ho9$isH|YhYiW7OM%Le{3kAF8iK>YmNgFG6n6yDJ>{ZGUtq8uUkHdHr0Tsk>Vy5E+9-v5k`rJ=Q zzHz=uAU`Gg!aa+x={uPddI@~>$RFhQ=MEir%a6r3uGvN~;~^zLWuLR2yC8%IM((w3 zQBs#S8qu#gI&Q>8?R};;{Uif9UKJ#RB929g`+uT*3-~MlO^pzRS0_Z*MaV-R!T-v_ zN1hxv80lr?r3ye0kuLax7vInV6pHxSc8juRkJyK>d7}{2BwN`BjdLa-PJP2e>{{`fQZ^!+m__cNSp3rcK|6Sd zQlu>nVDZd{?v0U^V9jP|`165k0x?bF50PuYiw~|HrLaQLLy*D`x|FLgUt|#*4RN4X zGG0c@yD$TxDfv*Yd_z}HFntG67f@|5p}~U3(ucAw`MI+KiGC`%Vs4uMREg{SSWOVq z4E&d;Tx1iJBDR{|T#0Fp+X~V^j}&_EFtmuHz+|}bCe?j*VPl$stHdb&nueC0?0?~( zHS|@{Sai9#jZ}GxCjZ#`-@_J42H;I^{@fhnTtrJO&7gznIGw+sWUD{ea7p;&#aIh2 z-gg;z16i?1&Fg#1Y!z%^|Gd&rz?80BhA<}8UA0k&HyFdD(*)oAs$_GZzF&f32J1O% zMw~m;51bPigw^~unUzO5ry=@K8X{vpqKv9yY_pJDAAuiZ?h!}jVgHKcFwJbS#a z{k(nkn6E2X5yl<3q!^}Ehy{juErs%NRYWCXk0s*pO}O9r8{K%lUR@vM(*7h88% zP#0{;S57|Fh_td!B~4mOfGlv>VTmj*h#F_G&EzL~y#7zc!w-4t57wzj1Y^D5vzv%o zxAE=PF&0+QaiwHq(XfAizhZpFsuu~;{O)d*V-P`tvy=2Gw|A>E4ybqY?+?`NO0;Wr z*OqjFkADaa2-aN1_v{Q&QM_YN_h}99if$rP70rHnY~5@2Ed!;owU)lNlY5f%XksZ{ zHIC{(qe^U-GJ4+s5V=)#{F8PrOaD+z)}HA{QS1MMuRHEu{jPilNBzEKW@D@(avVr= zYpB54M;h~lY+mYo>i0FQQvs*u!H4SN3meNTlt_2?pMDmegfQ`hGRoWVnBkbt(cPF8$kps68jS?szwryWN{0E-+xIOHLa~d+nS~m| z$1a%_T@0I7D$)zx_e$C_U8#21@00#+(R8HfHj4-$_Q8t3-`*N6u5=uE3G=kuUS2A& zxwQTZj-Y$3VQr};qgHp$`?d^J6XW`i@B4<-28U&(_x!vBapH}IRJ^u-E-?``3H+3sE@(ltp($mD+H}9j= zB1`+xgmgFd{7wt!X1y=gQbYUdD^aR{Rx0w_Td<4z(X~2ILXMtaci3j6VfeVNC!Jwl zYUwjr@XRFqP+%^m(+6jW;o}#^w!QUaQN^U&U~|0faj?!KYt~P%3a`K?{kvZeftg)9 zVF@pe#*RCyyQpI~&%1Jy)BY&A=tXb6%dE1=$EDh|*;l#D58Xc&wC`G@^>2xiWbMOD zx^_rfrwB$DLI`jMpKi)}FPWnd6#S{|mKP!hW4?^KS~z6rAIy&;h}t^2c*AlQc=%X5 zgXTA*3w)#H*NGjpORr70eCQ3?=HAZqtUUQKZgJn@$Jl{UyrzpGFsE) zbydV~>s=h8i>7z&#mAglJ#h4dQ>Z%1UtfIFUK1H>R3YSUr6@7#?Wic!60j}li+D1d zL*jfKEapMO3yAa%b(o*u)qnN2%`_4~O&hl5Ax>f0prI3ssg(QdD3vt8goqeqf`bTY zqEMe1bPl56h?N}6^Qgx^ZdaK}WcN7suXWCSdON)qJ+f0OX}<>rq{cx}Ck(;woz(jx z*fy;hr8~mPG0C_hCfD*>;uDGSAv?+$PYgy(K@cjxhhdLo4Z1KEia@*?Rj(0u<<;}g zuVJlm7P78eDDu7S%lRdq?`XW%(G}Ak%%2I$@9oI|Rxl}rcN-t?{oRcX?OUDtcJ-+# zQ$w)Yg5yKudo``NVUI@^c8Z;AggIh57HaDbrwi-U5xL83Z84N$g%LomjWY3ofEy!x zBWLSaf+zc@7Jp-YBHdradHSkB6ABq^Vylq?Y8Xq>WpsJ{WE;u_Fwp&3rerp;@IEvD?B326J}$_gkF{v z0vrF5$2xvb?$$`c`>%IBW^U>C*VIRQOl&*4Hxb<2SQzj9%r@7jwPmZ4ZJq@*ef&o` zf-dh5hwv{?)2pp{P^`50Ke@RO%e~)gOP->jGbFqLlORq41sezY{&6@@Qh!q)0Wt=2 zkxj>kQ!8>9ayFAQx+r*7ur`vkLKbvur+HBg`3lvOj_Alq?OB;ODd5y977Umj#I{ZOOtIs+U;7pEwDrZgq1Duc?_HNeHNK zKSd{>gq?1CZ$%=$;*KxIG4^KixHtqPmWzU=u-yePN_#bpH@<)V7aKlKadg&|N`F?8{?%o!``OTwN$)?{9jA7O4QS_zjae>Rm zuZ(n(*GjSrK_`3pG-ELfRJhDjJC%$p zeOX$}99c-|(x5$uouAddgb1DOIH-g!WuN<5nXlTva+K}}C|)k=89g(Z&;1%UF&F=# zf^DfS&l)N7s&X68E|{w-f-D4fc1BB9a*4Oy#m}|VW_@!8BS$TwD@b|WZc_Qh-Ek%p zs8(vrUYLHI{CM;+4bQ)>Sywqw!E~TfFFBy6NR9hq%a$FQbBH7sIOP2oH|@oaW+nsC zcAtpCjRVE|4SV0}_P(sE+@z_MKt5mPb;&RAA5JsNH&(mBv&36RjGh6A6iq$yb6$~H zoS?_B`HwG6h{R{uuk%8)II_UqU7$)%MsC@wvzm+#e0d%@n*NUK8Wo11G0=6q%|OoR zn)jj5hwR2Q9E({Jt;e|&!{FCm~P#IRS9`~4rSoHNmumPyCkTqlpi%_TkU=aB+vLlhfkc%}S=Z<~8t~fICpkK zFFA#-D@Wm(9!q1f`Mwr~n9t^^mpNZu41GMH1AQiWhS{l?5jAfmWE-c$17pNL1=^-! z>y;zf9{C{f`O_Hj55oZ72)!uOh!IUpazxXc9e~@K-hjCe2o{l#zYaqM9EtIu;I6V+ zj88RSn58Cx$AE+{uI^nu^;n((Ep%kSj1YLB-dFtIa~&zI5x)!t)@>1`KVzB?gVW^0 zZ_usBUJIX}&Nu&(?+ivzBW%~#`m+5^4JAwN)Ez4}eUsbKlH@Fay z9uPfpCijUzWu3NjJS4OdlU7A~hr{lH>9GBY4E>F;7j?W|`W0v}VO>*DwZ#Zey&3U^ zL$~+YIFN)Qy*;cF`Y!ZiByxa^OMjv=hn6|gG*is2!V?-&;hLqAvlp5nVw&fh*7Ur% zdM<1I&5R!ZCIV5ED)lM<+W~&P;)4wJEA6DK;SXyCGikBP>gCTGDg7&Xq%J|Pn%_>q z-&J0|hz%{rtGMh`p;m1GtU!}Gx$Qd_{*wy8gEMcJS3Xtfv34HDL~Pcfz`=SIK1T-{ z?C*EPH+LMhkA1fhS5v7j zUX0>ezez~CnbLoL>)8qklo)6jZs}-4ILs$O`ixp*@ehcK#53-M=M(-i{REP&ghvFON&kSv<%+5+ywQ;6&i4HrYp>l zgE1mWhY%uG(*~P57tzxBDj1Z9l<-`l=v_-@*+X ziwkd|U(&xVF!x$4d;7NxLB#rO>6pr%KoG{Hgmg z{{3_3>ogIDKO}K)sGyzcTnsaOqW7Hl9<-Hp;1W4SWy4WK5x~!9I8I&>`$JWLsldut? zMhInzsol)M@N~}Rf`wBN7KsEOIeVy0e1q07pfNDMi&bHbpFIyPg*}e8$tBC{;Af*` zOJhky?vEvDSt>f*xO1r%=+vXOtw*8Pf8H#!g8ACgM0u{^+u#h|v0LI^G4C%B%eT;+ z(LS14F;B#=haZwWG^S9aNn9=Z&*z}Bz>ujWN>iP{=ia_Pi71~i7;jN4wD=Ve(jdu} z>ky__o>6U8QqS`!cfXb36+h|^Z1qaK$WjMZfK9A76Y3Sc9gU@7HQU6%&KxOzVE^pg zyTwcriaN^JB!~NldxSEI5pZ<8fM-+krCRPGS^+D{xRx^mv@9Rck-bXtv5=b$8_2#j zn_U@Dot%yBDRs+-=9|dO6?=S&;I4(-!z2kCH5ytEd9(6^tsQiY z9>Zy*|M)fqw69+62_Ma|vPNI5--0Esz+II?m+9! zwifu^65bh;Jyx#2TEmDYpBS-d3Wy4Qb)9l3)V~7u*|dZfYnAgH_wCdtuChH5!dI*P z*Wg-7Q?NG$|H#)XSS>Yj`EUKY@IdMWE+ib85l;Gv!4 zbyXh-J!)F{wthBpn$%3t5=hXqRs%JwMB|OZ28i$TK}w&1y>Znl&t0Q()ZDe8}?%Ye|6xxPyx|0zMl>D?ZVG; zR6#xE)`s5ITaAjHeEwK6o1)W7`T1xiI2@<=+lcT@_UmY*w#plok4=b~HYM~Pq%^92 z?9gYMYQ@dX25v$E{HjX`Vf-lIxIn`@uiF8Z*}nXJA2_AOfI2HmA-TxRRGj-1nnhVq>i z$>-^U-!Y2;aa6`#j7#e6@~@KCF)O@JNJ1CwUf;$G!f4DL6n*VWCn~ek^3r2gvWuiZ zS#3bXWI>FD!2Q8dJ@reS@%~@FZrXEG#~3H$1Wvo1Vy~0aAUpvwoiKNyp57tXj{U|giw1S3nT#U1fa+mN=D3w4v2h z{N>W846Z9R}xM%{813hWbmN=GiY4T)3(*dTRHBqTGIWAAfkgZ@;51q2?%J?x&Hzj1u_$ zjFO6xE4%(d5T*!%`(;h_vj!d6n?H~%2~0w0p0cOJZ@TWp6y9N`DphZ06J>jZ$MeK8 z402Sjm?lAZe9VHiJ@x@b)K_ z_(geEkH`RziD}LI*I%c(wrz@R;hQE)r%nQ5AGRqR@rG-Wau3 zeurTAH`u&0uc7KMbed6a1|z+@Jit;9AGP8>cAInS__}Nh!75{Kluvca%LYuYApsU) zyN0Fho%v_6x=0L9w%kI)Xr;j|(%%P%HGP2x5=T$SXYmUrg|(h0SdIykF+mvyg^+!X ziv|?MV1lWaTK=HHiDu#%<%5oYhN&*Q{dm2<`CU;|i?;)V4-61EAa6qT(<>_xJ>l2W zGmNi*fH@SU#APmZf~o(K3em6D?W0&i%$zYI68qk#32IzBt!aApd@U{eeg$`;YPMZK zR+yOE)W7EGdap7%(qT@wzNc&;Q8lZTH_sMFsHqG*aT}L|NOCIlHHDnDiD{bl#k1R9 z0c}kuff%s{(fmw<1k8^ijo=O&VpKylw}iui^K>cL{jp|*be&^%HC>3De6HcG+sc{7 z&Cs825^SM*ouaI=fXM!-G2B7RbI6KXNRns&3+SYr>^q;BY*IK+XhCJ255wKJFAbP)!4Bmo7@*Xds)4>D>kLFf??5!@XKTK5M{_Ki^q-Cs~kV$J7|h_b-M$ z5IVqkk?SYWv}!YhJE8S6Lcyo)dkWyY!@iZkqN`Y)NP7}3hGMddN?2tTFg^d3P@-eIbZUyir={v&XSQyu~pE28)@U&u>>>PoJ_`J=O<478) z8(2qn4(w~m$3wrttCt1*-%awv=NNY43JFHoAJfKjJOi$!b@zYi}V)S98$sKC4HRqIUEUKLKm zGukM;4Lf)+?i;>7P2?bfflKkL4C*oD`n9ydasxiY&%Ga_yq(y%LFe8khgFyvjn=j5 z!QzeWRQP<0MNp!^h`6%jw@N;NSWX%$_$o(ERo#idG}KO3HeI%rSQ=c=u@P4nZG~kE z$*KIR81q%LfU*!KvgTVDF`Gviu9$vL~9*n!QU)<7!=J3?yP<-M7yVp5A zlMI;FN%}qeSP&e7zU1r+R@oOtQP3}umg!k2vyp6d$&_Qi$9qoWB_;M?hn8$GCT7y2 zuku9t*Q>mUzahW$+9C`&f}A^h(B7(M@m_8%fMX|Ssxqa1qQZe|bd3CF@^7_F1`3t1 z`*bBAbM~K<&j_WaWMwo9xb^~h9k9ntkHhqB(YT%00HfGr_ZSSaW|ADf8jUc`GfjIT z`uS-djW=?Rv5FNUtpGel*sueXdM=W{(=qHT^3%X^Ail+SM5yc^fo7<%2juo)J=cs$ z&|Rlz=lA@EE{CQP+269Cl-k^T!|n*3ZlV3E7a4!ocKWC;Mt^aA@4Gl$_V0=aTUQSJ zF6KKLLPj;tOSaF&(K~^zOZ-`52dy^2iquAHR1F!dTTRJWK06%J3ulFXs&;B2kl5hE zFo_g)H~wSH`sUo_#Ir`W&gGFXp+>=>2RPH>6@u$U9lax|-27?$2Kc;m%eBD`N`z0j zuk!mgVic|#0SNE;xsHibED*Ni7_=kz*YA!!sDtHm%s}&q?L`~7xJ%HH&b!s#BehM&0K01`mxD-bmn9| z*@&t*dR&xF+p&Z&KF=>=r`|G)&X2>j-kBD`m$$@F7wqn+B7Yw=k~T}@5UF`0?BWW& z7}C|6=!a?_#)OF6oREki%WVq3^Ai-%Ee!noPu5~qlS-Tqp$YNpO`?*GCoUh#E=~{< zIOlJ6yFUM1dBAcSP5z_Z&GoFF&CZZ}@7+mVs9)Gtv5UAZd9n4B4roX0>#wM15(BI_ zQ=usFJb`*A0^4`@mz^|BN0&+;pE7CAp72G_Ec@dyyJLrl^a&N?M|X@zVU{-e{$og? zESc`p8d*-pdZ^J6zlNVIX0UA??;MnL_enN7d2fv(OyuId<)+XNcw>=d;a90xgCj14 zzDbRO<`-@xm1>gT5(OFwY$Jkr6Bn1cMln^WIe@uNPT0#B+&!GKZ!#8dS}@H^>~X`a z+%!I#h7UCAuBYRWSQPVZZp_nvZ+gpy~?5};QBXYj` z{ki{ix@+thzLc$FzXZ7&aZs*reU#10x>pT#ZOA){~a>b38JNaUF6@Dm{jl+QYeZH;m@xUh=zN6X(JH9ph*yF# zw1E>{s>`&t5rrNjR%-L=uIy3Cwo6QxP ztqkb8kgQr%+5R&VKmM`)?H3oA`C2EA2+d5zn-Fz45y#q75 z+?GSLLBc`uam&Sc3X&nq6j0sqyF5?WD3OMD(Yt`qgEe&)oF34AbO($#5c{I>g< z@HJio>T=aOl!y0s-3O%)MVvwp||jnsZ_CDMOz>`TdViQsc5hC-GSt zrM=}Zhzb|*uT;@Ruk+Wh<39?CUf$Q1_>M$PMk)?iq}Kr=7_@Z5XLIYIFi3K~itzj#lNsFg zpBXWa%?s;|6+(Z!XEH7CjNpuas^@`sK**pFlU=}V>WkGH@pPb^a=H|HXX*P(dknc=ByFIS&;y66-zL4`bK zhsQV=voy^Jd^RYb~mdZ-^>X zQp#-J=!H{s8X|l5@g~hWo6xkwagPuFLk-0nqp7pU2;U(bF2wHKg0IDyoif^9g%=Zh zfiuAvQx;Zum~+w*7#uozOXrN?80}J!!?U8PA^40_{_jur67oN!N;?(3KJD^tT7pi> zFpgGNM?d?oPm~ST`FfQ(dp-;4gXNJ0*3~Ndd2nHV3eF8|lw6nbX?zxpAWJI;O=#7b z$Ww4&;NoSUJT)M=qxRWq9`i&)mT_5*B zitoK@^(7*uW(`rF>clKdmoCO>^uLOtva%YSl#d-0vDy&7vN^f8dvB5u*w4>b*Nq&LCN~ZRk!U zn(G3qS~Z`hijXl`1ON4OXHVuHj5c3TuKi2EW@+E5dCAv3mf;fkCzo>H&~G+r6XhrS z2>QRtEE+7_MYkW2F%{l*?)&#{7zqEvn%;5kD`9W0pqm(B`-vGbo72S z1mVzlMspKtI2(dv> za@zXB`Vg~h#P~rgHn04Kl-|ZW$sGl6!tzCBgGE|X!Z#B>T4b`2y&9$dZU!A6=CtHm zlRmdz1PSjlsJX~SJOlB2e7}{H+w%(+oZu6YCazd3LH+on*qTYWNI)+Sg zsbFF@6)Zt2LWB3Q-&TyTKO=Zi6<%NEs9(kK3rib5gwCy-Ex)sMk_An#U0M30M3XKk zEXvh1%!G}^F7|JK9!6!l_tzfgDdI;|Fsd(yV}@&4 z6i-XEt7#~Y|8EvM8MuEW2t_+Hy~!*96O`pYGyxN#%YomIiV(6wXoNDbeiprMfK%q! z`UTADupY;Z;d7WiFUw?+f!ry4Ca-){X}G z3?pai-WtuD&ok%p9k-^^y&QsQY=I&rO~ag}T!M3UnRUZJvqnA=4^0M_fM%I}Q=QvS zVcy*{0?P4>Jq5H`4y+7TC((+gdO28Qh9{7SzvV{ks8v9kciW^ zsaaqgOS!$3QXcF_luh+$@K&Ik?iF8f64m(xDpf!KVCcW<^m^-Gl4-2|+oZ>BIRfdU zKSZ0p_Ywm}Hl6n(j^cI8zp+=N4cM%YNeUSB%*;~uDrf5dJjL_>$nlPvPMdm=M(f+2 zr3J3vj8rHs!c;@v=t%W8)qR z3tuB%-Xk0qo(R{(hC&3LfSaxCA04r;yua^J?Z&vTJ8I8abEw}8vF#x0`$?pI{Wl>c zFS`gsjSYp1G!#VwV3U~RpJwSXs7IH>rv@S4v|P+sw!+gkSjCr)>f`|w6-e*Ioo7&& z8vCcU?#^fVjXiZ=^b}*s(Hc0HJu_&Y{T|GI&u2sr^27c~d)OkSvqj6-%$>CfMYHih z(IKA8I5(WyL9Xw&g7_ds3MME&YG@-huYL9~_8^c!EP~l9 z@(B9czvQ^7wQLMze#`wei2OZ2PaVUPI_zMk{#}-;V#E&tg?hyZ*h?L5bmQ-tRVkJw zLrjWqAAQvi5FUbR@H~O?TqVOy27Eb-qyZ)l;a_1cAKgEr#oHNnPf!EXsfYp&j|%>H zV?B0dV{IJ4o2=Ws?re5&=PDTpM>P2)T-r~op22iF_66#i28E;~P^QR*z-)bHFK*iX zRc7^5^B>`7Vnv~*S)Z;N7F>U*0SOQ$==p+$82gD5)h}rbuACA!2F|Po&S}!XkgcVRwxX8DqQM8>2mYRhF9)a zw&MibOhehZooH0&FBS$O^Iqxjt)~K{>**CM9N&ftaI9ilf8pDeJPlkN>?gap4y~FF zD`Zz5hHNVvth}S`HGJh4y^0m!vSL1vrY$R1E4Ja9CG5AZB z8#|s35@Qwvul&a;2-wv_!=v)dQE98yNq=L>_u_oTvyN9pDYO-e1PWOhy5OAva+y3E6nz1KUF0^J|kk#1IB`a@oA?pI7fHIH`P8(wZ*tUZtZReBfM_MokfquSaN zR{uw>Ozt~_np=-$&6{P&BWPuWcTNAGZK~r)gJ;Fb@6rF!;j#Nt=VC<*0CKo!ss(ji zK|uk0AC~m=xQ;dqPQ4tvVvh{Aww4~f3@<lWPUX&-hT)UfN=sc=Xb11e{mK3`qznB2e;z8~|LtIsI$vI0GeJu$8C`fq zU3Or+?#mia$WRWztGf|$VbF2AeY-URc65gr^42L{tWA3LxLx)%d0Dx7+3f>>CoL;> zU~#bF^2MhwZ%ev%Zo&R`kmHL5%dPYKuC6J_ z1yB$K@BmdYs6PO^G0-(NLvow|L_x@#t54<_S1 zJ;$wl+B&ypbQ^%6v&|-%)$Yynm6~kG>!qLcOhfIF9tZ?HGw-|<1a7EJ@^($1b+i-> zIlU>$FKnz@1p(<@Ufx;F4|cVX zxudQvx1yx3!EVDXhov06jt(b>728YZOZT&s_0Em%i#xEER^8?4+HKWlFr)k5sB6brj+0hq zc$ycTFX+;6JkM+CLAwXUcw~JGYF*Jvt0diW+^^&Hy!=%GXS>n5 zFyk}T*xlvp;XCXLadk4A=B-Ty`9Fe%?R(Zi0#1OueY&hw)*694a^lk59F=$(^eQwL>zPL1V+p5}nLIC@h zt^B!%D9i{zfR7#!Kb}iwQ08;PmX__p)QnbF%|cG?R$F)NfdenV$Ne7EvN;U|#%<{R zCzD#WTxTHInRDHJ0<5n&pYPJ@0Ik?{gD!PJauXXJUD1M$_J)tHgT5QNZl3nJM;c{a zUX5J_o1mk%q+#M1iAryCaOGZ9|{t>DjQ%c0!`;L6cU)G)mC?i8^zJtrO#iD>NeW<6={h8N{U zw}|^abhj$6p-f@Y=3>K^l2E9{bs+rc8qjL$goKugin;){*LiDZdA^rNY685^#C> z(0h1vo!xaMj6@!_6rQ;`STk&gB2mP^uJi4{Lmj|I&jZK_o&~%z2Ox(xYrVx`Hc-gW z{d#aGAYiph%N!KAyj^PJ36MGsoe#9>Gzq-CY=G~0N+JDgEj+xX9y(gK0XgmgnEyUo_<$5h=rQ>11T)6w?HWc1> z8-jp=yIZc@4-i(DmwlJy;C;)`qX+OcxLe#j9C;rKu!gn#6bD#t>!SSOZWr$Nr{1;j zLlB^zyS2z?TBa6;TyJdNoV%1Mh3#BgLy(9wBmg0`(+$cCx=U*O=Jl{O+mGP7NA%g; zb_05ky}aF%x}7eM;cF0ZbN}z~2gJB#O*8m%T?e%e^m_Ov*C)3M@&bA6hpt{g&cB40 z{ti>hh1rB6ZRQZwuz7C)zZcX)61Cj82004~nGY>F-I}xPhKH8kJqxkELiLCD-y;B4 zfirh-!x@k@2tM6>2`y4V-X|lC^KWNQ*4E(5F0i@VZa(PI&23&a#FU{Ma)*LhuX%X) zUxocn7UTmyI5hN~2LxYHhq@K@`cLe)ni#^5VIh_vV9Vt#G~^XxGjx07GstSKmG5?Y z+3C<)>XJ|1u&8GsT)G1T1m+2+G~zWb0q<4|8j=iEccIUwExY|83vdoPoDbB{u9Zf`?CUOK_>;}QhI zDkPA6_VN@mZ@E_3>N)Q3;?Z$z(TB{Vg9EzFH`dM&)1cC;_tvXkmk*3UZ`pStNJ_V`;iT8#2>t3#RTJJ$%zOXr@%~>Z4fE_3} z-E&ZPSgvu9SQmWD#6ww;Fpn+Lx82j($I860s8N7j0I9S7w4otNaS zmm-c1xAnhCw}uwOp*MdO7_bPXekbGy$vU4aeZ7nd!{)$AXeaXSNJKOmWqfRMI!QDCTti*6oU0Ipng;5)BM zN|8`F2(a$8UDDZniTnvqEx8H`K+Ks!&h9VI8ZF41{$6x8_5UdC)bu>;_Wx0yyg}aa%L(p{wl` z3U`BrmY%``2b_Y_JUvxCeX(4hNKQ zBVfYa@a>Q$0P0Gu8+feR0qfcJl?8bftb(k2UP{kixt-Kq9=n6P16PfLuYxb88xUTX z=Y~+%;c|wHQ6EJ2bp!-x&npTLHeA5(p(-^m!V#~I+tt5e$$eLPNmzWo!!87=};sr z)TK5Q@eG?DT*u9)&LGHR*m~#oyzIIA1B2%}+{G_#Gq2Cv!v^@ArPy>vbiRVaX5fy8 zh>)vbFIi;Zyrj)|bGKE4w4_R_>=76lonlM}&25#P+g_H2Ns|PwZ7%~6u(1b|!)?WF zx{9rm_07GM>Da4A7pZr56f2}yZC zx&x2Bx!jl6j#W|SJ6O>z=5a}oOxpdOscg6B+1=r}t9|1#@_OqIkpe_m zdku@Mw+1@Twt*O7p}o0VusKB5I%P3rU$n*4a&GUA4(^30eLj~v0TxFgd=?K%&>hs) zrp4SdSbCK^TL`lP!0OkIp7mKR?mf1F5Mx|qHfobv&Bz$}3Ww}>m^+9%b(VNQO*KGnRH%Ks z(@^(gZ=VO}3=|@G^GXcWS>S~@dH}Tgdjxys^}=XD-Dn(6^*BPt^ z>CJRy>E8+O28T9W)bd_F^U79f1_>h{-HAC51{QZ6$@8 z!WRoK2(b(4UbrqRl!>@|{;y+(rckZ^Kes9Q1tN~iq&0=EBFoxnbl9mv7~22$A(0oZ z=(aCh(aM(P>E0|={Le6&knR7@W4e_sv&9u)C@GZDi8#8|L@SZj)VP&l%e%f<5P3o3 zj*0UE-SNc>oDpo*i2r@%|GAJq&#^3JkVJ{RU?XRXCTEKy5wRC?bX{z#6{4FxH>*> zDdIXpC_?ADtb=a5fL8W`@P!bDypZd{iv?T_Gl#7WyLi@0yMkLoK{I9(*VXlf3xs`^ z)fpX6P7$4TeetV!F@3hjOSiFJ<*N{=_AB-&R{?iGmT<`V_TN;R&7asNXR2ujCF8u~ zwuj|WvvAzBR_H##l7J3X4MZ?H#ZfwmPH%02FZz{wB*;T=7;hj*Dku+!qfMDY;z283 z&rwt`y{9Q^CS9-{^xPqNI<1@K@=V_5w$jV8P)IJ=d)#&4Kqo9zg2H1;{h}(;+ZnyM zA>w!H#J@BozZpl@QW*T$abwn}8Jos!X@j+&1)J<(n7xx4EI9WXhC zI8}>Y(nTYs9eiMyK19vw5i`a$Lz5tX}6s-5@u?9<+*8=B0cBJ1pnA4U&4RO0u+wT)k;E{3z>qmyxk*yv*_ucNEQx z&A3}VjAmqU^9PMXYs*-EiAA1+-6T`IBB$AzbuyuEhDL*vb4m-s)h>NvUPbhegOGcI zo6fjV)i!M|XQQug$8_Le%evlL0g8^GJXXhAS`LF_*0Et!&A@qMTOfDAtdx0{QmKenWd;XI|^lHto2%A(jd>*HPZI-Sp}`(n;DTY^;%}1QjagSaBu3+DgL0=n|s@_JcGOcCFe{ znv^oL`4@CRS~}W-v9mpzMWvqdN|8FrN=;81D+42P2j>g|an*6VJW!}}a`|%HjQb`v z!6;`Il+BZhmN}}Y*V#}EX0qD1=T3WSWw%rOD4l8I?zM5+T`yW1+Qnw(T9@CiRjj;c{afv4xAY(borhgiYhslup&Z}e zSN^_UaX-F(@`lvYA7IY0W?5fN?oJl=D|lxGw{@0fKFs>}-jKWh65fga?X~3cUU#+C zaM_3G)3_{tzS1cq%p|$iJFRy3F(Yx)&HZnBFfTFZikY00tM_rIf8dvw0vTt*QE}^@ zLEXt{}(u{_A9@1QtomL-had(9E;Ks`<=`L0&KlI zA5$Fo_)G7THg>(WGdolHO>b#*yK@Ke&C;JAB%c$-)swGW&85DYdUZtak8RHG^tkm} z@O=C)qyfEe^m>Gt?O$75eAwlmrv0{0-V6Fg_Gf>@wYWBjPI7%~8lHs5{{u!vfn)Q-VYxg9Y)Jan8dk?r~RQ;DQR74M1jLcj7C-hA;`xRsOSqKEzWO{On| zXTN-+dShj9*3@53wmtPv-1z5ytXtPsf=EV$R$X$F@hr71(!;(jDE_mw_Xjb1Hqm)T z3$T-(0+L^QL0*>e<0v&O^g8AKlCQH}U-t18tD+ZLUm=22`mI)eFf2SrEG_6ya6L-jPFcUd%Tc%uO-qK~K91Py++7>FN zA4ucop-Y;sw&i?(=#up-x@9-m3c&961)bzOkjA1*=8RhEq0^#?hgst05UZ17ly{|R z8t=Fs)?P(vgDi5cjlxaJORhA4Y8pE3DD9pW(vLQcu+d1$#!N(iz&&DRN}bgw5L%wC zNl=%O$PeZ4H9sj1xMg4|k$700BO~n!F;C2;8a)wka!!-vOie5XG+Q?H1lD>BOdQeU zNI)g&P%kwh6jw~xL!{bq4Q?N2x!4MPJA4*xSL4jds6;J&{&4tyz#vIys7ES%Z`6n$ z!B|;~(WqCg7G0h>n;MB^#VlgH^vZc_i!`T1=b>5b7mSzKCw;wRhOh52BcOnlI$No$i0uj{H_kjM;dT+Oee+?XwszC+1!AnOx%v z#mVuq$g)#VX?qna#V8Y1x@CB53ia*Cm>-vsvFy-&B zaGmZ=mvB2KEcz7}9aFUE=n4eqVXeV%wL0dcihCll`N15e&WOeA25}Dk0+?a~yU~r8 zjB_1A;rkjCKOoSx!{jo17)QZ@>2V?e#3J-nCE`$}$q%V+6C8OD3_DpJq5g>LRGy5N zM;7ApbgfZ;kOgykm}={#4JVFf4wX+%;k+CZb$u-O8?E6|>~?Xlz#vJ%#46$R7O?3T zkQ(P4niixM8~VaL#{DOyC?;J2YzLg_PsXeBVhxiO%{i|A5 zy(Dx|UX$?M&tEp38&%2|p16M&sHUWI`UxGsd3_-zpYBRq*!z`+#w@A8ZV2Q|#{QA3 zCgIJlNHeSQ>R=@wSBAd{OYV2|&5>jBm)dKN?~E)6RB`VVJxKn|WV75M1+u+p-L6wnj~A}?|<8mggKPX~B-X5*hVAGj-Z zV)OM5qs9l} z@aA`My8Zj4#lX~`GiQaI2BRGi40w^q^Nh0g**E0B@-t$ieERicpopaN^GQ? zXZ@g{pX9vKc;fhItXX-a|5@xuSSME8#EMAZ1&Qttj@Vk5p2L*Y) z{?5wz$>{fTAqoY}0;GotI+076Z%E}Ny;inTaOoEH;c~I+`5c!geSbS^d7mU~^9Sxc z*z!Zln!r0fw=xVPiwn0XG*a=rzs&y1tNmj^YZEg(%vh04Ex$2`sO~79Nje?IF(Ud~ z=UgMJN4`N#Fe9l+M<@0Wwr_z8lajc>*JKLjjkSwh!03!1uVsD zkW5?*3^{bT>RCr^>#WliQ#7;*{qW!tx?!Psx1St_Q4|`Q=@4ciirIs)c40h2V4Fin zhl&2nwhs1HwN55S&5Cs|R>F_B+%_X>e~lppn>>o?Xo5zui0rAHv<8i--6Kbi1PxX! zSYJ2q%ssBeT2qtuRR?P;?KJRT5eVx@h;5o97GVv8J`OB@~; zVo@jRfP}@G3OV8G?_5D}Ubb2wR=#&}k-V5YM%Gxn28`mcc&hOlGhFb{!}(uFenyGW zs9Y=^>a%jhLeHAKl1%{;MaRNfB&q6nJk)u|+UdqKCXrr*#L^y3@_SNA>!*79{wabx zl!xDjp&!(K>%LY%B?tHIkrm4$v+LVoX=mlbnH%KtpXC5(>vqlo{GKf_Fv`BTB6q!IX4uH2`P z@I?hnE!rIoPfo+iLx%WZgTcZ@<0PDuixJIEtkVw1>hrVxANj&3h7no{Y&7(V3L-Dx z!UTKBwP_Om>lZSR`a55%_ZMr};BvmAX+oK|ns+HDBKxm++Q0fJdn~TcUX6?})}cs} zLLS(!1oY45M{`wYLMB(CEKF#N5b0<#=zd<+hO{gwNAuJEm!_3=qmkkZQH~QdRv})4 z3w^L_v0igE9K6yWG8!%1peUneqJSd1y>_B8`PM@IOSVRnCQARlG=rnrq>S8WuR!Nh z^@`iUCmVVU-d7p^h6PnkOIbbI_0qH%_?~?QEL{9At<+H|)t+9}hUa`D>*()r$%<_Z zVhqiyY5ELQ6#^nwm)q~2v|i;cQiQ`95#V0&Z%w*FkL;pCiw8mTd^CB~!DI8#xs*9( zOG<&Ic^?X+{Y;*LPnDmCdBvdVKcWbSQt~3Ta(^g$)%!K*Va~krm7i?iIt(*^FQ+>1 z#8(yr{W14RyUfdIXR;?RwRhjpzLP#9XQP{eoszuc)uPJh0)U6ymX`;XqninS1NRRS zAEK{D?i)4`F0fl#U#&)!63ZR`cFsy2O&1B8&JP>zD>~J&p>8W&3_0)L{37l(4@$Lb zJ~Qpht~EJnM}UlOn=uw2jW=tC8m&t@ZB5<2ia3Fka&qwOgAVc}w3V7KU~$zG@hg&- z(pyd*NwVzrPONk^x_2}0qseQX<09^{=C&lgKMqJ{yDoVrM;QAay6rzPYCE3KTHzgd zp@-Z&Dh+`b+38}hNj`1-1?usX95cShDQKFaS9wU$v=Zg`nIc$U-Dc97sz>Mb9h4vZ zUq|Gu$$RrIO~0*EGvshvhVh_B7}xQiX>X$(Zs-TMV91Y8!3v;hDvQ%pGjFe~Uq6@M zIh+1qx;z#fV58iFz4~75Asjnbd8OVx8+w&ReHD5 z-=@KVRuk6hYrdbj*iPMI{q-n)kkC~*Ziz< zJ2Br02_AXR_M+VCL40pg_u%#_vSQ(OZ3yCx5PvcikY;cMv)SVe@K{nkB=|9;kb3OO`*b z<#bikw<}TO19qaS=PlTUd^EAwiXvPB%za*b!aT}o>0C3U`4~pxnKE}cIr!#Fpa@-K zL^ya}S6Fxdh8Ol+LQ4sutHtb6Jg;q^Viz!UFi+uJad3l2H7m(;&&6iS~s z;-kop?EHyJgY+)xChkASchxY2o}}A2WqIq2`BJPGpgEyEVNB;Ll(++@Gr#Mf+sX8O z$bTEt__^c(V zhRNGQkS)%j!!+>blnrO1ER|>w%Pw$o%Z3+=<1h`qd@v&)aZQ9J^&oP|6kJ_h8Y4@q((^fl~*p)!J%x;`j^ZWh2)+g2aR5XBn_;W;@2`DQ3mRlr_(>?x4UO)z8ywNqoW0p?%ek_adHzYxl zmzh0Bh^ixwF=9j3Z6(@q-0TJ__I~p##T*qOduYMu?joQJ&5StkM$bL}M=7@PG z?5WN68zj|f8<^P9)bj(zL+kvY*7`KGx!Sro%bPpS`bIIpp1&c5h=ASZ;K17SvSO~Z zIzX%J`@s`WN+^|$C|<%Fq0!r_(OdVCSU)!KKlQ>`)!o_0ARRyGzi$a8)v^)I6~X+i zdP>>h4r?@FF?0ou1A{I3=?t?;=~>15y$4@SLq(4Y+s76N$RW!EWHDJwdB61OY9&l)v~B1>acnDya> zMEaIxcgKo_5|4i_pNAkRSz)}f^@G+s;8L|oem1YE7XlM4VLenfoxIvA=27QfvMKPf z_V>lBdD_;y-;S}E;mLk+3!cl}&Aqwj93@pg{}Uw0DIeG!5E<%34e{hZPDV|DgbP=(ikV$3~{YL7EX|?Q7DU ziL{OG9KMnyC0mosVc{Op(<*=etC33sXHN5PHm$v+@(<;f7EzY@tCG^irtuCyn{<{>0Bg2YgBP59w@mBqU)QpHtv6vBgCn zd)yqz@`&l@D|L=?Hv;I`jFvFseJ3u~JaqFAl~g|=xUWQBMESjNOXy`(1u-yiEr6dh z<_RM)q7A#FK>%K?=wn?|?gU%)39N#O*Q6txWifrhGI}K?1Te4y=Kfz1M<@4%v?0sF zd(9jvUb!?k%AwEi78td#*xeIlyMEGv(hxS=9#`y6<^hk7bQuY_DIC$e8=g3%u@}4N z1bgR`vm%x1jt9qLSPyt2%5q-0WAQ%SMZE2q+9HA8Ap36D+32|L_rBrg|M5!^-oxY< zBeDqrB$FgjK0IugA4~)>(iEC0-NK7^*w&{0`Sr3Ko3VW8Z8A{d`=irI&EO6eH}**< z`#CllVhaSa6_C19H6b(8!JIKaKiqAZov-PS(%X{Y$X{8(NA1>G2_nO{( zS3;v6%kE2=fmu4<_t}|iY*>J2%cp5&<`<7VdrR}LzP?{DEJ;VhV!{H_$h7FzI-=G$ z5Y&1Ml#>%^4Dy-jrU%TjdMKw|Mbzv+(M+p_mPTP=?pRjsE}M>d)iisRqQv%(@?={M z`ZVnh4qD=@4rxgcHYVm_c(aG0`*#eNRILBzNRqF{n93m7Qqi&w%|XV|Py;DtLDdwu zmZLrJ{B_rqE>2b&fg_R-yXII@!d>6CV%f*j6L(x~#JH$hiqoaAA#6%$Wl@aTSs+t5 z`B0UeI_9Xy_si|&Eoo~<1H5Lb(>Fz(M?}wq(rmzk~%8G(Am?<(55Cca8PGl+Dp^9%hpwtaOGl;CYk?edpgV-}u5Ez6ANG6R4|ZFz820|nQN zQWQz7qOHqCfZ`Cc>ioTF6xkpBq=*kGrWf-PWqDy-~&?-+#;L6j--*r!}4595cS&M9&69q-xAwG}J zn6zZ+pZRLATFa60mn4LV)`LgilPfkUK2=zJXT-e4ZL{GmiG9o3q}d!do4u&k^v|+d zyFg}9TqT!9cyX)I-@C?EISVs^dfZ@))JYNPph4NO%b6qSrw^Ydw}{FJ}z) zwa)30J+(GlfPx@QXIe9tu|Qt(&0#$ukAsBAaso*p?2vXGIYR;V?L4c_$&K8I!gkaY z|N+io)of0Bhp(-Db8*ae5vj*CFekH6`hML8#=O|Dvn^BlxKM$&;# z;D;>)xaMc@yp5gHT#6v{Zq&2bL_MuJo|?+6w4uM2D-td5btLx&e^K)x9_r{|Zp=!S zpfINmDGuvvMsH9$;OzFHv&md$27D`e)22&WVqga~S)^>!x!4^jKIURnGH66uQexG?<&GZM1lD7Gg7g;xOf-JkScYBTI34vz@* ztM0a~RwlKLISB}M;wCU*B3uVN-CcjW=B}jRh%L-8Gm;lI3Mq72WAJ3LPZm^(m8a7^ zF2AW1IQ`GyktBC|nu?v7vo6EcJy!`d8kF%CGwdVZ(BHUBW63{z?Xp0lRXdvOq>k&G z-vr>J^-16nk+TY7DWQz@r3S4-{wo#qrDU`h#Y;Xrr#e%w`b(7!&HAeFO-j*SPg7*S zCyrK@zqM|hS6QpqBc09-?k_V5_7|pl6rCj_Q_FnKze@E>p>@J(S^xqq`vt9v4R$+EpYN}8!VZ)KgsZUZ- z^cK`xz?Q!aqJuA#EimM|AU{sT;+~UdQd;EUw@%Ip=>|G_VzmX6#XpN6eZiQ+>-z{5ztAcs6MrvC*X9Tw zcg(gDez`e_ysF|!k3#FhaGVn{4SSBvVKCrd4Qo&(XKc=n;NsEq*&XQpgI&|hIEfK( zLH3wGzMdNlF@$z8bB;FE3)*56EX}?THIdeBxVmXlU1e#3BES#Utvqif6;16AA$d*S`e4M8(DN&JNDVXnKNlgcSMw|M77f0E0C{? zCsB(b%aw|cpP0i>Qg8NIAu%njAsK#V#vyM-qeimsQ8&}+dYDyiXs@6?Mb%}}PObUp zgH9ntw0XCzARXlwo3e`JVID4swb zG#Jq@OE}`GM;7u4^QKcACVJM;kP+SL(cXL6D*vq*U5jSN{F{NX*23-7G;fU?wNOoC z(-~V8N4}-G%qv0uq+9`9Men2t4QKNmICx(x>}#PtEzjz)-L(3L!^7CBs{r-IpY|PZ zvh>X1cF!6jJ4VHN5C^S}a%gVU_>kJ{fxol9-vrb^ROpo?Y3<<4WmwU>v`o&#LmFhT z@;;A&)@>H-F4eJ@mda!+5MZSvs+_D=i^y$N*&$Nr;SB@-nq~B1+b;!&4Wwg{b@fe- zm-MJVg1%ga|LOTKJ&})6{F@R=M-E3@T`=+i)VaL`7v!D54MVLV@gH=XZ#e`g7sm3~ z+-*w{hpbE|hIP_M%S!xsU4|PtbOX>O+xH$Nx%BzlsY))&Luz3;|HS8R8-k)%-;C9t zXRYurnyurweP4FY{=!!Pd&R#?gZm#W)I+PLP&E96f&x7%JC?&muknd`!sF?!cX^9! zWRI^ti6Z`KrfWE^STK(D&aHCr1}39&Og!YrhGV@q``~iUNuY#=I&Sor_0?en%h{@) z`QdWI310KSM(C4Fe1Suf8^87Y>I2RuYFAAh6|DSVEH6r9;(zX^&HNR7A1&AM zgEzKNKHAjn?XHVDSlR8X7F(|fS&*8NJ`_XgQPd;=t+YU6Eh)R5e|&+5jbJ@vKdN5` z${*$S`lP(`>(1B-F&XSutq)e$jK9-aUj~v#y-#*q-xb!vZc63LYwtW$cd zQHR~)L)q>_ZG10&mMcn#f7)3Xa`Ck?V(gQl)Ns5;uY#}P8|o>-e08EBecvC7fR+1j zjEy~G(?liB5Tx;~2w3T!@Xee0>z1Ui^V$`6v`b&GiyBEivM;jePpvF@rZ5!VK&VaJ zUsDCDG`S#FnCvc}3LeAQVi$jBC*fte-4Pp99f%VP8{_iGoS!Ld=Lj9 zT{aYTTX=8onh%lVP}>_XcCwO9KL(h@Qs|%LfpTMetheN89_k>D8GTG%-|W5X%s&0C zxU&~qQhq)Qy-Nsh&(9vEZYaK!rtF9~5yNP}Cp{4(Qsc|_4kTB81syr|hV}Nz@-6&y zsd04J*j9#|`K69KELYfw5j}Ud4c*$imOla!3Q61?Xp$=n44XYD_w#c>Tq$l@o`3QJ z3!P^cu_(XQ;yI6VaqR9wU4=uDl~{!cEVKxBh1@f%)sB)qT&u-o8z1@l6cV4(p1an$2UxetAkL>_Q z_zz-kG*vx0k5b?#+l;zYe-h_SE57E1pF%uc2@`ML--QHJKi^?tDw~1r-|vkZNnDqi zE5g8ctK;fsu0O3Yx_=A_xWDS^(p$!xfyFG8rP6}lDm9K-%`6AY`=WLCOMUK}V8qie z9?JqJ5agDUXdQOwi8r_#HW7^e8M2R+w~xY|NbOi6Q6vQanhIT%M-O2qUG(3`e#{>> zEut}WvClUxoQO0o$V{PRy$O`$?&q^vO)lYS`Oo|MsdTtdCfM^$BUpH#KaO)_4ig!y{cfMP<<(311D zg8n(R{?h48!Oyhjf8|{?lQw%?dFTsnU)7VsB%-D@M&FmaFT@3^RkXV(cXZ&WA!6+n z8Q&2bf921^jC*58pV+|4(I)c3M2FM3I-5e(o0>&IDn_}u!GJs3ta_-VpvCI7ppBqw zBQWU4TdJy<*PveIYG~VtCXa0}^7CfQ*~xdNXxG>ywn?Fv@zgUPdJgRMRDU=Lofl|5 z+&>cxy0`KpZTn3^m15;b9Zz4rsn!h;hf0xcnW454ow@_`u&D-d4pHby&W>-eD_;@o zR0yE!W(jLFSn|ew(A~8V>HeJpxkA%Q9TmW2L6Boe+olVAbeBQHQ7d<6vPl)SR_5Xr z{Yb&`?=`U=zb4(yjwHpJF|^B{tHnV@x=pb?Dk_5OqU5vrYw~s?%z773=6vSqyNQQm z6Ah}Bk~i{&4%e>}3qI;(G@K{>b~VHmy5{9OS|-i#Nq>3mF?-@&s|uPs69BMnc=Dz7 zj~WoW5WQSVMS7BxP?fZD7LN?2(q$60(+>({SCxLI{3!O8Ha!Vy?@Ys(oZvp!*2a|? zQOoJ1gJ~cf*H97z@25gY>Do0wdiVT`_xL7Hvr@w_mE{9wy3f~s`~SqvNDlf=v&k9v zBm-cs+f(mtgnqy0#Gz@=2~?q^>r%#eBrBDn!E)%y?(0&M7Z_-5`!%oi?uzK=nqK0R zuM{Chha;l>Y+2ogf*0>i^omBNjb)_Mv=SLMX7ps@%-Kz$qa}lMUkphRol{pevNyYC zxKW`>UVPu}w*8EY_uiijjP13I5jaIEVk=*-A=(y~@I_pL3;gTRtRMuN2~9AlzOAX* z*?nlqU72|#+CS&ENK@tQo055xFW5;?R7>%;Ux>$r>|NZycY#yA(avGrJWkr>_h*ap z#p77_=SwTPiS=DscHgz}@C+aWS8`7YEMtc6-W5#eZtAQfsrgp*?W87ZK77X>T@#un zM4M|-j*ZbG*;GO+>@g>L^GtG^_Dd1p!)VmJgC-?qY2fuFjpGupH50wZQu!s|Gt=su zOxM??O(d8`CM5?v)86dzZ+GQMcpR*qmgwEfaN z*W(^l4)f-0TqFJSbax2C%lLZisxrDyCrq1C`mXqjqG+s}>76x41lyr|E#_Vx|Ht7O z`R)4eeP_v3i!)`(OS49-O}Ub+y@CF?M$I*WX9OMQzp@i+c(@B<%E{syr?0K(yxokw z=>JbusP@bDY(ko9$BHr#h}D6*v3EMd|PHlA@|csTraotr*9+h&4ZQ4%~ErW$1Yx z6-TVN0=WReGu>>vD`r2si&?N#8f(P9geFhkQ-t$MI&luM!ey_+=+YzP6NGUz$2$IY z#O4^i9G{C;4_WKzf?V6=)EXILv(4ianbRQNMdBNmSyNp#D;FvoRlE15n)u=8{aG<3K{vvIk`W07%P>cX6r28KbH14# zigkr1Sn_;}TQ}B-9V++vj_-Ly+L;7!i*)n-R272*;k1iYg|LhwbHA_tAvv;ei&fZd>45M?nwQ z)+EouH@`R4i~L?e8z9;(sZ;>WbMQV$ka}b}vt@^dbq*vEvgOGo?DL_?7ysOww6Ta5 zqcUGK{-j$(XgS#hmMg;vG-lM_D3#0AF$0gg9)G^-NW!U=&{F;43;5PuqORKcRrKSMmV*On z#d6vV6~jr>n~{vfPoOiiG05m^ z+q*8fV1Z$oe-&VZ4pRBL_F3+#N3wBObai0!HSXWplpPt=nW7J&<@l{IpZHHnqkWA= zc3BX$tSxrd9=MRDYZ(@c+o;u#%yPMnGz=)OKIKcDGhqE?{;k`x6#AG_5rYZH)O%Vz zDs^LD@U9q3t5?mb)Pk3WU(d1}vT;xU{#VUJGf7VXY{Vk}C0Blkl+=p!7qvwO!7QmmyDJU) zXj}u$pbjTL`3i2LSc1NnRyi1e*IPtUU3}#h<_dzL#3;j0+L5_uV~{D|jg0)``O?-> z)jBL;*Q$tVie6k>wjJhC+99#Oko;{5`@2%YH*=-o-KsN!E#UU#Tl3qf(oTT?jp=iw zas2SCbRH}6tEB!53l@^vD3T|uuSA`k8XmgJujy*O)+es0tFs8+>u~V?$Q+CNd%}Jj z`|_hhE{`KO-y%u&U;<6J7MS9k(ru8Vg#GrEKsV^0>LpL@_2(s0GFF)SUZaUPnaRd< zGagS z;5EKkEG9Eh1hC;zFa;+M6B^L!q@??k{{U*-d~3{~8SEVz6MwW>5p2YYnO?horz7ff z!ZR4tKFdVoh^EFVz96LWMz^)Y9*>w(BdNvcrBlwHr3%$R42yQd!}XO*QJ{*#epaMx zv!dFO!LBL|sA;98jEmE!m-8{*ll-+zVxo81D~*rQl@qh^v{H>6y$!J6OwXQ{poK^CRaO3ho^GD_hqPFB9h9SK235*|A z@D_`XzeN=WyuN5slo!DhI)Nm^d2t_>jh!QoYN3@Hu<4~y{ol+;z7 z8`I0&k-eT_Xm8GlRqBl~WtcbH+3?a63CRxfKS>m)30vL&gq4wB^G7-)1sx+jskb}X zEF~=Nll!YXnJTPmKK;b{P!pHx>DzJIF)Wr%R>xQ32fyzbx&2SSlQea%(za|yvqfXF zulSQcsSOxhVypW+siIvg;4fYr`~n!F*Ctk8aNR4kSJ_cZ&^}#S^2|lrfwd%v*^{-aJv+Iw{bR)xu6M zPsv$6!&r1f<& zR@Q3K@ek9lEa?RmN}|LHg`Bc6?xwNS-4Y*VJxe?5=M$o22>2%=Ty}Sk=YbJBk>-_+-SWslV8qag15q*xc7o_9c$C*MaQK^+uhUp_$F} z;yp&LezQ^`tgfSP+MzL1=4Zu9pO^IB5ypT?(Go^b=Yc;gbnte|Oe!&G-;THK-kLU$ z-4H1|UaoLm@oH*50W*vNxz?gc0)2Ez?o=5lqPc|* zM8CZwk_lF8eWh@)^|CQ#Yq^O8Sz=IT$YllNB45T{~Zj(&-AX^Vxa#x=(9@x$(|5sSNt;y)ZjS$e!8=fYI6D>=gdf;mwo4VA~u`0DS z;5%AT&CfX@p%D~%{B~3GUaKj~u@W98)6^2-a9C<6oNcp<3+QN>mN*P4uR%JTmn#j1$|sbj zLo(RQ3`1x9X?dear8%DPRtJ@RI@o*E?XcCS)>fgyCAy(5JS-n)_8EqN0FQsI^zsul z;Gm>#u6}ngp)f&;pg2aeca)J-5Q0khe1|C#ajVIMR_3|zC@4q}XK*qX{HkBMoW}ab z{}X-Xv>+f)N^9Nb(Sv=6hfp>z3~2pyy4XyFZb{UCcynJs;3V&jPB0=K^l$8;N`AL( zM(843WYA{!C&qw{B@hI)bQ-F8$g^6pl<0(sO0lh~!ln}<>*bSI2F}*qU6DwpKTlaj zV5AC`7LHM+T>%FeFHhl~x(^D(Q-)xrolbaBWt~DA(eqn zT()d1E-5IY-eUE3)x?r0na0zC>3r~f6b^AURRb)Gsp<#-kLy6!-K|>xujz(OuPhi) zFBa6?#!a`5<@(q|t*#OaS~Aoc2ymO>{HR zm=+;372%4X1$|`2*}3{-iSt!#cJV-PY&=ewY^Px%wL{>Rm@W} zqq2JhblN-BI6w^4WFEsI>pE)4Zo(0JHZ5S?J!;LkP(OB}i~>PPEDY_dFbwSaJ$@kDo4rf_S+N zjMh)nPav@3*yiMCkmmoE;K28nX? zM6Xpczg~80**j?ngW4e^TP}rJNEXp;5@^-ymWiYovoLUk%y!OT$qu<#W-zE+Mvc;) zQW-vpX7UmR@Lr&H+{=y?lZWnpQnRf2%o|w8PgZPMXt*aRONYrgZczlh&fyxtzy;y( zhE0;muXK1P2`&k-h+w^B*Mfr;n>UPO6hWD)&OFPPGdR$@m|0dVR$g~Wu3}W!CYg%8 zCM|00Tc+jQdLhce+UH8VN&7U)a+MAaLbMQ$+R2EdD4NuzrrNK1siPb$kx=?3QwES+ z-U(KZ7qoW#2CQJ#?xAU-#6vL*6EjIuwkx)+8ZTHbNqiav5>RfdDw0upjFw(_X3ZC} zIvSM>oXLx%@i?R~^F4V4t~S9F<)|`^)j5P~<_{E6lIF&2n)hoVv7w+$@F@ybEkg6I522c{NHPnWR$|MNF@kK$pshM@<*CVF$QsA)?{f1PFLz1C*j1 z!FuzTmp?OBA_)yraPf0DYPCuQRq86)iuQ_7 zWBX@Z(X#atf@ba=gG2BykqBPgK}^KKz%&W18yLDGAxDB4f@!>nP7#Y2%Bt<$6f;EA z2_ix{`sEacRoRGUGuWt=TDo++9yrmk>ZYtCrmDSxV{LNTlUT?n@l6=JfM)dqBM%JN ztYfK+m$9HX`|FfAKDg?#|!qyvCdly*|Mq!oHbZn=A=M`-x%TrzmosB8+&dD=5c z+EbRyoyxH^?Zgtx*|P^LnDV4>V-&%R3uiE}YaArL9az=DgN9Ty10j^5=Mbi3?_%+j zmJEzk+N}!tRM-|RG%QwftYOnCOGZE^7S0-41$)sM9^B6b52qRd!0 zUZ^`}?G}=S4wh08grhSRBF8dn#lv@LHhluKAd=^a!NEpSlnq)ZA0&p)ny+mI83dD| zBMjZ^NH|Bb2!$+R>+cw_aOufpS3Q6bj1_8UEzg*Ug@cL7*w?^4mUyBbCN>dqDm-lU zC|EU~Y#1I$rGPr(p>yEvtAm}A=r}Z@Okkqr=Oqz@8swO>i%B#(YIZ3@9yrEc?Is0S z>lrrzb5t~koT&iB%c7jYouZMf4A9M(wGs;=HJRN>F^iCfe#zV;wP4?b!cawj4Ap>q z=1y6fVUeB|mQyUeELJH8tfHU0oiBxU<{{yNtRf(uIb`T0t5`?v*R^Qfq8UP%8RNDL zAsDk_@imh>h2ertTDc9QOx4qasRrRE(P^sXy9J87!n%&KNkAPZ6NK5+8#i4(GW6F? zJo-NgK2|w|6UYb@;~TkTAWu15EDyr5&mx_#a-vYd2!WGo`7G+A0J z2NY+K24MndgVp^+b|klrBY! zmN3hg2w>@q8&ZZ$VuDeSE+S$R5Uj*38+Yx(kS2j>?UUrz5KA<2B^x|&;p%NyvJ4&_ zyC^i0hgt#S=ISPA3biqrGYroZ9mJ#`9fTUet4Bs&{&LDGgNJV6Cu`G$ojyQn)h323 zkrvJRaOs7bA=@O9f>nEnN-I?oC@dpWt_Tg86hXI=czWa`L%(!J@QgvHY}z2v%@t(g zDgetu6>~ODkcig8H79ANtP2QcsDp$#)D6zXgjYn62nnqiXV%B)i|Dyp+8^0#7XI3pc(>QBzO1zvb|j}m0O(1A5hlM_2kz_6_zIB?n2925h?!Y3-a4L0;b z(%T?Abkb3=Uo5M`A{5OY#-b%xi89sejKQF4cvX%~WWz zNHltn)MU&RyEZE()IuSFp~6TrD1``wkvl7ryLMGnMlFOf*M^TA95+Fn2kfF1a^hLz zHqP8Mn+Y>JG|LLu@Uh)?i8ONRD9aa{Ic5`V{b}RpYp2ecs|^gI6cbU4n8wbbAltx( z;HEHQ#c~@%IZhPOcN@7u1?*n$IRE%gJ?uIzV=%z(jF}-MfC40v5S}ia*X;X!;XmdI zu}Y|@s2#4;4AZAlN6l)-@a2dC#n)$>lQKfF2oeD#Wo2PiB8ozZD|tPisaE_3^1^y6kxJyAHNe* zDluY*U!`=GsGO@;Wwm1mu++FsvD*;Bj?9_2AAi>L`OSKCZ$^Xy8%jWsHy$I@g%1T#Q{HYqlps_`5q>w{|hG@Jt_vQ4p^DnrlbxZwA0=KOxu`g*oR z4k3j6ER*lNUv{vYB~(YmGqvKPBC;`J9igJ`)U~3lcp6i5?-&dU^u5a%P*8h~lvGFb zJsv159!p(=wX-P0zBwil-Uxis%7Vv5bpps0#0?Jd-3u~1I;wbE`Z%fIt{J|Uunv!>MS?n#nY-P+|#vo>w1R8&xywFg5ACdDfW_YzJO_uf+RdzGCJ z5vLv5kej0>xsJk<@v{T5N(#IVcWiQ5;q8h>F>`apEvso(E>`h&_uFEznX>3jq1$zH zz^u(H6+x-2;v%bt#7q6Dfm~Y`@@nA2#3jz%s+Cmj?4Y_m4l%Pg#k9`qU<&BS2F{-+EnFJy7}eFz81l5$X1NG$NOtrI^E>5%4YeQ;*D?ep zVF0WNCdDKrWSb;`zc9jV`tD-}TU~*c%EMmC4n+g3ph+Qwl4_tEQy~Liy=!e|f5H3x zqx7D0K{2feY9K`w;J=l$Zs9l5aJEdD@*h8T=c z6%k^cj+QFLMno7Qq9Q7)91S_7nAg(4Ms;p;>EjXzWJA+i4R=3GK9j55A3M;LnDW-1 zx|dWLXW8O=##3U3?4GB}_nlm~zTHjj$%l@AZ0wiqChI&!4KDO-<=guvF}gZArtyi_ zvH0;{P3<_2wt!C|VHB%&P~eC$MQqCy2u99NjwpgFivsI^DqV;~qa>?^o(W-Y? z3kdw6u7Ftma{7}K27cDt96$L1*9+3`=_9~3Nn#E*TfK|Bd zs?8kw5;R;63I2euLwSR)1)*IId-*rD!awIYOeu9Kjs@r#hdFvQ=@XR@SAPYISQLaW zafWoEaVQBKf4U|I$0iRZ3)dlP&4rBWg$b-Y7tBHJ$vBElP!=(yRj376 zAfxzO$wA0aHl>9i{3J}+3dZop@wVg$PxT%}m%dEF#e?1Q2-_5X2w8mO0Rad{qc5B1 zFYR*!Zz^)v+r1xU<&1Y1>w7J1J7;Nejd~ZvChMK|-S<@L@b`!40%{HPFHJyVlz$10 z3}7~-j!XvqKgPq^jja)wg;immYCeZHs!-{GN|SailKOf~rLlSL81s5d3$`;A7A3DE zmX!)?0e|B3maGBZ2q$m?k5Nj+Gv#vC6nLcZb-}%F2Nu9CD&`-;+1D~am+3sP1vxF4qY%<&B}G{QZ$&o3 zVt4h~|FcO0f5;-sH!7g|$lYh#ZEqZH(?4fZ=IG8^% zNrdSWOBH%s;tLK&kahkibvu)$*|n0eg3_)rR`8lYq*Q?1$#FArLTQ5ljpp#_7mQ$J zz!RNe0mG15Js<-o;Z}GEfM5$qp93E+Z@xQSJdack=fD_Xw&CqMsu}hIkUdJHHlcRw z9;)Kde*Tl!h698SE@iG)A`j_cZ-?9SZVyY^7~s1y(NESdT?Q$3M%w@i z54M1LsuBU^@;+vHOedIRk`TL@z+)aj^tyW9aDX5&68;yeQo`y-2mm!VVqv@}b%mycZ zw_cU@$Tk(l(1=!bBk zw5YGt7h8b{7=wS4HSMIcWQr7MryU|Y1s$;X69NZa0daSH?(kTZM7$~x18PM3!@OmOM_sum z+j4V#I&5T2D2tLl{MUGVA9p-zirh_*I0;?>JB`ywu<5S_)PkYe3$T#^Q|Ahtv2Dq& z2e^|arZ?^T7(QeCM^XQ~_a(LLjR7=%R%>R}`H77Lfyn39H8d~+pIl>J&9u^L=vu8? z{x(s!Tq$I+?0XKki{RPpFSI^3i`nJzFT_AlI^Rs-X8)mHXQ46`)Swfaq2jgMhXuxI(ju_$4L7-_n6x$a{B2BQ zosU=2Q+Ut2?XgoLL9u*?tqzkM!JD(u0vjjWO9t`$-9mdW(%ndfA{*K={B7h z<@HX(mPbs@a&bSdNlZ<{!{TnwZ*_WiXvGvxzG^q=k5!(!cDjC@x>LrwPW21bv8V@b zu>K#jx0np|+bnFd)-mvbo$2ojXZW+I((e!@|TS37b*HJ((BwJ>occ&=zhC1 z?!_V07%RkY<}mW{HKcz+b!Ri6@Z`8zv!79?U24et$nRb~dkeVnda&2&j@j z!=PmnF$xMKvo0VIF6p{BfhOp}x>T9P6bxgr-kANKj}t;@*}Emi{Tn+r10BEmSRSWF zsQ`X=_z#ud@>7kg_YR6CK}l}`Ls`oMML=h(&m2w^8YB4+ORb>m0*-CCcaDUO#9h;T z{r5AppI)5j92$lVv#IU#+j*li%X@3(llJ`Wafrk}(>Q~W4s+efvxa(nMX~!<_`^I* zY##bx?p)qe2f*d=f$Hb6#y@SdVZQ%EAA>T6nYb4oBK4rzUG>k*cPwHq*H0Xsef+a4 z_nkQC%}wV#pVH) zT4k+sL(I3Gmb!F!3}iitCs=Tkebx_Ig1VAt+_>{E?wJ|X_v zjejkC4&UUpHZMw^b%D4hry)u^9@8;}UsdPt{^o8;)VuDJX?hq2Roypl))@A>Ik3m7 z2yT?s`p2@z%ue<@9tU!m+}&69-mi@?e@iF6)VdWE^wADyz1|a6Xuz+f)V*c-+3ZUA zqE%xBR3X1b?GzufWQq?45b0O#b!W2kHiS#ogvUDE2py3VLhaD>r=mY0N3ftABFh6F0Ll44KeY~ zprTJ;ha?Z9-$HrJ8VBPV>&6*E&2e^?v++$^nug*XmY74byv~3!H9U0h^GABjl{_iJ zX$*tPj`qzT_B7j2`j{?h=b7Z6JK7DuPYgNjsBW*?eGjY(dsNy$P1)7>JV;^m|T$CK*#50IU15l>KGrYdB)MA>y z`N6hNgM8nW^ceH{vuno|hOmcc8?z6w|2Y`&bU(5h*qzox$_RItKrk67`|^g z-6Ud_Os-Jw5|cet0-idSX)p3uf|5g?H^k5C9jNHGiMj6C^QPg_Y(KHZnhbxL&g%z* zU>=zyn+SSDp(J$bKbmEXe0M$4c06aJ?c+zY&%O>{SJQvc!IHnJ@m}tl%JG710yFuh zqI}VL zvztivcUpS*zb+5wN zuDd;?$D(#!bma79^R3zMug07-*jjN}SanInYFVYy{#`X;kO0Hv;~fc*bmm>H!>Pnm z8gI%>ZPHu!?FVqPQ+vqN%FeeX<(*F*dOm+n2*1MJUb0nzTfsuU%!zW*94urDpiBo zxxRWsKZx9ajU&D}a*9dAs#Ce8;Ja>su^>+7|=SDY~)kBPqg zO{r)N)}cCSuQS^xq?#1>`IuXjbKb~8)TA{hZ4Nfo|2^%Dc7`+9(*|#IiAZYMboSXb zow}YW)STAbel9V99Co#asy zx-hbJ(ZBZXCut2mAiJ|vuC3V#Cp37~rhA8O$EwXzv-b+2(}7=-aqYidn|FF=-bb3J zUUs0~>Rmy&Yq<=}4FQvB$8~zSH4Kt09&M_VA)iHj%-@gpZgyrv`QPI6Ap+)fA)tNpldDppyL+__J z`EA$w$8%4wT~on=mEV(k*3gZ-)E?UZdWR2-+M~jTV8l=9t7TSI=+jt?KK?eUmfoA1 z_cxC8R@r}jpvh0DH;zNDHbCYiuXMEay{EaZ!`lN=sy)H`+^i}a-THTuHh~#%a8tL7 zHR=$n5av}} z{iG)_RUMQ~LrqgK=M~p~Wd4I`{w7b)1j+U`G@cDMg@f)-oAxLSZ|35k3wP%DUho|7 zm856uhrd?t-zOCZ)s;cL9M>@;O!CUe{Vj!unDdy-+ zU82Q9>7A14h4qd$=RTW3PrDfEuQL2T5XqpWGdOeyUc*2GuAI&H*ZvvKPRpgFV#KUG z%Nw9ku&z{8#VN2*l8}$sv{64?{~ukh)2U4>{`dwg7|Cx;d&Sp?f~u^{P%t~6DuM$- znvv2!NL6(;Ed*pQFA&ApoEJuSCkA1jY!NRAGU~tKzVzl_?G_#eA6Se&g z-t!6+)(+*rM-M5gv}~NqYE5?Ts=lGv^}N0eJwop_iNzU$s#6o6>e^O4+<9>}Fh8`G z+D=8k?Jn;66KJKANe>#E;Y!f&OQq7CSPR-&UC=dy~))%I$YSxB&C~2 zaA^9Yc`wDT*qQH6n>eybU-U6@U1nh16^>yMCjE?0m;Pq8Wm|)nMgM09WwcjTbSB{u-|bo}j|1TkC)D#8^do@lsH@ z(;r2$^C65*|B37P`BAz!^hUKERkdbwZo1LyQy=rArS9|3d%QF1`X%X0pA!0plg&{A zb+OX?Et)HN+inAqy`o?8+C^uDVORP7_GEIdsyrTN<+e)$M6IO;)1Mdk+Ggn9Y-Jb= ziGBqsieO@p#RW04CON@~pI(*0QmOQrW*QZlV!_2Q;q|}wgs(fI=3^3h3JP89DE(ZwS`moDdNJL`;~YvJ&<+I`MomX=2hPiq__E@T*HBOvrPw zzxQQc%pU3qJwXe^;M0Qj%EY4_1vB>RYxUg1{6FiK)ciYa?oGW@!<@NoGumYnya7>3Zeyr`VruD$i=sr5f38`cah><_2I?VXg4`|9PJ`A}8x4>K^n z{M55MU*%^HRjMsY=}=hI<=@v$6aN=21;QPtG#i!Ix#-Mi8Qz?~#P_#qy47S}(`Wq) z?Z)17D>l#hcZ++vHeol4*2i-<2=c9Q(hb*k9LHymRu9+txp6Z2&E8f#%4)VXnka4x zn&K{(qwv10Q@=`9SYg&>zO8Cyw^}HE9p{x2)v|MzowZT-MVe&k^s@2tv#UEsdYE3> z+x?#m-4n&H+jTjnNWP2)PaIALa#rp(mrqEcKVdoS|6QPLE*V?RSEaNK9!~mn=f2(J z9?akFxwHC8LUiAhoj-j~M!8XX;PBbNeqs9D+^eaoQ%X5| z31sgleP?9nc5`-;;XwtuYSpzsbvAcR#+mXa$sPnWzN_LNS`R}4{<){Cu+pdWkpERM zhGV$w3lz0`d%cqWS3eq~hM5_+cy9UBb9-9$HT`BXvJa9ekEX%rb0;!$ModjM69gdK`oyz&hx92 zs%Le(Zv$+e;#E_#+-KaWV|Q0!C@dBDd}}}20~fEu75TE3qK*DlqIhjudMVneY7Si| z8itB#>kXQB&$Q(qA}wi6ps}Y}UA~un4jk{NEmxfx1{G;-&_1A<|z?= zZi{}P-ZbSxDx0Y5IewnC8)9g&4didEkLMp8I;f_2q9O@sFLF?6dQBsK+B858prO81 z+;z#)5cWlw&;ye(ATy@QI1TXD16;NhAzlpHkXsCtJ^ebnvrGnQ;S=-&?iWl#W3&#M z>2Au8x1T=ED&t%FyP_&E9I@gGAMBZ*mNT_5$4K=zl=Zc{Tj(^fuxU8gvXO3HAr%%18o@l+PN5mK>U&i{9Rx9I#Eqh+};a@+R{m=1)e zkBgT5(R8C#y5;^;*qf5NcAX|@>kM6Gr-P?qm$I7D-E|+J_RYvlZyHK8Z#{k8PrK6X z)=TRngd0DDExzT}dJ8IntD4V9Z6T%7t?`<)t5Y6{NM*~(zHLUUso?KpH)?AmgA0vV zeUp|vX=jSuVLYeR*{X2VAoyO744#T+s&PBDSoFr(N0Rj##Od$-`kblk{>z-mChsR& zU+r(LvvXlK-DlG4wcXcTDbviTEM6R=Y($xh@0J&u-gkTNY--(dzTY~>2)^Exh8wxf zmgG3D!CZOg=_DsmQZLLvZK&gr^8YWXyX;T8OCq&jW=zfC2M^!$jXooqWHiPQg=U1S zn;sHxaG^D-3~rqMCNXs%`Za7(vPCEcKLI+Yg)Jr7l~`SoF5#&+@^jptybWEa)>00| zj^YDIz8v)YE2n@qx{`>=N;_-KzbY0_o?cOQ9s^S4BiLarYktn@MZk~Pp+W<+65cwI zacUTZyo)MZK@Vgwh=cDCkEakx2$T5_tC`ebpxlu4xH=UpE0rJ6ar)$( zig|fw|JtN~BSlzuxzTBa>d*pQpbKW7Zbj4};7fpSVFv5WY@st?ZpVp{EelkpvBxPaIF4Fnu|h&Hi7>VTAEe`tXF4o33zu7N@DK9&(TOStXkF3s#nUWK4)6-{V2yDv zj8w5@N}7LDz;NzY!F)8MQoNU#->@nY@52-6scwE+3R1onIA73A?Tb#?iIIrp8%|Pn zk}xeIa=#;21;lmu4BNF!g867hJGUSasOSAQd8zC6Yo}1I2B%udyhWg@<^)^+9(_F7 zCRrEvEF`Irn0mbGB7<(V|E~9Rfb&eqMn|x7!ZAuf7;PT&iAD5!`|a>eL@hE{J9{N# zFicugMw$fX>>&rG3Xv@_LQSEuNJvu+#busWpyS_2g6$}Y$WBQ6mO z%oS4C+;s;c`;d1r=b~`Lz!Jr1*HkXGTntOD{%?8)?o4ji_84t=Fc*f#iPUuvE0%5X zfSVq!?|@uV&}&jpT=dT>fJS_rw8t017bpu_%o2WcIVwxK%wZN&O!AxIc}*sCkyUw7k>AYR4v%=u zevgvL%TYq20n?f2Eyx*^Mpud05~(gz7HuJS1k;FfjHHUzJ|+o;uTHgoI~8a_%KnH( zg?#DEp5a}%4AH(WW`#$z>;5^qxrqlZWRL>lE`%otrUy#?H2nT;EOxRt`}So)0hn^a zJLwrT-+bD)KR|t`{U$?uoN2rVKr(t)1ABu-bU~wH5IUf4yH)LuOA5m;`ca*4R&Sqn}oinB;#M02qNk|gQhgo#WyA_u;3h6{ zRKFXcPF$BuUVuL1OE+tIWr>6a6M*(^RA*KX0Uc!bCxXD&E)a0(7@>8U= zVLRWDF6NIFs5`I3YPuWDtG*LOkBOKLdg^R3t&oaI9(EJ}g%d=Dd+o2-7i`TS=hP+! zHlpJUjbQ6Rh+4z1^K!NeD8UYS6A+|+JC2xm(^7&5W+IFSlMH4sk^lvSVm)l?Y6YII zDd+n#zw-NVtG3nrt6cf59>c{Qe^0y69Iwl08DQ~X@sd%b)EVL?=@wk(yr=5SdD2oT zZwAhY%fE9oqYS7+9TUmSXCa!=UwClG{`}@3TX4HvD+Za9%766L@zJRBDdn!&vq)m% zocJ;={f3+Fa(>$(62B1R7C_0%DOAs`_@0t`T-kHJSey<=W6>}6Vv&H;A~2_Tw&5D*OR`I7y3};;plTFe1Q$o!1&;NEU2MGY5c|?X`+Co-2Wr7T+g=7P?OjPSB zQ&6GQJuKlK_*#~2PoMh8t2CD|6+@%o-6Z0YF;yx_1qcd~MlpyDL_y&p9g9WBv!_cCCG5z|FM31_M~>VpBD&n>rP#dpG3feZ!2c_je|ibkgo zccCSo@^0;euUl+MLWq&Z7M%hGTlg6tCP|p^BcWyJ@LKJx?U1MHS&Gx60f`0hlp+|c z5}h-3>pkny)FvUHIEyNSLC)9hjT6iX@S{;e*PP;1lXZRUpcf3Ya=`-msW2O`vA_wO z05n@mkDya?RZ2I))4eE?9NuY}8L>zikFkS70EmGILVn?o!7WUbV`MZOuy)trK|CM0 zyzTyG?|gNS#ZH+HqcIHh#7Bf}M|cQfsz{1ri@T_S1hdj%nyI|Y5BlALuM}VSmx()1 z2{C!K8^&W<``0`>WYdo9d)*)eiZb8h&o~WEBUZ(q!nkmJW}y`#v@B)`0qzvZZA=Cx zNpkea>k)Hkwg9Pu`brE^#>bgb+;>$2s4B)WN>Mb*U+98qJL()qJ-i>u&c{?$e3=DO zc!Q0HRL6|HoFYg1nhWvf(4kI%kS@p<5ln>0Np;mwy7@fIBKu)ekZ`cC%$f}|4&AK4 zZl#R^URs-DkF)pNG}+UQQGI2E&@fDGBxw3HlDygtmMJRfd;NT*k({rwKY1+y%sjbc z<)pv6MLCgp^WU$01@Psu7SVXvRM%=@O-d@U1_PxGVKutOpLVWr{sNz=PVIJ5a8&Lk zHDIRMvOInfDd~5~5N^+DDcY8wJwfSZBVvl-NP*Vr`2DE8=j+q7ELNs5GyWqSzlNLB zkBMr9$yBl!Bw$z9&q1D}NPuGUuPsiW@@90ZMCz0qmSAQk>KtJXN_7ry85a#orxW82 zWYLf{Ccxu=Ng$)M!Z_e}Qr1A!aViTu3BD?daZbZiJ2h5_VHzxdy%7Jyj`M)(Rz6|04R1U-5=S zzJ#xt|K-I2Fj9=ceTN)FgJ5_E6p+haE(W zPCVq)7cvR<5+S`4`Ps;ba+q+b(>F9{lVeAwVN)VPwOXH^wW>__YUSebVMvLT6coGC z{jUg`DBUE_nvz%zWbP8Fi0sy)R}u2cn|fHL!=m^6DbY(d2mk_ z+}$%_*P;}rF8`jz8kC9a^BegcoZWxh^~ymQ!J+Y|L2jG#3p{OSYNAEJ6(XKH>54c< zDu8qO^F|@_hKyrNr$wn>o)m^H5>MQC($T*PX%OE=#UxJ(ZyqfNWdjG(tFEu_eTxP; zqUcz9&%C?S&mvlWwR!P|vp~<1t`u1Dj*bUqVas8?Izb}oPGXJauchTh`=;ek5MJX? zb|ndPxjO@+_F{FcX2PYX@>`COVru1Z$p03%e?Y6C#a?T*vO1uhD5KP%ofgQ0WwD3y zlts^t&i3NgK-QWpr@we<9+VQ`S}vJe)KP*&E^gZojY`0shGzJ5wj6ENv-<(C*R2AT z^D2e}^-nsTF8z3CL*H5`zYX?&hpp$AdGuX2JG-AT($VyH>U4g;9o01j2K4gWl0&jn z0@}uX1!q+;L8Y2D~wj~@~6RJO>$j3lYXSA7OF0UBR5I&`1kjBt1X;kA)exqamORLGn6yT@4oE^Eo zConG;!Gb~u*w|ymevmY!5vdT@d&#@b&75v*9rqHl8|^T2*!UBKT9Pz; zwV@cqwTCp;s}ObNh)?|z=k}eNa-qR)-x{hNB{{4h_-(Ct=qM>lS!<_R2pY^O|0P92 zsq&}%>IxA;UXrLwb`v6Uwa=XD%Wmo_u3*!v$&bA-=9V6%%z{GVkB=s!PC+KqFfLf5 zBRI~)r}8N~Di~F8XAcU3lPY8$6!~-POMx$%Ca`g|*sV5HT1sq^z7xn_uL=x-QYkqm z3@4}!i%v@pala@BF2@>dbGs*Lja_a5RjQa{&$ut?1n*K2g+TvQA@BP~s*EkuR;uA< zOvNqYYl5AQ*(1C_1>;#tjxg%e zwuVz(Vxb=xHD=aYG16=78h59ulDNe8zejK3^`Pi{j;+$ zTa;(4^U)sJKxF~Lwo#NIKr$F3A{=YX!t?xKTXO|Ztir0zw&Hq$*9`)6RAH<8(iDZY z@WrQwl4ivNn}-UcXB*w@+vw@;7yPp|@oowH%Ip^6PO%JebiLQcWyjwhsWDMW0fR<6 z(B$^Ue3REVldz}kD4$SI^Rbd1fm1F@-hgVD$Qn9lw=CD`r!}$kXVlYaN)O7ORo8fTKtK9|7dQ^goQL`&5 z!cYt#4s9L#j)(99w|1P(G+-h|bJZN&f?K^}?7SgtGQ(s=eC6F{;-GWQw!m7|$PSg3 zblo6P?KB~K|Jxtbp-ovQa6yITa(wFHBdx(7x>dXT?Icz4Pu}{Y86QEl(|%Ld)S%Ew zEtAH6@my@T%R_x3LfZDfp|k7yL^^%c!2QRytbZ-R$iM<;_GnRV098P$zn$?DvkS1w zLXCl{#F3O9u1Ew*FsLFhH+Y?jb|pPEiTN3OZA17a75&^Z8*mTXVaLd4>Y|{;9qrp3 zw+fQ(FU;R!?2x7893Ds?7O=HiY#hAgjAV3RJO(|0#ti81fZ}vw7h3UjtkgGWcQIxs zz=0i@!AOygqaD9(WO0~~uyG0jbji1S;sf5xg#eitVsTfE`1{VEj=vH+14Cm{{#F?%J(+ur-{=@{Go>$Yd$k`9B!_tIu_|^tG8L}e z$QP_-&E(&J?i4+wvvCB=>1??2nfowX6|60HxZeZj5n4?g<#1zNE-lJce*VS*YWDga z5K)a`qo6w_7Si!5vtvAsbuQp7TjB(?#hTZHXYRFUHFT^4%%lL49kkdN#{PaTh)IqV z;N^rbg5W!VAG}IEx6sG%nDmAnYf27T%pok6#dJt*?LR!59yves<(A+D$$+>vXr{(E zpR~ZdH2t&QE*BO6?7TM^ZYK>@%wjhmFRnW zq!Z0Y%l>{T+_vXtZvjL}J;8rKJu$cyWEWC5QkXu_R?NQeMV`h0!-OOTpjM)3=}n4S zR8Uuh`?GN#=~S+x*|$B?8z_KL0m4-OEW>ki>vJZm9N5UyPyc>s^u zp2|mj(~h)T&?*qg4p)H9OTxI?PE1ZS>;c8>3>9bM*6*@^nCp+-$%bIQacX>UI6jd} z9=4l=_lJu(q<5Ksa&A%?GyWBw9)E_BdQW?l$2b>h*Cohr<{`=TI*kT28a#FgYio-( z+A|Sr3SFLUKtHGUBTuTr`N^hpmx5`i7B#`;xXl53XZNR}MbPTsl2PE-n(@tpWjENX8@9vmLpU6|_5G}M=4*o#SL zptP5U&M-EVMH9~gO_Fe`8_aCI{K$_b!~<3)#zcSL1zI!Z zej~pPCK1a)&OhuNoV%{fy@B({I{B%b{Y-AhhNXo^0+PC%2kj{2f4S9@zVNAf5a{&U zh+vSN5{Ei@y&ZvQpyAf-b9znvv)j(hmGF|{x7Bnf=-S)e6BYt1VZLpSpaafC3kvcA z)xax18V~PF-K@NvFW8L*lv@47OSkI-Y7ad7R@R_A zCUDI)Kyh4C_=DXM=~;X=i<1hI<|CqH6AFRUNvV%ndZhB z^5C^?K}3Zb$y%7%Gq$GFJy`ZLCO zx|wQcn~Q0kODHo^{A`P!nrEXqr;5{|GjmMoq0cBN%k=m>veg(mC~2lL%OgpQITs^^NJIoCWRfXTGC0UgsV9y)iUm}lBx0e+11UYB z{r_2e#tNeqk{x!nL&cjWb|7$D)zF3EJLW?(?*~9i!AB*e7jz0vxY=(fQU5cf-N*4cQR@K z2wp~$M{^0aUgIQMi1(<9y8!HVOfKY}#F%COt!MHr%RwjTPn`0d43oe)J2E21tq;J+ zHRH@@#t$&)ct5?dv)~q>&_R*zpq21Q&qZT>lM|pIU4Ps$?Cw3|qecpk5Qa2}4OaZt z+0+Ko)V279n%)!rivjx9?ri%ay7pX2UGb05(Y3Ckg^XG0)=*-narS?;-iXal3gKwgw&c8wg5T8@Ei8NmGW|lV9BoHmjaK5;=SNcb|uEZmdiQU!|FGV z7{)$7NsoR-V2Ipxp&Sjn>HM4gl|0j=l4UuM<=uc~G}9Yt({%m1>?L*3Tk`{-7aej$ zU?%=O=_RYHDK2~!JtsW?m7KGNwY#;@Edg-QaXt9E0#^dA+2M!@0!{>4eIUu`jk%P+ zJ~W4C&ml4F0uhlm624ldvcf8s08zBBy4FN78#59d&%vPuK;qA`FK82?0=mnTy z7sv=c7;)vAFN36^sO)*!5HOXTOo=Lx*GZ4*cz1erR65Y=9&iUdd6a5O* zb64lVabzgpbpEkDtlh0aDVf}!k)Ap0Ky?f)x06B<64=2lF@DWb0=kx20V1MZ49LTq zVv4-%{(s~^Y*M31tI)>-$pK}E*Oi1kWYA}dW9SSzg{Ew=e3VwH1r66qG03$Sv!I&p(Ln#hFAV70jJd0zN5-GEnQPr>FLW3`Oy-Ul9b^hVJE zo?8q=Batbg`s+_1Sa-0#+mNDuUY*)A#Tsx%@J~2RoBlK2KwdyaHRYFUSG5YOc(@tI z6h;&L!w}O0KgRzRFIXv&9HTL;Lf6L|Rgi;7RsDHh&2)rgMCIjeNL(tw+E5!AFU>6V zo5jfDe-L8{uOHcZPHC@}krh@DNO^S70jV!+A((+jy$}$b6wD^oljFneIfGT>$HjRka`!&ET? z{#nMc@!Q|G5~kzT6pAwqMBIoo`221Gq)1t9>SWNV zrrv@2-n#;>0r)#8HM5sOUx2BVA>wW}5882mi6h~8EzT;D%~6L4a?zo=U>_R$wLoN1 z-qN{&`m(Q|4;M#`EVgum7H?DV4a)_}J03mvo|5x#vZryke7Tm z@D+Pdr^TYhJhO#%S`C&G!_%C-R%`A`wYYJ`SvP7ETbD(Z!4uqqQ&K(Fz<<#3n-()J zz&+zvlz{b!S%p2s02P)xgGTxQ+vP4LJ>yhXB*(vR|A7CT&`U3m(lQ^wVS#a63f#?3 z)WrK0&B(BaEni-`Sed6*LMSJ$vi}KKl5W4@WO;okTpdMcINdG$%VZHORx|NU@XS9s zqR!S%9N$@=OS&@3vU*E6s!s@6*Rq zdCLqMXrsLh>yrDo<;Jq|yUVhQXVCRD=f8%(V{J8c$4gKtUs$vkpFA56p6RxOvsO1h z=t^c71z;r3EMn1DGUWkTM%gg~l!%tzO~hbRCN$Q%c8EQz?wD zD{h3uRB)@E#&lRcRk+WL(Vpb!%@1VX?$#cefNg&wdk;OA-~CRf9hNwq zKeWqRTK$LSa{1wbX=rFvza?gqFm?qRvou`cp;*NiD6t(rlw{vdoJZM3PZ> zE}*LbMNA5+MGT=8@A;d&D3okd_P{_?+3eI};yYne$8z|C zo4`(^a~E!}_fONr7VwcF=!q8g1$tX}N7}!0sr6614hQ|fK3DRQ6>PGYwi2ry!_Qo{+wP{!>bw5DVDR;Jq7X^g%#@ZT++v-$Lp9<27Cc#U>k=&?&MRv&cZt z4#@kYCef%igd-guoK?anXUYfgSM`UnSW$rYX&!G=t3RYT87cAggJ&VC2M#SSf00d?MSY@a!knQ~JUX>lM6E-wtKzLUA#o@>!h#sv!k~RAJ0C{|@TX z^dBRVt&AbrYm_tIl1*>HhAK3Xr=R+hL8x1hQLV};YtyfDN3hDGBMYS|j7gt~RT4Ao zb-N#UE*3Qsa1a|_E)TZp934tH;)_W~N9~?g6=y>|nqhv?$Jky#H}}hBnQoK9^0o?t zRNZPvV7YKpT#lvqNZTsF5u_rG=m-Yzcfj2Au=qwoB({Bu`*PL6d&U=+QDLqh@**J$ zseqCES6Nlj?1`IGvd(3pLU7So_tYykNzvHQIGI@-cfGJXHlNw6{R35m^ihgp_0DeG0QDUc_nf>V;l`Kzhi^VxeEc?()aBVN`Lt*_~)?Fi_2 zt&j2&HjO<1R>YEW7vI}g?n|(;H(1kaWFND-?0^fb`gss(MT$Rj45O~Nj2hQb|5pl( zN8}xg1j}o$Vt$?hH25N-PO_CmIE{AGOQqw|JTZ>u40u{zun``kl;DUfjEB(gPNb_F zD9O3e#H~jny&-D*p7kDA#uT)&#qud0Gv5$F{j=*}vE0Ng0L7B+ri0kz@*A z1Iiz!HlZ5IkE0(~avOy_@&R*|uHypHp8oXO37NWRgUkK^f%9(01=RI~z}*_~+|_T* zZ@@SmUrWU=7DeVZi&M!PK>$sFPY~ike=IPk6a3hK3jdQp8!3_DPTj57=yv7JLnI2BbrD+_YF0)QM}kG zT?UG!lX`dRbZCX)Jxm+Zdl4wbv!S+p(PB6ur~6*I05&lW>G-6{^=N=%SVD|BjElBU zTld>`@Y}opcs_sE=OQZ)*d*w)Uw~s9WA=>!eKqVJ>E4MsIDxJ6Jl{K1n@63hto@7( zTd16uqOSnUW}I5c&SrL=t~>~eYZ9$N?Lq;W%F~Ue=RB`#ws{|jeXGEZ2owup;O_hW zwq3`(ph66Nul^j*c{xpg)GIC237h3Ycqn1iMugEfN)y}XyqF@MwC>Q!Y0`eI; zo1JhlLG_fjW3j;bG=n4&Ei>ac^^vUSrPV#9-%wODW)UBCKfDrClVdwhc2oH=7jLgj zM&QIxhz7uod^^4HUs$vF4JGXX@DGIQAWcDYl)Pq8 zOQtvOW&15P8)3_}k-i)6S#CIxHIpZUYjYaO=fg%QS~V)X`)E7TSS$3(FzF|NlYs{i z|E<*SZHP?tJt-{|#If7UMQ1hS<|rryAOYq({u(){p`qOB`1|c}7CvmBAB}4D?D5Gl ziQv7wj+%BgoYb3$2 zES(GmiKTcO$&4pCP$|FcbDfbN3nM&zaYj=VnPuP>w3B3HQ^{;o7PQK-;LP-$F`cA@n&~Ap7?NG=E;U1Hm-1=zEoL%EVKVRQ8 zosP`i$MQfrsk_^OECkr#m&^`9(N3z5@v{z+%abyy2MZ+@SulvH*xu-Tg;2&E!Oyc_ zwUY4XQ3fJeq)$9Uq4W9)w@z-zV1SO(I~oxN>|irq76U^uM(ieh|aqFkm@y#=EP74^pPI&)oL)HR5L>M- z?orEs%<*B&iAn!Q8>LWh>{{cBIZ64oH9lygSp~^GDy~blz)Xy7`DNR#UgK)gV@7vP zxGp~XgQ7Kb>CDCUms3ey7|>`}EV7u)y@y7iV&~Cbvzg$uaGG^-uD4OwT#WE$c?@VB zS3`8;22InJF{c%C%Nc04%%(HTMtNw#jLl4AG<4@ooK2RU?Q;QyOz^3l$T_@ z$6c=0!=L48U8WGpiss-h33kO*WEMg0$ehgX4R-_iTfrl3&jXsc{iUPJ2h$O~;~b;w{~M@ zKa*^20>J3df0B1}U*s#dev^d!tp8C3&)PL7hoXK5{0cSkkpEzj4nB^7WF~SEl4z=& zvAPviJ7H|%{hy97a1{_p*f*P~)q9B0H`+^Pl+|NB^7d5Ga`lpw-S=GoYVp8T@ZzC- zNZv1A3ARr>#l#E`cu9vJ5S4cSk9Rj+o&lL9j>`#@8ZqG<#7M`_p_c+t+mFbBo}}H3 zD!@1qoz1A=I}W%Jm3<}Hl|{ci>wx&I;tLGy$bfh6k70z@4!Mh=3I`cGOv2f8L_?Yhg&Hq=SX#Lz5(xd>ySj)Hn8f+?-I_Q*%erRwd5#0}m!|By zg$Q=@I$qT*us1zgUuW<4G!}d{BrAd?%nsibc?qo1CsSrdRFxO01xItV=+SquW;zSE zdYiL6>|{a4a(w7baHFc~!GXP2#q3r?5B`Y-KO*xjl6SDp!VkB1$$*yDeATopFri{G zA#{=!gAHzq(njWA(SX~sQtF5_*d%y>GeJtJ`0FM;U2UDe_cuN+-(EW~yJF#d0OexU z0Sa#Lz+Gf6{F>IN4-wgM!*2{OvXc)9dhXD#8o5OPah*>w?3j8>@xDCoM*PInw7ibG z_NE5-3<~rem=mKeYX(|(H}rKiQ_VAiyp9_9glnb&eyHY{DN>+KHD2kVOJ%X(-qlas z-2u3m0V~FwOjZr(0>V$eZ`H8Gb?!+6OVUTG>pH@kRNKZuQCiWJ`95XC;a_yXi6k}H z1+RM(S;T~pPdq%9YwX%R^*i|v2y%Q7%<{j84lA*$X`ZLFYOn5-`+P>Y;v*dS43O=v z5P3=vPZ?h%jAUwWJZzbiG%Crq`sBhE3J+y8@6g38?ZvB9xM|2TT$?6QCRyY)<7+)( zY}jRNf3Prd%{$wN@nB0eUnBAUqp7Rfp^Es{?$-K(CNEl(nX`9s?)0^9zE#w0+OBsZuH3_eW1qHM3}pMrO=3+~M>=J6L=Yy?2D%IY2t+5iuy( z{-q05N`6?16>Z&8@JH^&*JWBwKe`eF#5g|fCorph{C{(5Jz`U5K$Z>|Bk z!IWM34|UeVp@37D0y4N6Tm-kz#=N{8QqrELmhyEtrg`-NKS zVu(q|QFCkYIVKc2A$$y;Hw~u(LOt&(dvCSM!@2(w;oS8|+Pr$=2RZAR-im;dBcM(!gh<5~bvA6-40mMkU!rICXC3tCaj%Ia?mL+WJjIsP= z0O|yQ+V&g(^rBvA^0N?3srbNGv}fx>pUtrp=q&U@O09?7dAHB^nC7n)4y1 z5mMA;ffji55CD_CF*q4^SipV|?N53WY^XU<1{7S;Hv`yU*sv*wzxuSX#tX49e3QaM zX*~;}{W`nQ$=lT2#aw~=+38eidYLC=>tn8Wj&7sxU0%tjBri$-n@bE?YQDmHkxT^O zEk)}7DN%0P(lokMQuR2;_ll688Cu2{l5=81YKomA_oO@;+2NhsDGPt(=Q@T9|*)o8ax}wE+$0UQ3VPi zK!YZP4^Kr2B$tHQWvPOm+0pB?YiQE^92GR?8R^K&EJob%92mLhnVHflL5PF|j#M1n zGi;Mg9I0opJQXjVSiZ?6G zUje%)2mC|NPcvIudleu$+7HBqyn~eCTzUCLdT*%vvNq*}!oS0kHWaCY>%r z&LYMa*85|S75p8hgP!pilf+McD#ko!99TFb1T*y-SrYTeR>f_u2}ZX&#qD3as~q^k z@})I4`+)lED?r<BOMNcXaz^NKfncT5Q9@{LP---w$ba!NZ}Ou{UE_-F;8Ch6o_J?n~iPrbCc zWNitT+GVGT9Am3va$180;uw}Tf43V`=O%D>%|WOYdud@|9bFn!)mf(lOL7x*>gs6_`tpz zBd2D)_!8eiyt)(BNjK?p*+#AadK04moRem7&*@Pj6oa6Z?#ZA=8H(ca=1@tF$eGcO zUNISGYgMfzZz{rGtHPHCj}f8xK({z!kMYJ>(H0rQUUdf}jvZD__p^PSV$AE(I4)nY z^J;%yFV`dMvdz-Xa_1hp^vUhyW`Gk1FpYR1qYce)XFN;d@aV=qx|Ryu#_e7cHl2$6 zQ9R>{_q-Wss9Wmr=!9r+DWL6!DCs=HiUTvHKK{?DRI#S&~~-k$mDXAgwIGnFaG+= z_dmB$L{>iwpi=SK5x>hhIg>NTh^&n$aX?HjzMeudEBAN-$__o!z-gxF7J%FlP(Z5* zhgCjwZd|WuaXH15U}a)qA^V)|MZ7Eqy3HNX^L54wZ(sB&=Je{YcpxC8^sB81V0kXy`8!jg3 zUTviKJj%PWGE?GZdIKYMwvB4k&&8rfZXe&Jm(Q#3^C^}9c5M&~8;c}Ja`COTub7WAh~&8yEJ4p}Kd}|TIcrU9_*&O7 zjhSGt44))=g-3Iyn%}3s<-7x3S1XutVg4ijM$>DauVp4Kzh$P@j4dA#TG^xOrGAJqwb&zXK-V-#nXYq*fYkqY840Of9m zzJ>JPb_Lmg3LVeOTBh)X69|eD2C!xhdflSAR2z!s>I0Xf;nN>?+)gwm)C#Zbqjv~ zdu)w4W@Ao=NsXgBr#BeVE?OMjIy28Lqeau6jJ%E|)V0p)6>`(WYG_j$OlOS-PFd;A zKUOly%`%8O6i6s(_dNE!q&{;$cm90x_O(^WW_kL&CAo!iE@QLgr?=IzcZs*$xD*-) z8&Rqag1EmeaC&7DdW8<3dn=y2UeBpB5qmVB%rY-aF|GHsGBm$->XKNSZ~H`v;V;sU z)`0zGy~Qa(_u77|bxS>NdN{rtlP^1!PNF=bJP)6B?5hPT&Uume`*+w%UUL9#?C7xw ztYD%TAw8O|vHP38!<-2@J{CoiH8Iz8IAO#1-%3NgR2-dbVfpzdSf!Zys z)@c+hA@FGxrQcb544q>eBVCj)&3 z=BuA4ZpYb#Uc{z<71F(p0y%S5;BLU523KG&d+YWp1)6`~Z{-i?*5GHF%w#Am@x0^0 z=^dZQ6JfhUb4Ppn3(-fPcQ=$V28R75*3FT|W@1V+2IrA@=22owCB=54j2YG`=@1!N#X)WJ} z1W_>{_?}EnJ!~?h95Z?YF(Ey z4R%me_Oc=z=!2!l@@vzWXZ1)nb*^DZP&Dpnu6Z0U11ByW-<6@MDI%K9;O={}Wsf*| zX{WH8M=!4mUM99-g~P-Ubmt=FflY}>c%cq%KY%-9ha$jqk;?v@`T)Xcdr5v^ObJT` zbz_6Tf2=^Q@pmr3@~M}!Ggf_VcC87T>Bqa0T*vjc3U`&*|EC50)Z_lgXR@Rp@FJk! zej@8ap6ww7eMg;wn+Q1kwqe6SEVZE*w1D4Mh4LYgYUlZVg&1zn%G{sJ3d>|i2_;>fe$fi9EG z>_wYuKwo3ky@ulv8r-Jj0*%pn!Yp_1IMRp-^sh~2c z_cTUx$M&9@sL;^`x9t=#nY=F6WSrM)Avbx?ad7Z9mX)0^@uH=8R@!~AlRI-j-7`GU zTYCo{ir8b9FWV4R^f#3npzRw&->C@uz zunu2;87<=guUNojyM#A<%h;!IfNjkj(%G{Y?}1TlHp$@ReR6twfF9y(ziO3Q;e8LA zqRwjz$#Vx-s#JPXb^+V=t!Mf~))g5UanNL0f>PkhdwKI1SM=F^8Z)-9r8_NZR|oD( zDjSls9D>8Pu4M|-PIB%)s!mC_bbBjx4}sX*A>uWW{|fcH&(6G6C!M~}PUKRPs)FDO z2W%*=Z)F{dp$beT;#<2vV&jGKy&d&@T!Gb%+)Byf@|WgJ8VilT-J z6r~3`VIw6K6MdihGJa~Cl$D2v<<%%jh*H|hHrGm@NNmAMSVG^|sxYLeW;zwW9fI#t zzvt}!ozleEyhm-WRu@7BYs%;s>=R|Z?Q&I5M9!CLKnPprOU$*@EashQZ{UDMtt@+F zsgMmfgl<3$KDg`sh>|4yk+GGzak+fKzppmGTlyQ0Br3_=FXSRdA^Xf>l=AmnCSs+Ppd+-HwKt)p@)#|YM_MQk=WMaeHr3lRpydXFa zd zLET{7GbQC- zZqb&A4jnbeB=<;KM zKfivK(8>rexuLhLuKbY(`|M8p&Gc`8k3f(9>30nRYO8yC|8?Zc#K*mkx07yHP z;-unJ1j$0|=am=hGX;nKEgY<1T-r$fIT5L(z8hyXV1_~v7iQP#pN^K6icaUGvPV1m zGI7!MXq@=j?Wv{%v&`AURuqyK=!1Oh0z=>Ag2ZU`QXXln3i5-{Z2~QYw>W!%)le(q z$cnM#>{Tw-d4^|BsDX8kMkjzu?4S}#n%jIyJ0YGX21by)Yh4s>zGn>n(T6iH%9Vbf z)gT)O=C?LX_4*ftBm$o`^r`xwY7o@nT|js$&#E&U$>*U9V+_%it-Z>rQEjbeda4wJ zu>!5Do1!z^1ENMB3sF6;1EJhGyANq)Xa|G>k=%7BqP*YK{Xf~;N;oldFkxXP+BlXR z9G5ks)8#Eo$V?{{tJuaE;n9!fVOkG_-u#+W3`W{SjN_0m-DyWwd=uIlf#=9ZsR12s zlKFcXUdPJ+8;#NQ-#Ino{8u&_z|3BR})P$R`qncsUhfkmue z6?po?@j=QM^$Zw*A=M*u+|PTct5tk(F^y1)lcBD(8431|kBRmJ1o&Q2JVt-8p#kS8{s^p}sk8luMV0kI!mytnJp}YO@Lu z3DlI6r{%z(0saNb7rcLPB0d`8cE+9~)uRS0HJHWCMf37(@rph#C>Fr|%KIAd==BW$VzbJybj2AMu&c~PwL?mK2l=f zRF7O^^1O2Fw5K52TXRh)J@e6-AntKvWc&6XGDt}Sf$>Mtl)4S$FyL#Q#7(o%rJ0uE z9O8CQ*v;{Z2S2F-lIneDqh|^Vn`Fi97}f4OMpZD|^?hy{2OiW@2j+5U z8x8OccEC-n%a?f*vrB*VE~a@x>@vDI+p^hK*KrlM#&EQ;yzU2bbqRsW>o8slVS@ez zFw#GW{_`;?^?;X_jxLeK8sZ4%{M2Vlc^n2V>SE<2pk`~lm)2rt;8rH-!p}rhzn*mk z^pDN9&b(-YlCm|D(x^?2n5$56ZV2jFSX5{nWFUdKxTYrfx3bk4u+KC2ooczr%ZhOh zDaqwrXzx;nq-bhFK5@q~lcj0O$%YU8L2>w)HiaN-O|y4%*t3~!}+bTJv^OgF2hM2ZQdXPNeNgO2M#NE*ouV#Kp7<$Qm;L3F*pfT?-cPx-&V6( z$@9&TXgXhC(M(iCoB6Z#Xg=2eGy8|g+?SY!jdVm67=Ms9_oieR`|Ha?X)!H?P%6qL| zNr?%>1uEe{ldjDRo#R)W(47e!$0>o%bQCWs%$i3s5(ot@jE38c@p92J%II;PieR|W zo{WrR7|SgeJieAQ#(k$5WR!hQrZo)H1=YHRFz0$VL!PEMj(h6o?>@JMIDEAy|FAc* zb}ziSiH2sKoWE9F3rh}niy_EjSenU>=U;(RWWnxu@Z3_FEh zI`{Jl(c`KfbFoy zjkR^bmJ#nhIB(W|-FiZpJ$bXygoFvXR+-NF1Noyv^wU)|bFdX3e)ev|nS|_WJP)oq z(NC6d-#Pt}S`kz8XZeEZPk^=JV`vV>86ejnu2m9isqo%@L8&jnQ+QWBOql6Ntd`i` z!r1YSnEE%)TQFL!IiQk)mx2!gJ#5Ej2SYqQ2QtD8HWF)`a z<^_F64CbsuHAxE4rFa#Pb3N98BWn-XA%(I(+fsKXU@?Q}Gm3lR1;R@G1B7TT5|@wR zP+@L-EJyc;D_k-;sTYk9;q6Hs8_PA)5e2b^8Y~MvC~+L#Pd@*+puegZaseN_z?~Qb zL7+MGfz`0XxSwOee9iv((BbIF8~Yv{zn&DdF8V0B>mnR=H94BKUG#@XAm7I$##}1X z?gYqV^R@}EmSAS`3|=JA%j|D1JQGA5H1rj`97Laf9jbpg+lP9v&}Ez&n$RuAs`01d zJo`R6*QSU&8z3YlvR4|nLD>cbTFKy<;q)$sWYATn7UAN*F{^>SIA)?~uSKdyvoTpw z+X($8vdFI@am8)Wp~Dx8by%b7;)nIZy|jks<07`E%M+zQhr%g-)P^j0901H{dUwsh z)r8yDA>o8IRmu|`morMGcF(dpnZZ5-^2S{Q@cB9#Ly@>=tS>h!lCcaT49hwT$6XiT zDnJvtejB{~5Uco$4#k*}P{Bv(u~K+oCV1;ODMAZlrRAt=l6OrV7aT>?N#reiFi zrF|R?HBLrfA0RhlkeW5(q%)R4{9a3=pK9I zhbvEG=*T>8@5i7Lupe5`BZ~lX*Q)za`3`%R#5E}{99N(R>Y%I!9F%rr6lUY6gn8`N zW~jYcD+^!h$vWOJZ=!18B*POzdb7RuUPf9%|X&4Md<*mDFpVFoPUUqX(lJhc2GC|F~Rv`h&;sgQmQopR8^NS zs8z?I=2*2{H!x?p&hP%5KlQpj{tfPM{CnK4)#160%>%RYHXhUrCNdO zY$L#zNwOR0@qp^YV>d3QUO`9k?{mJd_Iq$m7hr+e710r%bl3l`0Up$BAuFsJTO*Ug zqGhhaf>k!bk;O-qx$nP9<;sFi3(#}bxX6Lzb?EIqpGL-Xd0T7A>X5=5CV}#!=3Eqk z&Pf|P`26&$#%TAh20(RH&U_;?z0BhdGI5hr2N`FJ z=yX;9L}4l>Y59Nbm(MI2dLIPKtG(aOg$|c@k~zhPK$Q#{OAhx1V3VZWlddz^G12&%!z4gdP^0i(WH(=_YO$z2i){l0(3RnrMH`tNpsO-hr<+ zzI?ozPnB}}4UxS4r2arQ-gQ&gVY2l+0H@F1tYOb}yG71H+02xJ(7~Q-PwO@$!HsuZ zOtX3=N)!)R3gLM7ASwT1#A!AfWgwJf$t?Xj{`ofU3XC8yFy8x}KDFr;Q|H+-$*Bdx zlLNrK8t>Yn4~DtDp)+X@{XtJ0cxReF5C`+SZ+ISCR52n@bUQREpfbLY_jkSUyL8b* z5oe_QuEVLbq5gT;2K;97A*vFD={atn>u!>zAI<h{I=k2J{1VEW=gtL+35@+-M=F7EQAB#o|>giv>a2odHAkV1Z;PC|WIDa}$8Y z0iB*Z?SB^p$tNnc37CGaPjM#HUj9dHsl_wxB5sqRbONGk{W;3#KNL|_!{Y?=lw*xWoBBunb6 z60WzV)5>_*Fm-DmU;6kFTl-$jl}pm+&w^KKSvAZ{TITPq&w()x(YYxnWJe z*SWgF^wz7HTiyV30tl)=VI|Ff@1%|Rvmn_S53e~Xu~VM7no#>V-1rZ*eHacE5F(di zCBrcEyeBEE{2lY!Pm6$X*5SK;K`@#55IpYtjHEYNexgTur__wYH?}hrjChi78v#|s z95V^rBU7f_4O!g<5voz*HPoocc1@GD6=XAGwuo*%<7deC-#K7-Y5R|`#)YYr>ad9M z3{G#ehOSz#STe!OOYdzPZV*7cJAKKrkX|-!6mK1yI$)YyB*}0P>C^M;?eYHa5NpJZ zt88>X8uIOTyafXoUhl}VRyDzv>6K+5qIv(OIAP-9QXp{nnkNA2=i%U>1Qz=rY7|b- z)SQSl7_?W7NE73Rqg#EBSR;Yn6zOZ4VD=uj<+$x`LT_((h+aZJ9i~n_p;RwjT>e%4wT`UIE(eJ`g>dCA5+2fF)2Qf)BHq z2yKXwRsqJm>DpVT2=VW-)s2A~ok^@1j)yCj&tADD-w#>W8FzlS1PM_T229 z6PYky!K;{c@v4V8Uv4em*o-axnB_JAvPwa)0jX!Wu0qzv@uCI)%Pd8w=-#BCk#vI0 z|4YxYn+ZQnonNbNN_7GU4|V-LoxybXVcM6?oPsz)tPlA-17IKKOk^4>I=^c503@PD zcdV2<10!BWW&`uci`=v|*{S~2^c=9#JRl@oJ6?_#hNL>YW7&D-&C6uaLs)qfUiMPM z&Cd~QkQ#UGlU~SYFQG(r7WzEQjV)DWiv7>Amvh@=A?2 zQhL_&-A+<^f(%=R^Yf1)d&e$^3$EgtoCnq2A}3kvXCpwiG{@!r*Zbz8i&3c<}dT!Bc?+C9@j0+_k| zqTEK;5>9uYad`O0ybW|1V$K@g!c4YaLi6`!Vim*y>1qd3J59}h48p!^FlGO6G;fkg zQ!gKrA{zdOx@Qq2)f~c3q{AT&;meJ3w5gYB&pSshLmpR7jW^Awy4c+aV&cYCXv9%rzoXOX#_Ou=Ic^fO3nWwu$HjAIjbe zJ$MGC0HEbga1690mM38}IJ@xdB4LD6tKu>56yz93L@vs4#@1yTn{O4**i5_tiY~yl z)ZWjl1X9}p+=!I!dUY6-_(MoVBzvfy$xWT}6k8oUK9~o%p3l{;g6V>TX}l!bJBKLU zYPj;U;csD7Lo+zWPLbK`ekepW*Ve7QZZdF1B%Yl?m8dh@6N9nXO%qdvd<`z0rqvIO z*_7Nx99HA6eFfVW^0oo9^~+DQ%HIL`p97uk>VpYWqE>p{tH( zhsXDiJL^No8tJNL(F#24=mC>xBUK-0iYJ$XI|ePo_Xw~oS%|ki+A8~Hf=7Lp2O!)q zZ$qnRO7+bGEXX-CQ3UYK*|o~zfjl>Sd=BI2>Xjrehdv?!0sYs~O2_Tu*T6~I3S#6Y z@D8Q`|5`~V$J8pM1F3mmC|eA~4}jz3r3`6_pfEqHxOE zD$TQ9gt~H$^GqDJt*R!!h)dTSCl5#w zn#+HYcv_{oK@?zkINnObO(tMBk9=sDcO%Qp}BJn2isB*QsQMp(Ks^qjMXNDKU=1;(&Hv7Ma` zwyta)Z9djn-HeVT>h!X!8s9elK+ezDqH}QgeMhrliSUUsfLnPDhbatF4Fcx&+>BQ; z7r3nMD~C(^MfCa1pKOD6(A|6FR=D%+IU;42(Q)wfE+2`@L$uq|2BzHPOb@bl`)~t( z49~O;%!7i4H20(JMi83I=v#<8<1AEJ!v?rIuo6!+kusfYH|!6Rx1)=1>FM(O6P>(% zuy1(UZ*FF8Mbt`0{AdPhofUdBaM#{a;=-0GdqeG>j#ryNWvCXkU|)H&*}PE<>IA3m ztV{QGNniNmf|w-GTd8aKu7x6Qboyf+={qJU@z zl{)%1F8HeI1n2cBvcH^|B>lx!iXy-#?4nTCST)wlA@hYt z=x-wDjfVi1nuJSAz|OZ7nlyN)M%2!3wB8Q`{TV^8I&=B}W~*ld)_mddpaP7ao7}oK z0AW2~c%%wnuAGJC%AzsSs?+7z(i0FNHHCVmH^Z99V(LIU=I+SxuNoA zQE8`UfqkVN7l*%qPIa z(1JDZRf`wkFpkKIFFQ7|~%a+SF*nYBYX2s;wKmT|i)9H$Q#$ zTl@4>cB>rLEv+OzfC3xIEm7Z9+H&Iy^U?7G)Z@`+}RiVW`O!@2JJG z&ison@sVEgr}e^3^~?Z*_1Jc|=y*xya@UP9s&x*D%7bTBX*8+m}iYm z8kEZpSy-48Jq}su$;y~?HoCp};<#?#y6=2%VC1~!zZ?9<)m>J0YAxX=dDAobX$638 zl#R^7hiB{Pn9@5rKh64(sKGL(q)|Oo`ODTRk!f#=t)l|C$6@g|(D5NRHFXTNUfEed z_UhUNf`v*6(7c!h)}rqslwb>Egdkc^6=zrkC|`uz{j_yk$ScYTKJrIsg(=Ts>PhwG zCv&E%X(M>9!G)S;RQ_fm^3cuKmx+CX41g*%A0TjcQsyBnu=BrK zcA(@WQL~zk3+gm~C{dWKG|Rtd1y>@EGNG+j3Z4yH%?Ns%2yNL-oP$&43i@`@Ooj*f z&rhp}V&l0s7*-|~_eY1gwXh(7(8h#kq-o}UKQUibc#nBbkP8*xCEFNzg; zbY3JTBD%q&;px%9pv(8nqFqa!f$y#tFG4PIB!TV_pkM#3279I0t$>5e+?74WwP>XQ z5nN-_Gkb>{8SCB!2JNO(CR8-U>J?qU>4@*0Bu&Qr{ZFPj96nHqlZZaJ6b>c1^h1ke zb7H36dWr;wq0S(?#rqxqLS%vODvuD=rynzL_N(EQ?v#e$Rh?TnSBu5+9I(%;#O``! zV`uu3=WK?Iaaa1uhQqpXx$au_mkd-hL+_BvW64h%d-hmAE{rmNfeK)I5%z)*3(=bi z7J$pJvo`Mq#?vH$V)%=sa`0m9sDHeK!_OY+d<-U^XtyKr!+l?w2AT!sk=j?ng_$UW zc{aVR0vUCyUW&nf$NloIY&5#|zIw*f)nUS$z3jfvF>KbZBDJuf5xsop2F%kEAxmIs z#+q}N^ho(zHT%?1&o?fUHtl>A#tF3B+CQ(@Wf{jRgyA;Ojb&>3fI@o*gVr%Zp|>TE zVMij>uBqwa6P~S_DPYNyFug(d0FWZp7PzGc#QjgwFIawv! ztpWK4e8wX2qBx5`+iWg4cAHK0rF-^YL#^;-zr4K%CjapKUAuu`eKPt5sG{}lQyE4G z>2goie{|6GKw{@rPH$IgMxtLA%b@G_vs zu3{Xx9ll%bFNn3)+d-oemZEVhw)dm19dOJL zW7#Bh7XHJ(0S@QnYl+$>%L*F^SMJN$^T+6D{*-8239uVVryX$57G!L)4&0vk zMcW@$j7Q*id2br^980{{{fGx$F@`DmK{O8_vMubhW>D~YFf)oJZE{J$4VQL)W6J_aAu0EcetQS8U!`#? z#1Yum*z|)`Pc+^{oFU&Ut&lRXIRsui36=_p%hR?I{=eqLq5=H+Ebc^XsMMm44W3^0 zbYj*y21L#hsUqUZ6iupz^SG`E_0ZPdKXG%5cCXJ>33gUaP2KzR0-8`EUwe;m#3{ht z5u(%h3;`DaNz{@97fzrEUv$$cCW@!@Q#;MYpw>8U5w;aUSo@y$@N8i7(hw~Ckno?t zK${)AGSxarx`3Jh_@IKUPgik&v^nk4mY8RAg-;@&l$mVL5&*uFhus+8yNH6`)Lyl! zfRW;S$k)Lbam{1{x)Ug?8P`6o>>JVV8L*1)&Z>0VsT1m+NN{wn6+0n!`8^-ofu67D zKelXiT|D-0mcEcl(8t&Gv6I2P`(yZ54;MUf4qJJR-#O9-PKt5nLKOdorB8yVBb z!s>uY{XX}bDApgO*3sn{p1pnBTj~M0mLhc-dyP+yv%-{kb)bXCGtc_TY!i~bEk=hT zx^#KR`tSR<2M+F}U3>QZ_yRwTWt){3xgLN!p14QwEZ`>LMD6gyf3R*v!z25XMk7DB{( z-QoXQGuU-Kld(q|z2u(x;z95(1;lyZlK^n8aK&dGhgYl!g3SDv#qY6Jd&G2%G|C)2 z@I*EdtJYQ7HETwtEJr`w;50;ZEV1$il>BDYeyVxx`_jE@TL@H8-afA}YT)bCwzX?I z5Fyr|Oizhe*Bh#)jW(wwP*;r5v-y{o4bVZFRpJ5173rem%C5BvX+*eH$Sbv@Ze7D~ zayYH-Rs%x8x4v+yWhT4nbP4?uXuMY6&*_xP)9i9TOoska!ZPR`^)R;Fmo{C&kOLBO zBT_b8hLT4JBm$#HjR>o2EOThqNG4VHR3~*smTnx0slKKRvuTg@QR!2WwDP~ zo*iC;$v24uF|#7{e>(t1uD|eBSlz)X>Cyhv@|R5M>(s-C`CR>M$bg<}$gY{WjJUL9 zg8){(NN;`$c(ug#WI#APY@k^KlRr^uWCqsKY-0TdYq@U!OL{MP4`gWiU~W}T4SurC z?rPcIo$CV5V)9)g%ks^DPE*)p?!@m(&2jWTn2BT1*@F+T;WQ)m7E}xhiMnXL)2BM4KkvHBy7X3%1^evy$~Szp z4!bP?CxDwBgOU=-n0=J8n5bWX{*jEF(I?gc#(Y$ae4Yt>hG)A#@Dx5mQe#v$P4vlM z#~1~zm)O*BXQL@18|f^>L`*y2jqgt#J$pFBi!yq z>IGtOU;W?6zn*Q^b;szX2Jr_CCq%*s&YATxl(wB&NbvA{eqWsa3JT>x0j!4Oz@%2G z8#f!Uldz=;iw?owjSFRRs%kt-vZsspb6v>ASR(<@;FNI@hsRjz?{VVga>p!hDAf*9Ox_`iD81q)!8FtbP1DE%8_Lin6*QX^# zmmy`rQX=O@;gT^j_BI)2prs|~!raZ4__Zk0ozca;Eu8QPOZG8X{=hMhz zG|aQoz(Xc18{(PT@m5g9&Dm?bEK=brAuo=-pj+~Y;DNx$itnsn`+3uE;F; zJXE)gYuyluJ|A$*sn1(J+~=Mz`qEFq*KMk<{2(G_?)@CKwBp?v7c-7#=Mxb0W&+GC zIQ`WTrWIy$^uCdx*_sEoW#%31FAq2&Kke4}@Z#w@nUm}pAf{nYWs|ZF(OczXEin0D zc*!M2qeB3FH8lF(f#1^xX4v3uKoWJtFgU}#NN7-cyLLw(RgC@UO=2^rT=sQPOs)1U zGv~97xd$TdI0~$C{(~w;J0LK&{_dwMPYFPoTw5J$Fw_YQZ%)NIvNyY z4>f}rTyaGzXL~QjzmkFn1y@3qd1pio7Y54xRKjQB3ghS`XSB^EysPwGE) zIn6GzCr}sw!`IS{V!3%wC^E73lk{=p_n3dAM>bd`0?b}*_?^^8fog@~E{6R%0t;(x zGxy?zM6g7T_3eL)24vq50S{PwuM>ZQ+50}eze5U3{rNkd-(*-1W}AL+{EZ=PPkYm;tDQ^}aSc>n#?u zg|i@GH(3l+Tj{pKD=e*I!x)fGzwMHDN77(EnlE{%qd7Bv{Kss{Cv#zPvr&*tNYZVB zw?T#TxRukuM1J(U8H$oN+}{;&{!N@MTJBiu(mroik;0roI{yBjRuxarHV?pv3xP-B% zE6&NPI3Gt}%OOw2Ak(jfaN~cX(!Q;U@-LBrmU2@nJiD$tha{f)d%#rdu85{J&*j** z=m(XeGbDjoUjVvTxDMTkeU}#a51T@$^YnJB*iz>d*qiqRKj}S99DkaRLF+|rxlL;>;a>v4&`IC={~+`iXB zTaQc>XOPMd}_E(6YAHmsZa z0U6LoGyw>~;;{HW)t#V|foy|uJ3rQ%Yr9|)=r=P%K`zMZQ)$$1h$F#E1X+S=&QUGbSCE0belH9)+R&*~n zFqqu?fCCH9JG>43gWa4n=dVP}mBw_ouVv0l0?X4KCadwTM`sx+W2P$;74L@|gexX8 z?%6Xq07k!JBt*CmInd9w?f^~DKc-exJL8g6Mmw4EVZ{NoN- zz08q97B(eL2ch@n~pe@u%pUGFKu; zgaXEi=I0N}2GySX719RN2F)IPT|1?nuAeX~_8iCecE0f+P_ zUnp`Qo8XT>Ao4p4F9Wm9 z7svPx{cVCZlyWV#G7a9k9gfhnfNActuAN?@>B~z*MLx70ehhR!R&>IJo6?cLFI?(w zvyzG5hD(r*Mr$Z&u_qdd*s=rgOOpP6-pdEVIfX*q0J#Yk3^ZG>tJ{}QR zngymL66k+edC7PzZo){8C;-!xAtOZ62uRaS3y?bsy6Nscf>nDjo+uu@4^@R;eSnmxTn=gA;f%(`x&<(_!DdB=yhfUuHxBw?%Hev zllT@%t+Y^v){|L>me}2rPO_4C6z**5Q=>`MyB8g^rBX2;lJ;=KijlVpb^z&+X% z@F$>Q;295WlaxsVZu|Bhg(0-(&!-PQJn$^CU9V zvUV;i!|Sji*OP~4&X9+86BHC{4>3g6hd(ty;*09MZPR_BfwUF5E)=piL zLl0-#KPC+uMFV})N&JwLzVMXrpVG+=O^^<>>3eETp^!ToK-)1%51Pr}QUT~wW_Ses zPa?@C*VU*Sqa@m&!hx_zjEB2qf#2QXfi+ln9#-&)CpLg@etyo_keZCuLI%Mg2Xkcj zPnBeZ*)wf?y8!+y3Ez+o_Wovc3=Y_y4UjchL;A97m`HW@Zfp+Me#ho?RzC>Jqt*5paPk~6||dNr=w9KROOnrk}95pXGxpt_2l~}{pJhd9kSZEgC zpk>vYKN+0sTV%hR`|IQ#e33VSjMkp?EuUwty3l7T1BpFRR%+QEdzLRE zTNa(9<|)&ZMC7}M`7`|NByoAXB?n<(O+8flVpyj5mA(e#j3jC(?viz9aFV{Uw_6x55PhZR`V0Ll>#|mK{OCul%$&mlac* zT!1P5UEP2h5BB1AN&3`C(9U%UKJ-A|fntQlSqXjJz=4r58*-gKq(EdZ(vbf9zI|C* zs}K4MPgcnlRSZ3B`mi1t=iAGiNLk-+U4~+LGB~sfG0Q+nwlCTsVH@fZ3~4K_B&ZM_ zW@@S#K%LIAl?~?uVfOSEjIS$EClUj7jJ;W$d4NFT{Odqk;8Q!bVwDhAJINEc)2 z{=WCEpW6r??Y5v%nH&3nLbe767(BBLms6tu(QuiKy8m#pl0|Q_d|aeVINhz*g_l#{ zneUle=4f=~dCjqm`NLys&SC69(0AXO}t?cHbJk~gFKF_*NEz@j5f0{whRb-oz) z?}xXk_rZ-rw&y14yAHEbw)^q40^|Qrk#|7CQPOWJS*pIxn3PWQ7*LzD7QcxqvPc`q zDDGgc6gFyoz{5MH=eyCYktIb1aykIJI(qkQnlNEud+l{t#%K-1bUXsGjdNL!{1(el zcm%ycvC%H<)>8%S_i7v01J1}UKgHK7SCOKU(j5v#hIVe-XT#h9*#93Rz*)98Kyo1* z?obh;Aw8wo;-Z0}^@Rb{w*3z}nuJc&QaEt8llE1E_5xgDmC~FV|K>*N3_E!(^CJ=b zExwzd#1`Pk>lnwU*LbSJOL3RE^#hpA0GABIFXkX{kxI&=B6w*}IRRVq?YGm&5!PzM zLD$|9YqQWfKXQzfHv=RsiL2u;CV=T_p^*C<-SRW239*DiF6Wl+!Ls|o&Gc4i+`R;? z6}nLH#MzTB?q%;F!DKU?TL-*C+XuR$;#KU@i(|eB@V6p&hdOuXx2>uL8n& z|6!%GN#l@3ReLY5wl`os5t}+_s z(bNn7cUi9GKd|;Ci1&QwlrY+ltmeq0yLCNG<>C~WVEa)ZIvB`JmP%|p{1eH&!9@W@ z3Rht1Ps@j-WJkOv%ce4KfHv>A^)F9w`P|hFleOi)g(DWf%p1wC>U5S=hd?>0=>lOZ)J}FMEVq z*j^7@pmE!c>!zIrFQ+1-wiupsz_puyvVQjofS3DW6$CW=G<9aiwBzMM)4rmMK6R?# zOu~BP{5ott7@029)HoVlv?-D3pNU1?0c}92G0r=sIaLj{Xy1sgXPF(8w@eUalXOh} z4k<2!a3=Z|qIA?AZyZ)OC{8ut@4s(D8EUV~20!Y}Q=Z)`D)z~6^nB81+k_6@y4Sq^ zbj6q|M!d!@wY=#3ZP6%){UM~Y0pfp~K6msz{Dqis#k5_P^KtH?tr4^ItV;VhdT~R; zfFn6c;V{`&j4A3=TP`!b64p0U%^|3bVEr0<4U2w-Xd60ZDq^ptoN>m5IO6KiM;wo#xw|9n?akR zihO(cUzu;h_IB4xts9=C$PyL7bRSZ_Xtue%@NJOLz6I&@V@d@aVN2}tUf6^#uE1{9 zKz>9df5$4o1fQSn4G~;*p!4f{<-^zr|3DXT6YRsbsw;jmFSTr}TU1kd_-zl8cI@^) z{n&HG(hXO$zhz}BAri0{-*%^s2XZ+jYvoN|G5ea`()Bk7vQS?wW#N513g*|Usy==k zd<6d(qz08~#r``K^6S6qDuvlIusSs!8%6~tGh4I0wHQ95*>0@av=}^1(lL%d%-M9b z(^j+#WKXW$zu+j@WLi}`g~wd2&760ULz4>4Jfl#ahtt=?elog8TfBO-|7*&GZ@Mhe z4JHKP%c_^6LVG|udSgwwoTSYy#{}b-mQi%~lASVJA2&1Z-BCZ?2#84H@0~#3D6oDA z7q?o0NGkrnw2k0xHEq`Ej3W%*%#|No5#0R-<3IR!yJl6U_QM)>VD8@aDwG(e-lN6M zz!?@Orr?FM-7R{9)+W$V^s@)kBRh$~oyyzIq9UoT8GwtcHw;ZSqO&I|1@WQTa^C9( zq%h@#t`8x~sp8;TvBP1woB7S)jbn zy}oUdV1Ya$NdQD3EQEpTJr7!%P&vkg6I(v>#%CW1ki~ziVb}{}fk0txkS4_wKNo&T z)!7zBG!;6CC&NXKc_+=B+V=Wwb)|2euL1}clCM#s2!Osl>y{K9TqERx($v|IkOXv` z+^UzQoc}Gs)SKU-9qCPHau{M5{W_%So{unf6`_PD2J;r1C2(ikCkXRh)7GTW zfY-Wx{w^nV?|uA6__26L+&=EYH4n2`aK~Cx-p=TlQ#b`dVHd}+so;!|aojs!9=+&j zHXivaqduk$g`#jDP^)JMVCUc?lWxy;c86b4TC(QKRRJYzB?-2Qj?q#8ZLcR~3S zi5FyTRlgq~;M}GKV#AyZhOXxjtRgQ2k5ktP*vYGxIR2*PZLh=(UI~b|?uzahq+3U9 zlBnpB6@}w}UxSg*+})iKAlMdE%ihBS=Gk=o2<(bU{7!=dO_km{)*k#4#qmdW+?#7f8AbyD zVD!avMg5HM3CHOeAlVRc%g4hUN0IwdO7{`53qTpp*zl=~dzQ%n(JsR(aC_0v1|%+? z?86XhRM*BAph4B_CO53L@gVPY&_m<~dj4xj$QuqDDxj#C#N3K}YYg&Xb`XiDOcNZ! z(40bgOS~w)aXsQ=sDOaPdICwUH~c+KL=t5<*4?F43G+OWNd^Mf`+Z@w zYJ$2|edZ+3#yaj7-|!RMa@pOkyiqjwMERAN|9uXb#^@}%o+GM<4`C{uelUOW{3a2i+&o;zKuKj0#Sj{Y&j zm26&md32h7O??Sag~pkgA;Be+Db50`yAwAaC&FU=0S}QLD!&i5>CIUr>ra@&q9rV+ zUJ@J2AFWNY+Z_(Ou?Ygzf__LYgpa>k#Dg7#o{*4`T5ePxPyXhs3a2`*#EB6rz9=;I z7SxEFXzsiSLTs6#kAvmp-UNU(AVFk&YCpcXrhP~28tCsd2of)`n)3L429-kBF28Uc zMnx|%y9Q=3XtX7(L9j4HLp@QyEF?N^Px`aZCS?oddMYFYLx?ha=- zdWh5;psooxiZhuLEQ)E6ysN4#CO*WChF?Y$Yk;}C=qF6vFG(w*6J>zZ5`a6Tl;RQL zm?97ka|2r=3R+CGSjgc7es~5}zGegK1nu{(0yWg?Lu_jYq<|9R!55KCPJtJ@oinst zBa>&{8}cvCQnrHzj}dSDP+<5yx6<}L!7R@6zQD$_0GKR4-JE3-C(lqakEk*C$F(-KMf#k9J%!?+G1tL?AolSJ2`3Kk8Mu{ir=T< z(b9D2SfyRk?)Y!&zfbvVYi&C2i)GpVeqHPF@*3Yav2!+vD3%RcAh~ysbM18W`!5>? zUpu7SIPRY5-1np=)|z;UMVMS#89zCkSgfh4x(7a}&7|jAZ1LF)x6s7tr>2EwmhLuH zvQ!#}?Yj#}OrO_u$8B{;TuOkhIu9ZBYx3%;N`W$6T=owMxj0zNuF}?OpEKqQ2IoK! zHG%7-*?GM>GC%=f_;sxPot2lN?c*^btXM5cy@9&yYX_H;^k*sP6)8k<4Sq3BNJ`?R zfrV&B;@|KMqy`krylzK}AljFKRE2iBg6Ygfy8Yvk95N<82hKd3}{5a@?$DSb3-4K41Ld27eSTH^Oru|6Z&kF~=XxwKdyOG`fL z@C3#}3`KEojz-;)PnP!0$6=gX=y@o}hX-j6#(b1q3LcG-=mwh=UK52tMcsCzt)+x1 z=^~ay&=7a4KL^p7xnvxQ{(t`$%8QQn>FTZu7TTN~o!d!8%^E8H7J)XhF8 z2U4kzG3D3dwsJMDMmv5c>w!m}ZsSey>B($Uvw+X~D<@E=??LK$yyz~k7@$K@&QtbB zQvX9k{8!n0&KaK9w<^;LfaX?+K`?v$HtOtWi+FjgEzTtH``jru{fg|<{((bl>f0Q%t z1@%SiE@h>At{~DbGc?C(=!sa4wF`dY|zQAn^T7(aTKJ02>j6 zT|hMtKY@PE#>9>(V`Gm~L2DQFD|hV%azj9jkHCp5vNr*N5FR*h#XfK|>j!0`;UsZN zah5tVQ_4Cm5P<%04Pt%}w_Ghx*%7*Xj2?uRV^BH-3s!@aU}fOYRhR4ZO%w7*A^yk1 zHlF}rlibW`Uz#R7fgss~S!%w%m_$2ssoNH|wnW|`5P^szsDi=c5;#+*67F_no%xNS z*lA|!$!CI1JdJxg+m_>k*I<2*DM z&hxDT%%2GA_vZ|XuG5B;8e3y(oOml690kfz(%1(LJ?-G&v>Y8fF3b?YSCLMf#KT-% za?b-B1Q2eM+&%O@x)gvAA2Qeka|^6x;Mc z%=FqvD!-qrEE}6%a>=ROZPt1_>Llv^CypEW0{*XNxpzx|>W9X{rhx z=}Q0)HL3efgbi5Qp}$wYMS)wjn*Fm)#v4ttqyVMD6Yh;={ zAq0X)S3a_9Wt+Ouwc}ZsrN@3B|s5#&#D}B%W zT;w|j2-glf26i2ExP4gt*)lu-LG4okUi`2#_q8IEX5~Iaap0qP(M(eLj>Y~6T5B;n zh^1>6CgAg&(tGP^3-lOA3WsO2@Ul!%>^AoR<=+~0 z-O_zAJVtpQBhS)WZYT9gzDYC={6CmAhwLe*Md?^8QbX*W^ow}fE_X*5nORwYBpYH^D(#3J`;^1RD`Z2+HFQcXF=L$K&S{vu-3ZO5 zGZAjC?WFhFo(8-;;{VOkk`mws-j|V^g9|YxjjlZUgk#dJD?$CPT+TG(J|^=u@(I}+GpX9+ zJH`a)15cA^XtIDn0R{V-YZ1OG2aVf|x4DoA=RJ?=$C)*P5C9R z9{giNG3&WMWe`z^#q=N5$)ENO+US`AWCed3VJ-%aRfyJz7_CS;=wvFN^7R=Hc*@z{ zZX2I79gFBv@UaoHl)Labq)aCXaM&&ID?J#SP)8ZXZ?YhTPuT#u|1=QjA;3*FC~|W< zGe?UJk6UHk3(s(xUk={X^-$IaYg18SLr=VcFTIGaTnY;K#doxJQYDHHQmr&Tpv5KL5(J zM;2h>Zn#w6@CsUiM|+(S(VZovJ5~k=69Di1<$n#86W%((YtT+}`_3R7n}V%3KXpZS zBY|c6_v?*f%mG4{jEkt`_G2^Wt= z>K80|t829^UV1NB$fvH-H2S9tk$or!K9r}h*b)ubnyg1V^aUU(9{Rt-_b!MTRk*B+!{*;HXMwNNyrZPsR^?{`9*Qm8ngkvfxt9| zc1LCWpuvjlPus8LkSUV6?l?St3!L$8X$|r?=uhtl4*z@*ueq8(l?~JyWeKi#pbeF7 zfT>&nyVmYYe}6o%$FMmGQ@b7>L`M?#JF&&3%^nfL| z49^e#Vj$qPit(PY6M1=w5eX|U;9qpzze21Y=W6bPxxRpTa)5`3vYiIxtF!|v<~6q36Q9-izM42Q%G(wH zF+5EYS-KVpu?M^FN03Q;GJn3(AgGEeqt?n{C|=@M{X_tt81F`?Mn>&A4PohoeutH(? z?Ety4<8c1^uOiNv^4*r1hxDPE;YrE#PbrQI=w_Mj%dW>;&)n3UhqJz?0U3d|5uZ9qW?vSpLhmoT**k8jjstst3aVY@OG z=RnnWI+Dir281MrKpb*1J>J<3@ECw|KL`8y2JYirT^P`axAhca_+4-(B;hjlG&hgz z`ZQ7q$QV7p5gOoyaZ6TeU@DA>kcU(U6216JEoQ8Flu zzM@uYvT&Lw38KSSD`7(EY&PD~TP2QZCh~-+jfNoY`XIHnN^!iL!Kk?O#{rfcV|V!h zBe3H3xJGtP)pdFDUpxVltFXG77mK4T=Q02{$A}X4p#6Sllf$km2nrjPC=t{} zB7NEyt4Mb?WvpyovQ5O;5SRzeo@)m#haNR}RAQ98Tx@>AJlzII%U;jYaQW=t{y62m zKU%e^=XXTYr1ZrxbEITpog}#oU>kODD8T7~AP@aVmMie!ZiS(fOm9*?EAoq*L9+n z^4hHCPbMtSQ6dtBu+r-=vFPt8a=z6plj}{5#5~}Ci=**&PJ)l&k9NMDLg!NoAV{iX zkp)~)x*|o<~K+=XC02_?=YzuBN6&oNLRLIy<8u5vi;?ah)qAT=W?xSiS#7d1&ab{nM6=swUZt zcSkJDu#MEitut}%vaVgXNtT^Cn8|6N%dX{do{bK8@jlzN=che7UjyiWJ_s)tFdJ^b z{Z2w2@DN~paDT1nz^zENh8Mp-WD@G%5`YKi+5e(?prZ5|;N214GhcE|e={MmFkgtr zgbe``jI}|TR}7}tdue#XG*IS}9atZqjt?+DC_YCTU0?>k9P)Nh>UYG3q)(dn-qsU7 z$@~mu$a=9jy!GUMk`r*?TIi`nc>H0s(O56U&;1MO9Bbh9NQk`6DIX4vR=;=z-CTbc zmM^{^NL&CifK7Z)|B&t*|HnflfH}n4Yb^wRw%KIsR@Xnx6NFGdSdgLMc4%^#j4GEb zBYf;;OTQ?2yZ(?>A|(E^2^lTILF?Q_Vu?(NLfSyot0R&PJeSz`I|f_Bl77~QdB6`f zZ+@wfSGsranjNt2W(R04U`7wcgI;m}d{Lr+T&muyA&}uVc}=u&9DEjiA&Q}4B{#x6 z1BI{RAA-9!h!jPkr02JbQtjye*(SUgb*!S$NlbL5vsI`Qn*V=*2zMmx-pCd+!ug9bqp8BOtL&QWjr~%3`c3W@3W+|ALl%(_q*~BBl4~q3ToED zTC3|?^oD~1G9ue;{dVYs`>=kZ_RbN`G=q8Xe?peai`I<4)3MSc=B+l4PDQ7}+$EcR zZ47EPPIBWrhL{;Z;6?CtY@;*bjgb5F11r44Y&$8sCi0Bk1qqe}MOS@a&oWT<;lB%x znQP zC-05xwLDi(mxg6YIaGk~g6Vz-bOq+-hOy7dAadXKAL3BbzribcW@|Ou7tO2AL*~aI zTn}5qG@Y>KXhNQ}W@KhxYk9$d+zwCJ;7wKvYW^Cz6NHa zfr(UfKMXlHhMf20pzJ#r0q}tf4NO*uxpRAvvRWy)Ke!z*tzA;|47aJ~Sgpf%|A1Dw zJJ>5i9%~-7>e+Q`kGdl#H7sMu-qW#5aSfEZ6VhGkPb9P2NWyZSJk4eK0Q+zppx!V* zk?4*0=WuuJyJp@1j8s(1u%(hd%1dU5I_7jMO#XQo49gB>r(+X-%-WRF>-45BL3QT` z`Z9&ut5qG%^hu~K2(QFFt@nj4GPHLcc9J9a4!54C_!{Tl;*unGcH zo2P@R+<|G%bwaMN6MhLFC7Z|1zVLRJ;KfMBm8n7i^=w2B=RgiDWON|PYKycD$HOcG zlO6l(dl;2D|It93n-_<$Lv zBE;UBqz{l0J<^;0mnLm!wB8lJL_&djh&-Nq`0+TF-*(FHtv%`g6s;DbodViDRX!pm zo3SG}j-QhGwmWpGFpvhnD!taDj)|+wP=2*4_Y#%eU#zzNq(2$KXbc%sjmdm1`L0g? zAS~ckT=tI`jFa{y8}ZLikDv%sJg$$&Qw!3w&TU(bLPD7iu7%T%Ac!sQoZ*>x9L_Kr;d?jnY6G0Q zOIWRWN4Peqe~*T1%}JAicBrq1p34KceEx={8#bkVPZ|Of5UL zhHmwljyuXrY|QF=q4Q=Qa(7c?Rq<}SOm^h@bqirvcE~j;uS&mt`i^<@(L}m)4deuU z7q{z!G83fA^qZSmK0g9sasn|sX3rd48d~zG@0MCMbg73}zqkbOOjYE9 z&CT6z&S#Jo(F_d%9~L%`?Rei(==t|JGwhC^-(v?`e2e$qs*1?1+7hl}lH~|>G0D|7 z^KH@^^{(etQay|rEnQ&WJ7=L>QVjnO+}g}}y`9`>eI_TY#JP)EAj*%?_pNz{+fqom zKy5)QbHHSaO`t^p^eGn6h(khGiGOrwIzzR4nYk>|!_0_R&klpMKmR-bc28iG8l)te4=!UDc#@|nOoN!VW67qFIzS&VqSjUD?*b5pHp%eduCXQj!@7Z)0v{xi>n(q-ej z=X3S{K|hCIlYc<|%nd}E-CBX8eY253hmmAE*BkFXM%Sy{y(fWZ>BjeULfCAZ|%LRA!86*y~wo5$Y zKPnJB(gF4ahsH?{c)%wNgbx0b^{3Ee`mqTn^q)K#18-n<)8SBuD8Tp0B=G8wHRzRFWIS7(>0Vfw-YK<{L^7-_jiPNOpmeL)Ea7cmyYM{M3f>fe$8x zoZ3nH1cdS|JWD6!`SgcG$v*=mCenZ%eGRf8cJw6Pk{!(e+|Ui=8RZl7NAI!+hxXP; zf5v`fAa*#AIaGx8uwZ>8k{kFWhm>KwB%OK)N%I&wvq<29@QZ~iv#4c zd6oywVaUD(CeDC;Hb6JT=EvwE4wik3BoA2ufuWw{5D%gZlkzfc!a{QhP7p#)0U#QT z17yGt7RldYc&N_w`!wN!ld$QaYm#k3LT(HL`6MQh56C0~v41N);spHcklq0#ouoiJ zvmrai!pSFaVeHvELkT*wCr%`gJeweIOr5Qt-IHDd5>LK>as)yg5(jcg4A}rs`Y8`Y zkerAxn_3X-i6lL`0DnY3>pKfIgone7hZ@39K$0F|gyoPAUdcV;e#8QE-= z!6!nEgNObWen_2<3GDvM;!@e*MO@#W)A*!7+LQhAjK*>G(3G@c;4%ky{d9-NL)xbd!Ux(z)^y$z93nz&kPbum)7}UZf@IMI1K9`?b}(dt z`Vt2u$aRDcF_L<(QR@s4Jg|iBs7d+QOxX!KJ)!?DAWwkEP0fIR(GF20>SOX*39d=d zGEdHvW(4M$I_n4@0o^J5ZTfn zO@TbqB%U~7CxS^K-UK8!gaG+Wfz}v9hDZkl&oqSp$Q~I9oDe3m6RW(#3GZjDq=e@VbD@tAAIPJJXGcSL|6b@-r!+8HD}(E9*kwX#Xr1`~Ej zdGKTa{A>xA>9xm#teXNO#h4| z>0(LBp(mdiA=<=%eYBlKVLz1g^dy`T5cq5Z#UUr6VGgB$a&Q?5=(hSvJVHo!)FITe zYq&{Bc&EKGPBrr4RV*h&B7l5eab zKhW}{JBmnmmx^F}!}pX39Gf5?&7Dwyae@(K=Y%J);>!-f_=^LkK=0^7dqPiUz}X=W zw3F1NJkts21U(XMKGwo^1P>fAH+SnWhajJg|HB{$_GFWClT85au?Th+0X`~2T$9YO zpY4(X@KA@pdG>GYg!yk0fw-XqnLs=11JtrZ>#{)K(n;t<|19R-Nj@jop(OP%Ks_t#(ssm#$pd;wO=JQc%>bPv4e($costJg=MqD#p~oL0!2Lo) zri_4i^bZOM97_&%B=(6u3QvL{Z%lzaKy%??{29g}55|+|q@KUW*$F)W@@zcI2y|&T z<{nKTdlVpe1U&N(E}v)N(oaah-jMEW2z^FK9Q*$g2Zv!g-1XE0#@$ z3;^X2g!ZUNdz2?&^mIA2hxlaPAG*!l5(lSAK57u~41v6`4|>8AuRgtyhu&wL9@5Bt zwn86SB%F#KNrVsRFayjaKOzL2x(9biaqJ*(Ho^xM!f&Y|*~y08y)$W9Rn`BEG@2kK;>#xuvH?H%&T59mRYe_=cO4!IBxbtiCSJDWRdPOgxi zjf6WIKqlqxk1dG+{|pZDldCWTorrdS0e40a4@ z=RU7t6*K5ckNx!5s?=o~MJ|EaLQ6=3T7f_y{geU|vQfvRkol+wM9)}SS_d3H%Y6Vb8;>V!9jdN`6DrIY0d9<2y}1PuJW2@jr~5)ublj1P2fCz!;5efCc1 zkUdIBZb>H)$szQRA@7(6GQxF85coe1$qi-@J*xmZmIly)gzZBi4y=&g+0(G_bCmgJBt5$%H{^%B9w~vqx~Iyr6VeE5G*I

UtYF7C<;4VbdWu0U&)Zv0<@1pk7MK1mjsJn&fPUs7d;S z;MoJ7K>Um$$g`ScI7S?UBs%W*Wc`u&$-J-)#SOLV2tf3yA>1PZ8ukZlWDjP;$iCqx zc3=nXV0czQ!w4V1WIF_8?&y8sX3Q{BcSwZmDLZUrCk)B{210(6KI=IaKr8QKA>5Kp zR0-@h+7d(m0up_|LK7@VJ(r85hmk-%niJ570l%R=EMdhmca}qHpO7dA z0)e=L2|0#NF@ZgkIsxBA3BQOC_DBsD$N^A-y5;P(G^( zG$2T3k_OK=a>);MKb?@{y7hofnUhrx4eWynH#Qy(k{=a0C$%s))Pz5pc7)s5LvMJr zfrdk`qyXm`4$hKK{(5ARb%6;!TROrV6C@{0n-}#k4Sux){<0IVAbTi)eC7xGVeyg% z!IFPrA^P7l8438A1Fti9WbCXaq+oh*NdxOLL$x!UKaGb3%-I9qAa%w-^grUm_(70? z@R)KU0g?fr86bLwPUGz5hg)GfKzZUu2E~y6aS7niCbJ3Onc;*9u0kBkCzwJ3p^`&h z!=4f!W;0Ak2aseZuSq_+<>?{LvVU|Z>tV>GJwe)Rfzy#7eyEZgfRLY!fKETBr2MRe z;{lN2#sT#J836PEf!0v;DIvX2-`)&$h`=`H6R!1EK!HBoysr|W`y&p54g$W zJeBM01KkKf|0sEuN$g_}(!ig8ak5Vd8TwfQc_)oz53(dA@eDU zKfeire5OG0>?aJ#^+A$J>%Lu*A90hzakP-};(4|c_p%&cp|Ttk0(}>OWRTf!lECh4 zfw!>XkOQX@bu1*|(CL}SA=rjOb~ZzDVFQMJ3P^nx5Z|Imebxc$QXjp9hv7ncTv-Ai zjRW2m5`Tmw+mB*UA>qazDFPpT_aX;$5SreW$t3uK2TU-B3?O;5fwiDR z$%0P2!0oTG1b}d?kn`;6QWI_%9O_9wu#=5ocwqyS{MXl{4ndL}NS&=DoiLrfk{@yG zED!haY$v#XAi$rEl1~~4f0Xypf!UrVf%t?b@Q~wKA-_KP_{{r2kejceuVT7CG z2w-3x?VX+^B>0Sw^eH4W1{-T6C!hp|<;q`x>)^okNjb!vBM#z#Z0QNv;0OWl+2)xb zb5Ej3Y@$i!fs#%4l_>!F8%-d1mLC;?Cfdp8B5QK=kld0TBMH#5O|g=$KFS&)Gf_NjQdhMhDvl z2LbUZ51^B}ZuC9+Z0y`pLx4b=ivzbXCqBvA9WGM8saX7lN0$wL48oTYJ;86+|Zwz${>Vz<#RcKix2<=ILf4+r*)M6O>NCL4^wB9fr$2C->~c9HsQx-R{ZcbCvUkz(+>kC# z#GU`BvCn1)I+dpFNTE#hO0ZDb^ba?bx%Y)JF;B;d-X&+n_jsx#{cSYhQ%36x3Rc!o z1i9v;qQ6XERroSipfod@*`*hCoXoqC;6zvafVd3kDYI+jbpD1e9^RpiIK8#8v80)= zU4;wJzrHcpOOi{jhng`#aAla(dFOTx0b*t;=Q|M@I`A%wV~x`2ON5M#JRR^6wL0Pr zN|^NEej}Eb00Cp`53wwQcmvMaU>B+Po)8=Qk%llskMV2n#aIif2QnaDX=*WOVkYX;NR(Fxo+L}FgIX>3Zy4xu2={T>- zm*`LOBN|2Q|FJA#`!ppq1pVMfQXb@6-oQ*lgG?mgJN*VFn+?#_53S3nfZZ3w0<7R| znlquTWF#5J+fo7!#~N5i<+*-9rqf#GSc~kROC$NIZ`ne%mVG_ybXWkGIVpl~>nKl< zVV5{aao8-|wtnUY@Ev9gz(qA#C8mW*JXoilYR&n&^%O*K=vh$afn=Q7HlA z0T{w}RUGNXg$Ua`add4#{%0yAF9i|*i+X3vY`14f#JCK6oFgUtU3 zbY|s`J~L0D!`9pE_Y)*s%sQOSenaoGV!NLD`;obI^;AMfCN;sJp1H1@!zw*zzpUKe zD(#EylQbW#2Sio_ZH{Gv7;nJbl!8ZsJ$;9F_~!J;g5L96yRUGC+gNClEp%;SU$5Dp zy*2{}-Rh`zwpMWFYM*aHO%W^(!v-i1cFbY-O&LY@IfD$Yd%Fp^;pw3F1HHBQj&E>@xIRvy*2Oc{`85 zfVJ?gza*L`bUecDr-*`lH}xZk0+LLpp6u8y*?g3PjA9|HE}7_4f!i`_L2A{+^}mU@ ziB1?sBH`I|RxzHe69_pFxfOx{EHu#EF2s zsg@Qmo0eSW*iHpS6mX9MR$2?l5c^5_tp5+VmKahgDp_+taD}0(sW!VWs-&^=lS{S` zD?W?z3f`HS_;{9Ik!7_-sP&?_yY+xKi20-WbFEcQ$l!ZNA;RTIsY19_`eZ z4$b7Y#GJRPjC8C3cn``^KJ8#@s*y0Lw;=Diy2DxJum26U9cH3j|>JB_j80H# zJXJ^W?LLix6`@FUrC^@Eh4)d`O>7ifRofFg(&Ti>7{ zd;{lWXmhvA&psM2^=L}aIpP4XPm$f%fD`Q8UgG*o#}Vg4aI1c|s{`L8u`D2@?=@#% zPCN(*t60e|^9v6D5wUrsD@Y=n=bW_2{rcPss{B8m%90Rf0cmu6|B8MJeQV5MtEk<| zGe`VOsKh*<^83nT?Wm9nvpN5AkB?9UQSyEat_TxygAyOoS?#}NPs1I~Gl+}rRajdT zo z1IZr_ycu*~WH^l;25jfX5%mYPeMc)Dqwre&T|4b?h13^ZQ<$K*^8=h1q(CsSAjxx1 zYnzrh?J}lF{JFR94U@C`M?o2M<(m`w5-(wUi4Qy9$8`CQCsFfMlJ!-q*L}bBRVy*Sb)>mzf{^c;yF=IcWR%4l%Zn4)SsURo&t$y7i>D$;v zis&_*V?O99Peg9Exv}*&^Jj;6rRJbkiE)e~99LlbZ>yqp3u-}Cs@jPN?CWPPy z8yq2=kXFTVh9~^&RR&# zi0YH{T2ivI23$ZY`u`E26^!JY_m1CsqI>66hX&p=r9&2y^SjlmiBx`fbI=XN<{H z%}znfo~7Jn7zT|KGGIu#BrS6Ixf--)FjlJX#M>#=3avcYbDAf8I<4l^(5gN4gSg$# z00fNhkibt@9;ViLQMIRQD{mhrD7qz2&RP)>^uX|FS7&D$3CHSo1{@GbAeX~-YKHqh zfYbrqwdy+cko2ZJ749XgJ!*L?k}>E%8FKj46BZqhQOz{EYm_i`lzi*!|7TKDh})eV z%mf+z6yM85g=c8npy<2VdFqn1q02Ut_Ans}fE6W_aX

GIi8zxX*nB$R z96SUOZX-NuL0WbI81POOsFz4vya%8Wg8)mqk81ntT0QUT;X7GNGvW3VMx=)0a?03I zMo1eXb+A2_jZ!=yHRo2qO+FH__5bz+2s*9jm|p+yf2(bmuPI6xr%IN>S{wPIjksK94M+A4?Lc)F znvdWGftHOtooLOXy3kPoY3;zR(i9n9cf22m+<1j7OmnQG7cxbV&`!Eieu3kh4Sa}W z?TrDqMn4?Vzl}4j!dtnt9DmnE_G)OB@BD*ZR5o90eh5)dZ%;rC&YsWr5NQ9AP{@Mk z+R*3tg1nXVZ%u*lnV!{cBDJ@etfpBP1angAsFwyIBuq z^V{uQncQVMp%-@r$rWUb88PeP-zl-pcR+G=e#B*D5HTxI1Z*OCZttyM1KbE6T^+?4 z-?Gs@>5KT-K3&>ZqaOJ!_SJ%@mT+Skji4xiaaN!r&3@1FsC7cv8pOzavSESY%P7Ba zwb#U29Fb*rJzjmE5~S*&-QWE71OADc;ILRLlLZMW%$6-889%m)YV`kF9%d;lgwH}Q z@)zUk66gFE%aES;FqxbD!3O$Dg?+U^GbJsxEu3Ws2v`_qmI5Vc+|-*|O(^$gEhU*;HuX_oM;qKqs`A#2A@?fghqkHHebe?TdKfHQTxxz| z?Jox1l`VYI!D4+y5L2Z}7+|T)m>dU_UcX8)bGb9>aHX<=Y=(%oH4E`bFMNyd10AWP zcD;KwC`*xw!b3zV!Xbu+Gcq8(I#uGDmIvu2tCM2UZdI9dA-$16fJq7b0wD{zbd8=o zV@C4pC8W;#=WD`R3S_2PTDH?GqI*Q5O^G0dIdWr$8uuq|iDvi_gr}RKQT74Brs)l7 zaVJO08FR$hID|TsV~)8fM~B19%AGQxs$19zJpi?G@-8<&J{u6@O8pECPzB99rEDWX zd^*@U&FEwSG9SdVyo>?Pal{I#W*XX)o$eQxC7`Z>e=M>7*( zwl_f_1rbGd?E*Be__=K*S9=sq2;r;+-Sr6{aqfZjvrtK0e)wR?c=xvyEu2R0A9XfV z2{X-)>;!()z9(Lw18w6{uPpDN>)Sl2s4#WcbM;;8n*X1d$ZPqJ$D(DWa&i2$-0oMB zZhA7k2AvqUGd&q&ESyZPPBiU0b2Bn@T@GuE^T^WRdOJ*Ine;T54a}uE%BmF5$-&g_ zybizN8z|fK@}cQ^uN!jO_ikm8>k6dHZ??6>cKFZ_8CPPKv}WF49Aaf~TD|?TJK~?L zz}@Q%#v3a687>rEgZ8#jdw3rUTgwW1zI0T#3>w2qTHx^hq{`{UTr7c+2f1_OP9BHi zoXSzAr7ymklSXs5dAUAgdBqCS)x7c|8gFe62}F;xQ6LnZnkBUY7cj~@3p%mgqNy@Y zCMa>aNJzS(Zx(q3DRXMabm44b9#VHJnP3^pyqFR4dio@#9vrg*ZhU$T0vN2LoIy1_ zKkhDHqRt+7D;57mOR~E{NxpI5-q{HY=mHch%U2ld>ZdVyW7ZL-^R4~xez}<-FuZ~M zb@SUEI>=l-s2cjxWS7(~^0R_oO`_btMjujL3;s2b9#U{CFIh_m)UMDB-P_VaL;FUQ zA4P?M-#A+R0?l?g-Ap2Tk;FPzz)o9wVM|@j=P3E~hq&Vdz8#+=49G@hn1MK@0y(yL zeEBZFT%~xsZviseyQ}*;C(qg?=<}$u;f=F28v%I*m_If}d0N;3WaBcBy(ex>1VL}& z2Fq_Y=W(Hx-ACXjt$~D;15@W(S{O1L3alvH5vGe87hq(X4KK8W^PtXhZb_;EJvBmO z^Yn>=8m&LU-jb8maQ$6@&V&q<`moWTWB$;|j-US>IqFPi=a`*_FOX|8-gN6Qz(mL@ z>di}1s>5KZgQ|_=suD)jHlUz=umLuc+Sse1>hZNf!R8aeA&%k>ZW`8DZP<#3J+Sw7 zQKb%cdWm=Z*Ni|6!9oPQoC2I=k39R9Q>i<>mNsw;orQ!AWBvF1>0a-^7ufO<-%JPM z6l=9?W`wNZSV*ueTE=6A%GlzI3@<4EcyZoS{i-P=Zf#vyMWmhEmsdkW*mwqY6QrJ- z4fI0WuQb1VAHd3ap`=FA;{KRLGhE*lR_a|?0%t|QIlLo;4#ZQSuE6*oxr1j>ez{?x zavMZWHGes!gnCGdN?Zu|ed<9EF^T6)R$^CX1OH!iLE4uqcM|_NHwIvO3uAb6*d(Xk z;Tu1u#|}51(dU-Y*~R1!SbQfh*nZCPJN_3%AN#wjXu@DzE zS_8)`^7rDQL5tj!!OruKAjfUczG3YNh2*+&(V^AUd-$!D1@^?DY#`Z7zf~%z*{98P zQFU_6R|~ujL8HzUVzwA)uPW_Vgm&mvDsBR*8EFQd><=W5nlg6efMA>Drxb@}9C9UG zBUgaq4vm3&JTllA#H$&F#{&tB3A3=2Gu-ScnCd8Wv}3<+VHPiUIfS?%j=viO#%;S@ zK5;wi)<}tiHN$dZYz!Au9nm#pPY00%Ys2CfJ1!e@yHVx!)^`H;*V5#~qVG!Puzkk+ zb-743@f~nv2Ds#UNm&z1LLnIE0Hz@E@yi3+Fnn=n1aU8?C5`0_$Gao$V{A?R}Ghc`BA)iS!i(%y(A%uQt66o z2|~GEw^fsi3z)96xYVF1uNOf&f?mhaznffQf}|sv3e4SjY*22H zn~;uPLNmH_&>Vkkm=r%fpazJ--9Z9$R8CH5QO#!A9+DZA$`rjOcqol^ zp`sC8B9E$MhILG}v%ghQOwf(S9qm-dCZXd%g+|VJ6ljRXoB*W}ul7!F(!WQO6#dEB zP$LG%H%G@&9eb|g=*0RiYKVZIsSlLWxr$Yvpcc`EhGI{}0Wn-~Q>^R$U}iohky-wD zKkM9AIm)4lr;u%>Q7@bUSn2Qnu-i7z4Lq~|7&ek_+1-wI2O!DKS`1ODaO0FT7WC?R z2y(@i%?0E%JBtMB*38w|%croBh#06DVO2Uj3~s>T0r)OZAIBBjyLSd{fi=aHCsc#u zu{#u+z~roWQlZLmQRE82Ll?B_n!B5IxH2WUWhkSeaa z-f3vmMg_nhJw*Ir1Hcnpga!8)vP2nMb~|&=Of5Gd_sX^ewyFS`c>esFSF^pM z7;-3sBWz4P(L-=Z51@P24#ap7*HvNMRsS#SYoxURY{>79m*n`qd%&+Go^WJu0yblR z4o^hT+qouy4h^QX&0jGZ&?DP;cALgn*Unm-z_N%E6f39x3}B7M?^GeZvhHqmMDIl1 z#Eakdjh8Bp_Wd6<{IxmHj*!W38%kD;27ZnoHyMdGCy%X)Z1mE{mZcAEC2%^AKu_Df zb~#EwCAQLel>6t=CrBt`U_Qf3590;{B#-66Y4z0FU9aRW-CSl$SEO~6PByB=$93po znRJ09FRlu?zagKjPXvg%%YE{rCK&;T*p7@-Qfj-Oo|mS#X)%iriB5Qtt_g!EkU5k- zjPki-CmBw;qeGTgL5yXi8Q2Tx5Budgzl+xK#ynrn?HZ|!d?Y~(i)%mLt@$8fz$B?71Apqqo9c4vgx+x`&Lb;D z`WG@UGn@R|A8$L?*hlE~N7~eCZKvI}9RZh1mD8;D9;%f`W6sX-=Y87}*-azutn*k! zhJBzDcLIVnXMWq`FH;_wz2rWCj|>{SlKY-TC==@VBA0KcGGe{>HOf?GN>L9qP#k4n zsA_q>cN@md4^sKZ24}VM=D4J5PsFr|Y?&>h5J1i(bgR*TZw_9aQiD;@^1_h;?6qJh z;t-ITVg?V@rpJ#e*6Y&OqUf#|7d#c3GrleP(m6S)gt3HL!#6bu?EF*Jh=1W9Zey*< zkM}AbbwE9Sk3Jr_%d}B;aa=lSjc-I&fv&q&4u{B_*Y@|y(ryQGzS%^g_yBY@I%m0X znGrSrW;vZ39FYWn)36ZA@OVS|0>+B4@*+N^r~O4hx<17SQzCek1fp5^j6Hns=5~po zx@87DIHvcZ9Rec@|f{umpjCt52cM)cX%q3MQSx>nr2H0O6-XUV0c;d~^KID<~ zVGqVHR(R)n&D@-LwAkFfe~ZADwDj+yg9CYaW%?o$ zPBFftw5+(>wDvg3W)9k_S)y~8*l^#e-$oB#6;F1ft{zLzzXaDcwR-O&DC6_fRee|h z{I9pm>Yy5_z`_=|13#-tC>7@jUWeYCvjlB)vfqT>?7qNMrDcGS z@qek9>=ZED8<&w5hL%{)A9x45GkiCca`6S=#ru}n4{z=_(b7XE9qr9ho1|I5&qb)% z=C{F3DgoVuDX^nOP{s%FyuU~D0yp`z=@1Tka=gz;i$Twpzw(>BJ9tjS#{YA9HYu*( zr=bn6rruvqw2E?WK=^18l`s4>`n=$95L{REc}lOG+V|+pK6sihol*ysq@3Q+SRs`JR|gCTe&Tz9VD+u!R;4wFlWXYAc(6ajapL^^*HN^XW?D*eo?YH@{=@zSAnTOHf-#I;X=se(G+YkHzKfpr_dkv- z|7ZvYTdU<3VGfA)?^`4M13Gkl zVQ_THbF?|og}KIcwp#-3fm#PV4e$|>mB3lK$E1e5#VXe`U9fmsLZch$4NSOOqn)~A7#pD~ zOXC+tn4{R?%iGy`AjB#*9{1T%;SGB%;DDjKECFHHd~e5e^f6*tl($UnpJsN?z9RLE z5F&*je%5+RG0~|!R&YM}uR*Y+^uI=6FP}JATVHtVSufXvcV^J&q^XeRlZ-bC_6QHV z;nw6t)vkq0TUWWB@~uf>2jpE0rH;#=o>bK!(~sz>(Z7s!S$TaGeL+r=4io-()=3n_ zX{=eMK>{9oxj-6#JI5R1`i-FLmTZ9cE3Ny{dRPe0#eq~(+~c!JlDX0;mCTe zeJ1r@Mok$*&Sh`o!E+qDK&Xjzrm{(Ih9|? z($um*KZ`Pi=5oSRuKGFvpjAihPz+j4Se^q#<-v%d0#GEL%bGpXW-xy2*53=$%mKKF za2+{q_0e!zY<+gs3ep?0E|z=In4W87cch1^@I<@9K`0Ecu_}u1tp@jJ*eSGxf%@No zt^}p+D)x8|($T&MHQE_iu?)hIDUE#p+6_;DBgTB=fX^-d@d%p>9^t#&A!mQIl=+5E zZ0t9Ie9z!V^!770J+mMUE#fGfn;o0Mim23Uxw#!2YiE1`%nc?jQ?cYdW$4L z6Pkt61)tyxqi^f?uX`g0_yd0Wif%Y~YT#g%)1fu12Xh{$UjF~3YXwAVMK_hCu*AW@6`xa5-o0 zwN0zjX*6pYuCArZgpP&AA&7L75a&e#Hk$(jzQ5&Z9l7JY&+%q{%(@~9&$lw5CJ6mrB&)F-e zl##wcd!Tz22?3j6kA}Ktw#S53S$Ix+D$ogg?f0WrbL`ydDl6BYF2C~apIp2 zIKH}*eSmrG2p`Ay82%CTC@FN#`M*csr(vChgI`~ox=%OTIAadM5W;Gn^(SX_>gxjt zS#MWIz(}sZ8o`-0$w&{pV*e@UlWDqkj(fES9@M5vPn7r?U$-ihMhvK2SN&F1%s%h| zwvhb|2u$e1<^CqdA@xP_#D9E4r&!j zx!?xg4osb08-NDpsU62At?w@51z+T|!v=c0k-$tKN^!sMDpZ7^?@@3pl>unFd;V^k zHXD0He=^`%GK}#3gVtrY97Z=NR-fC-==`_b3iUFnynL?zjTSD}qb=8}U*00!dWY&_ zNjwGRgpO^^K_5RY`G()XpZf7peG4PgAfgBMv4|QEQ}pWNhvV>XEl9?Y_`budUGiZf z|FOw?qb|aACLP1(+?#cYU*wHXuG8iz;;}`;(QbdEV?M-U!zZ=sbwgyI^1*UZ2a@cC znOzsD>MD4b(XIL(dTrO`zOZbj@9MeV9OJPIH^eHSHMJy_g2ZJjWGe_Usv&JC z$g(K3N{MMIpb8e0saT*DkP4^?LX{LM+7hq|iWb=|r4oXp7@{N*iv(ndij0Vrwv~mp z5wxO|XrhI+LJA1fDl8bnD-w-Jp;%D_XvKjPl|(B5tPp605Cw!%Hju1ku&t#E!ZA{? zMgv+Aw1tQ*wTdW;3sgc>g|-NSAgF+}wTTNUYTE*^r6^TOg&8fOP`0UA6pUh!K?PU} zL_tVeQbcQ56`}}&Fr#fKA|OQ+6eDGo7%WsG+7yy8B(}t0s|AskSX$ITP(~49XxLbU zL4cx#V5L?i8WjN$s33x=D_SLpDMm{vV#u)=DP^+RWkI$n1(L*#uqs6mV4x^0A}mU_ zj6_B)vfEfJfQcJGqKp$;Ed?r!B3mnIL5Nvug-BW@kz`pESRjQ- zSPWp2+QuYUr9w*?MvSp-L>nkIWq`7cmW5OnRuZBKX+cPoO0i^EBM72`kw`7IKv80; z7>I*oV5AlcAR+~5kzkZ)Mj*y0vKHFWf~;WMWKby7kzk_{WUPwP%F7Zg6k{YC_xltV<50&8Wtl8TSD1Ju(p&|P*kE7B^8n=RIFGPg@RQ;l`2#qsEw;p5mpIX z1Y(sX5Uh|vi5p7=l>)M%Y^5y~Nfs4a#g>+>v0G{^lwed5t*s?$RV^V}sZz0uA}mHQ ztSeHa5V5KV$x?+HNU&HaEKvkYLfcWJVvtc7EK*j*V@8rBKuJq%u$Ed8R4t)Zf*>f` zSfd1BA_@s=B^W40qT0cqbe1PSqj#QFoQ}3NLy-13Jgjj z!nF}tv_jU9qN6Q>z*3;bRssNXK#aeVB8(AQfS^_oRiaTwF)fu4LfBH$h+9aoDymc# zM$o8H0*DC3kZM*kDHN8JV-=}tu&P!xictkv4OmbXF$h$G!DND3NTm`Z2*#mX6hfdQ zBt!&ZSX2}i3k3?X0x4~Rv7nWOf^@~v1JenAx7I9MGt#WtA9JWmXFj zl7y{`P$-h5s3}iSc0fqWi2Uewl)G6La}URmc=Smgix`g5h5f6V2BD8sEvqNmbQXc zB2Zw6D6}nvQd=xgZHpwT$})^4Yh|#pSxaKTP-8|51p#DPQc;4*Mip9G3RI0Ku$8D4 zl>reLC=|37186N^rIv^?i90aZ;7b`}2~wmGL5wXZQrj(p#>*jEiUq4m6`-V*lCV;= zWER^ZmesP_QjtX>iwN6LQlf!SMk5p|q?8#JuoRV53u>uQD+gEMJlXeQYb7~pcb*Q5Eis#6cI)&iUNYvg<>HEQcX+>mGG(oZyV8j%bS_q?3p<2p< zGTT^;QV7dsiY!$NLZc)WOJxSj1yF*Juw-IUtr{XxtVk&uSx^L42*F@fkz|%KmckVZ z!qsC@7KjC8MHLldz+wuBvI+{YmX-qqh=UOl3L^_@kr@_2WU)k)L0V9OSX)S-BC4_q zR7Fb>j4h%hL{ddrAfTefDlCnS0*s1Cq)6} zq(lLXMPS6Sg{`cjMvS2m6;v2oBN+<8R1uM67D-B218SmG8D(fxD;aE5Rb)_O3u?%< zg;c7IO9i4ulFF2#RT43h+AI{MWnw6dmQvV(ScobrC@}^qC|c5pD5O+WAT4E4wyM#P zrLB#Uq=?A2m0=q~qQF=zm4#tYD8P#ts}U({1rY=)P+MrJY>-eGltQqUv_)hVjb*aM zfWZk;3s9p*L1P&z6@r4r090xXEGk583Pfmvg2=%{l(r)!8pN`|D8ylHj9@W?Qj)a+ zLbPD0G9pD*mQl9AwU$b)MXXs_EtIJiD5!;Hp+?wOiB?(^Y-DAzj96At0g(oj z3WE|6RuE9OiwYr78(UO^N>r-B8px|ES54B(GfvKAy`Vqm1|&D2r{x3BE)5hRck7QM1f0UA|!}{FtG~|v4ufo z5hY+E1+%2JI;+a-#qD#ap}P_a>|6a-+k zf(R+9**hWm2_BuqrG|V8#%m8EBzp6|$;CRv~N>l!RC{rKPNe zU^0{ikzs71V2axUvRQ0`AfO6~X-JF~SxW^7h?c2XEJjdCT8aWzkg;uok}N7CBvH04 zMTJU>MwKX`P^?g7K^UYe1q4JZ+S@B4lD4HKZ7pKj(n{9b0%U?Q+AWNnC1vLK8? zv1(QWO0XLmjIkhAKqy)Owldm4s>aJGtz-(2Vi7E|qC_f6!C_fMQDH@D6#-&}SlUoy z1p=_6LZu>=D+y2=YZXP2V!#?%5MstPkws7xWw5CQ2~trJB~}D!V6CeqWs4X>sDf6K zq!kjer37e-0*XaO6_QaRlG2Jrm4!u;QCUF(v0{ZtN|KC31qL-zR?wm{##BTigk@+2 zVuM180<4P|D72waDk1`sq#9btpemA$w1HZ}uu()sD^P6~P-+#GSrX8e(jx-I6+)yG zwuOjPiv(m?vW;O|TLDE_6@gJ;REi2hf<_40La`MQs8K5|DN?azRY8eW1%W|QC?gtH z*dkO=tdV1Eg4Q;b5eCqxHp-1CvW2A*vQ`pQDB7*tsm5G@O7WJDsi z)GG=i#vyG5L>plnLM$Sp#3F(s#I2>Gkd$c9VyINIg^Hv_WM!pgN+CsR3sqW+0;HDE ztrSWM)Tvt#Vz6zslo3Tp+Dd|=2+2^a7DXjU6h#45MIy@4Pz9qS8BiF(K^D+f*(6IS zO2(8%RklKSqg47m5jY`5;gDYw*h>fyQfT0+QR1uYy45$?)6cG|plx1WTSX3Jtp-@pm%Vh*& z0NN>SlA$Pss3j>ZqEs4N0TNh%ScOW+C@B>XVQq|xR9RM(m8}>>iY=v)v81Uh1VI#G zTBw#bjHnH@l2#NzQDg+PtwPyrDNLDBn z30MuGP-59Y6|^FSv{se{i~(y{C`F4D8(~-osKJzEMoPg7QU$WfRSL;OB9Ks6jI^*s ztb|xm7TPMwP@>sO5VF`UVN%*k)KUnowjkMBF@Z%R5esNBDxlJ+jg1toMPvkHWhzR* zs4OZ<#geN6u&f2Ftzwb2j0To0AyI20*=Ye10*VzDrL?SKRzb9g*o8{Pfm+BTEu(A_ zB@!r#m6Zy}4XQ{g)V5h9s+6=ULb3vp86eRr0~SeHDgrfy6)LMLiB%;PfKjNR(JY9C zv=$XgQI=4tSp}9b6pGfZ5Tgqkg-Rl*B0xnF+ETKjP)G|JC6WqJ8Cp>WA~Gm8)e?zP zC80(l0I;m8wk@@!ve;HtFSYiEg!)0%yOjO2$xAC1nXUPVb4)@1xn#u!6Xve7${*q& z2d;`}pg>DxP!YdE8_`$2i9R>$gOD?ccv;^4*)h30hKh0A{J#JMjRU*r5loNge`$?h zJUOyCu%lc2beo~ACc;0~DVC&Kxb!DDLeXfQD}I*0vC905FTFR&cUiJwV`oXA{@SMu zr3a9SonKFv=)E+PfK^UA;RNRgwOL82-qAPADr`C;$A5SS6i~3ZeNRrU9hUUaiGbVb zs`-EPfE0NmteqXpf6Z0`Fx7Ht$>OV%g8#seg$MfODX15Ka*Y@Uws=%ea{|&cio9u9 zA+jy06+MectNHQZy&bF-FVhfGgRolJ#0&eBOJ%E)hz7EM%L3X>B6W9P#xFE5ZNXKu%i+z9!J!$lxSHfTFNJbNpw5$G_XReQ3C#yHy zEZ^qF@=up+6K-QhR{^J)&k!kSdP7uYd{Xj?Y2kjp7!gQClj| z0`aYnO+2OCha#iCCBfwp;iaVD>_L^wg<&>tm?+Es$Y zEqG)x^nB~8LaJnZW;z6GLgMmcDsqaqVT9c(j`)88J=Vj4^%1L}`oml`pLIF(+~SC> z-kpASU27SQaBq7)qM>or#hK#+;IXpeNB<2(>gA!ho|)JZG0v`{D_zLdXsrZPTaW9o z1>wAt33H4afFwomSouEq#*_Yzy z+E1Fi8a36)g95&!Gq5-CH!fc2?(kOdgjSo{LGTG-Zru-M%i2^3Pitb9{Zv zCp}!aM!8hWluW@bE#WjIrB#ARL9GWkIf4&}<#%;36)q)Q*)PSCvmfYJ(S_>gv~D(6 z-EaL*`*acBSJm)7_AZ#x4?^>tTkXED5aoizpK%ODt5B+oGYVMDlua(ByHGoQiIj&P=)zGS$_}N>U%0C!Mfz|2Dg< z`1V5&cL?OiJEXHs2i<@BCOFsOC0^Wo!fRlkTLL87W5DKA=zrjO24 zZbkjXhfc^q%)g9m`=_*tVWA0LqgrKx^vLW~c1S;hWnxDW-H|WA7FmJ%wwek5+v))y zhra_@_7xY)vxu2WMmRc5+}F5l-%se6&xO-)q8nw}o;k6uQ)32PQ1k8E+@o zwUa{Fo9V>puf1dlf7BukLCC3z19j;4l?f6+3hIfT-dAFj(nz?)?aXnKBg&l4e1zno z#EB29Mc;N9J>AHb+4oXHh*{rD)uyFYNjuH`sHt)o9tZ{f24softSyX?h=RCOdjr)b&_R1)YXK|<=5k4FHs{FOdErS+zq!P-b(bJR<%fLQOOTzE}PTKAywhq6F%z#g=}&BlW4oTyZE67>wXh+6C7l>>-d zlH>umD7gWhIhW2=)oW0Y?X`Ma_umuvt{8&tPUMzjHtykiIUOZ)--S)HoaSQ`81XEf zmLS;-Gk;)Ea(b&4{Kr2#N)&Q!wjcwhWjhG*&x7>RNSd$K1GKqn45|Y zhL}A}A5Q)>B+V29hapd7X!Fb+&awpYG>v&jZQ3q+cLfl0aaBG)SYi(jmKm~RP47J$ z_t{DBGqTDvuOWo}m?~IS5cd?er<9{D2V_o@ar`-Ummu!#&sMuA9q#teeQjeyYnHI<=lTiX7WKo&aK9HQyeVg;}n zfd>LY>C(#de3HO0iT)`uMx7KjCx4z-8%Z<7m%y?%hhHUqEYjOUeBVR8!%@288~>rP zAmDuh#INy<;I|6#CD-L_n;^w%Xyk+7djrt&q&*U&Xh5Q=UPHFs9CMXBH^LoE(GSQ- zT;M*(X>@IkEfy_vgb52d=c{&|m*ErN(B>W(VJ7hVD&w|En_^_l=OZ3ZM0fTUx)W2A zex~UzG>*%~NwqCjoox@2C&9IcLX6f0q}yG+z}pL(X0RJU+KCn>{wy3b2p6fT#p+ig z%DjBHjfX;e`^Y6C*5%zSaD|c$K2H*lN9%3{TS?>}h(6gUpYXl@w_x9yod-a8>$QDj zx0ei7kI${P|APIV3z7k;p21Yrwf_=TsHUvVr3&I}(=Ov!jtYHpQP?!ab0OOnHRRnN zkRsH6fHsXqIMx=pb?!@}TFZ(3o<5LDOd|dIyN7J0zLo?0--Yecb>m@rTz6V)mHl=7 zJHZXWAG==Yyo5UtGX4a6XbB2t?r!sf?z~$T>&LvTnqJ5A=0`)N8Z&i5721dkz`=rF zf+Wkq3S49bI^J~UNvFM9@5sCXo$R;M1lxnwC)YHz3O;1U z%7GB0ODCo`^%_S|{l>?;bpyu15=56o8hD&rqfVJa2prtDpdQSJ&`q9)`Gx8{;4K{OYmMn#JoW2lv zJ&w_{=$kC#tf;Dwi&oW8O^zzKRduk^C&ciS#Y<5DqN?-lW5)$43#tdMHpc@QS{ZYR zjgptrrCH(gFKEM8!%q1|)$20}Aa#vLd>)e3GNsg4HNIP|@neTW0&5FMJmvsxN^|@@ zrih6_n#1I;C6cG-ApeYnD2ri1yyLb5%(yvVHP6?1r}WWfkJn;&I34O&Q|BKLmpg69 zcY$p!x~BXHcU$f{i#}ui`rfnnj6@xX$mkHrL8A>=Q8Jp|q7+Fpgu%+H40D+y9?*oM zQSpgMBr02pLiP9Jgp(|SY*2$GXy_Ouy>Znt4q#Is0)e0HSs~9Io%ZQ%@ONI_fYdo` zmcen_D{Ab+qnX@e;-@uhfYx{-RXY}EUxJ2wl+!duO;eY@b6jNiC-L&MY?{;&RlJy4 zic*hhN@N5S<=j;_OUXzPkh_BO^l{Y=YrXoSEMJWa%#-iUDKsd&zc{5GH4!Unk*0$# z57jt!@rw{|uDgQ-=;Ql(8%BR)a4!#5C=ED5^QRjM1DlpHf0KWT*>O@KZn*WqNrYwT zpMlzY8<8Y7eGTfmkw!-p<;Y{kq;2lp9!^qRfJ`hwkJrpEf6}>a3N`wt!0G|a3$YOe zH10TL%99B|wb}>g(ua+*q0r5zD?l4{cne|ZS`s#Z*Vueo!gkAy9CaU5>q%eeiAKBK zezE+mTgZ?nU4F$QBwx+}5BHUu;4bf-OJuZ3o~zPF2mhiWhQf{F&3n#1CV5I6M?CWH zfe~B@qCdyMK@{(_R>(@9&DsS4fCq*J@Z&jnF8cF&-2I_4+3ciGvq2p2F#7w2(&C~9$(ZRu$WP8I7>cb0>+D?aJ1_w8j?H^$AH%%`sLS2>bDj<#tM9dz#8*Tz`^c%$QyGu+k7>Kh}N z*b86#?_RL9J#RWh9@YJ$LIv02kK-lME^hujV2fiasufte=z>}I@i)5aQB5WDx_bef zh(*0Kj9xigT5xwAY zJ<+On=e;a(jHw4IQ8(Q!o2(;#|F!@eO9o|6LR15+mZ@zk9 z9p@0~7ipUy>X`A!VEIaTm!r~{R@&eNGJq{YX zrJM7IkbF2TrR*AJ8Zxd0@=Q*-Jc!Qd;I*QOnEr+BHAJo zS_4L;Z)&~fG@i6^*6@33e=q4zOS*yb?|h*d2)=tpPE|Cyi5Y zbt`O(9~04YZEf^WN`46Hy<|$C`kj9n!-KT*PkKnu<#$Kjb}}d;${Y5825+M~lrUcu zExmoA=_877IJ_yeGf zg?0ODEMCC3YvXIex&Wx`5#F=S%s%{&`G?z1Q9K$qio><`@HL+0+#Z~{NkaNu$Jxso zpf3BxF!p9+a3ZdmE$(1|yA@`QC97zBk>xpHLYA-b+W_$Ejuv0zkpD%k2#h&aiA2o%7gg8>KAq>US&hNRx@mfx88UA2mTVZX^r5b>>ZroD6dOkH|RU5mzXRNIqryV zlz51VTO%JI^Mv|q67I}k5U^8Yb%OSb>kg)j1A;RwHWPrK8a#fA;vaK-!Ri_>K?ROQ z+T8B#s_N<&7dSL@58Eu1G9TyF&IILRN9i(He(5ST50Ai`5k(L-rOSNrD2K9h0#@IR zPBhLu$w#B~n7AO;jk7URMXZ~O5grc}4_Ff*btK?I^p2nlOXI4(m@g03$Y`itz-k6j z-t1F})WGHTu)(L+n66AH;_xU5RjO8Zti!^d#d!wV!Y|-HWRA%N`J%A zCFfI2>*NgVQqUYpU$g=cgkk~0wQY=SzZ%l<8VyvT*Ngh~@~SqaP!E-sA{I#C+rUZ$ zh5^CYM);;Ro!IOdVw1A18lDh&S8{W$(kL&E8XE0+t4)~bg62=l{7aS#e4%dx^E*2S$2Z+*jPcUAOH=)#u1b2gku9zHsj4sHR8^l+J&kkO!B_ z1i8Us{Pu73k}kqKiaj1kT>GpODOMh`&j6)^TJ5? z)!U3sAL0G`k+Kc#y1<^`K*%w?vX@xVn<&d9l7NBqquI}*^6!3+iKMcy<=dK6ZM|caXcdpSbt;K6JTeHJ4Weq()@D+?zYrGWs zGbQ?Wtf7=ZEno|$jAcpK`-dw4DT2vIR;2A6Jk<^ZI;03E%06?|s1;kkh3OtRBxO?(SXD9L6?$p5>Q z0$zKsHs&#-9vZLlUyrF~i+<>dUehPeueJZH;?^jz>BuDn!CZzk+Os$4`=11$mEo(C(Dj`wiICSg= zywaW^z1|iFH>PK;6hKcH+xhkkj@!F!?T*i3;u>Y(=Y=bCF|7UicqJHetxg9I$X_rX zSmY2_yW=b7R`r)_*;%rnO?kp+7p5oH!=?%FDc9yuhV$e6YH^$JzzaAtcI(>yFi#&a zv$g(r8ohh&TCfs_w-$g!tlw%Od&8w${1OKNL~v(4zWMx$i;hw}1L2O1W4~yR3)p@v z8;2w7xwhUq?=?f(Yjn~##KWsv0S;fl3zItl&iPvi9tU2)C}oXs<@ zY81gu7I`v&$0sogU2ImN$Ik9hJxUgM#yHSpw0!tXp7#e`70894mf z=$C+98W^1nX@}yEtD`qi#5vn8Mj+b}8nu{gZ3<`J$qLOrR0;V&7hBlgcp!&RyNL}X zifO8nh&Vw+S`sVdCUX@-sF`T-n9Dr|j8vnI%e7~NJwx+dA(HB6gD=fY-8wO&2S7MN z4r37JDGUN;ItIgg-R*L^GOu@Yc3r2Jbi{hPcWK@8E99HL2=6RDmRcZEnMO()8u!lE z_x{I4Ix&vn@YSKA^=ytUtYzyrB-sZ(gvqg}M#=jl?l9~%5!ZlK=?{iEZ6DmAJ9tee zo<3r)_I?M9o>u!7pAUVEj{utr<7r7`uqPp|H6VVvPoO4i?CH5=kku&f`87BxTEfUF zJRKpG-Z5sS9JH(l-^p(aO)NYC6|u{J7I4jxel03ms$*6;Ao1Zx+hUWA*Q*zH$^|-* zT1&q*cu z*mI&us<6MtTxc5G+bA3KU1-$=u4|2tFP-IsCqf6?^!ESY3f<%l?zbJ}$W zXDS4Ao{P*nSK8HedbqUkHv1FcscOyMsmOWnK+q2*THmcaQk!8*_1%sK{D!KzjbSli z$agaMvkBzEo(W)+(_qby7hQ0_o8@~Ym>Wfsr3pU;NA4CpsNK_DxF>473)245vJo2M zu1x?j0P$PAOw0fRwcyEzcDvEc-QT|fBB!ERUUNUvA+79VmDeRFI}Nu4FAP5|10SC# zj`+|0{USfpw&SsL?fjjEA+%de(Pi1wZ-L)O+79YZpggwI<+p?I6ipre1h&WM+rN&+20;&Skg6$_YEs{N4kin6a=Zd7Od(A)r4LWbOwGzcPSnkfaLFcwxh@ zZ+6OtR>XjZKwHBy(1=OEgjFtV#EDoi<$~!$nwC zD)&o}I7=rqrz{awKr$-I1*wtx2X&x$+%pTtdoCaHa7FNj*&gcIY-q#4H5HNa$LcQs zLMMIhkd$(eD`@3GT6}3I%*Wues8e>OI3X$4L&p)iu!0zbC>wH_GXgj%2zDP!r9`Wz z$#Xb5jZ0v`fp|xisB}IJM&?susbO4cQR%9yH>)vbneHp@OAhPH&iz}=9>q2~P~!b% zsq&LST33VYDn1uke5;7OBoIW*} z9&6G4N=aWsb~d&UQo_65fzAFh0&xOMN7{(Oq*?t$x!PJ2VPrf2dC8Zsy{Os&E&B5e z9`oc0AFP)w-k=Xod_z8n1_|ghKZOV5Ft;AD;elQG2&oPQW9?_rQ+edT>7tRDu zPf%EV?R#To^>Z#?+nO>>1$J%L<^=!rWAH6vG#pkWfQ5h&;Mv#{p8V>zkhY`T)r{h< z^J-1xC|@*YB(`1Y={dV2MjYlZ)r9ErooNlQdi2ur=d08bGTUX2KiPrl5}#r>1NQP^ zFm_7bm|B7I>4(W%R}O~}N%R&nJ3#t_m)V%|-1SBdO|_<;m}{ung2wS5u{)h}O~288 z23V`TG2p_iffYzr3K|G}Ij} zEq;1Erzon3&VCR>CTDbO>%qpYW-y6=-{<`!zn_@Rd#(C~yWB0gl%Mfq+egxD@C$qe z>oCw^@x*I-LMR*+zF2uZ)8c5O>}LCW?E{Z<74pdw%qOgeB55>rsrA8N}I-?%$p{ObxGpD5F~8$|NE|(aO{EV8oZRrQr`MLeK@D> zK{tXYXG)>xuN^2-LmH+uxJ@}$dS$?;kqz104Hk)ZRcZU{Q$NOMCFFJSB->=S&Gq6< zDk}$Qs4+!_ZMsq~ze6=1u{8=mZ@M@VsNQB0RdKQ3`Rv9_{Jw%t;pCWyU~_7ih0u6X zIvK8|sQi>}>i$(@KcYu&M+C!>nm!+yAUf-tn(;kGdR~CckYuYR%?s0hS%9Xaq%BcM zS`D91zx81)z3nWh+eCLy1lY2ow&9A2MzU7J*qPF0^a1_N-fpZV)Zm!Oz?6LhjQw=N zH+n6svw+;{KuuC4gWt+9^-)xh9QSz6iPQWv)Hy~b&;C6x{`k^JZ^_fO3d8O8y*Px| zcFF)_z1Sa#A*rjuVjSZLQ%#=P%>cuniuM?gFu;as0Apy&!zHoW{4~)(I6pzf+ zLoxML(p+X5imDhtYQA;VYe+>y!*)&Evam$q)tx!ZI&s_Vt7v$OQQ%wn?EmKodg60( zfm+D^a^35ATVmffbk}Ym)rZAb?b0_LYo^-KfqzMU>bD=pbjYoo=0lB~$-Cpn_w$yH zI~qaKG;H(_`jcv3y58~_0G)0>aKXjvUCbdNr22H5d+$!^M8kj@82i#6S^cH)##ww;`on5Dq{e+@hoF zrSy}Hec6tDEbA|kO+Khdr<<>j>q0gnR+{9cqF5>9j@<@Ny%&t=tT6PWm)->1dvsrL z?>qV0>8MR{Vzzi8an0j|1ak}7!$U(XUy|6+c3bb>@A^j9aNp!Ycl%q^n0e2;+F;Q= zNa(X^-Jh^Bm_cq5TNiE7qhRSz#ee2bM34g?-csG1v4RH~C1>$D`+Y1zdg*M>GpQL_0Ey5AZW!DLP@jndY?4MH#H1H-B3dxT!bBIfqqZUe@TYvT}FFP$D9)-vW^OVH{a z3{nsKkf_FGSZqa>ksEMkb6q@hs5%oHl3z71@N5qvuUVw9zN;qy|90k5KTZ#!HO^K` z@B}ro#9KC=M>Nu0l48ow;Qr%7tFCLQ-|~$NvHmu{q^M;oTCpzYjs3fN@`I_gLLs^V z4!n=8V&=nlf9Q2X!Sb6%9jkcf7?RNIo1EdCbj_$ZXM+Gn?eg&Kv z1zNL>xw~c&dcu`yU+6vcjQ)oX_<}eOF&_<>H9Sb^>XykkyqKl^e@KR0)yH?R%0=;A zD}Q$Zx3Hc);S82vf1+}*4ed#Dhtz6XtOn5j=K!$ROTxI@3Gz6*>$uyHEBF^YPz%adBY)H;)xL(d$&Xn_t=tC^z)DJmS3r}B0 z<~`RhyT8I&NJ8d+WrcRl8YO3j{V+iM9LYkBf@xo@;BLWgz0^=YrLCg+>_rV+&^D@m zFpsFcH~Qa$e8x#yHcH8e;ATnNy^CZG*C@`Ld6jQt3^r64ZS)D-LzQf75Hguh_bz;> z%c{weo$kqa2+;BP#Q1`!F9NKUUl)C-@kPAzNCZV`9?2j&g;rOiKqbnMsDSMAfR1p2 z0re{7)hxG6pCBi4aL{T}uFF~(cVrUMhDThx^O~jncXeDNtqicVU)^S@DsN9Xr5uog z*0bCwDhAeTlyj)e5`&aUZdMSfcYIsWDfaP>KkxU?q0hs9#ekalpAL140YLi|Jp8x7 zcI`Voy9r<391}w`v?AcDpW^#yF!y%O|835+y=MH4d$JG-!-`0bQfaV@ah?CEaVpND zno7bG&pX*7{>`W{+iL~nlZTa_P0GxT89#e}gfqnESKh4Yo`%gqgYnc7yx`V4tD!WJhB;DgPw+}7V5$tpYJw3+v#gegf)K0hL`xsG(^@OpVH&v0g)j5 zn_oYj0>+nF(_r1*qL$7Pvg`+76Ip4$ebIf=FK;rm3Fpzg;)6ZFhjmBf;TP_6RH;I( z_<=F&^b3=e2cBG0?NUB3ny5S#W>MRmW)F7zrK=;(mKYvHby^TRF37e8bsM#SY0LwX zGT1=xBr}{+ArzkHB0(p~iV?NgV0V4n&KmL(10J7jtdxn*RRv)99ji(EPPY99j#pJ6 zOHMNw{@W7Q2K#T0u)`~nm7gz>xSjL?S(GvMChBFX98T$@h=ymwq8$13$tV7WEOn%y z_ZG>TvAc%`mMS(npYI+uX6o2vb(&l+f8-Cqx4GsTLJOzfEOug`3&8k$aA26#xhRwK z{6}vM&cQfTKG7G)y&O4@R=={7^rK()iRH*KCx;6bUPi*ruJbpkX-YlJlwGZcdh#iI zA1nFC;tq@fTLMP?*DG2%A3*s9*>Z=3^jeI3;Bv@W%s?k0l3r_9 z3VB;eLjG5vaHv%B)EH|c_{y}%?q!bAmU&DmUMHVqtBR?6_1?ZNaY@F&T#Pc4m3y?m z-|mYnwfL!IvGu^EXDYVpf7PHT>Vcd_cO!EY7f@)GfPHXjPyRyXy^xMF5C%da@fTQa zW4jZmn8?he8u20BrZ%_mTG`;foj;6(t}bxCo>_)8l%$=+ODf4ZDO=OD-mqa%JLt%m zMv~dc$jFB>Gl+>x1a0{U^*X6}dv>bY(%DPTsxf1uUTkZA+f(t_K!x^&hZ!otlAq$o z-)B%PG&+wN&>fp`c9nGwpDPECApy~%zg>R1^)^ZkwW+~ztD~=Kz9*f`J+8x6;U}H! zlfY_`IT9XUAC+ z84~%zxW66No2CJ@T2y2FIusHD!Td-DHh~&m!k3-}zAF)EFLAK@&vokNA&j>ENWu=S z$x{=X>$&xc6+(&Zj|V+L<)yPshJEwBMDmgs^Ych7y75B@>%Mj2gXk5y&&&Gojh|3lTPaPC#$f;~sTzv#4}<1BWB_UlLx~%d+QdB^f&eN1RYk?NX(|n&gIZg$x!Jk> zK-Y)Ej@xV{c}n78N=c?%icNj5=6b4z9LLNbY+VlFLru?iLr#$JCG5%KX3-zEU%=<# z=&~-YCKuXadug)hyUDW!+7JFO|G>1eZz{CGPJV_^mHAcRu2A&jRu_HV_i?e9#;?Mi zsLVvW(H7y(Q}5>U>XE`m*JT+$kbp2sZ@1wq7AGC!;T(Z^m;vGHsdL588NO`=r0?YE z(6oT``)riymhCx`n~_Fj>eA@=vesr{?XNh`H3$B#v+5^5dl@>NmD5EU!74_5Ls>l5 zK2iqzVV_^aP3QrsdG^8-$!2wRCs@A3garQ;<(KKu1$r?*y!@B5+T5=HaEZa4wz z0UVvZzN#IqViU#kDqL?GXX>K~1k5*t&y2@aXO|PW5&|LRvD|fS|88mxF~Lrvv&3xE zA$#lglPHJ-z;>virytkuu9*{<)_=N=WU#(d5+d)M@!}6^!9irI6;|@FT)r3y+`d_#29wrzue@ zs^zcSwS1RFM{mQfgrFU1TA$2c)CzB;2*c0>65?1agH-p8?l=0=SOweFz;~5cKeKYxu)+NlEd{a z6k!;Rn<08(TJ!D?uC*%?&gl84h}|Hv2Ub-nG0g z&l{D|iX7Ak;XJ{ePxwwktUPH|m$4-y6?iGH#oKiIZR%A=z9$p-+7*eWP|CK^QSMh| zJB$H(_RngX?z*m2YUTzJxSS&xn1}jo2%px!z@(KQ5)9R?Hs1&h`_Ur-!*D5>Lyvi; z3ehl7jUDwGTk~B(IDj)Il|twAxSXGu&CH+P`KQ^y|9fxCb-uUWZ7OudR0K3bM-hqn zE-b1Gi!Iub>VHdP(X^(LGhdtffv{yCc~!4>jfJ69xN=_z z0>cb@YA}O^_X?_mS}8SfBW`EWS0+^A_RQ}h7%6u*%AFM}tcxQFL$W>kj^I98M&QTP z_KYg3{t2>M+0l2q5)>S7Hx|#!^2=8>WbxqGk@{?xE4?BH3E=R(s*}f&t}G4OcDM-( zYB=~qoKmmP5E%9TEHNU$OSE%XUgW6M_z@oZYkK@;Rd`>r0BT5*G(I(bhb_8qjSbb# z#soC*U|Gp4D<^~w=oo-_-MlHYJTL{a;4!+Bnkf9)U z9(DZl&Hpr=rO;hKNDPmAVSV-+f~656p1E2_YppBpZK+LVL04scryVk=&yHZw;bp+9 zhjCL5f{Lm7ROK%MAKTBP^X?xTC-Z=}mTcZq&dVQ_F|jH4k(hz}C5M{M{}ubim_J}* z(aYD?Y;QPu>^4#>CC<5H-PT#gu`|kN)(cgJs#EGq0zL&=eduRh_>4mDh2eF~6$Kz< zTPIx9Fbm_Zn4H|TT=~EYw_XThVQ{&84Co{)g|U#ZRale!iZ&7KrO~o4smL_#Gge@= zm@*HIXX8V=N5n)rk53A1Dd&92b-h19zU8?y*68itd+%qxk6N^0gSYw50xKp1%u;uR zVUwd~{lEkZX+v;Ai9Q8v;6j!#wqlbSs5X3;9&z+V!3O5_lrjPE02y$U(31>-o+$+# zmN@zH?BtBRwJQxk;9`45Y~s{$c?*rEE&v|}2yx`RkBAqvPs_+IaH9dJ`EUTnU##fM z``w&@;i=;XsuFJjt!IMqKeNUEY|V5{-77qvz~M|AS!szNcF&D4dG}E`R(mA!`F{O| zM^5oU`AxUKdA#`^TJyi^?yTy#nYT^{E->$OJuCm`Y> z;89Wy3K)|(ZG17dG~<5C3DXr7+R%XnLfTMabjOtB zvLUnJK5^Rn&n2TdxDET4^&MFO%G5XAS@QXg*ttWSiQ)&PVk8%>ED1O2MT5M>%22sf|1 z>zfRxh)z%KUO}5FH|ica3?Eh;KUVm8-@`0DM3JA7J(_SEv3MUCU4X-X=qZPwj@`uH z(wo=ary;oYtW9HW|AD^-QzYu|&)TxY>VEGpk2=HE$8bA+?abrO`N-hk-YuR(u3emy zTL13c1bM)SC=&~yR;TR%PDr9`7mNE)msD#DHc+pRexy26g24bWK+eAu1}&A4RUl8G zEyVaE{VqmllqP`tTK|lZp$!PSpmrdDqpk>1&#hPvPJ=fWoOZ|V;={1`D?dB14>Dee z-S1=0@=twrJ;c0=^tl_lA9wHI+<%lT=YQGTaW-)jH)H#j7*0_Ar4O5{$mjwY2h2M? zn0K&tZI8Y2xpIFN_kTIj|16KcHX8hRl%D~aPhWb3?CHgVdjIqL{7;e(Upx%c4}5Gd zR(3$mC-%N2(c$U5cd)r8jZgJ}`20_!?SbSB^?6-VkR%WA9*k#$_!?%b%_q`*avG-F zOtD4=akV;Ng}s+xQHru-j_9CxiN5iQ;IyzzmkR05HkAWg$_JFAlmOqDkRU6-II`4g zAmJhiu8HXF^PuEjHU?l&8imFIkuIj@t7#z*cu*1y;{b z@JP7u%q<-AHw6~rW(k9FR!9>9P@(+i1F7tOd@oRy068$hA%!VC7@l{o z%Qwby2pw`J;yxp@1I>Fac5~cx7rrLR{CXx0?<378S4r4|z0mysqsn4=F4cS^_0P#p z7t&u9!T9Z~ApMD|o6oqWUZP(PjJ3pFl>AJI052j7^56^GJAo}E*6Lb9@Ck9OW9(K=v z!E|5yBlk^>4=?YoxDe+}o9doNqRct}-S=mO%g7|zJFuJzdx_!sL!-)V0R3jZ@i`~@ zzMJ!XjBu>fXKucG9Oq}9Mmx{cx?{lkOAoAv|C!@DYI#33Pv~n&XN5Ukx3gtCVEiQi zMEjlyz;lRB%APiCB(UJURxv)>8_(0eueSx9korFT)8pU2sAlsY9nVnp53)nNp6vae z122;Grg0tzZvz}t45kiSCbnZ7C zW)MN^TTZekj=si1G%xc$9bkqt3tOGamy-syVV|=mT{M50)@&XtHM7YdbJfab4p%>C zdG99U1~4631?>eY@JSF<${6)ggB{@1*!aHy9|ObkMq{M5@lb1NX_}36ZW*C>m(;I{ z!CY5BHfh=6eQqk%Lf3Y#F*8akArjju+=6WBJ+r0T45pVsoj0TgGoClQ4YY&i0h_|s z-~#H{0av1_lozz#{~>;*4_^Z2TE34sjlmYW)Rg67 zer|$j2X_K!q1kBHO0aVt7``a0uhP6@R2;t>j!|srm(D_k$_we;uF6f46Fa;RA@w!(H-epz}n?EfV zNsx_CJV}hzZoA?M>PRJiW5-(+25oVv9ih(Z_D;xG%^5QIfF;k%Nvo$`!dj!uBmz^Pt@#Er#&x5{1(g1|q{{M3I^`71u@9S%KI@nY9cx|D)D?ej ziJ-0x>FW0_bk$ODj$lMYpBPTIIU1+-*7Lm)BSnc8H=0YZFCzd{hm!)fvrNi=wD+5xBG*RkNam;EpDv8$!JPgJrMqSgS4uFD&1?BPPb*wtcM#G zjKXIs0!>p!UmJ9$=bdazf-EoYKpUTM3cb}F1FFdc3WcUE7ia2q1!^nBOt=Jh_$)V7 zZ%KCU;6mQGf>D;9BKoFvL7=|d6RebV_#P6+FVu3#o?|1_K|ThqTew5RLMlgm#i@b`t;V^Lg`1+Xdnevq2ALkG8+78ygs9X>pRUu1Jq!VEcjusX;)PP%n z|8E6Jl6J{BAZ1&&Oz0dP3|3?1cgk8krG3K&5|@pF4v;NC#YHr#0+j)z!eLbD3K>MJ z6zvNFKPsxOD!}0$WRgfFI-TF(Iu_QZ>HBY-H}l8UE7PnsFT^K22_OI=2q+~GL=)x; z1OWupP1~|{`Ft9yAGfqG2P11iNb*bf7#oB3Pi3 z3IONQ5ND5dG{h~y@Es-NBOTpl4#~K}*^PDFk@&wktf820UAq!kx z5!lc9;QKw^VT*jF`ynE@rQ$O5%8p$E1A1LXdm%^z_o*zW+msYY zR=p+hE0XLqL-iyA49AfDCt!*mWpwI$VYYy|1I(0mfz#4Y@m5EKq(XQK1et! z_$~;ptQKwne+#(-Q>GO3vejE;KYE@r&x+&=k4H#Inp%`cGlMYnhIlmLe?-*0ju=AB z`;SYnnu6|CaYdx{-0JWg%~q0W+`yaJ^+kNJBZBZk9HsF?rn_ZMl?q^LkyuCu)Do%o ztiG}3C1p5;APq{G1ht0!8WhjosWc5^Y~vc^u9^B@ydttuHp)*n8tRdu-rXEtFtU#P z4yBo{x!h|Re*W8Dv0T29ApX6vl>L!a0}}wv*W5hI+RYVeTsmOZ?68IwSD&s0@k)Mq zZ=~~P32K#Gze6s8C^E9JHzVpuZ~~K*-&JSQU1z>JM--M&cnxPtWF~cLPI_Y0`D>tj zm*tKTlGge{C&l8Bo~buujMp2?mYD1MSzD|$-w^)2m90ZC!94>`xSp$v23|~~g|)*} zU(TGC&7R%PE+&_FWKK(iQVxl|L<;QsEJ5*DDF0;9FN!tFOI}tWLV1Vxs{Z@=s-A*k$=D<`H)n$CE@m4u~GE0#wB(zbW|bJ(_DMD zTX7&dq?sQSHle#-=t1C=h>8wa9+gMHI?tUJ;FEc4hx9QXbAH3dEj^NHCEwC1;o0~{ z3LbTkW`I%;X^fgizMvo!fPA@Df9&s2HFa1OJ}zmS-fhy3wJGSR$G^JsB{(BRczNl2 z!$mYhZI+B3W(E zXwct$DZZ9#``zhXSvh8eqeY3BHbFeb>%7k8_L#k&L&08q62XsV3DJIk?|iqq0&^jB zz|mu5Y@+)mB{A(~GCVTszTt1>FcJH^oE0T-D^K>c@|i=eV(jLs!H`rueb+)Ir72ag zCiz9>1vt8W;zgUkf4HzXBajaOk1^HM;}-ZQ_oiqo{syJ%Z4QUMRIyX-qnLQ;d6Y&v zWY^#_pB=_@sH@UB6e$1@&2-4a9CO%Zl}Ug5@B7NbNPiQH+!Z=troWoY^ zFj=AYgP+6YyZ<_|zG!wFQb{~;6%iPgA^)+@{HnL~O8$GdT-08rv_GeXu?6>tYUjcF z1S&0{!8cEy0U)ZgMV7lOJoZa|ctAEOk&-k}{jIb@E2jbjnS9Oj26zyty_THW9$Obi zmjhojR?{Whmi_&XmZ-_!jTS6?RwOC(UKTdjU8Q?l#fI4nW0^2dySCgKU&A>(xP;I zfYK}h71GgO;H9#Dp=yg4b``a>A%n06SBKAVZCsOt$5VV~8_MLrjnEu!<@^u!n?)D%r{hl0D*ThpS|OSt>4^aAN;1x%<#B&OMC(*}Y$lu=bJDy$tQeA0%^eeUa*q`>DK#EPy4GX1v(wN7;bL zA;Wg{Dn5^$0tZeTgct#>3%(v<9lGUli-1$Ub~vGpu^&y+F2vhwg17>p6C8^EbO;Vr zoBv7Fjw7BYczY`YKB&>C8dKJNpJXDHjXU&fATj1Uci&YE;(iJ z^-t~F+bn1pi+lnG`#z>4?(5EoojxuXP?~}y27^bgBJ0T=aX2~ZHLL}v|x?W zgDj(mH9Nzrb{+h8aD;De>ksM}Maguv677AI$ax|AN0hzcyM|n6&bb^c_7zi@P_}ka z@q$E+7@9OOfMh8Nnz73HM&nufbXK6A!Ihv4ANplwZXM*sSpR&E!BNGn|oHLqDu#m4^ z(T)@Foi5k#MddufdQHEBCNHDtpi^M6`|ksUobch*?v~)DvF?_AglWbXGOk0(@GGTO zp1_&=Aybx{t6?!cY7w&KbBYMO$x9kIy#f{S{GqNcfzP4grFB{QK2aN6g&;LOkH2U6?z<-9;-MvMffm3%bwka+M3;iot~4Z>z=0C z;<_%0K#iSpYwSH+{)FSWQpw3+G|nDj0~h}wyZ_s+it}Ai&5VC-$0-c|;fw3A0hE;? zk{iR!8IaA`{yn0GAOo~>#DZQtb_2Re{6kT@0o$Y>s~rCm$sz3Qs``E+ZW9-+=k56ug+@gXpC-exGKB(zifd3QlrKxdP56TfC}F-JP_dyLjxpkkEbvzFz<1d ztGbiJjFbYE*;Vc;h-ZN87rr6oNB1r3GrzMa7Chplg4yJv`aS|Bf#K%^V6Yv1p zbqN0hpgw+;d|~27-wBR7cmgj6A+GOw_)U9r_$_>7A5=C*guP;6dxoU)l*gud8D}^r z3-!C59{p&?+~eK*egN$Tnx0dvodKdlPD~t~CQ3i8BCYq`6G5JVv+uPcPI_@Sq&zaU z(Z#n{umPYqP;-^SJQe+Xb4cwk#1H6A5BR*37@D+;H&?o6h?Dz=E>VFiHjy5~M^8T4 zH#zG}+cJQqV`l2ztbO3#KvpH&`K+O^-JMI&AcsNv@3-L9`S(#$zph@=#+vW;?ap1& z6({ViBk!-6)?C#JBTkXAi58`I?AOvEHi1GFsz(;1mX_1htc>N_&!DMRYOM+%s>!-i z$}lOvP#J?5N8Cn-E5gG$itb~D@FEELZ$%}zP9v}PSg%FlnWhHyD7HV64`t0oo&(t0 zBZ#~pemW`uA)WefXFtsjR^Jo`r|>H4*VFr?6b!8*gWf=f^+?gt#KATvK>ob-H`2x* zd+l>z+S56a`cCnIew7!C`6Q`~-6nD;A)>L&kG(l<(mBbn6T+)n`s z_|%&CZl-4Q{|Jd`AK@%|F~xTgS@yAm6}LL|~u_fJkCxk{~;!j5T?G zS-iUAa!^|9o_bAIFN#cFaB9EE+5Ty;gCE^{n5wc?MN=DStVr5nOzd}4yoc8t9^uTKik}PUq&7U(3*ogp9^u^ zSv_-rSPr0TYoG+s@a{C#K^>Uwh3;I2(6`s3z#|bzlPJjPkOs7es3HufWa8Y`(iLWv zM+6QhfLDAji#FHXm4oTx{sxKtOToF_xgB2(Cut-ON&K?A0b#i4&XAITbjrq*?&kz_ zN=xmi30?(c?n3I};*@JukeVpQ z&=r0CZw8kiOY-p&2w+UZxt$aIcTvq0;$$WS?lT*hp zbwJw-(hp1Y7qlh1N~F1bM}`O$X^64Z!XbLW1$PW8qqArP@EXYjK0=reqZ_USotyqo zSYgt7pDH+-BA|KqUIfHa4uY=KZ8*Peynq-;ahljv9Ch#5K>Hjx zuD(bkYH2-iI)Vk1+jU`Fb26XZi!JBPP+ya*w1^ulg%)!D0ez$h%!pzDI(Ir?UnCcF zC{>$*`%b(ZYr&z6Q)8Onf6J9H3n;!?2nGi;tf~iNS1@WE9)Gk$(); zj~zuA(>=vMS@18aL7i(WL_Q9LpUPw~6X(Aaw{+%fnm@N=ZIR^#ckhNt1A`Z1^QSGr z8+B>9pSWh*M6(408O}h#-GtopVs%$wZx0WuV?e$mm*JeO|j-a_@!9q=~B2g(Z6A zy#oYw{L+I5=rn)yQYiGxT3EX?ghJR8$98EAf(R-*738nHRP~F*A1ATGY0@SOePqSj zwQj0~(y0PYy=1`nbveZdn91*s7-K;@ z{;1Ip6F++By{JWL5xN047zKHk%4|)7Y?lk`{T=BciW&ue3tM~ZyxjoXGhNRljSZQ7 zd;mHTfVaaXBpGSs6WVPbvGaYWrF7$s2-rnCTCQ#w2odl{#aXV5nJoO_sL}ZXm)uzN z44Mt!MqMGULv#lV0)3460(?uB!}7Kn1#8+UJb<9}c=huwx*^Fai-GZxG?1#(ECLae z8@8Y2WDg8wmoy428Y@#i@JWtb*`lNcMIb04y|-f#$C(&&ZEp}wm!LXtC->ENgSIM< zf%iLMybm)VWMY13=>ENzcr?52zs`s=uZ```{7>39-M-EK9}prvyAjq7a3-cjkgyn%_Ve#IS628 zjTOVD^EV8uOSo!-#Sz9^f!>2+t`vUS#3W6c40{f^2V|4!g?ns#FP`U{(1ho5OD!r9 zQsT$`%U6N`=>bZ=gm2gtU~8>fg0Y`rY+%f2MzGhfr`YZ^P`v{3R#R+y@9CL>p+C8M zHZwW1VNDHln;%5{{fh0MWb6&mi){4R%SoOwpJT>t)AsR<>z;!bNpsTh?Ft#OQtT?1 z(+cu^MW1kZ-J(&i_3fbfn^S$~$NG1)$ze$F_h;E}RA1XGiu^pK?8J8^3vUn|f_7ZJ z@01m|E*-KKV|C1pZ`wgqq0-Of z)O(u%jW7TWI!YC*uCVTM&eEiL-Xltn5UPBT+to6&U%s9!fPxqpcLXW{(P#Nw>-r#P z*_(}C0|f(MA|56v^-cMP1dRh&K9> zye!Zh)nm0W$7R7LYYD5bN2!Vm=;+*9oa(%h7hDWLCWTM1a=YvpH4PJTp)xF@T z(=ua#JoMXjz~00TEr;y`sN)s+on$wC$4=0W4{`*Oc=1;SJA0D|y=d&vQVZRk)WU{VD6gJb z2T>OH-8aIw{jK-gx$VGwRg=$FD6%0^L<8F>+TgZ4QGd9fU*~OeY%O;+3u$!Owz|@$ zA8rns{A}tmgxhDkRTmJO4A%VnRUqo8`^E;n)p#iAAKEs^iqvHL^eEg?Nb3!i4_{Gr zOdj2sYH-m{#_Fha?sgJ!`V}43V5_fJO(%^ zi6N-IHVS-Uz+}Y-&j%T2q|RVM%U=87X1{ry%+?@YsI<;GG$ z=y%jkyZ*$L?ojy9oKOoIa2@O~yA0v>zL9BuPr~TI*$7RXRUE}Mmkt+MW55bYn>RLx zW`kwf&~EKYQe>VcDyF?4T!55aVa0H+&i%LgNgt)pg*ZpA*@qx_Dl6~|%$6hmVwy3} zIfMDwFT1(rR4lA1vX;e_o%a1|ORr>si!dFA??>+M&M?*7RALH+VSptr;Qf3%_s(65 zzF8Um^!0Q3i8I6t20JKh>9z7mjnD&* zS6o?gaS-g26k!nDxbOx!9XcbLYR8{nz$g`M_b{@cj%^-4rvi;rd2UzKy40Weef~cZ z<@zqOA$0g?ZX$JIBnd4brOLsn-I42dGC|g>iZA3qww}-w^{z3E;it*wbaV6koFOi! z#m0JMnQYPjE$^Fv<#~YFsDqA)%ZK~8ushQrDA&B!fLOGAj*^uQi7S5g%JAA33BK1i z$rg!IrZvk6Ju-qDdo!h(|HZ2dq6B*nX3uHKb;>3VTel+K19m7G-B?zW@21Qw^YCiG zTEhBvM|L6>#0&j}wG7i_6^6{ge%~@<_XPRp)^qoL5}N`~K6(++To3ULL@2qJ1G;!CF3GK11>!5gVM#vG<_?Mr}Rppqd`kOK7R=M;ey@SyCaqHu;ige!;_C z!_=|q>3LM1qQND=i72J+_RoKCZ)!au!HdaA#w;#Yu;+6;#MiU3$r(#zL!*d8puau` zSyBS+pZPbJWM==p3lvf%`?XLC-Bx#1gjpj&)txQ_>5Nzh@4<0^>G05wQhQDqDQzn5 z(&z9Bjvw{8GJfKoL@3u-+)cmOtj~tIJkDacVQ1zwwW;Ih(<9DU=D;w8V1M1p+y~3K z*%@v`i&V{p+HPNoj%X${h9TAJf#;DutL^Imh6BH6{k<=N!NO`32&noJph%Un?&&SA zi?#f|<(ugpfEvit9uUCB1~GhwDaw7qXXG$Wf|3HSma`oPDrPEVLWjT|FrHa@n5L&q zrPoPv+Syb4_IAV}9^t9d9`H3at}bj!V{H{;B`sBkcOy%@c~xb|ai{#lY}uW5eCDBu z(d#f^_jcIzzRz@Ak42u8MM4Qc7(URf@wpFx)$*`nNK|1CD8s5+iZyjv#MeEiwG!W; z3NvtkhJ1;rH9p>r;1R1DbLZjFN5bt1CjbY-jqK|(?AkDuTY!-!f&i5t-3}D0W5DN^BtYi^nNv< zPns4%L6j)^4;oowmH2;ir$U)5rX41Sn-Y6oZ(gFn%Ax$(f5dtNAAgf$C)xH_zmI!{ zf)HR5r_t(@WGAt;{Sw|QhAxPoXw{Nn?PtF_AHtU@1M+&qbR7MKO~B6S<6x1^bm70u z0n?I#6XEyJE^8h#DV|a_^Cu$bYm>a5>j0Tv@Ov`n1|9ug&wr3SOv0E@7HSwEYq%PT zlcrDe+N&LD|5(RcahJ6CrMQ8AKhXl6FG14+$c8k*TD*QZ1yyKA&496a6%PO*_;0=V z7f}HDV;Ufpb-|ucFuz-_Y<`-9YFG+~Qo8Uealm^evRvPrYR9l2Yn&i}nwPYXC|%1} zyEM!+>6X&asZdp&eiJuf!-P=&7EBvpKI3nDk_8G5GKvyn@zN418X6T0mbQiCX*Tu)XPYW~3Z(Z(vMVrPqevqv8y(sv zf{I*_2SN$yCB9g4x69xfK0Yo#yq1DR`R}BI|w{Dt> z2PDk)u-mD@=*<_R4MBe-uEG{=#)p`rMtNT}3adwyU^%V&!1fZqki0G3DsPL`>tHuq z6<#0~inFxGA~%vF-PRs3!7fg8}ZVB2#C?u zzu~8aq&0phV40W();D?cp(Fy~ZQFX3XMoP+0`A`B_5v-mr+{Xkz3NnpjIwARUw_(~7l11S`U45bx!ERLbeD8c&?R*1`G^usW)>lPar+btC-5 z{Arv0S7+`wsE-9CxGyZ-ZsvCC+3!h>B;W$8nX7sCKMLtHEF&)|hn2jv@Cb=?Zc1 zyUzoxsB@#;wR2~yM?)6rb_iU8_q)ljR@Wuhoj^07n?~gJg`844aSxJU=BiB#XT-|g zXXQBOb4$TAPe6V?vs|3_7UpE6aCSgF7I;u)bk+^jMF{!eE>s`cJn5XgCtqrNV!Hv@ z&5h6&od9gLsfE_aX;DGi@?wI1ZNg`s7u+U$=$}SL7mPlc*r*cURz=|cU9b@fV7y_* z4}(TAX59F+Ey&T}KX*O>+hi%Sb>n&H`~-@`@_kzyNwvS9tC#w z#O5KSBA3T+<$c~M?Iw1@0XFe}c=ow3?mvX}nv;lq4W@l9D7zkN+`AaO-|Ms&Z~LaX!Tt2Ao3Kz@7KXHR)Ti|));{ViuLcwpnP(m z`Kw6x+_#VD18Q(>_xb-|ArsiIR+<=Yor>5H-`?hgr~8$6ru`r-*#)J7-&2X zXFfzsGa(KrKoNu$;I4pX;sKtPX(MN&*C9z9e3C@nW~Y7)2|oHl^bNA#V~zc?AH-43 z+Xi}P_%V0jesvResg4LU5 zOmWeU>EZ{XWW21Fke~5VNEnwy4l@TEimsz0JWWfXBSdy1gvEFkmDR~)&JzWdO0CBE zQPq?Ka^jd;^a}r}fg~y)Z5ny@tQ5Tzx)(<}03y#fz!fBnl%Gm0 zVGh9BWEP|iO1@C>LZX4HIRoz9L4F1z`kccbt{a5v^BF*o*5^&0)rP>Z2o*jmSQq5H zF1!qbj(z;HhCE#v*PY7xrMuzngB#m0#$HIp5QJX1!$)5?a^gZV$OzX3O#m8~6irlZ zmLIGRp42|KQ`K{w2ZAP%|C?o>ZV;A)PN-BFOSJp#Ir4-ivY&32Ji+OuPnOolp3l1? zux36DW=#2we*H&Hvzo~pq{44rgSco7HJaqKjA^I+PZDv0tV?!3v>EHwgD0MPZx+Ci zj|_%971En+G@nhL7ALX->F-a8)2(?{Rbtj-k((yD zh$zOvi7Nf&UYZMRDmJm)Jkoho!AF1{1Be}zuvu<=pSsk$=8kB-aNgAcsr+eeKxGmA z^gkxb&w+1C$;r=4nzvl~9FJ`xvOWOZa_yKwUNyN_r7&Y{vEe@$7(L{Myw9JSd(Cjgq#Q+zMY z8M6xn1n;x}5VI9xPpgC1g~XH^+L~T}q^Y>7>EkI-v1YypIYV>viwNFtdy!R>g~0TQ zfFLUSx|fM%P&USrfzcsU4KGiL`{wY#;KJ#=oqQ@IUBxCX%wgluXSU;7)h$7Uf_h51 zn;E%6DPA{sBh-@p0Wi=J_T9|utF;~A@tsy9{ao; zR93m2vi_tFzPx)uENe1WO?-j!>8-jKa7s&gcn1PL4-mjwsomS1H38fs+dEJO{BjO8 z9E1{b6v|gmgy>jbLzqiI8ZCcl6(8-Zas)U^K&=Ua*U=CLtug=mTlN+>09TC1vID{7Aqw&skK_CmT ziZAazqr;$}xv_1F6uN~fy(syb`MA>Xaq5$Ai9y6^EbsWt{t$9cOQktF9aQ^D;rP@7 zM9M4*{JIRleb9KnuIap@d|<$u*7uEW|1(A)ZU;LuPh9%tE;q<7odd@N4Rf#%jagq{F*y%;Kk3A)Gsf=2 zQM2YAKuU#oc9}KXfjPxRy^axR0TAo{>LiU)sj*#^y=tt7q*qQc0c0n7h(#Y4md&d1 zNqGUk8~MCg*&CPPNC$MS%XE?2hj`xR4kCEks(%%ZAnX2^?O#UrxA`M+&8Hvt??#;f zxe)jb12I;}YjPEPe^(Jg`5XUeFS`jw_l5T?q?9yfzaGEKxLKA0vs6e`ti=FdgRtmp zUswV9uJMD}V%No~8jf2)dHwiSi2jU|2Q1Yh6__O+!sMCog}KF8g{e0T<+c(*D{A}^ z6CBP6`Q|CY9(qV_4{6;^$Co({1)6c}!gxfVLw`W7xBL4KuRnDnl%}DiKeNN=)c3v< zw`Z#BXz8vpy3ufb&1|x-O6q0Q>Jm-agp=hUvIjbz!6187fdwE#x+DX)GJ7-vZN{RY z190wNEDI{0H>eDad#u;)Z&`7ZF0&`}_RFD;^aEk+9&vim7`62fM-enaGP+~g#~^)o zf_yr9j{@M#8D$r#Ci^s5c!uz#JU{7A<_9A{N%=E9PQWh zVaHJ?F>*d&DlY&!m}od+0M__pwM8i z7I3xlW#*d}d3htO_??h+i@z1d{f4F7rBVR_{2-YZ@v)-T8>+1n#@d6p8&y6Pe1nZW zbEqMU+VgW=k6*wNES%j>v_RaZ9nzLjB8nPWB_Q z(uU8uD7_Aj{no(;%Scs4sZRR)R>*8wV<_<8fU{{CA@4y^CE z9C4Fm9bahWWia7U&&23d;#&L7LVw1t^x_tQ##_<5scP5u-GGE6AMhH~5OHBVTt#%H zKOD|gw@p07r^I?VK5uBsw?le9w*vSzXOnQe-P8EM7nv#@KJA;^|9^s;6E>L|8v-JK zL3{9)&$YRX_sScc1@TloE4mD5HiPIu?7kg9`{JZFbd(&-$_i@LL2?Eyjt>ZB_}iu6 zoU=fJ99uHs>ibvR@b)=53r8~i49_>aT3hWfayjM`q-X1o@rf;e);zIy7I)4);R<HKbb0=-}~SoC?h6W%Au5ud4v z>xW*F_t0{FOG*2Gg&j-*2qEQ+caSL*+oqy|(&$_o5`dtcx~I1s3x9<+`25<#jWu=D zm%A9=`?1WJr%r?J!qL2a(>|^LXU})ZoPV5mmgM`pJTS|yG9&zhXeqO$JeisctwL`- z5>6<6R~*aj%FlSMwqo7tbty+;#zdJkvq_UMy!jqsrX5v5AxQo*(P@0K7q zIVNnFE$fwLPUr5(Pr)bNZ+#X-7IWH_PG4DgGl4&anS3o}L7t}C^F@!$!R~!| z`hXJ2a44h?Uw3K~u^Sa1Hh><-KGDZC0Ch$PFg0zMQ71pU!ofaw7P$3Te~kr<)ILzOK49b7Hj`YP{bwFC#i{P!!KGw2wE^or4Cy{8 z(e`DTxchwwpDH<~Ux`noj{L~tuhUCl_zTai4ssxGw54#BV!X2M2iY4<;`}_fvi^BC zD&h8G3%fT8)zt}rdVjMOm^pmBSzX%l&0R30oHkd2RuWdDldwIe9ZMwU^scWU7@c#t zSqJmeeraLbWlm_c;X71PY8pc4QItb(!SqfEz)bDeeed_ISd0IoF$t`k7P*XJFvP@r2wAQa(LEs6+v(eG_fbG#vlq=SA*3sPI zP6U#4y;M65ySW&p8v)b88X2XD726tiEBemRxb*SA7b{`nHEa)Ly;4h=ZpFEeajHKD zp@;$;z#!F~tvV*3A?+`@0(4{(z`PLPi9{;mrts#8L(0M?-qJ2W_ow2*yL)_L9=IB9 zB;~|88jDPw+UKPj+y8)cYkgTxKQGf6TCz^9kD+_n6G3Qri23!Y%iyxqwkH@1AT(Vdd9aWJ#Qq%ji&oXP@G0LgY^cme#LwS zE&vqnTw44FAUIqV<&_Dm{!0v$r(EAbe&X=^Nu7)YDz|J13Zy?8aS!iEIN#9p4a*(ckXvzKh6|WLeLU|Y1^TWh$wovA z94Id}`RM(O*R2}5Xb8NQ#Ypx904Ymam-5MlK0B%9jKZwt7X3h$0977Dt*vN_4R*1yzf#w#j7g+7}I#H7jt+1COpQhG_0maf(-gxS1N{e9q=1Mn(U{Ef02Z4?tO*s! z^fFr zCnZAou`r6zFz=!cz<2=X=_-B4EPs(sl6j*g8}&W=ez^W#Y_*!$UWLxG+`wn7O2eXb zQba3UPx|6tC6%cN`^V4Nk#p=nUvp2{(rK0?OH8M9!oI0QXpIqik}IgF4cwedLL3WG zC^{vko3CsipL7hW3;|v17oOB#)CwwqQRRy zb^*tnd>k}7ZB9ctM_^jAly~x4D?Sq#II^qQQ9|1UISD03)>y zq3|8O?^xSTobmRsssEDDxA#*-r24z^hkh(`$;r9AY%m@3JhrZ`6_CEX(V`iCGlhp(lAfb4bTrtzIyj*K48;^HA+`9#e5HoEpFx0QTK&8buPT%0RvTIXi6n$;zQ+AjfJUy zzG-rfv;gKRNNK<`M)R*h(BkpKqQQAC)j(|P^*}Q_{ZJ;CA2@UvbIU z(r$|=`0r$wgYgg?U?_&GFy|t4)V3Oo>Z>8!*OCG0U?Jb)jXsH=_N7|8W{ijd++sjq zw)KJH8SYhumJTQms|ROVRdf9uYV8*PwS7x-G0SRhBB&gUtztU8;Tw4?7{I(K0_Nb8 z#;KW=&6!{cxq-$#Rsu%O;0)~_<7sDghMp=nF+lrl5Wm)H#DhOUI#P`=05w3$zxxtX z?u5V;KVV=T@0WOHnw6bIeLgo<&>JfEL}OAaZ#*b4#nzUqY*<&AJ!uPSEJk3v?M>Ek zOR;#KoLd8a>l3n@Aykhl_B7m97O>MP;_PlD9)vgOsfL-L#B>ZT4E;!Z+@2qUE z%JQlYvoNn2BbJYbJ}ACL3ZY6rwNfW+oIE;o`BpFs z;8#GgX9`sy0iqwqubR}hQXEb_4&+H{z7r9}qbiibqkwK z7kP{rRzqID2+J!QGkhrvmFP_77Cu(O7iS0YkrG9=)H*pAo-|b#T3wE(*OR$#mihGnw=;bw>E#?T-vun4EgXdjw53>UVO%bL`{xQXfK<>UP z$@t!0m*)M1GZA9dK(HMAz#Ao(7*0)nDHc4;9c*}_E+|EAj}PExL;OSDU=X$ga<#Uu z(GScZDYVD6VeFu5QN(B*EP5C`1g;6|5DH12?TV0KXf42&Ti(u{Ky<=b9)HVl7SaC3 zIp#DU!Zrrb2*;$Khaspakf0Jx#Go0AY2Ho=!h6^1EI4OQBliuH!$?SG=b~pj?LhkW zT2Llv1_jUvGtKOs^kBqXlTmh1ksa?x3u3=1}j_N$So&Hmf|%%lgpGeAt(0a`w8@jfyeLFXgnV{Ml&lZ=LN{3Ld0#R+|kZemoR!IG9G zPM{qTUCUliDq~Ky`R8iO1^Y(C@-aNXCija1XrscXn5{|dDGBn7e*@*FlTaU34k*f^ zFA#XO27#^7?k{t6&NZxm6ejh0Id4pns>j8hYFnh-cg>-o?U+UoWB5M$I&s@HOOlZS zl7He2sTtoy=F6=V7?MLC(HyY%dkMYoWuOUUR)OJpft_UF7HIQSrjwg3bTjCC2otd8 zoSMLI4L85w%ZxOePy3y^Z_Oy$T0&)h#9G|h68EXScU4TXSZ;&S%03?QmyI=#qniF)Uk z59g+vTx#}=Fw=j}ekSYp`($;?mr!fpcWvx?P|p5vatfhA3SXVksi|z)rEzmc4ziY~ zFCgL?FQG+om(O7#+G46ut>JK#Rm~z{M^B;bffw}PLKa}f^uOLQ%IO`}`^J^54YmFg zMayAh9-W)=X``UU4jThD(bjjHvc?Eev)qIC>UD>B!k?b9D3P;dL)|gv$H0QUAdSeU zr_3%dtz0TQ3{XGlG&SrQiC{ALL-Nl@JI1~>#TZZyTZw_9!5;SZRzV~U%H?>`o0bQF zN*iwE?{!tgr1}SESI-O9P|6iRYR~fKm<=BF)n`RLDAqFJC*w8zGp zUM-X$KdZXi{rhPJE3gSzSPS4t(ri%=$nc^{705ImgJ3_JW@7Od8Ze6&m_xB|SU7+}SsS(|aS7#^T6 zfObm8@6rt7*9w_5RnF_K(i#K+mzC(|y*qvR4o`7+0y00##AnQ(ixE@U)+xRhTIJm- zdlODIh_Ipm8ij9-*&l2~BJFoKE}i(88j{UT(e>Q zbdK>5-g(x{LXvH=T39bRZa(_X3__b#=&Bo~eC9F5QrH2por_5Wy5}c3s}$luTW_6v zSY64Z-N1F`8`Vx{`2M6%RbX;2Z@^*H4#V>`;K=%2r|R!Ftc^b0W_zG7H5Hd+X%K0$ z^K;Zo$3__M%ka0DS>;}R*gh&HKw=qB8^G#t2(D|n0+ae_>~uvv5isUAmDf4A6C{*J z{PbCkNgbXf#s^rOlPETb(a9R0Y125Lks9~A$i zautERdDyjG0ZiX29~wm89K6VLjxQd8Z`#ej(qs!!s~L!AKx56!b?76Le(#`W^Oc$F zzZi*=%$`6c?1>l;^O^RJBe>uld_)0&8FYTWP9B=;H^tYiR~Ya);HKZ*WTY4P^PoYj@eO~+B)L&vjSS$2M-x)nid zt421et4miJj|{9D$vS(w#z;f$TE9d2;g_^Yoi&}6Ipk+~2^&Pe%i3 zz+iFyBUx?q4t2}{?w1oNq9B5em#(Rd^iLL<-w62nj)O<$1|_*T1>81wNG7x8IKr)D zpYKAI7*so%*4=>Vr_;y7b@5n!qyjak@&j2OXpd;u(TM_ux!$A-N1!V-kq~tL2TEd* z$VDulM-K#a44nBuLZYJhH#=_0EZne`dWTKmqZ}+Lifhrb{C20Xz5xigxXrXmbCfB5$pb6^_`^HpM;49t|2# zU?2HHQf)f1P2UCpNiT6*BU)=qj=|N~8$zfqG5|zu1ReBB9`WfVHU-UH2r4aL3Ri^x zJ+#L2JMimiML!FeukcSlx~9@5db_$y-Iz*Hlg4SEE&%$h}^l=hEGt_U$6UL zQu8KUaDR^{^ejFsnnv-ci~AcKkKkG~`$E_in{Id{&Hz`%=>y2C>bne8=SMyK)u&Lc`+=|cyH5G?rF>Yc8&YQ;_il~8J9y+CtNRc1u~rW%DfV)!+bHr=#NvBLi&+TNrm7rhZr{@ztayBKDd8|> z`R{GrU_E*7;8t^{gSdnodzzs7UuL0`WpvA_7dhk#2lMc~A4%I=<<*RbQP zF2M~;0QTjm^AsD+5ME<^`bA)&eTOfv#0@pV+!|axJJda2$nvty#HEwF8k_rST0@|m z-ElsF6rLjMWO>FnryH~sP>Gi~IxDog%bb!wNpAVxuRw7sO_+0&??5oGzm>YG^3EFq z3^^DD3-+p#GhUaAShnA5Ro|S1fd1Mh@OmxZ?(!*aTg?p&nf{w*)~Y5kBqhdVYCBcb zjo({)4C9@Mq+%nt8}(zN;`uASit?IB{}ghxd#USD-Dw8G4@A8QR(L(N2%LXmPHg-g z9F$$T55KU0dnC1(635wlax_+9A0K$d)>teT+)++MIDXeTb6+BF1GQS#CQ6iWVfxk8 z{1*}r=KU`>iwk+Tf&QF`mJY4I*apfuK){u&v{lSd`GL?w@6BC*x{^*c+e(o1OxJNB zb0KP_LannP;hytDXD`?l91Xx!ba&k<1;i@cK6Dz8@#k{<@+zw&3%mrsAL|crvQ1$N z&v$s8@MYtpYTR5vp`-j10a+i5as7dW&+hd{0Q-L`5ymydN1>)2`!Jl7%AJ+pDeJtQ+?x_Y|w8dDRJzs;eq8gTpbAW&slz=EbERSp1b+kn~b-RBO# z6tY5XcG2XzCLe2=*8HyA5}e-;?y}RNko;A7SWq%=n?4bpG=H3sb3XdHoYzx3nWKrl z2v6Kt!AK!NNeUJJ73^g;JN!z+_By}T58kS4po7Wd5%QtQeyiNF4r@(ui3D*8TN_VA zb{LH{BD4qB1iAxUtY}0%+!Q`yWctT86SMznMl66H44c3(e8OvWuZfY1hF;poZ{QVc zTv_(|;MxmJ1#admmHP}c&h&yx?Gu+pX-Kgo*8~=|;bOXNHT*oj~%m$8!JD`2|OkZNW8!F$uI8E0itq*-XZ>`Y}hT1Y}fEx!*1%P@8 zBs3U}Ht2(#w1uN^Np8B$8!Q$j&(;LvPSRSgV2me&*NPNfxl?`EnmwxR(Z~~&b~I^! zosOT!7!(7{i3m`7^~0IL+klz;f4%q(3?I1I>^$RiZb}LiF^!5UM^qFfa~V|*aAK7t z6s0*)*G&jAB(*;#2ltn+T>OK(7gTksnmK+tJC zGjrps4+!LMPt7g$Z9S%`;IH&1SYEUp*1%%z|8#y3EuU=cEiR>!g+s2=@|WbE`c?5k z+nwO2_>O1`v5^6QWtI?jg5*)YIqU9@7dv&#D%-+ZuCYG($n0EsmboeucH^9IM`@Hj zc<#laZ(OJPRYCOXR~z7_9+y&@G8O5T$+G-Vf%89DV|b#L*t!!psk2Ae1_6LO(Ta9& zCVYH5o)SjyXi@*c!l5t6^bB0^ubII6l%RvxaCE?#r^g|#T}mLa1f<*@~!%~bZc*O1N~#-!0mV4hG`j)G_vUpr@J#p*(Zm1Q#*kMJv74 zg@W|P?n*SCnk_2rZaN@i#s=UG`jsxbKt;|CSu++c!ACYch#hGsRK&);N^f1RZjnwF zwyZo~`bNV!j|Myo-)HY3G_D%*r5@9stANSrfcb@VswP5liO&bl|{?~B8ug> zNDZw!KR6F#G@VTtm&)3uR_Yk*sJXnsV=YK1^EY$ZoV$cp?gGbSv)g*8MFY)ktKR_z z6psq6>#jkRPm&A6s>Hg7beXsRA|B;j#`C}X>PVr0r9hUb_bgp_kk53MCHLgb41A$k z8b+>*0eo2{o{DOWHI7a0C!2`<19#8m!4xovPnT?MGhN#z&@E+v(vd4iq^&I=U;CV#dCYhH7)o}lB{nIz_T}V~bjqej?#C{#magL$O z@!vCiM(8giVBiv_x*`0)qYo*u}HDZqC z_MwII)?gnhQOx!_!eD-eFf@cmKJJ=20~-{KfT|M!R}U}n#g2ocy^P5Gx{BnT6Q`wk zYZ4JOu@am!_Hc0a=`(hKQO&xu28MVcM7 zwM8nd!g2ifFpplj6f}|C!bc{oUAuu3Ji#K?aBhhm*#3WPu!zjhaZ_Wx6 zPzmX}DG8gVF1Qg+N57{p<1amvvE+fR_Q3&T`_GWL=)%Q+z*wMz>60&}(a=Asoi?9j z0tK@9cXv8wdaf+_`aEaOM=7#X5&2!pYn*O{k(QU5)$M}p*q=pd^EDm}mxFDc%VY_0 ze{s$YPpF6HeaMfClncJaurYv&NsL@Vb^x=4flP@f$_^vDfCs=_C;^Adou6W=(A1!a z4~Z{AdA`ViI+KLm`#U%iGq~X&ntopGNa3#(#SeEta0bJHH7@_?DCD?gGZEa5dEfDa zNkzE^D`(Zq9rR$=?z1xaW{Udk8G`|UxsNL5hNEB6e^7ID7F{#n@PYD*wvcXI%u~WW zn#&%RW^1FIFVCHR;JEP}6T|hRGp}$I^3st-BlQ^rD!cD#JHoSY(&uT=253@iPXS~K zxVl018-hE!!B{B-2bKh0Aw0=tsM0bex*D~d= zJKMj4s_?bqZ3*9szifr1y1Fa1OUIi{S)dHG?P(KWH0g?C{tgI9lt*OW#vx(YpmRTz z@E(7?aRV9Rd}r0-D*VKsajK+IlUr~t@wdTS_1*h)+NQNb_{xpvTQ)Vr z_C#vr;WEh(n5qE95Q}XA_)%SatF|nKkgfx1RgFpJ^_sl%!yx&$Zv1p!lgG#crhfP@ zkw(l{0H^hl83Ko z2``pF5UAfECS~fK5J7j$?Ey-fEI*&yv~x>$IW%FlxjE=*tYNRts;51}1A}ZpBRgiy zUwS(%XnmNwH53jz2-7OiIFkcstq9%R!;i$~FH6`5ihGFZ&=cdZ^mAFgzc5)V_W;1D6QtiFjGOACByRdN&3XV>e_sgHpsAuK4bus(^)6tmo zj94hqjplvwN#uM!i?plWuWlQI)0oT{bL)dvf%I-IU_iHu^E-jD$hY zx7Eg={oEK+vgil=wOqr!d=z*9X#?u_x&a^j>wo~mkmo`X5G|o+XMf*UCrdqJ8wa-a zIGAK|6w&bu`l)rfe|g)shE{g=lRgM!o+Jy+p&1RS&(HY@@t?{PNfizn)6r^cmLNL1 zBXR1n@Ev37XQjhqThXyOPZHr71-Zgu7L_L76D2c-wXw&8%IR0UXV;Io+EMJnv)!i% zcRid^e`Eqgm7lIu_QnX*QTtFt7dpxJM(g+VW7+f5oRlgOxy(E!iCazmk!e1A0^CfY zMlPbBv0bwGjKl;q(QwTMff*A={KCdsBrG1^*JcWf%lHjOa6h=F|3s?daU9dtKv#Z( z@frT}6vhSnvC+Vnxs8?G5mcw%x~rD1{&O7L#>p*bKI7)iGOV*ycL*q*u ztp0RI2&mh+xIb!EmS?~)=C_QMS#<1Xg1(~%cI7QfnK+Lzej}?0qbO=A<A=Rw10egbo$~Xs#(PTo z`v?@UnOhve%mwmn<#XduLt_wYmaPn16)EReSw?4GJ`acsBb?{ou}8d~zXJm6deC4D z4X@Y8@Q*3Bw5%kQdEG4^+?Bv$lesvU*ui@L*j%Xes~CEE&Wsu*sC*n8~`{lNispZu%jFHqk8w0 zzdV|lR}=>qV0tvexV8bDBi0eoTE1<$x#CJ{BW|>GEIW7ua|P@jd-C!oD9%(5AHl^G z6UyVr7NVGr+{o_QlXqi<)1?1?$;l=Ynstha0`v^7BS1juNr=P3uZ)&@Ex`)Sa^)>I zD>o*-+xxLc-zZTQ>_$0%qPQGjs?Frn7(DED{-O13IntWs%^+dE__?bWzVWbW4bWXy zOuIFMq?pv zi?}`-gPJBl$o%q=VV1;KK~YwwQD5!Qv>zvt$7^qwB)}2KRsVzE9OePPDSpiqmwvC` zK=oj3Sm9-XMJCRa$r!%UG)lg;fTC{=yGIrxUDJ;;{%}2w>j+_*TpHvHy)KD86h;$l zgp&A5^#Mz>st5J!WNQ_Zeo^sy9c(MTZJ6g4zE8a_Iq!a{cDypLEV=ZaJTGy7bD#~F zbW{;0Xoy1lV@&XQY_Qi0y?}%bxo7asnv_}4^F2wu(JYIrg(%3U33T6XyMx=Hw6EkhQO5#^@Q_2K>K(gX+zHFESa;PV0V^GAQ}>59=8`F znh_Z_kl`I0r3#x*X8*rqj*)tObyKS&WD9Vi$G5jlf!Uh;Pmfy{Q#IWacV4BI^S`YB zk>*pXmedsb+lk6${Po`UaSVi~?+-3s3EPs~gWBHbh<(=>@KOO<-f(vRfykH?N zjG?^92yCgy1p$RL11yPL`b8!~V9-3A9@PQCXYkXT@^`eG2-ZT z&z0=lrK@ao+SlQH_MrP_7z|LDT78~>Q77&RBV}m^=45bNQ z^@F+}?pVHv-ra$(zbH=if)__c;RiRmn>@+&CE^4{`Q9}zI3OzJG6h2Y|58SvR8J>p zRTOqPHlR}p0Z=Ul;=>Xg52neE=^p*3AR82MOr~JN2Hl*f9$d6Q#)I(GjelHX<)M^E zNDm)uGhV@UJX|@2)yg1Uk*L=RTWC$9uwJ?Lo#ubB-R>9_>7?WXdb(((A^r4c!g z27G*L?k^0d%d~j?_T=+_YqZerFX30!1z3`-{}H&z&J@5?>ABOZ4hf5;O##hr*l#|< zn4W_PHw;-?6c%G3h8zY%Huv+%2LuFL#A`CYH;evAegC;QB( z@OHPMrVCpLMqswO8|U94=LkhI<@FnC@Ea;lcICUe@wyM@4xpUpKB=St z*c5}2u?AG;DN0e@!42}LGLzvop{OKSD1Rgy;iyqKo?{AeiUKB^1ysqib?AjgDajBAQWW&yT^zZ%F}oQ zzE05C*|Ix>Uov$ay9sVMDpp3Gic+Zd$;Zln-2{D01Q9^}4?-d>9c{x0RkXh)sZ3T(t~CDK{p!t9mQ76(x7VZ` zna4uN=-?Z7eOa5~%yuT_OHJEtnL})4z#FbZlU}pYsv0WDR&vRUl$;hj=ilt8}7pi431-gVC!l5fsmr49V`kR7T%2ONd(_-Q?``mhf1Xw=5yBfbqHABU^X zO;11%()g;9-}k345&uty5RO#!K^ZVlo!cXB5+jznQPNy3skZCTzSVrVydPV9YjVFb zFeDU@&*y88kSyz&`7&Sa8(}8HZJ0GFl+QZ&p7~P`pQ77OWxn2)lrKHf@=6a@vJD0g zD5UF+mlYU5^|rV9pAUtUYI!8U2Re!^#MqmdIdgRDcds1>SD&eRdD)f!!l*o$wP0hC zNG4d-R8Zao?%vDuG%r}oA#SO|4w8u!s8&1LgeYE;dkar*so*s#eRsQ(+es~FXfRV8 zUhX0U4D3dil0N;h%v%^;T zCiJK6O@wNgvW29)Yj-3G_44pv@A-2Hd!qIj_D;GgMw)x7mY|P_7kd}#Z*XB3px55> z?2GzY-e(yhI#R49{_)mo5k(z5;=5U*HK}UbyPb|6GujA&)h9TiJ+t_)f0i zC}k;#*OJ3S_2U6v=JK{5e6}N|clt(IfNI!OjbEDCxbj z=BU6tYp3}pw8%$(KO!MZk?AiSJ-4vxmW3_}@EK_2Lt9G>BuO*wN-Tv@uG>Y*f&B*a zT-*7HHv5sR8Qu4lytHjzxdAuZu5A9%ZUDgH_S=>U$6H=*XC>(%A>;M|RAFus^%T74 z%^vgEvMS=6?#8ClE{Gwyc~$(2!oO4jG~8EFnS| z34URlImI*q@CXV~>Z;==9bVum+}{riP#eCK9G=?9jNAK(d>_$`g?}DHDBQD1ym2lt z=XqdLc?;-_xL$upC?jyKN@xS4NgWDaKln0-j}m=N@x>b;w$Y2cAo^cF!peOVVB%7U zJfZgJGw3%{!|Xopxz)_PVxOEodP*ba1_o6!A9l}INaDIRJMO2|##O`K%_fpF z!gQBL3)sPy9}DT-snhP-lB|1EFeEks1}N2Ntu#-y4_!;L=^aDnG!PLiOZ1&%CbeP# zhC9xFYd9##Cs>Cv6Q^`0CkyuJULMU=;%b!gUGIJ$oYn)Zna|(d(VF@MZPS~f5WX=& zsE5GYm!v9zm&xrc)V{rZDusVfosM~`NW@0-|AZZUCiJ#~A>)R^0IcVs+wn@@==RX} z;eI(In&|-U>c&sX2j5(+)6ky&19t3jWIJIl_Ze-u)CZdPuguu{X{~?!?6vhw3s*@5 z*nI;rB^#AbaH7reF4Dx5skq|PQ2B)aMz{uV2>_%knglHeAkpA2jjaDX1JO0}%c%*IzoTdd8_e!XmRyxBE?MEwj-#`qaM^4u;&$e3g&i=%X z8Q>S+GXaBgbTPRPMTtUv=L)M;-HIg#+V%Dc+ z+Up;S^{_LTFbiLFwX)g4&vagZ0G7{q-#D8oA7dIiWge`Pp<;sZxhI2a`)csngUj;0 z5(>x|(0=`~oAQ)Ggs0A~`vCfCaC@{>6ieUJ!u$0PPEDOmr#H^viX=qOk0xSXqUQNY z((%Uy%SO+Xb;noeW|Bg@$S_@KHz6`5htiRHF5^{#+!dde9!$nd5NtS zNjyZSyDZh;K?}X^whptf^(42Thf?1~9&(wlqf`(%{ez&t%_G7SBl#z>#q+ezb`xD} zK2<>W1L+mWC6Ohf?}2}AE#zeq_HZXrC?(PBYg9ZUH^mgKeA)V zi}ioE9)oYcCp!Xp0V~U@zo&ik<;*{H(YZ)Y8pZxejWxmxO|{#`{xiLipU1Mg@@kwg zXdh3Fb_<&Rs?@%L!e_&di5}#9fX}|9I_@y!w6<`fGR)Z*_Dhaf5{&)jXB3#UQ)`V$ z@&3Hom09J^$SRucye$oBEqDsnsI#c9-Y)apS>&q29<8z6ywAIgaEig%Qke9q>W_0% zS14rFbpIS>Bhz)r88frg)m7u&s{)?7(b3JLXlu1^X)~&`LZ)py;0(|9`uUmf%hWQ$ zc1i7K^?b0|e8~~nxcl**^JNlI3J%Yf2A_m`;aADM{dlaVk=|s`Y@@h{-kEvrnZb*S z2wh=hha&>DgGvltjcmhsYXaky;8>tOdQ27q4m7qKoZB$yk8I-$@hXxSmfmzg0o2pK z@`VJMZ$Z{n8K7Yye-N0#UDJ}g$%!g^B~u-J)I`N7r;D0odPq<_IQ9OVL<#= zKH1K{zZ0j$UtzLQM$*#BL+y^ar3pi(XxN*~KK?(rQ0yaC5x1C?j~^ zK_v{C9LIt2(<6U?3B2!MA0DsfOVqx-$OaWCyt0h5G%6}gNLWO0?iAT@X#-*fKwyt^ zB`%%rz5?;>IeP;TUX;K2*aw?yrATJo!qw2_^7=q{3Y(0Qcl-^-76bh-LgTh{33K&= z+d}lv0$ZSq`ITwH$PqT*TPQAvv0z4r!|+>Drv6^QtDtmLKvA><_6#LH+Uqj~L#2T0 zuC@dMlgZ=T>PJxK{W#z5uV5YNtuMDUP{^Ia>iTK?Anr3LZzzb%g;yf5c+-{b1%;0; z*WAbyIea-mG*<|{J8q^pa;p!z5RunWF&4FnZx=#=chxvLoB&P_j7Oqqm7Ge_kDjwK zFxqMm2J81I5oX0(AR8yzdPFchl_2@Q)F+$QGO3?wh^&X)z;a_cm~ zP=x+IYK1pD*-=v!Yz4`*Ext+MW!>&z?hDsLGBCRL;kC+Zrun?$`6TKf>aEi%=*y)! z?&rv}gQoD%bgG%D55U+1Nhakz-7vA*l(W)?jM0^_+;KU#X`>q29^tN9&vWw|Ph{cW zdAlGsphl&Ku09-NEKN6@bEt`PM&FzvUt|D%oYex$-b!5qdPg^{+PuhoGHm(kIxPqi zWOf>OX#6(blBe_WSbwX@xH1ubyd^dC{K>{N)yB`QZ{XIqw=stp+aiOdb#jw-UUa=V zR0D+YtT^`rZkey(WO_|)$q>|0MR?8Oj8hY2H&Mf^@S|SLcC{i*s;X@CfiC614!kAA z&Jns(Fbw09fFgC-^H*`%E4iMSRI^_tMf0_O?Y7>MpKf3@CYZSk5}By=Y^sC?!j~1a zR7N^YR~?jzV04L3d)-Z{D|6>rN#WxhLz4Nx6lFl^xg2vh@ykCDe1;7Cko5;yxE_S+ ztnP~)yc3nhF(yi;qUylgURS-vpxf!{wl)O5Mn;Mwhdf+G<)#PcTXx#-^M^kPH{O{n zl!2k6;o$gBB{CX#T_8dvWI+cb8M5mjjOL)}Fmk`V=W5gy3d>&!&VF$LMq0B(1r};U zNT%(nfkQDXK90;zkxs?3#w#sXPI_>Qb0*GPp%5Gz3UCbdIpNfU1d;Ld@LWDs(A<*n zD=Vlu$Nx&tluVSfGwiINN(ld_f;GPEd0z`KZ3>?+GK#SZRLj%6RwT7Drvsm*E zCVA#G3cz=p>Z|+CBA3)tm(&e-PBbr$1J^g>ut4N1$(?VNQ4GF#?d)g4E?-~HoV)u2 zN1Q%8aD52l;$rb=%LD}YO)QT#l)k0VYVFC~^*)ab`ZtNRNmrIpiS*VXuM_N1KuFe) zlRupd@_mCxP!8<|NWkC;_$;5s6L@yq6tNuxqGpl<=B&Ed1?osjt^WBmQQ%p#Zkl~q zA;v36R8P-CZ{x9uN)zTi)ITqDxFYcN$lPur^U)q&bEO0r5*+XNzfY&z3>9DDFZlBJ zCm$eq={RL1aCcz~0O-Of6NJG`1+Yy1mFLIiUkDtl#nZF(N)YW5>8*O}hRX|i&eCC? zJ_UDkTFVBk7l--7{e>*1{i|n>!w|ct;2Fug8=>B=RaTz!g8(@s#qe=qr%eL(^wa*= z^z*Uo)!hV-0H}6#vEAcGs%1p$R^G!O*t~21vh$FK*w%!CYmv;YKZQOG>lds-g4Lle(d_p(mWWt0 zXzwQ?xCQVK+jeV~UAj1kuc`_F7N=DJAie_}3u6neU=dy0>yP!!iEn>Sz)9e3G}XXe zP{g(grNEUl#=$s>K9~QhMLR#O?5KVGAk+<2>c=m~jG1=QLT?*Ynxow#5L6u_l&EWj z@}>GJ$|$!ai;_BNAvBN@DrO0k=eGMHHWrzXNUP3j@wL9S;L+iy9zHBxZ=b5j^JfE3 z`R*{oPDutQSB^SVHE-|WaD%1tD%5axA>amelM89*gv;;&x*I#WTjp9cH74DO0R(=EFI8K}O44qfXA+e%R7N#GCS>|?>(P}T+SFA8zjDDFY_*UO5hRO3!ap|t6OI4?Sri(#6q<3<8%hEP zP$UQu7qW=dc`JOl)qWOoHO_iD4YZi9?eL~hD)RkpjYI!TI= ziHF$)&n1$DvZ2j zVj>fWC?W(+C`LC|*_ycWY^?Yjk#tlW_L3s}H~|0C52DF^mdPj7^nuoE0R@n&1y>#g zJ&E3hT23pkMhjIgvsg8lzOsN9kxUOVe-2t_HT>+940cbrEy%pbc%0M778rK1P!w70 zlHc7j^W8!AQ|q2GM$wQ?=qn;ViK0Psig(oMW8xCzmx2S8Z8fvx!ZGt8qcr~tCbTj}_mCpnGuRV1d zQez-jdQU+iP_zPgltQ_eCMjOQ;AnrbGV5YB09M?rCJ0^?5ezkH%8+^DBevSl;{E>q z_3cI~*f66P46o%Pq)gNx^`BLvu8!9umm@#`<0E1QARt^{1ED5E%H@Ef%X0tTIm)CR zPz#vF<3O-I$lDSEz1aHGBFsyl!;1}e$Or6{q5vKd#B8efMA7!5`{>6`Eu{TguY^bVf|o#C!p4DpQyx2EJgH}?0t z6UiQTy>n#o3U`;C3m)9dReqL`MWzj1vVvXD^kwUzQe z()&~oGjysQUeA6CMLgndLjN?BXu8Oc0;p&?sq!t;W+C|%5fHpMiK}JtgZ{hxD{j1i zaMdw(;+02)%-YD&IU)cLpfriuSY5{vA!KiTf*7=T+;k6p;7q5)T1&+ld$^_ ztI}tgbx2lsMO+v>+>N3s-umf{Y_W?OMy@MxjPHX`=VI4BJba{~3r6L0v(e6mvQthJ zhUwKvc^(aJGkOsegZh!%$AROq1sW?bhqomDI~ zguTcPa=rxq;1$9|G~GU3yN$E&q8q`v(BxbbV*a%b59+<%HM20#8%yRy?V0PibNk@P z8ZSr)CW>^zM;rrCZ~m5l)FS=OICvy!Gb@$p>+=om3L8^fT8dRi8y}_DXC3ih*xlDC z)`D;m-7FT^I*6K#a?0LG%a*%%J|4bM#Ymwst6KPJxOruceE6e4JZZ&P92}wfr$(9= zHLC*h77Nwrgi?)T+cuFT{)24@JWBc&CjZ}2-j2Mm3?{d)E)I?sPO2I0_UR}7p5MwL zec{}W(T+S}dN{sGPxpNlrh?i)t}4;$5714?%Z+qnqFz423n3-KGxBE^~-Oop_@tpimd#^zM*2y2y`Ib zegkI}XzV{rn2N~(p>nC2(Mi43ge zFJ?-2i_lSVly(082ijp1m6qtTqx52WXwIhF7{a=x?o&+w@v>}YKJ0WX)LfCATeyFp z5edr9i|>+mO|sm@=rE4~I%0$uRpyKFFhB*K%_}jP;LV(H`bsnz@&(u)a{4e9PfP6| z>g~UQ`SEH?3FME5wVbuddgMbq%p)d{tkOpUR31=hU?jnTPwOY*2dVevlm zuVUD?!r(PR^- zMjdUlR8IO;+N$(YZ#EkxnHh!*b}`8i0the1m*o%uDSQuOFuWt=n_@PkxA*tXmkm)W z%~PBc+r7NKOw9&dn2YJ-bZDB!Yhq#*25)bROwY5zajSJ*Km?Nj!F(e2Y5G^tc)WI~ z#<|;WDFI^mU2Sh4HqhN8`0~#n$a^_Rd9;^r*k~{zmD%8p<2AXJWGYs>Q92t>2w%M8 zU-bO1%3_3G&@j-FExhee4A@xSs)qZ$wz;a(NLG*ag9; zI2HgoK*qn=jqt!%oP2d%!wwkNaDuhyJ{)+&HfCa!Ro;8F#p&4Q{`j8kUdNG&X235$ z4?9kCzZF*z^|9N3eVba10)Sc&dLpV?8C*a$qeE$ET~+O%f^tFEGxt#WIfD`2z+@v; ze_b$pkI}q?pO#lCR0Y*t)iQtz+#r`sgL<9}1&jLslhN${gHdciECqS@H_yY&QrDj6 zl;0eC5utu?YWke8jxV4O1qx18R0n(|JnVdyJ_F^hjoerHRRHpR1Rulrd~02r=`> zA(c@uq7bKxZjuz%_9A^gYULZ^o9!)IAru%{^!{06=i0R2@n=17zXPod9V&#_@U;Er zY)g%RQ$nJtAt_3gW5~vZm2?BcJ+8BRx_EUnIy5?^k?MIMoTu4d;@)8BX>p$T5_%m-IRS*1qG09Ch`D6HBm{$Y&j*0O4fQnq+|y2Sh?fGO6SprLigd02B0+b3XSno zDtLa&GdzCzEK_7-_Il3Dpmq@cQb`s7dunjCK+Fo;D$4>UuDKB2{e(OKgpdMFqoG2| zosZ(bEx3EDH2glhmUh#L=+{^kZv3M0YHcRN{$%slG^I@cAPPHbbO#}Bt*#9l-D;lo zLk3`TBq8OEbqon`TOTh?TUCtGD5tCW6iHw#7_&Vh#q zLw=1IWSD_rU}BZ#2);dy6p{%QQ!&en3|X6E=^~$rVAplUBB&?z0ST|P(;h(MYz~O@ z+Zv3JmOjgMgK5;m^|afO`Ed3&*B1CKfFS{b!9w?&GzOMr?Iig{%L)}6%PUA%G`1_> zJNggz%q2^KstA3QBE`EqhFe)=MZCe-6at?uSf_Qm75#EEc`Jcl3gEiZyh-GdZq#^;b(f%U8%d>G`;-od8xx2 zESPX<<2@`5-XnUtO!6%bM+eY=^S|mC4}3=blUhpQz#t{@dOeTD|DE9r*hR2gp$Kdq zj6(GhlBmsNwh|eo(7>`Fq3Hx2FCrG14TA?o=M|0*Zk(CnqjH`o!7Z_aIpGEy86h+_ z(FHRcVzkO)M{g8Xfo{Zoxh1N0iOo>${8D34LbJxxxg(7mU+zF5}X8kHFQD0$p|8BF==5CZut=O&yK-Qo~lAYd@iUK78+5Cgw4iKP#=lP?yOn(rT zj3ITMAandnqJ(X+Ou+Fv@skO6#8>;&STHycUNrM{&Mp-}@{G);8u${G7cEDFd>!8B z$?B~grO){$PQN1EDnY=|E5{2afl69^-{51{|I6^DNdT@tZT zAl{#q0k*Xov;H5iq5ITE+$8M??&dYvP~Supwlv&vv5h*73<|13(`O;aulo@?eEPLG z9d)}@)OQSrlEJTv*l9&0?mu}AW?WVO$l+}C4n@dy_}gGe4ey^kXZ4H(E_dU4^^Wy* z@#m~ewU=>KOowD1xDJ?`QvA&l_Mx|JlZmPC^m(vw$NzVFrja`xnybA7C*E01U=oFZ z%fA%FsAwb=e5PH!I2f<#$|lAxhJB3Pbx^78sxK#%L4d(O@bD=nuARfSQF@p;_IveW zL*@@bP_1p=g=ZOVwUq!%kitmB?;zxz=|K5bIbZSSXE@L|YIS@76#F0|jfDGjdt-jHt znuXUfQ#uzr<1G)bp0)F)9`5;|m;JLY=4`8GHa!T;cBoMY`xCP$!95nQvm`&}^ZTy@ zCb^e6HiLVUk->aoVw0f(lq5+woh^jbNRoM4=FETHV;B_PRZ#wvbEc6@RLFuAGM@sK zv+LKE-!9ZFDc+}B!=WwjaID!(jZGR1>}nsAeI7>>XjZ&q8}KFL&;|^>1j|iH{PVHcdRVn>4Xz_0qf7 z>p*c;8TQy2>dxeC@&2ENIn+EI-=jT*)IN;&e&23l7=0!qrMi_QK~CbG?zF9&%iikg zGfdwsLTL#_98DX`9Muik$5|lWn?CPHSv3(GyN@j38a*I9dlda$dz`4-V>5_$Ozr0u zkhH^|jt8gN#lC;0rQN^~WHX)a@6Sr%s9VPEOwx|9J7u0iG(#BNotzX;# zZ25H!$|nqL+alQpi0m%>7Q~4>Ohv4P4iI#|sjHPq^d#suG~C;ZE|Up}ak&9Hn_ap5 z`fFRsM;X-={A)q?1Sx@9#he&0?&V8r6GAeBCbVyW@JFV@&C~#98apbz8pb(FLOM^> z4vEuSI%^tXdtm5O7mwm;(mQm_&Ag4ps%<1#Zo6q`3>@^9Q>3b>r9*iQNg!^)h!>V# z#bHS_H5@82!!Ux%*OxKdocOvv>#G)ZZpTgI0+sFeP}~C_6BggK>?*G_T4zT}2~chh1AMWBv3S)xEa91zAsXCenMxqm;{ zB*Tc)p_*0FnH1c|= zW3Bs)HiNn?+K@+GNk|DQLK67@*0)X)N#a+U+UxjF;5Jx%alDFtQ3|3E5G6(kBE$9^_aS59z%=}mgl2zY2p9mO zb`tN}Dk;||GMbJ7)0$Xc4}-@NOrYJ?_WW?fk`Emh-@c2pbG~-szq{>SMI1>!y=K%J zxdfr2`&S+Wb;Z>mVSqD?HYg)dK}Vt@HhtcsjYh!)A@Ed6T-8iA`3FwH2Y|C1?;kxT zT=eI{pl+)KOAAV692rjl-Jm#I)KdZYqrEG_Sn+v83B9X%9v@54> zYjnG9_LLn*Vco&{JiSl%h7S*uOujh^AT+o<@J(C9EsOgCaym*VsRw11)Dnf%C03~# ze_aPWOweqFrUbdqgv%AB))_j@>b#QY(++!P&vwoeC7!!9r9Jhcd^}U0?o#H+%P9#% zgZAErvocvK4*R#6W3>Kf+qTgCHGO>It+(G1^w+RvYHL51u|*H3aN%{=E6$F9e5*XP z4?3;vYZ}qK=61tZupB0zsC&<==|*x14_H9JnpTi%kCE9{pB?D7*S}rE10|dWMcCeRBv7XnTh8@ z`il#K;?w8IJKvP{gTET#^u=Yp8}Wc6D5v1Uh_sa~d(g2x=9o~sz`KNj3a18!uB2v3rb_c-MxDprX8K z_bFDGA6!mZg(J;F)Qv*i8<2M7n(dn|8Bh6f1*Gav~@`veZ`^kAN7 zbllmktQTOq{M1Jh6F&sp4#ohV#pqzy*mq;)x5?;a!Fx5>ck z%Kq!CGyUxMTc;m+uteTfhlFyr@(-6@fGk&4(VyuGS@}xLr;WQnM`EEfG`mU^f(<0>W;`IFm~O zq^$FZ0k+r`fE)tHxbf|T@*mV%_2VCENaN`3r|w8sB?1Fg5J*EFz}Mh?hpaz4?4tnT zgY)9_FiB?h=KcU?PcR*{{yDcs}CKgAT-Zp!KNVMoB4l=nO-yPul4Khm) zJPmg?|AI z)FiPAq!2BBW>-MjeZJ4hcwWV>KRChgTf`Kis(r@T+S;Fa@8V1W>ZNfi zn`DGPZ|Ae1OR9z0%7!)H^W>OA0(S-d^0TU)vGjCN?upn!Dpu5@wzYm^czHuw&$2d8 z+kn9Z6^Myp>~!TyUWiGY*7F!8W!plr+G*Y!high+SAHWVkng)#bfsdk zS3pa4H90Hm7P+vEx&M}}@w2BYtNzZ}bZMD`C2jF*P?XJ0grT8Hn-r>N# zyI?$J0p0u%)nCk^M(^SORW5E$k^JzZf-eIFV5MOalpc<=HNh)1xVSM?bw zPb1WT?*Z}B@}g(J>=yLtlMec;fCH?SKUa{q$N>i%(|D|#FJjI#Vr6e3UJaB4@09vu zJOj^*HF&K7*;@vE0GfxF>e9@wF|4AU4qj*gLHdmf_K{xZ%ILfD&Pe>VE3%hj#4W!Y zYC0dl$E_3)FE*A1%0-V5g0Wdx4&7E7p)RM30P%_P6<|(fTn#RjyDR~7W&2NUhqVCM zuoQNFhad~7@mnZT+}3nRlqolpSwk#(NFiR&nRhgJD{tXd%f2)CcttA7(>mWK$#5eFj~!T^ntmz98HQXSnS1@ zp&28*FOP8!5)9-VctjKBf2rQ2tg2aMw7vt5XfW$8!I{jCr$$PyJHBGp21PIZq5Y>=moY%nIpo7G{KYeFGb8FmzYsQ?lK2HD z6!ra&-y56%NDsYJ`|mV-z0Rf z7CsaOgwHsf7;e?NoxCNG?voRn!@!S<&SG8jfF@Ar3DPw}hYEg^| zFkA9Y-_~ON;ZNrsTHcYz_dth#)`kM!a1;sNhjZ>C-t9nWKfwg`&G5f&-J`~Fz*wcK zq4?nA`3ZCj?jnjICA$%vud@IkyoZ97XE-LgD#G~G!H(VGu_9nGl9xIg@6QRte@KHN zzERMGa5}V|M23thtcpBw-El_-A@T@{!LY#p8b&hP0S%=kRbazJ z_jePZoEKd+&L4M&2fgyGBCm~L`+*AKu>3)1+rMetqj$`6^IyX4 zPXN~?B;^j*6|mm+Rr%h>bmX3vkpb0Jl~QJ|z+Ms>YLBeki#OM~#*)6-bUJyRI7tGU z0dSk?2LqSpCyGx81Nx5_3q-=%j$3cq`K3Sv;#UA*3QzH+CFLC`Aj6~ADEp$bC9%dc zxBUaKGS!1{3hU0gUsuTj)n>Wgcmb_0A$7e#9&kTakz36V4nQ~OW#rt{kOO?y--mp* z%JQSf;B)xh+ilmpL6RK=^I#loMLfWP(n-xYF2|+vWo*Ip6}gR;k009KGoiZSU4<}L z5*leu53V>k^n5hcfGgSsIlB-#r zj(osyjC2>XRy{+~Fy#a+KpvB7Uz`_&0z(}8>R+Q(ae2?H@6CYz=qV+z(UTC*lII&Y z)D9orYQP5nIz`1MDa;NzSOj=IvhW$M7Q1yh`VBw~%uWuQWBH)nz9BU+dIMu04`!s~ zaMr-PRrvmdV?u*R+2;u$!9S!1P%7EIN2U90s(&H4yO=#ONuW zetS>_mFT5Hj7Cz5RiNg2m7vtx&49fC!`6Zx&IfNL$%kGKDc&Z3n@fK1wpkj3HTD}3 z0p}EfCAizcVG}2c>|zp5DJ8W_TdqKMadsYWfwqCNLLygc#rhUmnzmiZPw8*upx;y6 zm`N4sW1HTyugqTn75zmibUJ6GJE+AMWOCv*!LRiFynI(AbbgzxM$8n*_54ux_e9AR z0rpMe;5_u%mL>s0LoO%_rH5}wr`fdWhxX~eCr`cg+o6lgVVSa=D8OAI(=GgG4xZ#1 z_xRNJ3zLu+-Z1zKg^GWAxVCpLaoi`yosC=QzpXgsXjW}|v<9)rOXja(yx34Y^zE(+ zdkkYpHouklJlV{+Na}s1pqYwv& z7Q63i)QL<(_fC7yCeU|!ziP#zk@F}zDt?spIA4eC4#xERwU`<7s9jt&Y~2qDgHHcG zZa3U|?W-;-Mg~kNCjqR}=ju#K4|89h2bH!2l7C$RtqG*ujLba7_^zco2U`=?QscN& zpmbwCs1i!jsqyvnUr5*o!@^zh0_qpPiRsg}7yN1iM@X2SpaJP^NdR@UpE1+xVn2aw zaXdH@*hja`Mwr=Iv1J#-zviz+HIoGEvi?>qN8GDLo`9ZfV0+d|`ageBrVHi1E15+f zh%33C{hCoih$xO?A)e9o!*T6NzI5Ju0Kb<>uvLu6EMPtp0$ob+q&BwC8fNtKfHEDW zJEAxB{O!Q!dF%~0y0{$;ifu?cUX^KMr0KW@(VBhPe$8w7 z)d@HD7rmB|BnWlPy8Z7KaYo6i>PULQkU&)2AQApHIQw^of8~h{bA5u_!?&s8%g7;; zSys`_P7^{2EDoboTvR}ZqjdrAOUx{V6|d)PFvMMmmZP8^756a&q5=|2+RVbB8i*Tq z{y(}Ib@M*M=iLo`Z~81;dg<_Fz(or8J}%5n%VT%j+^fP36kn&0q(tB@bb|qV&|4C* zbc@HvJNum~-279-x@fZtj&i~bI!=Cnd1wNU#9PRBp{|njs3hbLE7Ffn7wn6$&|jGV zyYNskw^pKxQuJx*#olZv(ym3~%i+q(cR2&|j`81afc?lDd%HOA+fy$bYB}knzTPSwWdGg#M?u|8&>9RehP&EaK zr{y}?!Cn65EHKK@RHVzyli)S2@PVk40|l}5hr917H`NO@Q6k;|y_>v+vS> zJ6uyfuXdyx5~tI?IppCe5AK-u9f?SwHpwS1&j_K-CH@^zSL4$=3L3hiqcyyFT5HkP z7~P;u*#q*v;{F}=IQ<;5u2F!#P#bN3{BDs5g`F{#=vMt~0ok)?Wr*RftWJM?eQwAP zkHARcrB2|`bK8cAv950Le8N9+LRP?(H>?09Lmhfen<(Zm3j?s@--&e;ya>VGoqMZM z#K&ci>RXGyfC7#*N9O@rCBm^o!Fdt7FBez{0?WY%oz`hF;ldrtgI=PpN{^(9`JqmxJFHUORQ2!q&dj}`WYQj z`k}RIWTewb9Pt5`@Fj@cu<1POdYdMiWtkhv$ai37{c5_BY>AVs8ff4YmZh39Xcc|U zjPaDrCGBr3?n8)8WO{M~UFXs*8j?x@0wyE@Gd?okAY7aEuXK6J;{# z(O$0Cr^{zixJ-&&zsb0ecs+#mnsfGlq5=cW{0ll4&MEPs;?mbqzIC$Y*Re5`6|0qf z6@@9eGu#}C&$f*c=gH4suKsY4dU^U3*g~qkQ^8(p{~9%%QN33Nd#5QVhh35wY_-#K z%RMQoqPpv1beV~h^O{np0jP+0?!ZJp0E5VeLExR7F()b-&;V=fQZ9LP;IgjdUBlXX ze?&Lh{ibAcTjVh7?>QDC#NEC|tBn3%qz!w3?YL1F?qWKI0+ait&*>XgV2Zx?<$w3M zK|V!oUrvG;Pt$)?bZKJ@*(^faPfRuf;Bf_brJw!8Ih4usjFuM#CG>e9U;ol}Fy-lz^BAJ#^45 zy)HQa9hZHnGgRUDIwxXE-(ifIHkz>~i9Ifak<0fIYtULM!V0 zKdM`Ks~@l&liD432isNdwIvfpyCg6&<>8nevNRpv`xB?_2lHgE8JayTUu5C888+J; z6q0oca}M{AFv+GXpd5+f6R&Rt6%X4Mlz(t(ey;xty}(!Jry1x%q@^oX%%jiLIG`z& zo0C%l@+7QvVID-E3(6;e-DL{I{wEHk4B!+d zbx7O%)i!WqON+=Nfslx*=aogNJx)XvvSgK~rj4^6RhVWNI?0X1X!G2FAR0zb%|~8J zpp|+a8TNh{esJunmd;Sr{WU41X@5OU!`{$#lf6RJXO;=-i1c+gMW7DfA!;;~3^^Um z>S@YhjLAq|jz}F3^eMB|hpD{G=5a^}WzfCk61@A6r!}P~SKv8*jT(}S@a4Vx4`}Ch zSf8Vm^V1?@^a}72d0dw&Azw-+mSoKWWZ$PpHS+$+kL~;ca*m)2sw0|7T>e}HQsBF4 z!d|tHELA01EYNG>C3U}J_8*0rK#`1bvF)ZSkW)75=(@!ljdUapIfwg{ot$5mu5{^)l~39*VX0%o%cQ{TucpwWv)CKcZY{nQ90(UU}r=?)k6WYLt^fGxR@T`PBUAd)$9 z6-A>%MLh=eUTT3K4*W^(vRi+!nRFn(+|eF;rYQ`eN1%+I{%bclQ z9jI2>1?6Ph4`wv#J!2AO$^c+tKMsu$9T}v0*0Jc^q>-)E7Cp4f<+t; zde6ZSZY*kwAr@THo}}lhcEuTf%o06QVIYy&@pUxbqp-|t3TX>BbXOs$ zE_v$iWs~!ahe=y({ct6)8D$UN6UJ8`u}c_BClz3}>E8UPwPds2(3>sscA;PpM6huI z$NdRGnE8Oksw^%y4@SZi#29^7GZ0~Wc^ortUG~3JT@PH#-o0-F=ZH8e);^&-3i0qsrW4>S#y9~rd++*O>gk|Et=Dw{fKhl_iU9joFg z`T6U^sHrBgbeq-YGVjEzRg=Tgn|W{&_h?d5&dQMu)q8LrP2Pl#>t2HAs-p`GsR?Zs z)asDmSqtFJo(m}DFbX`J#&OHMAE98zhdNJil3e8ACl^w)_n+E-Fdmw+ZA#!h4uO7b z0Jh|U(A9SKY5w5`c^*2fI0+WeP}+mE+0t|$h`IQTz8z4#FP9}r-1EO$xCY-jIi(j6 zI{5B!d?1Zb4(_{PC7KUT%=7qnH%TMrp|}wxL4dTNwYeX&l=tXlywGS;q_eA~fW6^Y zvOM&w{-@qyhbj!)FKbbnwT4A~dvyd8dkyQrn{47S^DTFG)$?_&+t)u5_zYlBfwHX| z;F2gXyyLOuV7Yr!Zq$d-iq^uXRyS$q3+Mw$txfd{Glx3zKr6mB{0vqE&n?C;0-+}us>^nXp22LsQX)=IA53U$2k+liWKy&UY z<;-aAr;HD@g}?Rb^OUtu;^!T(6Rjw5JU6c+{}ih&q$p^`rqdlLm&QEXKozS7S82L8 z-T9(;db)nuxj_8DnJn#NNJd%KT}5nJ&TWUX|6WgG2uLUS_-Oj!x%e?eMwEuT3Zq-p z1Fx}D9(oL}viQrmWlE65n-W$XRJ){nE-kaC{8_lXz?HP%P(aX|dBP-P)P1a3+owaE z0;D)t5|0t~J@=sW?ucA<9T;Y$%gqD9_#T8HCgnoOaG7i`x!pndLL_8`5b+sWr5Zux9L&fv*4y2dPMfIqtjCbVu}30Y zrucapD4t{s=}z2rJS8J@28e0`+usu6HT^n4^!rZQ5?7OZ4_X4K ztN_X9En}08z|>gYJ~4Iz&SG?fI6eJpy!Rm871TT4QE}WZMze;;RSl1%TiR`Fe@ls| z*#W5DrueL|EGUk7FD53*8a7COC=^WZjKg{CDbO(>7IY-9&RsDD| z!tATg)`s+2eT!;5zjs4$tW`$s8hb>p#*l{~W!sb~cmyG(?oZ0{#t(L0TAl?b>gW#f zJ)3H@x1=6jgIfrP9~svUSMcJM*$BoBH&ONb?W4F57}yPr^eEVMKZcSk+dMTj-;cPy zL_wt$W4JifF~->f6T7)qP9|Z^A6NCWvbBa&DQy89Ls>6QDa=>|K%AvA zWs^`DM9gED#uT27@;+CSs@?yt)jm)l5DBh^vK!{^!_(~VHljm) zBR(-S0w305AGBm*#~gQ>|fO#$YA}OfbmCsnaEVooXBjG zn2!2zEU2QCWISH^Mnd&@8o-ykZv1;O`}1_lYHosn24cc8RfhAS*iSiu?f}?#5=Vc3 z$TiO9fp@PPv3IF>mfJ@m{0?390~5?tbx9(OVef`lv(G2)M~Y`|aW1LwHP>!aO&rC9 z7e(-!Go0iKkD@O_Vn$TJ;Ei_CENV^moc$`qN~xflC5?>;mR>(2N)_*L{5wS07WLyk z#B=e;2(xSeB$hMWxp@j$u?^(zB!TH*vVp2F1ED)R@1WHl)(HN(BXoUYmIO`6m}~rr zCRG~I@|g-(8)jtb0CC`Y))2NQ(@P@c@ONW$DJidOp6UPW@7%+f8_n@VoGXBhpkcxa*8pQ}iui9n;1VJvxSY-BpESDfNCexBa#(rG8RF!DY~x`3EZxMsfCsHyXjU+f ziIRyXj|8+&&7Bhjf&32YbggM$XoGiHgb(0g>4>&-v)k^7o&$=r995ne{KQ0>Tc+?? z4>>!=(~&Q}EoT`m)Isdz*!*Go3|b%nR=imRMD6jh zNMaJbyZy)#w24{wR$YL5eFBrE)qLdQki@u@w;{Cu?-qbh!^`73?7p$R0 z+AE)s$@#Y%%mlnd71*W+spKVjLjL1fo` zOQFRTeZDZ&O|D6?i^&<5)PGO6Rw*uq%Z+nhAbeMS0K;h3n|(0@y}$vjjo4AeoIW2D1`;cA{17eGFI|29qVa!3H+ROrK^+eq&`&(tQ-?La zoig1;FA)J-8~D?}{2(oy9`xcOAD)_k?d>0bZm)ox4U)*t>icM-9g5gl{(Rl?~{FLlhl}Gqx`^1feohcWZut&u;_P0AY$SiDJ zpc0bK7!JPmy)Y@hdcV*L)=HwB9iocrG~UtR3Ic~f9z+3IW$nwo0!cJ+qaIVE8Ja7J zL_fVpZUEeYaNJ&gP#8tki2%ZpTZS=9_W8jQY=+_&^Z!4f+T4LHs7j8SSTRqc7;%Vi zz+ZnG2|xwSqe~KRXjy)rPvVuuEvfMCBJi=O=nJI&2Xj$%P5#K+UzBI!d!zu~r^%(M zmOIj?WFuXs$Qxy01D{B%3#!^2LQ7TW&GQmRd~R-=Og+y}R)@KM7Qx`z;QEbCA?s|Z zP0^~)hP_{lD?w7kg`N$3Lj0aBR0I5<9U}HzPk`hXbrg|)gf=OJkF1t8SeTf}juZ3l z0)>waG!HOI$)H+n^k{zyUh}+5&5AK(1tM>H%%XX@<4xk-v1Tr_hW zu)p~iCZl2L$bt@1u*FP=Thi_z{Ydl}7-Q$>z2)n!I5=Q^@ z_DVD7SI`S%9T+G#9Nn3D3{l|yRCPHPb&}xz*K1Y8n2H<7_C;T&-;9WzX^%i*-uM8X zFmd2iAWmk4(Uw|ZQe-O&eqXFPpSR)CkMI$h_VTu_S2kmVmo&YGh!rm)`JhOTRS$`q zHt4r^$|qndFxL4^SSd{MZsrN3DTYJP4t=iHzTjCzBTLAu6JkpZoyyQL{uP2 zVzK%E8|{o5cIosto+Tf%+WcM1aLYGO|6=M^u3B;Z-W0&+s^dcG;rRSxq4RfK{%hy^ zp6}gHcXVsVB&IE&mltS*T8r(Ut-FGNiigp`Z}u|`>Rc@lrfkU7Q;>6w`~?_^RO>1K z97!+nv__usi{^d-xTHFB;_Pus>X?3}@bu8@y9xM*TkOXX*cuR_bVJLGAPT}z2u6FUgx%S1=D*kUbwl}V z#3Ux9fIK@3g?a_0Lpa`HX(I~*<-#T#LF@kgZjb<9on!Y!QWwS+UUwV- z8R7!LnK*sKZ6+=R6D$ICu!kefiisNzx!1<pf zCq=KJLg1)75q5s!)B3{Nl7(CD>3n{haGT1_eR{`T)=v;QnhJ-O0Ziij&i$h; z#qFY?tFk9|h~c=txfe@M6a8(pDaEGk@IWzN`W&oz7B+w!%f4R|fm^3&^r37-$qE6?v&Y>xabYTC|2&om(Zr!ZF0Tdy;G0m48wmOZ%w3)Hu01VE=#ul zLa*gKP5^UVuMXU+Zo`+@d^PL{{@P_wE@4Yd+7chr(tphXj>Qb?lIjD~|F+&XBn=5t z>-1<6Q!vN@LA`~Tu&(<@gVUDLa^?}h@#$H`Y8`HG_>Ye`nBE=XXH+gsx#@K^+=-@h zUOMI}OtDFThft;o6$U|!V<5#s6Xhn9?#ubQCo^el!b)C8wb!Q1B}zblU@CLH;-hc0 zpf2OnL8p(b{C?fH_Ybmz@DTJ}aO}QyqR;KasXrVTA5v{EaP+tNVnY|LM&pVS$oPi9 zOPoT9ngw(odkVMgah7EE$?j_+8>d!e8Xj#|yeD^vDqgf&)XUo1SnWwqKPke?Qv~?^ zFGV!JyX_@+TxOJn_QJLNXPNvpe6jvD-rd{BJ94 zcnp0J*XPmJ%akRkw2|U>2zyB_xnjB4oa{dJocm0Vs2M;b!x$P*^9%q;2;_A83Iqw~ zXl4-0%m<9_3~0P*@X%1SV0uPH=(NWTHFtb)4=Yk? z_+>^8fy=X)*nm|o%`Zm%?Gqe1PoDc`CUG852PVYNC*T{k$<4*fI06{K8g|6p&Lq5X zxDy|qm`iU1dA@c^GR7lXfUa4pSI)nr8t^CT7CkOJ%^~-MT1#z5uiO~sP5QaK20w#4 zzbx8?vp+ZfI9`y3(-!RQX8z>K+{~BW#z-;jwA6?AdftyYyfSN$OGVm$<4KT(0&r2} zl*tf!@}583dRj=cc5UdXz?Ua`ZDHEmBmAK|Hof#KYavqrW_!J9RI0d428}XF%r#*_ z_Top(eiwM>sEG#1^^rhne)QY_U4BRwitwN`C)|4@2ga$LZl4yU^^DBWx`h9ZM(QJEx&->C?{`Q@pubDr2Lq zpTOdUj5r{xNthtDT|0~2;brFPe5nbk{Pw29IaB+ow+>!Bdv*IFtQ$Hjn)LlG_fw{r zjE8|NV`xY6B!b}3hF)+@q_^ZzVdNT^uoMaXiWv6L4|7)3c2}sdb8|Afz-qnoc|KN~MM}Q4AD-80+o0J-rS0IwjPa*^ z%yu#VT)pYACi3hz+<(E)Qc1*R*+m0_Twwm6t^c0Q{|PHxR3E`| z65}cUD$zwQlUyi;r}Ovz+28F9AsY4a{WdG)0su8+ zj==HRD-~C87)kp}mC`=njw%m>RKv&HHmwFc`2Lf#i#v-^o zY>b|IM1A1VtBZz={^s{LUUX#;kHi4ZoHLyg_hj;CN&O#UY&|dKH=eDoZRjU>ihK%Y za?(&bkWbxOe3LA4H3ecfx=f(xVeti9*|60pGSnAeQG-BDM69kw8_M=IM>t^}5#4u> zqFJ#80tEvbMn+I1&@?ymoznW?v)?&@#NtY+Naa;GJ}6}xdtmvr3fm~7@{620j7RRa z_uvgzZ8nMheNlU;j0nAkrxXf4_bQkFs(wP>wM)&W_ELh@TW8?NOMjDvIUl0HwP=ep zL2+~^`#g!Y&*sN^J(wXKG>p416-$SgWxI?{A91Vd_NNm>Wb~;mksq<}J}n;#0(d&Vr^4eR`)U%wr}y zG{&3?PkR_xiF)k)Q|b~e-okJp;CiF})r40z)PpG%3Jm)AYz@MsXl z;WG)Ri0&zFC(h#9+iPy*S7Y@-yD)mypsj2n;H_X*aoqgx|T~eh>$v-FA z(HRYGhGiX^(AM*>T-1s0-h3-Rt@!JuycT6Hn{%e;M~RF)(cRrXzPtgyHB+^^VxTXi zFzo7!dL5&?KMHcA@ewD}@WfMjII_X9Z~$tV25uSr1e&)bpOy-+&d%6}D-2tHk8I~rLkvC?i z{E^=chD2&pT8I%`aEAOFB1#}F1Z7pPih}S1v*Eo!%^ut{jR)ra!ryzzW+kwr#EO;= z5|w`*E#k*~4?%d^5Nu`#yaP&iDlm*oB?F@y=iX(y$$S=+r3k0{doS2t(F>%mq^(k! z8S5*aihD%67hL7&0!QmnLS$d2;w z`_69LdvH!j6kf2L{?^l&{6GykXb<5U;TQ|H_$*6?oUQCwSsWercu>)XNbIymDb z3N+05DLnw)qbKG7ri87?cG2!1s>_3`-z(U&n7IY{<@4XYgj1uHs)v*K$2u@mgvNKA zPgN5HP2l;+F=Rz-;`BXrEX8$vbqFXgO5aM3vwQO?WU8=8=_mS!4lPrQhC9k(3fUWI z%$#HL6;h@F7R=adOFjel%=*$F$vMD`3rH_@jutPOwOw~&5!YZ%QQ*(v~r=(W%utn2!ocD*@k11wmX8XYZX-Dwx#)P5! z2nJV-9O@1UDCo+EWb>XXT;y;)U^+!X)!m-lkF~`aT!0*!SHnBR?DzC#?*D2q{*`yyzL7{wtRf-^GWiN zb2zF!JvuNxh$tt3{0&?iDISF`{tSPg96vAqc;?Dl>ES&feFqc2=~b%zx7CGSsg8u(NfBA)j@HXw zn9&c{)sx7rT7EWL#r^!}If8V9k+8{;AHs+ugUDgt4l z?}yaDB#Tm8{(6}THUKI;e^CCfJL)x3yrUYRQ#+1<$sd|(NxjK+5QYwkEDI^Jh_+67vRQkqwSR9xUS1S4) zKPgy};b}F@gW73A)jN87&gVOKoBkL{H8kXNgIzW?spagerXn**jbeuhngw#8Hj=-KWgm zJqNq3)7P*S|CN0=Sh%9pgX}vDRY7{OuONWN5`$Um-LJS`ZJ*On-FYbZ7Osy)LL8(iYUS1( z+){%Am0oY3@3`uJMu~wn|I-+nx61pipEUnB*67)>QD>HC;BX|{s_6YTe3rHqF9~|i z@y@8Za_(dFH1)<})T`Q*BvR5R%+jFeg2#TXURFb(ZUqmyZQu)gAg;6>VM?$(%#$}S z`~~I2l~@yh!lb$7IL)?=i4R}$gEO`V)RNShl(iK6Y6RLCtlwNV@#p{wIBa7>@((cE z%8~dPb}vKPh*KeJkaH0S)tza+cTJRagR`FrVw%xl=<7fRm?#vFdIGDdM#mk2Vh?=&kV@z_|1ek0HK7eo@SXh9IeuM6W z5bY>JNb5fr#q)uOKAeLALWxC<)(bI)qhIfl|_6l{jfH z;ZNSaC;7{}>ypnj#Yyk1qI_kizi#9NFY!^PT3tWC`G+*)iwXYC6B9`1BBD%d*AIW+iYHNFs)t4#zWYFm&j-pROX@FUiBG15V%K8InPJHL$N|`JZy6L?#s3GLz0b0cpA1TaT--824;(!z(X9`>| zH|w~lOBZ94h6&db-zh4+B)(UN8G?e81C+ZfiD44zuWvEjS4B_hb)PDdYhaVJv}zkM zy)xIXgTVMBT2)x6w=dt&RZLKSK`=>4Jh?vCAx@6R!Xyqw+D!lP9qjhj!c=UDZ=acF z8o;2>a0;_%Vf$GoO1h|GRE+v#>m#8eMF&g@9QO>b(_`uYQ=>n<>J`aWFZQ{N9SLAtZu=Ka?`hJX3=jG?$6UG5;e^qGLiM0cacC1z5_GaPp zq_TiLHDLuai=+wX(Ada+4^B&;UHVJss_=}nm;4g0k{_FI=|J_#iqu1|E0e^%=r?OF zb=XZW0H>3mtvw>LuVMe}pkzM48DQVq!vC@a`%$z8$Tn6x5F5;+cdL z4DOlB(0!&BxI6;3f|4epnv~PcWB$A}#uP5}8`lj`liX`3Ba&EYd!U9nYOvOK=72Cm z2ep3(I(|Ka-7G`QSgPnh3-JN3X@ql*{ovnBeY-Td3*EnSY@NSG!0EA4b2cb9&tFJ<}O0mufM>iA`wII{fhF-t&jd$h(S zYo3}nm|Qjb|L~?i%k2t#)T5x?D#74`t=mpm#RQW$tQh}WXr;H~+5KsrK(yk?O^Q*q zJ1&cVTpW_&YNI;Zb)tRw(~5q}pkTWyRiR2JE*U&NvwvLz$Geek05zvo4R=o>2$-#8 zBlppmblAy>;`qqEtt=7=CPO|`4A0vl6o`tE1ziOmoG2lLADTc~?*F|2Ob-n;kMf2E z2@YioFuYoQ?bypBEj8;ptMNCo;PbZLtd!u1X{Tg(CKArDwHphkT9vqi_9XefRjFJ7 zjQnXuJ~g28bWV@=BRhAKy%8AEpkF*|CV=*dIm@6xp{}*lS|NjQmG>3;knS(V!e^mNL z1SeL76-Y9_Jg;u=&v6fzsk;vsauFKaggRq3bBJJ*ECmEn8sVBNUWJRSxA&qJEwTQAivW@O}CCr){;N$Z>_F6N`KLs<)W|jstM%NdR&++3d zAWn**LGSr?bzAik%`sh9tADzim;A>i&0QD7b@_(d@9>n6GFfrB z*FQ*#P!;fu7%(h~a@$8~StEbOgp}>F7P7q}QhQrd*!bE4A^OEC;qgR$wlL#E@w_-@ z9td{M*-^GajvBJY)gAq+kp1t5;}UnrreP zev}lLV1~ZCn{k?i4NFuO8K{|!+N@=L7r(2kF#SMJjDK#Y;~BgSySA(?7oNikvCjAn z2O@79?gn9Jlb;o(CO+MMeJdl8Lhm5+DcQ$PXpTrcwX#5T8 zTP2ldD=C>HulQNvwV$F}0;ZTmGyDVr;H%KCx)BiTo56_xoH8MwzRU)Ge8+crU9wGw zmFHO#z!?rjt7Blo9i_b_J2D4BL<&1dL6x8g{(5~f2v1*5#OPCE*ndKpp#pO`XP=l> zH7#S${OQEiQUQb>2`Df~kk?ZB!ONs8gAXGoFqz@vWaO@k9xHHfib~VdBQ+h%g@!5n z0j!@BgGc&H=df1+H5OdEH~TZn^)PDGx8NE#&>n$4*K8(fwBv9mHrXN&GGR_7RIOXr zxB*U!mNlg@lt9f??nkLZj)w9vGOY2KF1Bi+HWge5jD?;Tw1YR*L1yp^0U zbtq;Ktg|;?A^yF*$daoqDeQ!Am028qis1O)Q?B>zzK| z-O;sokHJo`GVuTG9KDh>XFaJD zeRCDRT#s*cDhOvv2>(uhHL|2*g73ZoOBo181CNjW#RAA0^qz9M zZF2TJ3}ms^_if4dar?Ud9s4ri^Ch&xfq&ZlRXd{>R&&bJ5tCU@)q z84tC<$}X_X#++p?ONlQH^t^uoeH)+z{5W*^hfBk>SO?`n7bp;byhf2hH3!RZ9GJy~ z(Wb;QkL{J~j9UI(2~juBsNQ;uFVm|y@9+~Y^!sfE-+F|XFXp!LD$PQFyak7wyAfU( zy_@mBg( zm>i$EuS6n%xc_bN5oL(2}`S&1N|(VYc|*!p6+2vs!#{j zHtNvLizoXI3|#$Ef>uczAG9Rsyb8@>ll+%jT4G^N4J5rVf?`3LDxXz=Mu24j%E3|T-QZBUBZvEI5StO`*B$QwxxMC3EJAtynIeYV$Pe{ zbTd1w+%O)%4}X5<5}`aM`wMNQlFTS9R_&jYtX0k{!;M=5^j@;ObfHS@5(;5r#sl&M zY8ehlB%PW6ol$Awb>4bi(9Hh|#>_xsn%a=E{P(U+8IYY^epJwurc`|PVP^09A(HeO zc;5W@axgIW2j9w3pEMGL-HoI`gmDo&si)KOXTy5qH(M7M0>?8rWKeEk0O1Y_*;M#b z?pz~zqVJ1jA^IL50$C%DV(K))P18*kzMxz}KwLdxZ_vsPfcSnr&vyjqNY_=oamSzl zd~ZQeMyNv5`i~FB*4=&g#s;PiCR=E7Osj zk@Owa3ZM3u@R6xOFHz>?vhD?EUc#>1ITXD9&h3C_Z2|_`)H2mOiExgF#s;qmO@+um z8NC;Ok(C@TeR!&@^cFF(w|8h1Hg}VQQjlP9`bkK-$%_^%(?%OsFrVB_P5Z!dlv@nG zAIJ>lXKSlZ&Vv)fySCNl$D;j;O*GWMs*|43ztPpli?2N>dH765U>0QFp*Su7Sgfdx z3gDSX^;RBmdOtDv>0-951;E8c>}KM3h=soVUx4YjIFQ(?LUR3!{ao5PV93#{dsgP{ z0FLv)aK<{!KJ zz~b1O#4#yVi*5npuZQ7RbdFWEC~5fn$n?7HDol&Hb49Ov6}wDBm;&+~?w^;`6cWuT zN*1SnlS2+_(~!l${gtE|rozR)6cfp`kqul{KoxyoF1t8m@d5;80gyx5A%h&k_9=Cc zerNgA!7#exrPs_S0^CWo9!mgu(}Xp1^p=s6lnR!JQ_@E4BhLgv>1L7(q+uVCXbGz>qkL$2HXouNRKGjbkY2c1v(iSZt zXiL83sx__ja_S<=W_WZF&yn14)Alv^>Pe_bNC&VwoYg8ltQ*zqeO3MT*pNu$UsBIy z80qR<*YbZ>T)eqfHlOvvlt7a%=m%FrjXz!Q=D@=8N$Eo^-CFK-$r!(}+w{^Qq6e4jyml;z#!XuL zqvc0W4iLCV?y4K_WxOPa(?$}%5sA7kn0wX0WM|ch?r0H;aOMl0nLro`H(-5HfOPwc zXy}@*pikGpB@*zR_}-6?LuGhx17aV$P~A;iXbxJ>l#cF%r9K!N-=NOW|6>mNR-%}7 zr#{lOk1C5!yQ7lMmS!U6;j*bd$6d$UZN%ac!SfC1AD5QxlGYg0iMa{ zSsEAvaPVLZaxgzVhouuim|Pp+i=cTx7VhLFH_qUC4s-u`AS1l^rdp9~L^x4J3TmI` zMxohoE(zO~lnlfW9FL9K4laZz4tOI#j;LSn3OBT7lhf$an76g1F&sqeCOj^)oRK>i z58He-wP{?R?L43e(xb((0eC#a(~pWNb6r4u6};($k3;M;bBM31+oD_z-|Yj_6^}Gi zVr&l~=P`qfS9*MH?-=>tncdOseuavFVzx@01hG*InKH8s7a>%Zmw-=5%qRT#*|2z+ zLLvC3hT##q=07r8&L;J=YQmcyn!RR^cDAUe72%j7c9ZFv=TkbV?esbc#O1N>`D z127u>dfIk;XV<9(kluoJtI)Z~_i93M-s=W1j9c^o%c@Wh)kDw{eBo-;=AWB?86nsF zllY(U(&RR*(I5TaBcZ?C|9BVvueZ7Yr9bJNb8Wed^?h3E6OV{Yg|E|$zV-2%3&&=rmfT&&hYI4mcAsh{ z`!}6tGT5?NoMSvRhIG*&{gBhedNoAN7AhUHu5lZI{?8PEE~w4bz1JcU^)@@`k_}E^ zAjNi3>$&?bzYjh?0(p?S$nuoZNc3mQm1KE!RR{x45jh9CJnr%KQX!~aX2|x1oW1ti8v5H&MC;Yu11V7?bHA&*uE zl2-7U#V_^hs&+&PZo+RxW*4A5kzY+-(+CNO%RKok@m-@cQ@Cvm4MOiP^rh!`rQ$3N z=z_QdxY2^WvrB#ur~!l$x=T+!GDrE+46&BQ+R4-@HU2_NGRmvUnRud!kKINWt3|i@2k#MpU%hjKo8e-z;pj=!p-O-Q zuXpp2@-{HR4R9^?lO=bN)c@OB2+Xfn#Bx;@8~nVeour)*+H1qy$&q)j4#&;fvk|5D zB@9|2F)c_JCVwd9@x4_AUs$i!VR%|sdG4gDvc~3yhz`Q%k z+>IWnze(5f>)d1 z>EyW^p$g-}y6o@3U<(?~-JxjTF6aUGNSr!>`cJIjYJHw}#orSy+*$l-yTZPe#yH>V zzbaIRl=VTC9m_IbhW2sS=j1l)hZ*_De>Aco^~u2XB~2&kSB74aIyn~P$)pCIVjK3d@xM)0<`*NfBYppk zfG;KVIe}KE5@eoRsP^O^#GY=S2sbmt4 zkEnGvD%pdEWjJE$CeEsyOBoR5S`{2;TjBOxe7{~0oEtzZD55zUf@4{q8Si_Me*O2h zLjP~nvr59Y^Vy1Iu@;17xRz|q9)8o6T)?njJiydAl8Zw6=TJBe!~al}Hp&sj=RMrUbcBUsms{cGFe zD(>^gvZ!$}xD4QN)?ReI7|?=CMN!U3m`Cq}4L)qU71@6B^?nEN8v>*=^;X1J?;vM* zNn4;IcFVvk_2M$%IGhIU%vmM_zXFLd3>KXzS3^3FP~San=k;l1e+rN@0q7W!POC}{ z>R~9yXZfrWPsaj?o<5y#w>a!yS%ffy8Kmr1`SvnTjAq>zyl>Ed&qKTaYHrGIA8C(X zUt^Y;lVfZ~8Y*c;rZ4k%InelE`3{DflD{n7KL%lNoL*_t{w}~8etG2#4v|uz*~0x< zHlX28bId7U_7VZwz|{YO+?Mz{-;NL*cCV)4Mr(okb%@CW5+ zUr|PJ=4;26v|bd)liWwO=mJsbzCOA#XChNCU!Hz0*PpOfz#(=t8|oiaUF3J1y0ypY zAau|WK4TDSl^9a`%k^JJv`fXLu)9)sr)s=$$^QJ%djk*(Mw>4594sEQKH8z__r%HD z`ly<}0Y|P&9ivDppLcv;-)k5>plFjW%M>t0EPbYMn)Gu{nP$N3E3aCBkR1*k=cb$X z#^ql}W(KYs_b@-?Z|@rrgze%HVI<=68VMSmX}U}9h#kE-sIovPL&N}tiP?D7)CbY) zCq~smQs{B@?`b?kmD;BDXql8ro_7!(UPbn9pF>zflH3c>-lBhiljAKO)z6lV4oL#X z!~yts5hTygZrt*TcXl9D+QoO{B{v6K{203ZSpB(1@UO>1r(1hjg2g{+8x!N(4pPRr z%t9uh#Pm6=%2_bo`!t(Cc=(K18QZ-1%iPX`$!g(N4cF=3@|r79?BRinzo8Tqta!Us z%=@1;mEe8;}gfm1C~>)zzRT$EtFrNMcN)2PQOTTNH%nyydG zr==vbt4tkw?2_J^0_)np3t^Pnufi}h*j4--ZNu^RnF|a1x|vTzZD;a8*6sS8Zlbyk zOzI5*nIBo2LDGgd)%|>k zQMUt?lqk>V%pa98k-+}{44lmpq&Q+`YZ8nCxHuv&we3z*FS}`dxpV|{k#O0jNv1gl z;AJm28_6{U{FF2rBQlJ!l{@c)|3+n@i%QpUIr3j{ymcx6e$2oLWJUr+2U{7PjoV|% zdN0)c$RUHbLUDjXAUKyaTloE(0QxY|;T@gjqo$5!>_M%Tk;nTL^k~bHp6|Augt5Ib zluGsPei;U4qPrZo!57qM2q4m#Oz~R)C5_)5#UyFy3RwzrLq*2>#dXVR^fHf=$8^ElSQ`(_X`14fIu8PxZ!_lIyVoea8Ows#U5Q_g(m5`>Y zIduB?_TssW=0~-^8f_0YmNaOP9_P)na&YZT=lF4^HX@o z>KUecs`oNJzscfdLouzrGt;c}0w`G|PD05+`W_l8W;DfuN2 z0>R%1&0F0+Bw~fv+3{`TphF%@l>v{+%VzR`_H$w`6p;BJi~XO=9~v9>d)A~fw${d$ zM>dNOc5peQh#?81;mo?2dHq2&(71{8CBaEwqlSh}DcnV9O41}O6w|t0)TfljZUIJA z4y9q^K_CME4;;*a5=_?Kz2wx1P3b!;qbjQ*CR`Ft?$_YI$ChJ&%^3(}0YIb#1|*-G3;z$> zIbO=pb?8ZWJRiHdDgKcTIY(-QY0?fKh&$6zwLScmPtsdX8|uDgW`Hyu4M%=B1m2%> zR8C4}<8^k`S8pe3?<)v&vpR$e=v3I()Ac>V>jkxQO^NY^35%+xoza$-t*5*8y(psv zn=k2%jQa%P^4ctj2e4VoZODx-UdUoYS8R)i_JbNkurxeeQs0p?l0iKhEazKjbtFY; zcL_yhXQh-72DuKl@=s*#CX1|mEvaV8uOTi#L4Qxi16(NZv7C;`Q$c~d(oVa+Vu!VQ>1CV$tD&i)45p>wu6Kw_hy$}%DY4s5_l<93FAGM8c_h6 zz6)qzTDmPrz}N!HWITz4^kb$v^h@C>DaX8GzRs?HO7A)XC|?={QED6BVgb_xYjk7bIVKR=n)?;;@SQQ(3Dm)y$-Sct0SrsX)Wg67Vu!cj#nx83rq{r=WaA>q|)~Y?D zUj=UjuvDO9kGNIv6^4%#H&k&F4;u^@jK(5RN`<8)gkZZaYQjX5D1G186!U z;0E;o;B;g}kC52-6Z55xMHnqbQz#TeZ`V5~dw!_`%8Bz~$V>wPm+cH^U<_y)N_hyPNyrfT92W9QACz+<73HQ63aw!7w8ib3{6jDW@U9f z^3dr`nvD|$P8M9Bn8PFTN}z=y465dbN_1p=4acs?+`jAadj|{Hq{y+e&vJMCI)^C9 zwq?qA#X-_#n#1e9xeQeoo$s+d_JLkv9=g!-M$*OxBkawduLV2pi2K-vJ41oi7xY}7 zh5pim7OKR0bIvx3NVH2k%KpYU!Rwj!W*jhR4viol& zv8=YAGV4%rAkP9^ZJg2)w=5|3p777p&|v>C&%A37D=&3OjC;rjRCpX-Q|s;Bn_5$; zz&r?d!&CRm>+C^?ONEGi<&#%SPO8~Oe;hjyRXTyHjF(2*BWJSr0A`Xd8oS<>cRw$^ z@IZD;1DEH{-g{EnY|Gg8fOiM*HAwq<&kiHS`#MI8x6bhNlB< zO!=`=Av4|giMbiua%s@%;R`Hx_)I;!ThKApWFFCrsw;qeWHYSUAt7|gzj5+vL)Xh4 z0SLT_#tOhgA%J2er(`&R;a^fT+_*N!uyuUT@wLQ3s{LeKLnbP)HO`Vnz zpqBG@;;;+p!~ti64f|JD`{yd+RyEjTU6g4bP4YwgGNuGOfAuQIojl5%7L<9It(60~^3pa1 z9J@ML1!=F<*W(v_<@bz*N4ns>jU7*O&X>mJjXsNOj=HK2{~!tvmqb~HS21(%E2v65 z=c#H@;Ux(vIZzzcI|@P< zxq4H8JoL922MuU3wJdn}eems_^}jA^mRyDtpjHM?!ayWd@KWKtt4ULip9C)e$>w4v zP{dPqlpzq~JUfdnCP^-h9GwzYe?laFOkKvb4#ue&v9&o}PMNA1{$*ivGwB7U6~V;N z<7xeU+u`_{W4=J+oE1>auiw`327;Xs!KRUmC?&A!vcs&ppVy$?A3k0AxMIX6?m0Ce z6IkVa3{~mtq_k~>?(t6poF|o@B+L}~_==W=&V=L|yvh>q4Uh!_t=y3jxu^n2YSubo z!l;rD%9^*dBb4++^%8^JV6~JIgr1AC>~XMrE%wtMw9P4i*!<3m)RSlTlS=78TsiB= zKNlea{e_ZXBz?T(Q^Y6jx)o9pi`D%{jH`?udVAzn|W?|q-u*82d4f9*km;4wZmlwUlaVWKs7u%ZE&^h2i! z9_Uc{hT3@X`1^}5XE+6bw+;`@_k-JnQpU4z0L=ZZX>o$3`Z|u{f{$&}7WGEjZ|Dib3y^rm6$;*uzB-VH-u%@#qSZ66ZsC3OImyzmRT*CKFS(tc~Lz z!=Mr16Tp*b>G791tzN>wehfa9%!c$yx{6;!57y40x2qm43l8-*7Y8>~WU6|UWSvQNBJ zRG2P@Uqtbk@Yo%L7xRq2f_@o>AYyYF#$#ZJHVObRc@RE#%+?hz zFgfBRPl%Gp6MgBbo$h}4r`6c2a2R&&#nEGR)(5NMjJ#75iEqj)0(O0t15awsSA_7R zJp{z;Z=6bFE?WdNK|_+dIJzkYjABFEf|LrGxct+w5P-y6z! zn#6jpu1jLOb5EYdEO`q(Vg=aI(3%FI1!#CA=gH}RNQY{GJNf;f|B2LYQQ$Bf*O%Xf zde&au_esOJRb27RpT?X^NH6OG2b2l2b^XCnX}iFuS58x8r2(JlHf#)=;kQfP z_!s_Aa!HHpl>M{Asp;K?GiC$5EePV%eZ*vWFPQCIIZTsNgBBJ2Bh|*L=SG)5QOc zck-=i<^>^$h3OrdwZhYQPpM>NBkc%ixk*fvJf~!J4$)VQA3DJ6_$46vi`_1X3+ZO1 zA6J72gyabLsxnok$m%VuQQ`wu$q=$O#k3Zq{S9f+!!NUV*K&z3EFr^aC20Y(0%)oy zN&$oBg!%K}H!9aX7(!TS)-Lm2F4EEw>R9^4^D+f4&s!_>w>NkI!Ar6Ga#2ajTnQQ9 zvYJL96DNnVA5dawYfvCMKe`-Tehv`bay5ZTnVnHiq)fUo9mh&83sHqQQAbZFhfesP z&@KSlX_#cj`wGX5$A((cCK5E_gqUYOV$1U$@?Je$=NP#~N;{U^Qh|s4qby400lq^H zz0zj$)|R@+sj}|J2lb#>+W{rgX{8m0p}hB*6pMjBhp>{8wEL;u`|M`$E&4vzFUqZ{ zLWB;^wxy9q^BwM;z!@wa?~tnXQ&5B#zwr-#0i^SZ=i|cjHX5nImhEy_y)U|RLjEYr z{f(#CTVedE)=`O}BmM_B_cCCqeth^EqjBIfn0!si4QubH*cAEO!&u+Ieuk0DhRVgV z5Yed?AoRSW=TEflnz|MoKH0IdK&_zDPWn0{u@Obik=W?xKtk$0;Rx?)k#toaKf=}Q zWrGR3XH70qKmknGO}v)xp1}+AV@uwj&tM0h+)nP))2^|fLgr_NgNb2~xU4fb4twqf zk|A^$oo+Te{C9%-ogk3-BfX)7RyBCbbC)rYU^yn)PE&|Lk14!uTjN;Fs{Ii8vHsg@ zQRFH9!4wZ~$A%{*Y_&rg!Q%Ijmn>1;U&f_>^e)=qDIL2ra*+m@Y)P9T<{THJ)PO8m)LkG%U) z_GF|n83V_K7ek#?JnF+`6}Czf;pby9j?b)Y?7VN~rXX6U8gOQO@MZ%k|A z7@-*=rnxIf&+ACIBL5(5{zHJi6gW!)#D~r;6+Bk0{=% zCp7GX{?dmtvQDxA=W)q{8%P1y9w{b!d#+PMr7Cc{e7ohHu2$B-e|dsJvmabA+!g-D z@^X>|*77k|qir`bE@KDp7K?4iQA7}ij>p&*1F>vX?Yj}-{6Mf#I9w_IHt%h~Vrj}yxPFruCQJp$fu#{lTs{kc zvOe{7fR26a*o`7gVR#nZj8XW0YhqO;^-Z}!PA=*Gc#>v-$n; z{oMOHe2t=^-zAHOgAi-kmrmUlRPlsByBznSh>Im2e5PSH-sOQRJnmYV{(!(7RTb&2 zV+r7J+RSofpeyXJPbmv(wZP8VNm&?@#&pu>XLou*ugC$nLsBh)#hxtO#yP;5t+-jp zjOM7stvBCu+!rts47R#=Kl-mkVadEVGFL5=N8Kao44INKOo{={kSzS5(6$d&E zr791}FV7~d@fd}02eIPmkSJozH72QwMK3*qiKs&u9WJ?aC`QDgWmQoLn!HqJt4`}x z|4kl0=a>F8)K2*?R3_8SZ`4HA@xf=qHnY17>%eDpT0HOo)=_5=;rRp@%|R(*c=~?7 z#km6$%8M6#!GEBx2r^ryOXqXOlrOlE7wlWJ6Bly0 znie^V&oxFJESn^*xod7b6$z=j9ZEj!4D%};uLu6=4X~uN#F|v!G`0nU2y-@p|C&UvQ}Rb4tAtP_ z9vt0ApT`@~;YD3B8*nP#T}!+*tCHkpxhrz0k0%PKjb`Mz=}*w*;~)zT`%+AoxI8}X z5Fc$XlO{k~sj}%fu>7xQ=)4hOD^sHa6NvYW@urIded-V{$!kA>!QkjvMIrc;8tMPn zE{iB4-1O6B%ytq-R!r0|n99ua(;|*x6Bq|reD}YmnHq+JQbYTGQsR(2ly2PbD6pYE zy^;K!Km95F@Nk=CCK_XdL#)|*!v+x;%Io7V&bos5YT*^16kyj}s^)_1j=i8Wfx*Le zmrK$bTNSU(qx!T+}e`3F+(|h(Dc8*r)e;4q-s0 zWVk*kfdKjOFB?b^@-pJ{!H&rJt$R~kMp6mxHJ3TrXiih+nD%$kF?raSXrU`3upJm@vf3|<%SY~E}llG(d4i0*Lbs1eBdCt~aM*Efq;Wc^S*p zNeZfZ26PvKzE~V+25a= z@Aun*%eKxWIK%aBTRuD?ApC&mGz0K}1ytDfdxaIBxUKmBSFr9ovwb?m4nq5S5PV+= z({}P&+%ik3>dMK(mIPai3A}`eg_Xe4=TBqyvesLby{(HVM!utNSL_d&hA_n;ic*wX z!9mVL7c5#UKABnF8hhod+r$0QaWIC4hG(wseXh){YGn^n5s)ksxM&&bEQxr>he|ic zX)IndO^n`aHK(6aj&wtl=Dn*nC=DnSjCCR?KJA_Chow~%C{fGdLU14v9}4OwP}_6N z9XRg9X#=0ceaC5d7NyR(J01f9@!-ps<@Avm%aw$N(Y@bpF&J^BJcCWnz=39FGkSa{ zW{lfHWIN@&B5cGYhyDKKNcv)|7KM}g7MN38pG-g22pUcrfXVmx5;$82@pVIkTm-&F zursE}a%>AhSmQv^j3fLhw0P~|fVeJN23L9I!^e1pw{nCnE9^{=}o zNCp&5?az0j5oZ)-Y_(u-`xgwB8>WI^?^)XV<7Oi5OY{;JR^s(-8Vk^-~IB25WO zZ%6uSL#=Dc-zsM*zhp{|B~VWO*$gP?A_k@m0LzbM#KzGZbOZqEVX#ulWyPEY5pCu&WTL2)?F7y3W-v~jda z9U%KS&CC2`H?q@<0e?g%&9aSsyk&1mpBQGGS4ictDx72tVFK3>FW2=(#EY{1%VZT- zleK6~J4>ITO;{1S0LO0{oM^vF4bEscv-)!-(7vsfCt|cE@o)L(NXFj8;b!M{H2g7h zM>fX06|XP3#3x0FcYWG`WH~(l%;iwg9?Vw~qe~-U8t*@($Ie{b)#YGRf0SYEP5}Bg z0Y6vP%pOlcWV;?anvUjFzO$BCESq6d<@Ny~T{?VYp` znGW-L1;=!)g@^W^e{8XY9min5S;=suU}30h;114KJU0^x?$|)sib9ve)~TK<>~;Sv zur*pAYlW=7KhueFKUZ0UN-OLCFG&bG`ms&f@hw`FRdm9*1sE?VGKo@}HBAZ`a)MU& zj4A?3l~q$JML1q$CJcKo`}uA8To(nG6>+W@gR(&wo1?G1UF$#WvPQd<3O7_V%*k>GSfDpR+Jm4n5VhA~oU=+1ggffF zS12Q@S02GDuZ>7qvj^PSiI0h0Ge$CmZ^Z0}Q!T)k#S_cq7@w zVMvQ=llsi9Km9Ic{O!}8BuICy-jBv|$UHEvwgTzXN7`tXa2A1C>gc&L!;*9MTBq^o z>^IRz6H$MMHXUqpb^q&%?BHyvLe`lw!X#2?Gu&|6h#eGq_arHvWJ}miLgad>Sr2&R z)|<$B&ous*e3ccomSthG$?m|zUO-FToad}9?T5_0abn_UVtZeIlotXAP_c@9>|kLK z`#fL?s1(i?Pr!D`03jvTk>)4ht~6$#;5Zau4aB?mhSIA}hVi72D$9l&{vqowJ2_-U z6bgH?AJw6=(;J&$o=Df0A-QrfkaEndJSe;_f4Vg_fTVGXj|f}tVCka|q_wAZ6A)5$ zA-hv&l@g%UR|>>I7CFf$cNeH10W*)RvdgQ>SO^X>y#e8LxG z-xRqUdHB)l=X}7xtN)lBy2VvY4slBX+d|W5Ghf=P*rCd}8&q{@_AP)%E`aQd>saj( zG%U>?6WB^TvPlLgWp8CVnjZ0cL(qz?@xhZrUa91NN3^m4EgDFI*Ad$z3gC&$Pbuhl zh($vt$6(%vf<^XxujC=8OMyE%hmnW;VpQ;47TFiwW6x-Mwke(ADi!^}8B4T^jg?PN}Ql`Hgq$Yb@p?~Mlx+*CJ8{e2^EdV`Ch~}yzF+le# zHI!Eg=9+-YXHBH$Xf3!ou234WjR2vbG1G`qG7zXL8zzI3Y5bi~=f~ITnjhYJEzx*t z#XTfB`Ox;QBo6!5o_*FM`~yEX3ZAZ<8NI~Q?d?!N zCn-wusRM%&sQ;{+T?d)IKGlLxE!5;H`9|~8968yVGmXF=raJ0Ve=uw)e^~E1K*`{ zSQsiMoej1h-$5Y&G|RWsob~ud^m{{2&se3@SDjUuEl|q zO5$i+aRE~Y4ZG2jN|4$*X&r7iFimz!clfQpliNNO#8l~G4)qu=AlE51d#J!K5I^aL-s#8#T&KSWq;lmJ_0#{b8Snup0eB~ER$3kheI^@73vwZU*NwCqwrkTSoonIUvN}XcdZBl2b4dU z%OY7&5d68(_m0#aO0|L0wfZaHl8?N=7)_J(Ad?)OY}khb^`?v^>Q0Rnm_`Z!O%`bh z#vRWh*#_#mCxJ|KRUgs@+DhDLXVk6F(&V8FYhkeFObQV>k{zPJQCNeQ)DK>yg98Z- zgi^#Ff8`?1Ci`RXtF&O=AIE+zMj@ma=bBj&V$*MBcDzm~!s{N$VXgZ7uQ=TQ5zbfo zJ5A!4gOwvtRzk&nMNsM!NWDw;d|_ZGc1j8#m)>jWVH<|;{l50y0RqyPBUhil7c$#G;%4P|qZQE} zc3Hwb2LjnF_)3~VeZ-j6!Fg2|PHuqQ0Aye3u&;l@aymfEa*y*>1|l5CAcA}+hEJYT zQo&GkR9kV=H3t$#qMI1OV#8tTAc_ zJ_11KRTw*%O^5V=eW;2Cs$4AVm`kAS-&GU*H9n8C3gIuXty~D-F7U+t(eekG%7?~K zXj$BM;@>%TT7;4~vV{P~XQqzSc#V=r7c3*^*+j~f^WtD)?4|yF-aHF3^=~TufO#X~ zra{9?H4kF2cv*PA$_}|og5YV6G4{kI(Ntrj9L*ZaFb<{tYhlhnJ60h@ZdhqfR>WhL z!V3#XX~z|m#WU(2J0EsHVUxE3z@Uea4`E&hu^Z4yhVb|Ajs;tHNM?nfNF3q}{Ik3O zC#`N$gVEoj?OBM!sYRPFb%KGV8DU~B2Zzd!DaoyP|Ch_ZL<9J$_?-aJ`=+}Sn#V!d z-iz4RXPg`oOD66R$^sxY^prX{8WnflEe5&rSME=uqhcV6+9mN5hTbKzVZU&%ldxqy zqgMVoB@=MMoaR#tYH6Weo5o-NsGgXc`Qwy?LJz)+4tX?)(OMa54>ka``Uw z&$)Q1T~~_B81_|S4Y&kcP9Li4sH|{uglRo_~g^X(#>~<;dnf!Wu;HVeM^Zt&#Ly z6)vbBiTeKYvbiYu#HR@AZQ~e+F6+AZ$d-%!+u;%i8{d}Ne>sHj4K(ix#=Ucsf!1J& zbe~NRwLs9DTN`=Oy8IfBF>J+zhhORMKO1Jofp)MSIq1~@dN6*H_*>DM4IIUVHa^!* zu_5*=EB0>;(xlLOl6tR&h}D8e0q$*ko$0N9fFo>^X15Et=%SDR_=A6 zaKY8?K#f>A-5A#(I9qh7>6XEI8n$K{l2{3({cx>w=%Ol=1&}ehr|YAIM@aiZ!QSi zC8rSAG*l-D5b-&2FdX2&yM);O&ZKeYDWGagls+>FE1-PRYX${*NAq+TJ>#)-Rf?V|Lyn#i`hqWo@g*iv}`wwKZ z#=J+MXkI4N|sVa9_#WK-44c%wFDpRs3uTVp2KPU4bkwCKoWP z_lKxHf0C=u?&adKp+hkDx;4{69@l-X2uf;VyM(E|YH-lL=;)2c;JL*BS@1WIby-{@ z?4O0hS!oa7ECQyPJSny5e+`$PPUKv$USNgW=+BCKEg@?2nG|GI^u+@J6XL}g_q{Pr zNQSrNZJ5>Z@*xwpo+h#g4h|_su@ok4`kv|O0dSlxX!QQBCXT9;p=ntv1UtLx7aRt) z&6CkU`tiPiRa9vYy`U!`9kzV*uQ#ct*?yL@sUE?$;{Q&D@<9nK#+& zcK`-l)WFuMLwp6d%IKY8Qyitq-YTJPo7oglS^I5v}g~IWS((>3PQBj{2t1xiJ)Z&PQn8XL? zpPx{eB>kka#SNY{1CvdzxWf1XevLYy{^pIXQRbWBflKMVyhu|P#s+nxf)XUK%_ z7g6X8;1ZURglsP12CStH=o!~zG&aC#+=x5^#=Y7|DTAUnT7As`!B5+VKy?Zk*`saW z{ij*8uIfMN{u7W8sqbK#tCiiutaGZ3T6T)78op~8zukrYrZ_2y{F5?SPAcR8rVGX@ z>qZ)72Cn943x` zj+_kp&)if%tNs>3b3`fDm-ShR!Rzbwn!C&csgY=ha5C}=Xi0m66d4L&VPI9pUgbk> z`$Fq%E@@q*4IuN-&Q#i3eMB0h=h|y<6J@Q!=-o*$ zKH$@zV|qh*PY$GKV*j4@`DOm}+d+ZK0_Tg~^BCcK@Ep6R)U9%`Vt93mu%t;SxlT9& zH+tc8T7IfF`kj0-$Q%I9&2->j4h_pdF;=~7dz?SaU$o8^b)JqX+wh1zWj-WVZu18S zs;ucL{1<#gDA0JO5XZ_-kT+^-!{`CQbPLZH3Fw6La{$1qvEi0C`gBy#AAxEw?mCtC zJ7pq*@umo`45G&oyw6vsl@r?Z)SaE-tsI=;9bZmCI+#3=A>2bcBbAzSdB5ZAy%vpJ z4l5TV8w1?1&Y3fA=C_82l}SZl8@xubQk}+EBa6S)!+-@+c>Rpu#=_HqjkYPtGJ`p{ z_CmpL8@ejHAt%t(z{fTR_|mG(>y5CGxB^lqSVv0-;L^PQE*`Pq4s18bj8=m`R9kuv z_M?TcY@1__wvVjI^?MURvsU?~Gx|0MJSq;FC6D#WOw`QF)emj`p`-pN-5kqvFY5_T zm4)RuIxgONEGfg>>WeE`i|2@_tgs(5@oB`z0=OyMw?pV(Jbq+BP@lb>36tIeU4rdM z$jkx%9>E>$NWvxOy2815ds)?@A1%~o!FP>W*yC@20oQERZ1fK|u={@UYM zOnpc0%Wogw{iafsHPiCwBfW`bZzDecgEn<;mzb!_Z2P$Jh5uT*qf z8cgN>sJQQQtM~);EOFqD0xR}BHYf3Xsoo#wiRPsU;X3RO?#JoZU`qNXGWWxN3-K^5 zAGT&BEe}QJ{JX6Ln`Ujs1G!R0k6luKWCF(L?sH5P-sJp_C6g&XcfOM$c92V6djnHT z#PD3NJOOEqi_1#N$Eh~xu{QS|grW=3*Afb!Xh z02>T62YM*I!6&lvH&C`Z<3~e~RJ6sZxCZq_XndpHsMA;oYDe7Rdy`~%1>Y>~|DRbE zC~xPMF_vj()-t3pfMjDge?7r*ijw6YZ#YSWCS<{kRS;3JNg}1oqA3HSGDKQ}QxK)7 zTKpUS(tOIY6SL2dHJO+>-1LaaawGON9ya(?-4t(!W2Q7pf2@|}*hRLY~&UDso|)rP~cF^H7u^S?KrUaKLY4C4BsNR3QphEVn>ki>}30xd2BEXx{fF2@KWO%^Z0neTQ%`_Mi~I0Dsk- zN!rLH?S(oQ+M79_&vToWQ6kT(6$PYev?mkUb5Lu3j_K9Vt)WvKdYBBVeBJ|f(!ufn z2~Za>uz>a3*OIx|hvpNK39K6x-^nu^u&9R6b6jO0%M1?MvV|B9TqnK~yp5(f`Wgbz zp!rlE6*#<=vX9BP6nL{v5Kv^AIihKZw!_=Kr2+a;Bx&JQ1}WUY~M*u5rpd z5c1HPXXMEngtePQE8D*SeJD395CCL` zsMg~0krLwse|*#IYK2SCdnh6r`^DopQd8bEt!SSLf78Ob@N#bg$r!+%0p0H`yMRa!sCx5{L$GCv z(E-G@WD8}53dK-%47lY`@nup4^p9cvQOG7Y$?N2r_XPip!&K^M$|O&}@xjs|*r;|cIH*ts z{~FN>AL}zG)7vkoKGaEp?mQG(H#ewf)ABp9G4-19mduE@xyPeR-jl&L@u{SCaGk!I z#oDI&0Gh%qD-uS)<7Rp?rANC5^3a12x$|7QCa_7UB3OHXU8f&{^f_HUp%_GR?3zRR z+|V?!hPQbuDb_}_P5cZsKh@6lDSjK#*l}qT%N47!SW8DUSLSV4KsEWo9SyeGM-Lt{ zxtm1gC=2%O3BIbXYoh@=g?|1a@zNT#aFWdq24nayi}{t}>dFXD6Y4k%H!05+FE0oGncJK{iaK?@e;+Iv#ZJ*>9C-0(eJl7PrQNcbUJWH@6Po4V! zVet9VIhB4zF`+GGKlMfdUdRcPKb!bdIYqes(!(5a##(loaPv8j@pyR`k*VBcB&>PM1<3Y(h zy@4-97+DU#y$b3jj=8_nt(K5DGfsBSTE%9pC85(d zk8!-cCL@M0N1`If?rmD`{(CMGa&bDXEyG9s=|VbIM0?-EdpRL>zFZ%@6B8#8J(Ub; zw$tRK*8dKFL!wShZUBdUU)1WUteEq-n}2ZyG5us+c-{W_>QEPf(i=^n(v#9HX~%D9 zff^tkyWI_kDRkF1GYS++?~XaI$uLjaR&XL>rDCcSsX|)}q+i2+Mh$iBTrl!EvPn43y!L%rhsExVbhBR+9MD`{$Eue2_R=#;OMLiI7+X0U2%^r{|k+Tc~mt1#5 zz!Vr*(Vr4CD*X&Dbr&U&{?#5IjvgLnRc+28xH**Lj-82Q5UH#V!Ac zcf3_<`K?E5l5@T`evYpRm&rKd2B&XEHjSqCe84fh=>=7<;$rqT^(m=_4Y0w9PcJng z+zSL4*fQ_(*jhvAS8B2Kp~qJB)e#T>o*i%;venyA;aa)<36@#og85Q*k&bi+M$g2d zIq5lJqBFW7=aO%Y7LW-ANb2j0qABtL77)ukgQ$^=RMW^5)FjNZ6GAXbteRlJ;HN20 zniEjT$;jX-R!+@ch)m7HsYCvaF*}v;F=U6o3u%qC&vyTeDHbkm3Z6}mf{+SYuccd3 zd%4EhECAv4Tu3}&!fYEk*%M-w#JA~KxL#U4;hVr^B_CnJ*8F4JU1+*ZzfNf@2lA7C z&rG(X*t4ZulD4Ig#c*cs{X5tNjs@id9UZZ|K-{^&M3&FO8dr!AM9c+I~ynxO8K9rd2%x}icoBpLfe;N=(9_xLWDJP z)VsSVP_O~rZ7pTJ#>b-^lRLs(zyT?XuvL4GN{GQW7l)un^J!($p+p$i0QyiKm|}91 z2ysOOgQ|dZ9uT8;5;JLrg@9np0M8jk8{d1>>Q)DH=4a99y=PEvpFin%FaGB~=i&a| zAW#tn6+uOUD2zpfMO0N-A|nArR9Gm)SfH>`6$q$^s*4m*7AS&<3l$ZBszF6qj1WLr zuu)M|5kU}QF;QeuK^UTuRaPk$MG=BAV1l3{1r$(NC@c|0L{wNPu@#FIL{&i*RfY@^ zg9aPMqbvxhg@5={29kE6`i2r@C0@5~o@8+k>mNanDpRhBQ36u{xf~B1gT5EmYqP#4 z*~*JG7dEAFSl#vgO#JSOX6e~D@$f3DDj4e;y! z1a}l(sGE2xu9Mv?^pB3bkKOGnl`OXYQVYM4xsBB1Ru%Di*Ps|+va^lL)!0f2rEfXq zsQx_zASBTOEL|M9X&uqqP`CIY2(>Rb67;Z!CQma%s1%NYxa7{O1X$4_1kQ9ntNHt6 z)0f9X4+O}^>gY}UjI=j1gvNR30tWOc%v2maV$E%z*=;&|8kS_)F(WS+KSX%bCu)pc?63*&6--zJC+Q zn_~s`sCCpSencYH%nfE&ob*x~*itxQ*f>M%s$<2zNY2$quKer9W+`R>5ylO&l(=S-~@CgHl5PD4-<$4`(~ z05f2raeq6?iKR&&G3?mafw>Xf{A=UW__#ncDZj?tsX2U-Il`?dp2!$6;xBX^`Y0)Z z^=j|OcZq$jE=t&itQ(ldRSTCNj-NML+q^d7v>KvV@6GM<4-9Xe=7*+vS`?%^VlG@b zZE?0;7lnCeG#9Rr+IgUOnrZytAzV5uX73?&9&hD^lCRpToBB+x=gvt{Eg1C$A&zDn zAAM0muox<-+%f=)9WB|RqaYy?W;QUpbMa?i?cSURmra*a4V*)$of!F@hjV3Oas#za zZ*pNvUHTCqRT(9U253}Ge!BB?y?7BOh|*=R2rHmt`s_Y>_@XaxT({C5>Rb1J6md-C z73=zBJU_sh8wHO;vb-01VD6Ir=@2EP(F?r5e-qL`3I%}G!6f%$cn_Q{J2($CSlb%1 zZD9g#Nv=?nNi@MO`vYS4*0}`SRYrAD%al8)3e)yeN7cXei^+?5oDBfRO#8vZ7jQF( zZaFontwVNaId{UeF6zW!v7+UN*xqpOI4PE`F*(g$`?Np7i`tVh)+w$*bK5{qbQ+CW z$FT6=YqR$t&rOR{=#{XsL{j1iwzoN_a5Y%-bj8TKWTt1-3%cM>$cH+Bf6!*pLdKzg z*Xn9+fPJ-vv3Yq-B%7vxR8m$~GZr+q6EMZ!5|kYxNyNyufm3;=RfxcAI=bjD0O{mO zBKNi};SSk;MS>&NAQu!yLf{Nm0Cy+*xT5ALv>iLZ@NLAV{cs9t$N;m zAX6rzMMFqF^+qCwpDoCU3XZ6B^39kfjopOW3_A)Eh!s19_JJ|mx-eEX_tDGP}d@bc@S6DtS$AbVlL zXxG^_v)&JF;DMIe2~aarpN^;G!=>T(!wF2zWKQsqCm+4Kzk?X1=%jMzuz@TRBT$-v z)Aa@(&jOO|?PBNsrY@b1l_7}px5%GM>%2=k)V83#8;G+yu-;seMXYH!lbATPBq?6l@3xWuIPjOLk{Z{3DihtPC;kU|4V_u1D!~9ewU;Ms!=YT;*vM-ein5|)8t_LJh%78g& zF)|yeUyDn)pxNKXRAGsWP7f*|)3I%Gql zX#cbNWoTJXh=3on11;q(@VvK?eaQ|V)9AJQPJMjb3qam`%FRH4^B_O-e{Gq!j+`Y$GK|_% zp2~#O{RbtA4RYA&gG@j2>FT<(u&i%`k~3FNMqR8eQ+ ztmtJF!An)f=j##5@EnI)<5W8jH$6zKXa$I8>IT9_K5#AW$`xe*nDjJ4OgXX3)zX1P z0uWIC{V>3{aN>44-51zg$>8w4{{=i3bh0LU)7I<*4fq9(6O^8fv@QU$Tg+;$#ouwj z8kjgs8H|YY0e)A!;{)7^OQ2!fw@HZpuLtrg1(de5Xlw!k{6sC)uyyn~=r~=0!yauU zG@geEj{WLq(scm9VN6J3fH9~vcM+al{A~j^y>)U{kPy8h9m;#}rm$`RQd^tn8hXssi}0McKup z0}YZZ4_*?=8HbW!U|pE`Z_L&vU!h1SBPZH06rlpZJyafBw&)XbcjSl>MMm`V>d^s; zNwv^yr4PjI`n+g`=GUUAz)x(6Y%;`&+#{Z=H^kG|_?#dX)I~OKq%m-%{igAyL2z7% zuH4~QBa1Qf_Qw|h%FFs$_#l4e9CBZR#)$maQ#s$l=ZTpLMZam*=$ls%Lrwd2YgZ|> zPHKxRq`t?Io9mLIgz#in9HZ0D`3p^sS%uFq2KhVPUW?9RzTeT)oUs9{1^_+^&LG^J zG!=6MZ2ckylz$%O+|Vs1JN)FAnyQ^+33bJHvdTGObJz-B#4`}GYze4&hsqS$qy0%c zqE9kD+by=y=_=edcsY^E1=y@9hyFLB8B3#sip7gg1{ynOr_G(DSMrzeaKL1R*;hYx zYxML32%v<1nmc-2Wl3-meU5EDBQX$rkb`!nva4G?g?Y<{Tp^Y6cQAfuRoZ<*?!v`8 z$lpsM@sd&83biC$(#Gxc>ZHU_kJD;te8Kdd|5Ro}h*&6Mh?_YR#MrV*5fNOu8hx(A z@6c672dvkWm1PBOscXSRAmHq=^~>W2kZ22jF76c;H%@-SAsMugx&u80rG`F1(CeNU}}e}mDwY1 zkA-|0d)r+^)yA?EPc9tf z4Vmn?viM%CNG4Np9elr`<3=60W)){4M%arSglbv)p+|0S>FhOCh_CcWi*fw13}C{9 zHJ^Ilog+p!SM{_%9G9(>11zZv%JV#DDbEQevMvZ=WGkL>p~EvEp9%A)g|KP~XjmSP z1V`bQqyk?I-sCy+SZ_Bpet4aJguZKoa9)^8M@ruHox;(<{j!sAa7*dNyM0Jbu=G6m z56dhb{hI5LloY1jHYxO!(J7CZXP8OgHt`V;8o^RXZ?Z=kP`6keta=a>@TKr)h(ebys>gLL*Z*+?q4swp z2BY^aE$mb~S_HQ4jYilh?j2_{GU>i*Hlg&v;~v?5x-`;6q4|P>6Z=CY*M^E~(YhZV z?=f76tK>j;wkxjC6gAtEG|HO^PXA!5nPwrR;6Xe zRv>n;mjL}H`z#Uw$vFYlIeZFtWV`!t#R2Dl&w&xm0zA2Pb(r5j4^(4rBHiWSJy9ie zj4X1H0kSyiro_K}eZe0^%^j6x$WwBsc8hy27~&8FZU;xOY11|9vluqq$+-iQOPW5p$T?q+04Wd@Zk2V`{{?YQaI2BKwWcokMp?(di!8M73SRU znzvP*xE&A(rm?d>R=_#MB<;Wkm2be83N`feQC5tnCts}@zDJvE=w2Vk%q=_lKqS>7 zI(E$~c}1$R=_zbD0W64Pfqwin2<^78)Q_6W5Kv2W5ZER4EAv||=yUKbw}NTabxMXM z3bycjLU}>;+^*Bg3I^;THq#fiAPS8M$)eD*(fSc&<876)H*5u0Q&M?elsvHuv-N(R z`DF7F1hGp5TAyF5RS6Vn+V=Ibc5v64Lk6@*GTJ-JE-#vE+NKz^dwOW$7Bw`hvl_<> zF@WxTFa4%{xHcD~vStf-%&9$(nz*WXxZh_A#bp#w_K#juSnL+Jnnp~0*j#j}Cy4a$ zH(sc6*t;cmC&0!yT1=uIAUjK4(g&{MD_-;N92O50M!?F&ACP5xFjOOM>hw%maUe!K z*Y_kL)2Du;=*OLI*AllbY{&`BS)k%$x(?d>&40598mw?=`?076MJaLL8owT=@N^z6 z@_gVDz)yGSbXEp{ckl#A4s10o2v6cIhdjDb(Fy!a<}l5ce$#kI!x13%k7)f(kzeYn z0i>T~bOh({<Z#;Kii5A*SS1FIGsi` z#JTqJw!fszz$*f`_d+Z!_Xc8Uo-imBbi?gj$~{7zZ<($DMeBLqR&k|akU4ha;7hR5 z_M@yNlGa8ea|XC7VT$@f5WDb09qshsWTu*bo~Qlitz4bV@JiM7r1N$+=6&6RW(Jmn z+B8Teih2e+z$L!#s#KUfTH(`V%mdT>wKS9Vsy+8vdwpW{doN2pRHz3t(HH`Ot_+sB zn{zZ^obHd|{TGdi6FAJ}Pr`RxeYD+D| z%Pcb?obq&|cVCR|hj9RaFdgl2F#?w^Y0scb@#^kB@oorJpLRAQd;fnV4W;2n4f(mt z%AiJ()rdau>UaPG<{TSfP*&he!VCqoFU>>qlRu)|wxYPa7dT88kZJrc>0G4;;fV9s z$~66&ZFbSWN`Jc@S|i}yhB2Z#r%Nf$=ppt|vEdc`5*s^!k(>I8zG`1v-flNHF8Y%C zs({y9AJ}{dpQFGWCiBu##FNOgBqtDQ+R~E3+8t&o{9})p6enWCH}RO*#g3u&41E*R%@Tp@VW}XO>8QP-HGgHf z{yKxWMY{7D)$JtUoeS)x@=0N$1H2by=F3oP1B$b~_U(sgFY1Yk?miN9!DbV3jwr~M z$R`F%+efJ8*II~9z+L?T<_s)=(r~oLF@N`4W-}x|4eLrrSMi(8|1QL#x3@(`;65x@ zAx@*Sz3}Bq0n5EZ|6YLuQ}LPBafRkJXc3OQn$EOnANBBG^5M~@T5*TvC;KH;b??Pm zE)X|c4!Ovq;)?9(Ra|;aY4<2PX{${lY#e{*UX*xrIoog%1WN9A{6ht^5LSXUrs_G3 zRVl$d2oR-Lt}5mLb&Z^B6hrGbhw(30A79R`--ZPiuUSGw}T`IbW$Mhx9+R|R{3K5VVp0aAb8%i z_vG6c_MtEAmU`=+)MVyyKy>&K>l9V|=|Fk@p}1>t+X*q-_oq!b;;Qa_>y8#qr4XAM zTREpcutlgv0ob3dJR7rDSpY8Htgp+YOer4lCUkU7Jd^R5O6@2cjC~6^ZT2T`j2lo4 z;d48sF>a=x-0^wem z4&HlrS%)!u`?mwuN-Tzg6TRrhWPxFYEXtY(s&dou7E4(q3S{s)r2o(IBK6$>Wog;W zmZVx|bxT+S+c(Nsyjdp+BKRNK6=qmkK_n>CPu2$|n7tCf0-<0q1{p*e;7IRQb7JOIE$#$RgZd~;_bsTv`7bUa6GgEHk^QNt6I&WeqP*74@ z6&bi_;_Ryh>|k^Sn^fvfY6wY2K1fCITqqS?yQ5e!{3*nMpfPl7mWG$!uEl+512reD z_E~RaxK<;gh(PiC)rYjc41qWS=)YU`Nb#^oJnnC%#p9$*jFS?=)(LKE6L7h)Ou z?x|eqXp(nNq@z6*K%}wb0{UJ|Jpn1l7=H_m!6uv&l?gxbn*0cRumFBM_3-)ta<)1H z2)}-p`nvBVX(Dq*elTs@1iU+{Sj`|FVH~vcg2Z$O!QeYratj)vR;&IP;Ag_v%5}b! znGIFHW|L)sBn8bB6};PUu@Beo;rcT0u<%<33ckSdsuXr)vvjQyVQ1vBuZ5lQ9vE-s z(wZ9BO_#tH?e3&AiFivn_Y3Gc5j_oG^eD|{H;DAKfqt-Ph;J^1+qT|b zTZeppZ{cEsYfuL-om9{@g?htBk-bVAgPm2^VHR!ZVk1##9 zfzzZ2a^R4Xa}TJ3c;3}_F#tNz;f1N0hG?a2mVQD zAc%J=CaH;JGw)b-b@b$uxsAk>zha!)hklhBY{=jBI}MmK#p>o-zb~KkyG0jX)a+Ms z0f$%>73PeGDWl_IOt943+sd0E87mSHu7)C~vCFFzf>NFQPglgTJHG+AJ*L#m&yAnM zG**4s=Y~F##$wLv#ZNv3HSXOv=Y%v8IHksxxD?|^0tQT#7rUr(T9VI(KZshw*S>#& z1dNYSNfF5r$axNL8`P7=l-;0Y<{Q0D=j{4v444X|KSV9|M>}i>v@jOmDyIZQqc{9h z0Q(>PoyUpq)pJ$IY(n7t-QVnhmM_d;In^#M1;pXi;`Hh8cjFLL7G_>tk*y4;i64Cx zc_LfR8k@k&_J<Bpcs<$*{K+P`&^4yJYoNS~29@&W(eZimNYA+<1p{n!G)ou?K_ zz$6XBU;6PjC<`+7mPw@pfJxyQv@@k-C%uFBS48_LexCDNUv;$#>YhDLm&07Ljv zi7;MnbF6CZ85u+Hl)4S#vaFHx=)%3(t-7=pHj*~6Sv^ElXME_8f?OK#|4Mg# zdJYt9SJe@n(noA`?5c`9+*)&3E>T>EO~IK;@QiMG_ArZhw;)CIj)|TUckA*@PW!a+=&JQJJt{(Zx6nSrsOM1 z$riisd^*!{-@?E61u#d-g%0x#P+J060h@a&(Vc?pQdvYDMsKJ99Ax@0ZZOTr=ic&h zhKa!vI;IgDLFA|m6Q+6ybIl&z=s3AlS%qJZ6bdrDHx{Aum6Kqr(+@aCg-K=0 z5rve=%=B#h=7Wd({!@}P;YIFZR?<{!CvZ80ktY)J?lIJ8AOjcN$|E5}8_Tx0kD{?b z$>uu`EM4w+8~`mq(!Z@*pQ}8N%8u~b!{4lin}UhfLH><#4k{<$p1_6;LlQ*79T{Wa)d@K0tjzx$jz*f< zHS%bBz;Kr^${kojid90WtF(uVa4nE_0(WVRa z9td(1kLbIgz)z1i$6T@R8B3q`TRj7O06RD4MPFUwpgD-xDC(}VGo=vxPlRx9qp|^3 z=>ez0tW|b(g}T?EZr63OzaG{{X~~xstF4MiyeCkdMSZv|8YdO^Ebgc`{7{mdo7Y_&QErG!%E^6JcDbYs^aXXm}5EaY+ z9Q1^FTGUc6n1dV6f7Q88F5ZpKiN5PL#EP-RmP44wKS_`~3w#=4rrn7t@;44kGCYEU zBy$UPnvZ|h~-@<0V>sM>( zGtxQec~;a&7F)egH*Jw zy37yYoGQGFPF5|tc-8u4L4PN?CZ3(lCf#i?P=u)&2VuUtaJjbR) zI2TzstjL4F)=lpeNws67aw|e1+gdL=6=2liN2b18o>1#)RLUSixr#d%?Ml5j$Yh?1 zvjqarE)}ghgUQJQjVo8skqiUyL_4M73kvBn234ethh0%tgvtqj4ws+VsCXmNgT1#m zDa61&-TMPAsz{0Bp1Q|=blP(x06Jwr-+hfvebpNZ0n<_2SH?`$fcZuQ#^2t4{dwoW z5BWX*a`4t-4i=c>`od@jf&VT$FJHXDJ_1jXENxGl>JeNTsHr^e&`Qxh;GDW@Xr5Wd^ zpdrSOa{wL)RLk(uryL8lwA=xOgH2iH-<)`}*}|O)AMx>>Dl6IVI^lT(aA4mZOpJ71 z9hq8^(a$*EOWJ^6A50K9NxPT$azaZpiL2(@FT-Wuv+GSQH%o6IcxG z1#stcKHCbasc{yE#R}-VwKo{Lt?_qm6@_@(#c#KlcRN?@Y{rAFn~}$bRy@zWkH| z?!_z2=d{5+j%)YZ_j)*1g>;rR)~K$-NF>!`DDxPiQ1!a^&-J;7aS!2(*+x^y=c@de z=7kT>e0TT?R0eqe!`u&DGY=ow7|!H<4Hj~?=R9N_2eE}OWE0^3-MpChf92*wIs0d~ zz0!coUC-xtq8~GnIpf1#_lk42$mTBK?wb@HmDo`Lz8Q(CWeVG%fVavy&;!g(yv#uI zYpv?LxXphyAX8`t?^%IYX=s2#DdwkXMwa)Y_x_6Zn<$@*yK3ETu{MFXe|-0xArLWv zQ--kW1pEG;L8fdj2b#}`9TQM6z_?nvN55=HdJe~yB60&O61dME`sbQ212f8yXHpu< z@Et#EwMw9EHbq5E7iHk@$DzNJ$B=`b%J1E#`uQ1X z2Mq@K4LB2!i6LIxA9r%1qxty&ZF}sk_wb)z z6t8|0N&KGRNSnFw%!_qlhceXu1~Si9TQk5R z^hnWOKC|$frK+b@?(nkd{U9yS6BPHC^jbYM zYlci1+tr?^f@vmJ!M4PvgXW98d6`V>7_i+Ah0mELawy6M>($Y6)WQ;3WCG2Q7%!zdF zY?qU%=l`n{+~9ZxK-Raety3+coJsr}NtUPsoA*KQ9gCGr>tl>_T<~~qE{lg#joIg8 zgnqDlY6i0s{5hlPBcZMVPwGOPB5lSL@W_rIWRH>#S$lcW6jhRiE^_GU4Y0!lSi|Kg zG=}R|NB@ZMb`{zouDIASVjz5PTNg0O)T4XzELkPUylw<`pYXcMLuaO}8>7gJu|f4?Mq zW`JJ&16uy;4ka8Ibfz7J(l*jPLV%sW-Yt4ZgPus17~voTh5gtTfH|LBJXiPb8y~mb zcusG^qJR1YH{Ud0Ezi9fL^kU-Rxz$Dq#mtrdBS zjzeonO+`*7LxV-> z<^Z%63?KdEi+q_%QqJR9jT<&^2KKCK8V!p?Bgd0re;(7>2Ip9IbbC-8oR~)!9mz^Z z&VV`AC&zyrha zl>)no!sA(XT?H6xTZ@2sGiLzF6Q%lJ>(;HYFndKN)^xE8Dh$DN5sz@SOqqSP!ola2 zZ_(mALZ7Lm({Rd;X2<3OJc;)}EZY>H80cd(g;7Cg3R(J-9XheD z$JWcM^@2!i_5PI$(2F1$M8xTnqqVg7mc|)E;0?C$v}eevH{+kbpg6M;eRJfTP4~qc zD;V1`sep$KoOv)EVDZt&){FHK^Sdf%Ef;)_s`wg`70>ZHpJk&QKXF;h#zl@PpWyID zw6iIPPg`8h`LMe73L?o}ZTy-q?3d)L`=&Uoy!m57E z7M_(r1Bg%)AwNH^4u8;ED6)22!~*klnXOkHR=U^KMHYud+-945xnpt5;!aGy_)d(z z_mUMZjMoD~BDY&B-9You!Slc%RL^X6xZl_#te`GG2>?hC0fJB+3L%KJKZCmt7;og{ zC3x?A_ge@GY#L8+7UO|~FkEeG7dPh-GS8IAhO!3~n1hoF8FBx=Z!ej82Q?o1Ib}Mq z91E9(vng0_Z8Zo5q!q_*=S4JW4z9+rqYZ`tZ5H#tR2ZtW$>K1>>wAX#1r3#L7MsA z6ZPUYOZmNFj?YuJ=^L3QY^q^88I$adpH^eeZf6wRb2$I2wk@KqVN02$+C4B>7}vxE zLdu{34pO|q^6w_@q_L}DR*kHGJcZ#M#oTj+`Q|9^jH*s;9$jmVdLOQL%Kdk^d8a6n zeY$a&=C23}GWeA{VR3wr9VEeH=l#auYDqF3c8n(yWfpYGex=vs2)LS4=g=M4Rgv$c zl(jKkkBnD7+Df7$Q*RY+pfZ5kXgh~y)D7a%^*1931(;!qgIY#8G8En6y7(W=>q`hZ z?@Y!BKVZ{P$e%d?$}RrnaB)`vkr;ggC`&_9XeT3UZXj^+51{jaoccxJc6#IY%w)YX z+Y?>D({&68vnFNZ`c+q{D?D;NEw?Zu<8}JY`ofyvTGYjE(|0aldYHaYC%Q8VH3Y0N zhV$$pS&3B5vLPm>bPjSRT^-dX$G{F(Mw4cP_R2b^$IT3g<-fht$ElC8ZQ>lo*fqKz zM*-z-?*aDW6&XCkl@J!(xA{)Q#8=BqKz^Bp!bYk?tXe=PzsGkxdcyW~HMQ@q{^pf^ z=UTZ*iR`}fIBP4|+6zhbF*1^_&=gb-z8&=|h4Jg18BD34@gd;}VO%riHSAE1Y}cYD zv3PI1CaBLap3tk{+i=XrYO(Qx{rYV^JjNV>O^`Qo0?Zu$zhO?zGKhKa zSrf|68(_cpqsM<vd-*GzM9++j2{fQm2=lj69%tJq68OQ1;xgwUs!;5h*o>XUK1;bw+qP z{^0-{Pq-oM;IO6=f%?(5O%6zO!#OfrMbnsQOtBzFeZQ_}FSfn3z1bBu9(-Srwq`;j zpTs0poJ~ON>GqSY$M8FIUsQ~uxEtUWKQMEHz=!es3oO08j(*l9ZNv6>TuRzkj+Q-# z#7&e!C-^5MIqbet&O9z`Roxg^?LhQthV*nLd_G+4@^Ti&PS@hl4ou+GO|Iy&f5gKu zL@=a{9r$8e=M<3a;a#0a5padr3v$Fo{R8D!Kmzd?Sc}vbTN}ojvN-xC8~gp-(xNI= zShd}@(1X17USeuNv2hiS*z_LY=g#%KYhS?Cvs?=8W{S~7pVtg-LGgp)d`V*M5VH2+ z=Px4hp<&ndXS;l4eQl!KoIEzR+e=Ai+%VK1a${@M1;r-$f zWT<>gfzYdKLnzjChbf|>>zS}kvnEXSI4)KZrk0SoPa{}I%Eu-w>PGxnKl8DtG0gX8P@_I z{1`}`>!JuwCv9L5_4~K#*Ph0IqNK6gYJcG*k?wh>L!7je-f`EUVZY2o>mxltP~sWe z*&YE#4C7z*t%TTn8w@ zO#MBrRNojxbrd$NHllI2Dg18_jF4fw35VjE!_s);1&qGKs_LwS@guNojSOcK#`t%! z61KL$&bQ#aL;H(rc^{wyXs|uq^r5x6^EHHRw&?e z=9>KF)Zewngy}Y(-?f!!XLb#SD6Im|&;J1tg$c(h#pKEfSnfI+<9@Y|!6K@`vgRbm z0Sy&8!wCMs<@c}b-}iR&7j=!Ey%Rpf3{3nl+1g&%@JMknIbKZ0E%fs8p)G61Zi^IB zIZ6QTZ=664q2JqO#5##9hs>=XWhfa^p*J87n4(38{vv^Z0l_0~{wZZsePR>34u@2 zz%2&YElA=u)a+La@$2fFhe$l(Kqo2>9}4hY7T7>O0!^==E*|06SG!fLF1ue3=0I<3 zM-+x5+~Frz+xy(A8};RZa5q})ZHniFpADUe5U8W3JQ^`Lu+Z<PExL7RS21Rj8eF(x}y zfyT?gjJ%oqCncCq1S9X?O_rSs44}7YY7iB+D`~rb^^{L2i9CE$ZFGkDQV#Z!|7r z@;8Ftv;EgtM5@LPo|9OBT(D(#JZ*$}TaYh+x+OY@qDrKMKYGeD?liW-T*ra;8y)Zn zsvyz-mfVIX)u|jVD(9F>0&zSp_$53oVB*}{iRlFS^aqtRfZ-I4+UtJ zYh&ak+3Nba#Ze5Oh=_Or`G3}PARyK>>5|GmwgyuO3eA0>^(RObWjK8MfZ093mg%5* zqMOBx7z^b!Z~Hx`;#nuF+6aJr9yG*f$6qWBxONP?AVoOlS7oGnuv~@gCxLb}XI)0p zN#%{SJKd6Ki4P9bKoaY#fl{##I;Ns)>RW3UgOL$r#D(oXvKc$y-H$ycd;KGOaz3E3 z$M|PdcN&GYP~?)pb0#2(*lz+h$>Vczbuddyefa`Z_Ec2t5dd~yJ#%;D4o@ZEnDQ(# ztHWJtj38805{j(=ZZIME2V@`*F3xg*V@ZS7`&fK9qrn5r6=iJKrAcJu2qVdY-cn+C8U7OkM{l|sREkE_zDe!ssk;_A8Rk7wpAyC(Ci#WHaYq%})1EObsphsQQ4v*lF4*f79Uh6KRWJnu7ub zk2SQkJqTb_mmeCA`B4yDS0NC|4{5;PA4_sQY}gp%T+7-6`fDOZqpU%{m?|PN0x;B3 zJO)$>$KKq5i}H`(8pJVrkV=|}Z@SkF6*p_JCWGK5H(j9px=+?)pY7Sl!u~VJFPV#O zs=|%S0%t_pXymzGMtK<{4&dBpZTq#M|LTFp*pcqWlee*MWG=er(&&74#XsYw{tR_c z4^h1ImLHhXr!l)A6=esxrQJ0VE&*afKyVRQp^nZ(83~c9>n&{ae7^mPYTJ*XZ&rxL zw-2b3B-}6&ye;OTUL|++4h+Xzx(&rhEyyZW5&AvAIqnG#lq0n8)5_0EbMr)t2>11ex-m0yP`_;$_` zcGrp{UR_P`h4qe4)X^oX^Y2?eA9pu?)O@VUG3lF`p#D_6IO#AMA5bs42=(M7Sv1cY z{W8x0E$y&#rcS>KOMWFGOiUoM6@B|2SY|1n+5;fcb6Ma1^~K_jNC|iPt~pi>M9Ch3 z&64_kaPBqtrFtw3@1tDvvVl_<_D0p(BtydxBcME!GK2V=s;LO|0;?azW$6Z4}5Xkn~SPL54Fj0d76Es75;zs z7&-r2+eqeBf=|qT?wo1{MDZ&L%YA(;dmNG?16+Q8N zA8F!U_Q5p)6oJNgpMK8q8EcnI>gzD}4+(ethuAKBW+}N|$GwEu{P3rnOKz7eA;|CI zO-#oSbJK4_LH0xUpzgQEaX*u8;_HO(HZ2z}{|x9QL&^+z6RG@f_>+Wvhc9Yz8b}?- z9h26lRM!Nq1NNr6)p=?Y4|H5pl}VM!W8!Kuj&Clu1zyB?H(u8(l3+O_H!ik@Y-x~Q z>{>~ZwGe9n)oYMY=6@Zye;{EwCi>J9(z!!kT}j+$MXnIf#p3Dt7_8U9=`q_7V#4em z?Q@kv7&goaeoN!y@*g45bj2=OnfH?&Y&!}%G7kgwHwMp_T*0U+X+PPh0{;mTYSJl(WPUzp;Jx7 zlBm0T%J{TR_b=I~79Gb@sYWT1Hq|UKfyE_N$f{fuTh%>IBaE5&Rn_d86sAurA&*%K z6v^sj_YW*L|1BVpQs8Iwol!?F;>|_q#p{6mQ{k`-!6ZPm5|t4}XFvGUq^x<&Eb3Jb_^xR5 z=#4}$!QRG_vSq5!9563MnVfOpgLXQvx}=k$$dq}cp+yRA4Yj%xdHPsQz;UNlw%hhT zpN)MJrqlI}govso0;rV!t)!9EQd9iqX86DksKQnrm6YmnE4QAgOIWT5&7e|EVl3zm z-u*01uaJz2aKTMb4{4}nH8Lk57rrzpbn*_wR-%1j1Av~g7jYGGJbPd!Sari%DFRRD zwxD_l?Chu5=>pG~TiJS-d@(5p_V2a>Oi+Tv|zS z1JcH~KeV9>tGATUeaynjKZ3W79izd^WAYflAxN`AxYp}%qU3q)&&d|@)tt7(dbl!QF@z3Cp}{gRNn!At$OU;)Pd~d< z;c;Fn_et!0AC@nlw}i?u1Bh$(s}&)f2X=%G4!!Oe-brv6k$d`{BFr%X%6R^W+zma$ z%=sBwgzFNB_8+!aWF8rP2)Kveh#P8Xq}K5oR1gz4Z~IWE7Oq3O3e|FqsMA!4c@plx zT@i)+J=#4AFqOA}X}Fm=K5YW+yM#FsJtm6drGr_uE*{^5#sl6BizTk6*#9Wc#BFm_ z4aEx++BV~(Y`%Wg5;hpD${;V=bA<(qu+%$9WJrAem(1BPBYtKbJu|QkOntTwpm__| zhyLFj@l(xinUy9CO53@96O!6Mw83Www#EtOp3(U;EjxKR(5CNdYqHP}qdY z4l9_Ch$$;xW%rX!C;yLzth02usQpdp}Yjy<5B|1 z_DF6g%I*-~AEK2U=kBKvR0&aRs^kyE<|$0Z(@>=27z$ByJB}Bxv~C5>j?xpyNw>Z9 zFmkttg?Pll@tmgz#e>fFnjxR1B^oe|-{nnD*^p+o+5$oiIe)z{KuqxXfo$@#F6U=r z90tSi%H4z3P9~}^3UR3&9C_GG!4joMpj%$@`#ux21F4^h39FiH6KOwa7d!@Z?+zb? zVBL8NL)(^WX4blHz1a5PfNl9yOeqFzC{iKUjqc)3R1hw0e8QX|gfb$&Fvq7Vic@juHv=x} z*wJA#+I#jZ(s) z@kJvA;aGbuc~U+BqAuPAxVs|bS5R#c(T{-A?1T>+$_H^D8Leq7H4 zx&yljs$glVJ1{RJpUhB#bWlJFQUVmD1m8Q214E%pYw9O#u&XBT}lxIH4pVl2*$BO_-V zkrbWB6!5a`Moi;B`(Ql}LUKnA@RRgi0_1SCsK}9&pc#h}>Gosukj)| zS$1jx>k0TBUU#+&EU8{5%gFSB)Z(rq^Wm;XU7xQu*wJH(6m~}i(XcM+LjPJ3Rl!uI z88#b*L`@8BQkuc4nLKTwj$1=auog1z!W-pGj|ynlHyu`+(*PgVr|5YKCReB0uiqj zho(|<#n?9kPI6*D{cEul?PDW0n4FxSsec@pr2EJQQ!mC2uJIW@J(q1*g|Yd4VxRcS zm+yS&AyU$lovYRD@cF(&uU@q_EsFH`(JHg#mr0>D<#Cr8iB&OIo|`T-H-3RV6tVmg z7q@2CG@a{5dhtrZ9I$`iGSuFDOOLahobJclBO$^>$%V}Q9!vcG8)C%TQ1oNxvL5S- z865aNMEnaG3#W2|I0@X?Ng-EHHy5VWOi=xf0#q>NaHjxR-+>ASs7kbvvmNp_Xp$#X zg{iKs8>Ji1Q65Uq&~=?&6bDfS^c*a#>U#OnoBhvw?637FE?qpDaV#@v73ZUVe91Ovf1wSE1eKZ$lpu0z~$ED0aOU z!rNADazG_peB?hQUyPs|q2d5K?VeO5fMHC6>7#4EN8cWIM`eBTIhaEmsAM0pa)b6| zO6>Oezg_%7(rNBCKTuVP+h)Es$F#*)?MB*{LRqiq$jvs$$#O%4|3I5^K0wl&J$IJ! zl!F3H$Qz#Di{qX+svEK*O3N+%q*dVZ#X4$#v0=_~)SH=$qeoPD6LF8gyGU%UsckDM zcR{B2ZGoY0w3^5T+o>9$S#^+4)rBXbXd4K%RCWs8PNL4dz2)e>UoHusyB?D}iU+QG zlBAAo-}(^x>_2%OcvI9kWybP^7z~+*xt~|@-R8j$H?ZEL!GBR~Ak1P8hDFPFG_}vBx>*zF;^B&A|eXKS1 zJ$QRXi{7>0!7cY?M#TyLYtXS4$pf#f_kk)kHasB^I!jE#I>1sF{l zRn0DFFD5L>CZY4);^v#}cN^(xr(*_=pxhq*|3_%_YQ)tH$+6eIhV{PPgW`k{Y#BOV zssRlduAp)3g?|)r$CLW@7r?BR`Sa&A$Lz*joJ>sSuX!p5eEY?_7tq)Zlx6zb=`v>T zYT&ng6VbJ0GdiN3-Eb+m*m>01ru76VLS@eI!IMG#)VHJ&(?9CPXr8Qume9a!f87I0 z-2WQE!xJ=_25!N$T@HDfPE19{_WaEmVt`cV=XCi2?2_f>j@3%n*C|}^CN4ErKc0VQvM?v?gEGikXI%dkT@8$jHQrx%r;ndxrMxNA{g;7zRJf`n3Vp5cDA zW!QGi(L0p#FX;Ofuom9!K!9$MUi}rAf>HMdCe;eSmOjT#j_ObirA|h)W^A;sA#5CY zDJM}k@S(u0yCIsKX)0<*U(S!Y0<@}F^UvHD$Jb)h8jK{I_EC&JX$FsT3Mn!9tcI&^ ztu2w{o5 z4v<6Uz2Ywe%C62T^_fj56q|M)(oIdB%D(P>_v(aIUOKM2s|OgsY?=dzYF{$*H&Fe# z7^nsPTmK@!rH?sWVf?F0?R-F9*!ZhxM&Iq%{q5BXNYoAmD*h(Co}2~FxqW!QNVney ziO8;m3#Az}6luEA#XNTv!N|-Exr3Hjr5TC4sAbsYx|&MSztC4bZ@yFMfe2x%2OVx< z`C+ILORxCFooduU)5+$i|DuN;k7&S!UA~yK8oH5%+)`oIRU<_)365W>m-Y^6$3KlA zMg0A5hdz{WxLqsLD@qbf{vT0M+22h6r>jN%7vv4qf7P)w zJKDbvF@$qCr1OjIS#3Z?9Gz?Zfq0PNFW$+y90QQlJre}8{$AnTF~gO%K8cEq417}P zt_m=ZsOv791y;^1eAsAu!ZBsQMZ{9^UP}URWoV386b<|R^ z_sDG~qcr|yK*|)8sS|Wd!7J>A7+bLS4mE&v_P9mhYzaAtydbIM40#gg3!~QS9h?V< z66$*yId}uCjO;a@z&|TbS##GK9!$embv!*LDAv$CAzWgG1%rwhYI{I1EDOoaw>D}U zzz}gps3)}RzJ!!gR5Jz8m;E)giI%M+FX*oMXtCPFXa2;&FWe~#aG4I=nW=410jCXB zR;FV*?p$&fY*Fg;lm)QcsZaqj17oFeCUhWe@hD-Lo^`#Co0$@!QG43oJ=}kqIU2r| zYEaoc+c6i#k^EH}_I-n>KDfH>*fj#O!dburuzb|9hu6q@{3up=Os4#XxrPAFh^3w# zN}~wV;%v8x)yaBn7RTCHhNu{2OoIHkehpCj=pbrba$9~eUP#|%suNXZ=8W<4&)#7a z;X>I7Qr%ED#nmHQnd<7E1h#{GAyDFyt@&H{HDWoXE(#JibE4(Jj2K%9RaO?>f>Hu> z80m@0lmlDN?!ylX^oF*h^l{om167CQG(^)c88^uD_3pus%W4Bj$V>$3DqPUs4R>|- zu}nsr?kNasG+^mL{5-c;Dh@(ci@XEt*`RDVD zGA&^4&CNlq_080R#~2>%Lo1KUP0O1;lW;^xdx_WdaRZqw+RD_`7GG25F&z_m`xP-;msf3WCXVVA!-!1uxjWYQyV7s9PJTp#F z=&*(DNbr)mO`wmSIs?LP8)yg(JoAv6%*4~F;r;ORy6VJ^vG@K+^6>@Kc6 zLnwar?(#!wVc8n*=s2pTg8i5_xRI&ctHd}Y3XOi|`YrBCLLSeFf!(@~wIu2W-2>($LQQ`8#LT4e zNBm7sr(OL7nJE8D0+NojAL;;iPBV{CAJTF+Wp6{`mR;Af9w*y=efRX3h&=035yOw~bji3p+Jz5(JH<=WDDk0Ja zT}e93qSys2Lua!b&a#$dc zel`2hC;vJH3IM(4XfMS?qx{4Z0A-jo`i^g)HBhNW>Qdu8end$;+3S4r<5h_LAsDFx5`XH3!xn3l5a> zWWQdkE1Uu8gkd83vcA1@XuW6{4k=TUgg2h5O_v)B!RRWCZT>@)iX7 zM<|-)N~}e+xu$BRd(5fHc3*{KG0=4O`*msWxk-Tx#o8Z1=BJTzO#7c^(3E$OslI17 zvpJDk`mLljuI2)-9EsQ6hCo2Y?OGalx?ll%2PU%U>!cSpSe#CSok<+idj0uxRzIDN zhmQ@#2;WJngWBez?1e0?C2Dvj*}tXg!n%@IhvXdvboFg;sffyfz+uEJ%oV*5u|qpo^4FU-$;vV2nz zo&0j~K(1Y|mD{}+Cnfred}Id!uw+1b?>lzPZHw2!Rf#81v0g$efz^7{85^g~avEl4 z!%3H7ki#fTHHW1P+(eybHRWDomF3}mbtXt$kDwe zlUr?>D;Ga}1SM2t1b9G~N#~sYjP=T%nzE6a9^L6VRaRSecJ$@}|F6+&>su_HfjXp| zfy;RyQn0Q|6AODRC`l+lP@qtAhg)xfs;gtbJM1absm+LuRC z*%5;C7t ztb&)Fv|^GotW-MWr@Cs5MODO2U|Rm_HqXs%aM*G8iT+fMO8sn|yTReZmt{jga{{ou z&r!FNjq53On^Rw6Yt@XFZaj(lB|LvDT8+M+ilbTDv89zZ`>oL4goVF;wICj(=tjfy zZqJTRo3QG0GdwwK9HS0z!>PZ4^zo6|qPB!INYY$v8~Uw9S3avn1!BKyaub!-debH! z9Q4uxc%j(Bt;Z*E$ZM3s6;i>st<;CK+iksTV$@xb?urX)Hre-a6}`u?mitFr176X+Qr zGZz>_lU5GXt>{n#k4`iV!1@A--Tk{jG&NH`dn?D#>=S{cR%KNd;XgO`rMu|sfVF1* z8@u3Pm83_U|KP>gLMAfeekYdxmVTU1OonIKXD+w)7!gm@bZYCrqunZ=ws9(D1L z0>$2X;Sm+5mlh=TDk@~0bi>#d_8B(8gyG((lI!QX^Z{?IyoM7|#mfcRNvrG4OzNB&{o~Wth<2gwhqS)+^$dwg|cD^;X^q3 z<@4NmVVedUJ*R=qoos`-@;2J%VHgKwrJ1I;Lj3{`Ymjxs$a+Wp7pd2(rbZrdZq$m4z!{ROj02?S) zO!RF*6=Y;<;^eZ5JX!Fm;trXSUO`d1(kdO6xB>U# zdG*0d3|UHNFx&%xAoGI7^pIAPcGkYRiLAgZOAD-TlkkN`?G-z@;bqC%UyGek9GxOC z6Cx2_^zn7C(>2o%{qhXd+Xx>ubmXM*bi3fyx(a z{BaN{lhAn8C<8My{a8}#cIu#@V(mE*)mu^WvuK^ePR-BPQz&*wZ^~lOxm8Ak9yoGlpP)%ky(}$ zAp7a{b=xssIA7fg4cE(gY#8=le!fwD_e}q`kc!SjHx96>2nvcz~88g$5uNjrv-%?q{fIaWzQxI?hUf(z;^!dTBvBQ*70Puse1T7J zN-H=}a796OKFb8Lzw#PCqn(t+<91w1V3)NQ_2?MlSs^B`Gd%X_=vM!TsTcXV!cq;5*4Fo{rR}39ADc2@}Q39@akMG*1 zDU##k#hR3@pH#{ZeGe6LVcoj(9s#p0$|Fpciw^vep*9wEFT-T!25<`EMUPyX@2e`D zJ}&<}zji)95dhd~Q~*U1S{D#zl$tO0cn+TvAZSDKEd|q?g=CvxtibDe_I7MisC8>N zsA2dTMc)#R+xGAoxLeLG3)gUe3SyXdxSXr@Z+Nh4C>gc{aMjye>{69~KzOWN0Qv5~ z&jWkz*SH+b2^N&(Y5B1Ar1V}811wP0FFc9#uq-@qItD=d!So2wcQrvKlua`solv-Z z3GgTXT5W%z_u4C|ZuG&P59~VHR}SHevYS63X%6}C(CVS|u8h^SbFBC2{1gwMke^ zG(i}`7qH?mIrMtWJ1Moy*z_IcGoWG@K1>-OLRX*VJGg=d?||DlSURYQ83&*5&SeY- z68hHxy5ZP9);GqpJb7zIRYG3&`k zz9RfNg)?*oz5-_j*dt5}D;7}k=uyOgIuhzic7*3GrYL z`LQ?y#)rv7@BEBPXWDi0T$`UI*$!uv5J13%)MFQj36Q(QhfVL6IC4H8C7)41e#Wu( z0v0vxkf1EXN`#5-I7h&WCnLAdA>dW%Hjo3$d^=c(*51KfU18H!IAXEFwndP)12UtE+@P~NLfp@7n z&mOF-IO9mpcz!A)_ma+yNTTF)uS=C2Ga0=-4(d>ispOzwG*_H6-r}}!OR-Vm=!)GN z-^b8Nh#04k8ezFMCsKO4#vcL%yZs}IF>(6u0N=lPrbwbIu6cXn930#BOdus*qMryOd;M#YzjMM}`|iJ)DjHFme0d3Rr6M*k)RXN0 zKKu|G!&Zka!Q=}r=3NYdfDvZJG0-WTowL6A?m$3 zZ^X48RxdVAh=oKuMq+kj_xEi3=Ki@~yjT(XA1z&g4(JMm^ED6mxp4?G7w&IuhGPeI zCj7ebhZxZor^-zJ1fB-YUTNYIJUwUq;bUbqV~DH zoe=f}XV*RkqK|d_p{QqC0L!qBr4~4UgI_PWDAlgBV))UQu>z?6%2)}!MLsEu`A#?$ zK)o0tXOp)bWRA=Xcj=x`D^BBWw4Gs>=B*FhA>NR5_c4FG_Ts?3KPzcEM!M>V^?%Zo z6`y!y7%*xETbYaAZ^n3M6^x$LCIgiU{WLHfvD_VKa;Hr|SBaZGaQxFa)Q4L>0uGga z6-&s`rGK=oQp#=x|AQ-d4Feya&nUf>j-#P34dU^d;!LPYyB_-~3g(x2-ght)<5}V2 zdvEQIl7NLyxeyTQk|IY&tN%eq(HJ*x1*3A>KJU$Rxql0%A2FA6c}+{pRdlWj%sAhx z8iw^&hJ{BRl$*3zo__B~!;}a-Ipwm-1F4?jP8KIywJ2!qLG=u^dltQRjH}Ln|IZxZ_x?5wui~KY6x)Pl`ipbX7cyYACy}`8Ggmk1@ zVX8MN?4_PE11fJv8kkpdc%@jsWlS80c{snT_t%BcJZpy0NG@grD7zgqCfXe$puOy0 zi5^-ndZyt+QVLlSj*Ke@JZG1nEg<$g8v`%%0Q}81P;5zfV;dR*y(xc#3H5LEdW7PW ziA(%AUj$GwwM4b`wGS2L;T6*191a|pmlBm$uhEm-d1~QW6W6gCg<+Yq7R94_B3(b|Y;gJ1iyP1nbM&~9H0S#^d`A3U`(w>+j^(I3%YlwZb0bIfK7sIDYmXamMy7+-!H_JX^&pLoJ`K}KU58tju)LT z`fy_Mf!_{t1-aNjE;_cntOHmBW@>W;nF+9r31cf5`lloVuMv1CTq*kF!pK-$a?tZ7 zSb=`j`F_2B*J`GmcnL(Cy?<-IC_RgfI+sadKZGJamY_ub zkfYgcX*qmsykZOhNkF#0eIdle0c@OKs}Wx23#-gzQbD*A=J&u0!p?%@X}o(ODG{?j z@jPpfe&#|(O&H?mgZrbJqg?S`{p>ouh56JGO1#1*PTDS$Y zFTl_En-Bvg6}vNpdeE=50($uWra%o9M!ws|1uotaK@!8`dXP6sew-FS^g@&6lUdt= z92=yrH`8Je&%IEnw-(-hAj|VrZJ(rrR(f0_e05DXU_~tBDQAYyik)k$1J2h4ggy{r z*C)ylabujdgzMsC~s) z-qO-gcnJ%>`3RoxOKV6D;XsGE!a{|ukpvaV>~Pdf6}Rse_rLaH=0@f>44h zjF=S@)@~Q*g;w!5vj?DQ9aYo2I5nl0!x|UQK&5$*7$n7N*)X}&)U|Jz}dHPVt z9_t%Vk>xdAXvfp>^m+B-0471gVu&3ta`wnyme@;&-j@zOmz=rVs4X4a zzt`-+)Wb5N>4`~VSevK_6OzG;(+%�qtjRZx;H~Y%MrUm|@vgP4_*}JHwQ2iq$gq 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≠#QP{2yl_p^x7R(h*hZZ;)1uX?Ur%V$o?$FUC&A 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%0AE)fuhs0GF+0{sioIMaIA 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

u|s99h=%ZeL(lJumP?L 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

ozl^S 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¨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%0AB2Wq&pgp%T|EUiSML=mjJ_r>forQT&I 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 B;=%v` literal 0 HcmV?d00001 diff --git a/validate.go b/validate.go index 04cb1787..6dc04565 100644 --- a/validate.go +++ b/validate.go @@ -935,8 +935,8 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // the checks performed are ensuring connecting the block would not cause any // duplicate transaction hashes for old transactions that aren't already fully // spent, double spends, exceeding the maximum allowed signature operations -// per block, invalid values in relation to the expected block subisidy, or -// fail transaction script validation. +// per block, invalid values in relation to the expected block subsidy, or fail +// transaction script validation. // // This function is NOT safe for concurrent access. func (b *BlockChain) CheckConnectBlock(block *btcutil.Block) error { diff --git a/validate_test.go b/validate_test.go index aa91333b..d45f7ec2 100644 --- a/validate_test.go +++ b/validate_test.go @@ -125,7 +125,6 @@ func TestCheckSerializedHeight(t *testing.T) { continue } } - } } From bf3195e4ae905b4f7b1a1516342971b5e551f434 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 8 Jan 2015 05:16:46 -0600 Subject: [PATCH 176/190] Update TravisCI to goclean script. - Also update to use the new container-based builds --- .travis.yml | 14 ++++++++------ goclean.sh | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100755 goclean.sh diff --git a/.travis.yml b/.travis.yml index 0e3948e9..1284c11b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,17 @@ language: go go: - - 1.2 - release - tip +sudo: false +before_install: + - gotools=golang.org/x/tools + - if [ "$TRAVIS_GO_VERSION" = "release" ]; then gotools=code.google.com/p/go.tools; fi install: - go get -d -t -v ./... - - go get -v code.google.com/p/go.tools/cmd/vet - - go get -v github.com/GeertJohan/fgt + - go get -v $gotools/cmd/cover + - go get -v $gotools/cmd/vet + - go get -v github.com/bradfitz/goimports - go get -v github.com/golang/lint/golint script: - export PATH=$PATH:$HOME/gopath/bin - - go vet - - fgt golint . - - go test -v + - ./goclean.sh diff --git a/goclean.sh b/goclean.sh new file mode 100755 index 00000000..5087ecf5 --- /dev/null +++ b/goclean.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# The script does automatic checking on a Go package and its sub-packages, including: +# 1. gofmt (http://golang.org/cmd/gofmt/) +# 2. goimports (https://github.com/bradfitz/goimports) +# 3. golint (https://github.com/golang/lint) +# 4. go vet (http://golang.org/cmd/vet) +# 5. race detector (http://blog.golang.org/race-detector) +# 6. test coverage (http://blog.golang.org/cover) + +set -e + +# Automatic checks +test -z "$(gofmt -l -w . | tee /dev/stderr)" +test -z "$(goimports -l -w . | tee /dev/stderr)" +test -z "$(golint . | tee /dev/stderr)" +go vet ./... +go test -race ./... + +# Run test coverage on each subdirectories and merge the coverage profile. + +echo "mode: count" > profile.cov + +# Standard go tooling behavior is to ignore dirs with leading underscors +for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d); +do +if ls $dir/*.go &> /dev/null; then + go test -covermode=count -coverprofile=$dir/profile.tmp $dir + if [ -f $dir/profile.tmp ]; then + cat $dir/profile.tmp | tail -n +2 >> profile.cov + rm $dir/profile.tmp + fi +fi +done + +go tool cover -func profile.cov + +# To submit the test coverage result to coveralls.io, +# use goveralls (https://github.com/mattn/goveralls) +# goveralls -coverprofile=profile.cov -service=travis-ci From be91008dc546323bece271902242bc165f0338fe Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 8 Jan 2015 05:29:33 -0600 Subject: [PATCH 177/190] Update badges in README.md to SVG. Also add a license badge while here. --- README.md | 7 ++++--- goclean.sh | 4 +--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e6b62a56..77c0d188 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ btcchain ======== -[![Build Status](https://travis-ci.org/conformal/btcchain.png?branch=master)] -(https://travis-ci.org/conformal/btcchain) +[![Build Status](http://img.shields.io/travis/conformal/btcchain.svg)] +(https://travis-ci.org/conformal/btcchain) [![ISC License] +(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) Package btcchain implements bitcoin block handling and chain selection rules. The test coverage is currently only around 60%, but will be increasing over @@ -21,7 +22,7 @@ handle processing of blocks into the bitcoin block chain. ## Documentation -[![GoDoc](https://godoc.org/github.com/conformal/btcchain?status.png)] +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg] (http://godoc.org/github.com/conformal/btcchain) Full `go doc` style documentation for the project can be viewed online without diff --git a/goclean.sh b/goclean.sh index 5087ecf5..f845a01f 100755 --- a/goclean.sh +++ b/goclean.sh @@ -4,8 +4,7 @@ # 2. goimports (https://github.com/bradfitz/goimports) # 3. golint (https://github.com/golang/lint) # 4. go vet (http://golang.org/cmd/vet) -# 5. race detector (http://blog.golang.org/race-detector) -# 6. test coverage (http://blog.golang.org/cover) +# 5. test coverage (http://blog.golang.org/cover) set -e @@ -14,7 +13,6 @@ test -z "$(gofmt -l -w . | tee /dev/stderr)" test -z "$(goimports -l -w . | tee /dev/stderr)" test -z "$(golint . | tee /dev/stderr)" go vet ./... -go test -race ./... # Run test coverage on each subdirectories and merge the coverage profile. From ee945cdeec35c76a151535ef66aba573048acce9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 15 Jan 2015 10:23:47 -0600 Subject: [PATCH 178/190] Update btcutil import paths to new location. --- accept.go | 2 +- chain.go | 2 +- chain_test.go | 2 +- checkpoints.go | 2 +- common_test.go | 2 +- example_test.go | 2 +- merkle.go | 2 +- merkle_test.go | 2 +- process.go | 2 +- reorganization_test.go | 2 +- scriptval.go | 2 +- txlookup.go | 2 +- validate.go | 2 +- validate_test.go | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/accept.go b/accept.go index b94ae48d..c4104c55 100644 --- a/accept.go +++ b/accept.go @@ -7,7 +7,7 @@ package btcchain import ( "fmt" - "github.com/conformal/btcutil" + "github.com/btcsuite/btcutil" ) // maybeAcceptBlock potentially accepts a block into the memory block chain. diff --git a/chain.go b/chain.go index 9066a2d6..da64b1b7 100644 --- a/chain.go +++ b/chain.go @@ -13,9 +13,9 @@ import ( "sync" "time" + "github.com/btcsuite/btcutil" "github.com/conformal/btcdb" "github.com/conformal/btcnet" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/chain_test.go b/chain_test.go index 22f0d01b..1633a27b 100644 --- a/chain_test.go +++ b/chain_test.go @@ -7,9 +7,9 @@ package btcchain_test import ( "testing" + "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" "github.com/conformal/btcnet" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/checkpoints.go b/checkpoints.go index 17417f11..8c64598a 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -7,9 +7,9 @@ package btcchain import ( "fmt" + "github.com/btcsuite/btcutil" "github.com/conformal/btcnet" "github.com/conformal/btcscript" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/common_test.go b/common_test.go index 1010f185..9d7c6d5a 100644 --- a/common_test.go +++ b/common_test.go @@ -13,12 +13,12 @@ import ( "path/filepath" "strings" + "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/example_test.go b/example_test.go index 2191ffa6..75f6976a 100644 --- a/example_test.go +++ b/example_test.go @@ -8,11 +8,11 @@ import ( "fmt" "math/big" + "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" - "github.com/conformal/btcutil" ) // This example demonstrates how to create a new chain instance and use diff --git a/merkle.go b/merkle.go index 1ac7a5fd..97c63b0f 100644 --- a/merkle.go +++ b/merkle.go @@ -7,7 +7,7 @@ package btcchain import ( "math" - "github.com/conformal/btcutil" + "github.com/btcsuite/btcutil" "github.com/conformal/btcwire" ) diff --git a/merkle_test.go b/merkle_test.go index fad68b2f..2886dec1 100644 --- a/merkle_test.go +++ b/merkle_test.go @@ -7,8 +7,8 @@ package btcchain_test import ( "testing" + "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" - "github.com/conformal/btcutil" ) // TestMerkle tests the BuildMerkleTreeStore API. diff --git a/process.go b/process.go index d6162590..70f52344 100644 --- a/process.go +++ b/process.go @@ -7,7 +7,7 @@ package btcchain import ( "fmt" - "github.com/conformal/btcutil" + "github.com/btcsuite/btcutil" "github.com/conformal/btcwire" ) diff --git a/reorganization_test.go b/reorganization_test.go index 1acaf23b..470b4fee 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -13,8 +13,8 @@ import ( "strings" "testing" + "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/scriptval.go b/scriptval.go index 5980948e..85b038ef 100644 --- a/scriptval.go +++ b/scriptval.go @@ -9,8 +9,8 @@ import ( "math" "runtime" + "github.com/btcsuite/btcutil" "github.com/conformal/btcscript" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/txlookup.go b/txlookup.go index 107c3ed8..2abf4f4b 100644 --- a/txlookup.go +++ b/txlookup.go @@ -7,8 +7,8 @@ package btcchain import ( "fmt" + "github.com/btcsuite/btcutil" "github.com/conformal/btcdb" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/validate.go b/validate.go index c8a84b2f..04de256c 100644 --- a/validate.go +++ b/validate.go @@ -11,10 +11,10 @@ import ( "math/big" "time" + "github.com/btcsuite/btcutil" "github.com/conformal/btcdb" "github.com/conformal/btcnet" "github.com/conformal/btcscript" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) diff --git a/validate_test.go b/validate_test.go index d45f7ec2..60d72ad1 100644 --- a/validate_test.go +++ b/validate_test.go @@ -10,9 +10,9 @@ import ( "testing" "time" + "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" "github.com/conformal/btcnet" - "github.com/conformal/btcutil" "github.com/conformal/btcwire" ) From 81b60312363f28cfad801d412eaf1be49eb2c961 Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 15 Jan 2015 16:57:55 -0500 Subject: [PATCH 179/190] Enable the race detector for TravisCI. --- goclean.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/goclean.sh b/goclean.sh index f845a01f..91833320 100755 --- a/goclean.sh +++ b/goclean.sh @@ -13,12 +13,13 @@ test -z "$(gofmt -l -w . | tee /dev/stderr)" test -z "$(goimports -l -w . | tee /dev/stderr)" test -z "$(golint . | tee /dev/stderr)" go vet ./... +env GORACE="halt_on_error=1" go test -v -race ./... # Run test coverage on each subdirectories and merge the coverage profile. echo "mode: count" > profile.cov -# Standard go tooling behavior is to ignore dirs with leading underscors +# Standard go tooling behavior is to ignore dirs with leading underscores. for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d); do if ls $dir/*.go &> /dev/null; then From 37d0e1918bd22dbbd1708c558b614812419be350 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 11:13:42 -0600 Subject: [PATCH 180/190] Update btclog import paths to new location. --- log.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log.go b/log.go index 4998869c..7a79f9e0 100644 --- a/log.go +++ b/log.go @@ -8,7 +8,7 @@ import ( "errors" "io" - "github.com/conformal/btclog" + "github.com/btcsuite/btclog" ) // log is a logger that is initialized with no output filters. This From 3a35b009ac033dbd932f938e1a8f96630a038e6f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 13:57:29 -0600 Subject: [PATCH 181/190] Update btcwire import paths to new location. --- blocklocator.go | 2 +- chain.go | 2 +- chain_test.go | 2 +- checkpoints.go | 2 +- common_test.go | 2 +- difficulty.go | 2 +- merkle.go | 2 +- process.go | 2 +- reorganization_test.go | 2 +- scriptval.go | 2 +- txlookup.go | 2 +- validate.go | 2 +- validate_test.go | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/blocklocator.go b/blocklocator.go index 136236cb..544cf72f 100644 --- a/blocklocator.go +++ b/blocklocator.go @@ -5,7 +5,7 @@ package btcchain import ( - "github.com/conformal/btcwire" + "github.com/btcsuite/btcwire" ) // BlockLocator is used to help locate a specific block. The algorithm for diff --git a/chain.go b/chain.go index da64b1b7..4a537005 100644 --- a/chain.go +++ b/chain.go @@ -14,9 +14,9 @@ import ( "time" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcdb" "github.com/conformal/btcnet" - "github.com/conformal/btcwire" ) const ( diff --git a/chain_test.go b/chain_test.go index 1633a27b..52aed532 100644 --- a/chain_test.go +++ b/chain_test.go @@ -8,9 +8,9 @@ import ( "testing" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" "github.com/conformal/btcnet" - "github.com/conformal/btcwire" ) // TestHaveBlock tests the HaveBlock API to ensure proper functionality. diff --git a/checkpoints.go b/checkpoints.go index 8c64598a..1ae74d1e 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -8,9 +8,9 @@ import ( "fmt" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcnet" "github.com/conformal/btcscript" - "github.com/conformal/btcwire" ) // CheckpointConfirmations is the number of blocks before the end of the current diff --git a/common_test.go b/common_test.go index 9d7c6d5a..1f60983c 100644 --- a/common_test.go +++ b/common_test.go @@ -14,12 +14,12 @@ import ( "strings" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" _ "github.com/conformal/btcdb/memdb" "github.com/conformal/btcnet" - "github.com/conformal/btcwire" ) // testDbType is the database backend type to use for the tests. diff --git a/difficulty.go b/difficulty.go index b09c108b..11bb36ba 100644 --- a/difficulty.go +++ b/difficulty.go @@ -9,7 +9,7 @@ import ( "math/big" "time" - "github.com/conformal/btcwire" + "github.com/btcsuite/btcwire" ) const ( diff --git a/merkle.go b/merkle.go index 97c63b0f..83e5acdb 100644 --- a/merkle.go +++ b/merkle.go @@ -8,7 +8,7 @@ import ( "math" "github.com/btcsuite/btcutil" - "github.com/conformal/btcwire" + "github.com/btcsuite/btcwire" ) // nextPowerOfTwo returns the next highest power of two from a given number if diff --git a/process.go b/process.go index 70f52344..fce1ee33 100644 --- a/process.go +++ b/process.go @@ -8,7 +8,7 @@ import ( "fmt" "github.com/btcsuite/btcutil" - "github.com/conformal/btcwire" + "github.com/btcsuite/btcwire" ) // BehaviorFlags is a bitmask defining tweaks to the normal behavior when diff --git a/reorganization_test.go b/reorganization_test.go index 470b4fee..85346df5 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -14,8 +14,8 @@ import ( "testing" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" - "github.com/conformal/btcwire" ) // TestReorganization loads a set of test blocks which force a chain diff --git a/scriptval.go b/scriptval.go index 85b038ef..33387929 100644 --- a/scriptval.go +++ b/scriptval.go @@ -10,8 +10,8 @@ import ( "runtime" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcscript" - "github.com/conformal/btcwire" ) // txValidateItem holds a transaction along with which input to validate. diff --git a/txlookup.go b/txlookup.go index 2abf4f4b..4dd78a6b 100644 --- a/txlookup.go +++ b/txlookup.go @@ -8,8 +8,8 @@ import ( "fmt" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcdb" - "github.com/conformal/btcwire" ) // TxData contains contextual information about transactions such as which block diff --git a/validate.go b/validate.go index 04de256c..71e5f3c9 100644 --- a/validate.go +++ b/validate.go @@ -12,10 +12,10 @@ import ( "time" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcdb" "github.com/conformal/btcnet" "github.com/conformal/btcscript" - "github.com/conformal/btcwire" ) const ( diff --git a/validate_test.go b/validate_test.go index 60d72ad1..bac033dd 100644 --- a/validate_test.go +++ b/validate_test.go @@ -11,9 +11,9 @@ import ( "time" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" "github.com/conformal/btcnet" - "github.com/conformal/btcwire" ) // TestCheckConnectBlock tests the CheckConnectBlock function to ensure it From 9bb251f530fd71c370861d893363b361e824a75e Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 17:28:19 -0600 Subject: [PATCH 182/190] Update btcnet import paths to new location. --- chain.go | 2 +- chain_test.go | 2 +- checkpoints.go | 2 +- common_test.go | 2 +- example_test.go | 2 +- validate.go | 2 +- validate_test.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/chain.go b/chain.go index 4a537005..931ae995 100644 --- a/chain.go +++ b/chain.go @@ -13,10 +13,10 @@ import ( "sync" "time" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" "github.com/conformal/btcdb" - "github.com/conformal/btcnet" ) const ( diff --git a/chain_test.go b/chain_test.go index 52aed532..6b7559c5 100644 --- a/chain_test.go +++ b/chain_test.go @@ -7,10 +7,10 @@ package btcchain_test import ( "testing" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" - "github.com/conformal/btcnet" ) // TestHaveBlock tests the HaveBlock API to ensure proper functionality. diff --git a/checkpoints.go b/checkpoints.go index 1ae74d1e..188b042f 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -7,9 +7,9 @@ package btcchain import ( "fmt" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcnet" "github.com/conformal/btcscript" ) diff --git a/common_test.go b/common_test.go index 1f60983c..fca5b61e 100644 --- a/common_test.go +++ b/common_test.go @@ -13,13 +13,13 @@ import ( "path/filepath" "strings" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/ldb" _ "github.com/conformal/btcdb/memdb" - "github.com/conformal/btcnet" ) // testDbType is the database backend type to use for the tests. diff --git a/example_test.go b/example_test.go index 75f6976a..0a0d5610 100644 --- a/example_test.go +++ b/example_test.go @@ -8,11 +8,11 @@ import ( "fmt" "math/big" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" "github.com/conformal/btcdb" _ "github.com/conformal/btcdb/memdb" - "github.com/conformal/btcnet" ) // This example demonstrates how to create a new chain instance and use diff --git a/validate.go b/validate.go index 71e5f3c9..17bc5939 100644 --- a/validate.go +++ b/validate.go @@ -11,10 +11,10 @@ import ( "math/big" "time" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" "github.com/conformal/btcdb" - "github.com/conformal/btcnet" "github.com/conformal/btcscript" ) diff --git a/validate_test.go b/validate_test.go index bac033dd..c0ebb163 100644 --- a/validate_test.go +++ b/validate_test.go @@ -10,10 +10,10 @@ import ( "testing" "time" + "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" - "github.com/conformal/btcnet" ) // TestCheckConnectBlock tests the CheckConnectBlock function to ensure it From 14056ad2cab5b34318e707fbdb1aa01f378c8b49 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 18:29:19 -0600 Subject: [PATCH 183/190] Update btcdb import paths to new location. --- chain.go | 2 +- common_test.go | 6 +++--- example_test.go | 4 ++-- txlookup.go | 2 +- validate.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/chain.go b/chain.go index 931ae995..e0333770 100644 --- a/chain.go +++ b/chain.go @@ -13,10 +13,10 @@ import ( "sync" "time" + "github.com/btcsuite/btcdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcdb" ) const ( diff --git a/common_test.go b/common_test.go index fca5b61e..0f261924 100644 --- a/common_test.go +++ b/common_test.go @@ -13,13 +13,13 @@ import ( "path/filepath" "strings" + "github.com/btcsuite/btcdb" + _ "github.com/btcsuite/btcdb/ldb" + _ "github.com/btcsuite/btcdb/memdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" "github.com/conformal/btcchain" - "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/ldb" - _ "github.com/conformal/btcdb/memdb" ) // testDbType is the database backend type to use for the tests. diff --git a/example_test.go b/example_test.go index 0a0d5610..91345971 100644 --- a/example_test.go +++ b/example_test.go @@ -8,11 +8,11 @@ import ( "fmt" "math/big" + "github.com/btcsuite/btcdb" + _ "github.com/btcsuite/btcdb/memdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/conformal/btcchain" - "github.com/conformal/btcdb" - _ "github.com/conformal/btcdb/memdb" ) // This example demonstrates how to create a new chain instance and use diff --git a/txlookup.go b/txlookup.go index 4dd78a6b..95484b6a 100644 --- a/txlookup.go +++ b/txlookup.go @@ -7,9 +7,9 @@ package btcchain import ( "fmt" + "github.com/btcsuite/btcdb" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcdb" ) // TxData contains contextual information about transactions such as which block diff --git a/validate.go b/validate.go index 17bc5939..d7052626 100644 --- a/validate.go +++ b/validate.go @@ -11,10 +11,10 @@ import ( "math/big" "time" + "github.com/btcsuite/btcdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcdb" "github.com/conformal/btcscript" ) From 3951e75a3fb7a60f0d3d52a0f7a6d3d7d93e4c28 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 18:40:47 -0600 Subject: [PATCH 184/190] Update btcchain import paths to new location. --- README.md | 14 +++++++------- chain_test.go | 2 +- common_test.go | 2 +- difficulty_test.go | 2 +- error_test.go | 2 +- example_test.go | 2 +- mediantime_test.go | 2 +- merkle_test.go | 2 +- reorganization_test.go | 2 +- scriptval_test.go | 2 +- timesorter_test.go | 2 +- validate_test.go | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 77c0d188..44f6db1d 100644 --- a/README.md +++ b/README.md @@ -23,20 +23,20 @@ handle processing of blocks into the bitcoin block chain. ## Documentation [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg] -(http://godoc.org/github.com/conformal/btcchain) +(http://godoc.org/github.com/btcsuite/btcchain) Full `go doc` style documentation for the project can be viewed online without installing this package by using the GoDoc site here: -http://godoc.org/github.com/conformal/btcchain +http://godoc.org/github.com/btcsuite/btcchain You can also view the documentation locally once the package is installed with the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to -http://localhost:6060/pkg/github.com/conformal/btcchain +http://localhost:6060/pkg/github.com/btcsuite/btcchain ## Installation ```bash -$ go get github.com/conformal/btcchain +$ go get github.com/btcsuite/btcchain ``` ## Bitcoin Chain Processing Overview @@ -77,20 +77,20 @@ is by no means exhaustive: ## Examples * [ProcessBlock Example] - (http://godoc.org/github.com/conformal/btcchain#example-BlockChain-ProcessBlock) + (http://godoc.org/github.com/btcsuite/btcchain#example-BlockChain-ProcessBlock) Demonstrates how to create a new chain instance and use ProcessBlock to attempt to attempt add a block to the chain. This example intentionally attempts to insert a duplicate genesis block to illustrate how an invalid block is handled. * [CompactToBig Example] - (http://godoc.org/github.com/conformal/btcchain#example-CompactToBig) + (http://godoc.org/github.com/btcsuite/btcchain#example-CompactToBig) Demonstrates how to convert the compact "bits" in a block header which represent the target difficulty to a big integer and display it using the typical hex notation. * [BigToCompact Example] - (http://godoc.org/github.com/conformal/btcchain#example-BigToCompact) + (http://godoc.org/github.com/btcsuite/btcchain#example-BigToCompact) Demonstrates how to convert how to convert a target difficulty into the compact "bits" in a block header which represent that target difficulty. diff --git a/chain_test.go b/chain_test.go index 6b7559c5..213979fb 100644 --- a/chain_test.go +++ b/chain_test.go @@ -7,10 +7,10 @@ package btcchain_test import ( "testing" + "github.com/btcsuite/btcchain" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcchain" ) // TestHaveBlock tests the HaveBlock API to ensure proper functionality. diff --git a/common_test.go b/common_test.go index 0f261924..64a14064 100644 --- a/common_test.go +++ b/common_test.go @@ -13,13 +13,13 @@ import ( "path/filepath" "strings" + "github.com/btcsuite/btcchain" "github.com/btcsuite/btcdb" _ "github.com/btcsuite/btcdb/ldb" _ "github.com/btcsuite/btcdb/memdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcchain" ) // testDbType is the database backend type to use for the tests. diff --git a/difficulty_test.go b/difficulty_test.go index 19aa278a..e3a84454 100644 --- a/difficulty_test.go +++ b/difficulty_test.go @@ -8,7 +8,7 @@ import ( "math/big" "testing" - "github.com/conformal/btcchain" + "github.com/btcsuite/btcchain" ) func TestBigToCompact(t *testing.T) { diff --git a/error_test.go b/error_test.go index 4f7b3398..1962629b 100644 --- a/error_test.go +++ b/error_test.go @@ -7,7 +7,7 @@ package btcchain_test import ( "testing" - "github.com/conformal/btcchain" + "github.com/btcsuite/btcchain" ) // TestErrorCodeStringer tests the stringized output for the ErrorCode type. diff --git a/example_test.go b/example_test.go index 91345971..f30f9e56 100644 --- a/example_test.go +++ b/example_test.go @@ -8,11 +8,11 @@ import ( "fmt" "math/big" + "github.com/btcsuite/btcchain" "github.com/btcsuite/btcdb" _ "github.com/btcsuite/btcdb/memdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" - "github.com/conformal/btcchain" ) // This example demonstrates how to create a new chain instance and use diff --git a/mediantime_test.go b/mediantime_test.go index 1b714007..69f543a0 100644 --- a/mediantime_test.go +++ b/mediantime_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/conformal/btcchain" + "github.com/btcsuite/btcchain" ) // TestMedianTime tests the medianTime implementation. diff --git a/merkle_test.go b/merkle_test.go index 2886dec1..f766270f 100644 --- a/merkle_test.go +++ b/merkle_test.go @@ -7,8 +7,8 @@ package btcchain_test import ( "testing" + "github.com/btcsuite/btcchain" "github.com/btcsuite/btcutil" - "github.com/conformal/btcchain" ) // TestMerkle tests the BuildMerkleTreeStore API. diff --git a/reorganization_test.go b/reorganization_test.go index 85346df5..e52be822 100644 --- a/reorganization_test.go +++ b/reorganization_test.go @@ -13,9 +13,9 @@ import ( "strings" "testing" + "github.com/btcsuite/btcchain" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcchain" ) // TestReorganization loads a set of test blocks which force a chain diff --git a/scriptval_test.go b/scriptval_test.go index 558d6194..5dacd826 100644 --- a/scriptval_test.go +++ b/scriptval_test.go @@ -9,7 +9,7 @@ import ( "runtime" "testing" - "github.com/conformal/btcchain" + "github.com/btcsuite/btcchain" ) // TestCheckBlockScripts ensures that validating the all of the scripts in a diff --git a/timesorter_test.go b/timesorter_test.go index db2f9e24..297fdb7c 100644 --- a/timesorter_test.go +++ b/timesorter_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/conformal/btcchain" + "github.com/btcsuite/btcchain" ) // TestTimeSorter tests the timeSorter implementation. diff --git a/validate_test.go b/validate_test.go index c0ebb163..c8fde7af 100644 --- a/validate_test.go +++ b/validate_test.go @@ -10,10 +10,10 @@ import ( "testing" "time" + "github.com/btcsuite/btcchain" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcchain" ) // TestCheckConnectBlock tests the CheckConnectBlock function to ensure it From e90d95358d3c9c091da1ccca2d3e54bdcbe38fd4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 19:35:05 -0600 Subject: [PATCH 185/190] Update btcscript import paths to new location. --- checkpoints.go | 2 +- scriptval.go | 2 +- validate.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/checkpoints.go b/checkpoints.go index 188b042f..2a1f44cd 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -8,9 +8,9 @@ import ( "fmt" "github.com/btcsuite/btcnet" + "github.com/btcsuite/btcscript" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcscript" ) // CheckpointConfirmations is the number of blocks before the end of the current diff --git a/scriptval.go b/scriptval.go index 33387929..20bef703 100644 --- a/scriptval.go +++ b/scriptval.go @@ -9,9 +9,9 @@ import ( "math" "runtime" + "github.com/btcsuite/btcscript" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcscript" ) // txValidateItem holds a transaction along with which input to validate. diff --git a/validate.go b/validate.go index d7052626..a64b950c 100644 --- a/validate.go +++ b/validate.go @@ -13,9 +13,9 @@ import ( "github.com/btcsuite/btcdb" "github.com/btcsuite/btcnet" + "github.com/btcsuite/btcscript" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" - "github.com/conformal/btcscript" ) const ( From 31fe0eac0833187e6d84161d096a4cbd6caa1961 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 23:20:12 -0600 Subject: [PATCH 186/190] Update to new location in README.md too. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 44f6db1d..5a0cfd97 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ btcchain ======== -[![Build Status](http://img.shields.io/travis/conformal/btcchain.svg)] -(https://travis-ci.org/conformal/btcchain) [![ISC License] +[![Build Status](http://img.shields.io/travis/btcsuite/btcchain.svg)] +(https://travis-ci.org/btcsuite/btcchain) [![ISC License] (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) Package btcchain implements bitcoin block handling and chain selection rules. From 0565be965aaf577934eafc85f03cf1ef95bda6a3 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 16 Jan 2015 23:29:54 -0600 Subject: [PATCH 187/190] Correct godoc badge in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a0cfd97..93164da5 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ handle processing of blocks into the bitcoin block chain. ## Documentation -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg] +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] (http://godoc.org/github.com/btcsuite/btcchain) Full `go doc` style documentation for the project can be viewed online without From dd512e7315f5e2ecdd65bd338dc645a6bca86a36 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 27 Jan 2015 15:00:49 -0600 Subject: [PATCH 188/190] Update database import paths to new location. --- chain.go | 6 +++--- common_test.go | 14 +++++++------- example_test.go | 6 +++--- txlookup.go | 10 +++++----- validate.go | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/chain.go b/chain.go index e0333770..c356ee3e 100644 --- a/chain.go +++ b/chain.go @@ -13,7 +13,7 @@ import ( "sync" "time" - "github.com/btcsuite/btcdb" + "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" @@ -142,7 +142,7 @@ func removeChildNode(children []*blockNode, node *blockNode) []*blockNode { // follow all rules, orphan handling, checkpoint handling, and best chain // selection with reorganization. type BlockChain struct { - db btcdb.Db + db database.Db netParams *btcnet.Params checkpointsByHeight map[int64]*btcnet.Checkpoint notifications NotificationCallback @@ -1069,7 +1069,7 @@ func (b *BlockChain) IsCurrent(timeSource MedianTimeSource) bool { // Notification and NotificationType for details on the types and contents of // notifications. The provided callback can be nil if the caller is not // interested in receiving notifications. -func New(db btcdb.Db, params *btcnet.Params, c NotificationCallback) *BlockChain { +func New(db database.Db, params *btcnet.Params, c NotificationCallback) *BlockChain { // Generate a checkpoint by height map from the provided checkpoints. var checkpointsByHeight map[int64]*btcnet.Checkpoint if len(params.Checkpoints) > 0 { diff --git a/common_test.go b/common_test.go index 64a14064..7b6c692f 100644 --- a/common_test.go +++ b/common_test.go @@ -14,9 +14,9 @@ import ( "strings" "github.com/btcsuite/btcchain" - "github.com/btcsuite/btcdb" - _ "github.com/btcsuite/btcdb/ldb" - _ "github.com/btcsuite/btcdb/memdb" + "github.com/btcsuite/btcd/database" + _ "github.com/btcsuite/btcd/database/ldb" + _ "github.com/btcsuite/btcd/database/memdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" @@ -41,7 +41,7 @@ func fileExists(name string) bool { // isSupportedDbType returns whether or not the passed database type is // currently supported. func isSupportedDbType(dbType string) bool { - supportedDBs := btcdb.SupportedDBs() + supportedDBs := database.SupportedDBs() for _, sDbType := range supportedDBs { if dbType == sDbType { return true @@ -61,10 +61,10 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { // Handle memory database specially since it doesn't need the disk // specific handling. - var db btcdb.Db + var db database.Db var teardown func() if testDbType == "memdb" { - ndb, err := btcdb.CreateDB(testDbType) + ndb, err := database.CreateDB(testDbType) if err != nil { return nil, nil, fmt.Errorf("error creating db: %v", err) } @@ -88,7 +88,7 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { // Create a new database to store the accepted blocks into. dbPath := filepath.Join(testDbRoot, dbName) _ = os.RemoveAll(dbPath) - ndb, err := btcdb.CreateDB(testDbType, dbPath) + ndb, err := database.CreateDB(testDbType, dbPath) if err != nil { return nil, nil, fmt.Errorf("error creating db: %v", err) } diff --git a/example_test.go b/example_test.go index f30f9e56..4bbb1248 100644 --- a/example_test.go +++ b/example_test.go @@ -9,8 +9,8 @@ import ( "math/big" "github.com/btcsuite/btcchain" - "github.com/btcsuite/btcdb" - _ "github.com/btcsuite/btcdb/memdb" + "github.com/btcsuite/btcd/database" + _ "github.com/btcsuite/btcd/database/memdb" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" ) @@ -25,7 +25,7 @@ func ExampleBlockChain_ProcessBlock() { // this would be opening an existing database and would not use memdb // which is a memory-only database backend, but we create a new db // here so this is a complete working example. - db, err := btcdb.CreateDB("memdb") + db, err := database.CreateDB("memdb") if err != nil { fmt.Printf("Failed to create database: %v\n", err) return diff --git a/txlookup.go b/txlookup.go index 95484b6a..6925ef75 100644 --- a/txlookup.go +++ b/txlookup.go @@ -7,7 +7,7 @@ package btcchain import ( "fmt" - "github.com/btcsuite/btcdb" + "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" ) @@ -77,7 +77,7 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { txD.Tx = nil txD.BlockHeight = 0 txD.Spent = nil - txD.Err = btcdb.ErrTxShaMissing + txD.Err = database.ErrTxShaMissing } // Unspend the origin transaction output. @@ -101,7 +101,7 @@ func disconnectTransactions(txStore TxStore, block *btcutil.Block) error { // transactions from the point of view of the end of the main chain. It takes // a flag which specifies whether or not fully spent transaction should be // included in the results. -func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]struct{}, includeSpent bool) TxStore { +func fetchTxStoreMain(db database.Db, txSet map[btcwire.ShaHash]struct{}, includeSpent bool) TxStore { // Just return an empty store now if there are no requested hashes. txStore := make(TxStore) if len(txSet) == 0 { @@ -114,7 +114,7 @@ func fetchTxStoreMain(db btcdb.Db, txSet map[btcwire.ShaHash]struct{}, includeSp txList := make([]*btcwire.ShaHash, 0, len(txSet)) for hash := range txSet { hashCopy := hash - txStore[hash] = &TxData{Hash: &hashCopy, Err: btcdb.ErrTxShaMissing} + txStore[hash] = &TxData{Hash: &hashCopy, Err: database.ErrTxShaMissing} txList = append(txList, &hashCopy) } @@ -253,7 +253,7 @@ func (b *BlockChain) fetchInputTransactions(node *blockNode, block *btcutil.Bloc // Add an entry to the transaction store for the needed // transaction with it set to missing by default. originHash := &txIn.PreviousOutPoint.Hash - txD := &TxData{Hash: originHash, Err: btcdb.ErrTxShaMissing} + txD := &TxData{Hash: originHash, Err: database.ErrTxShaMissing} txStore[*originHash] = txD // It is acceptable for a transaction input to reference diff --git a/validate.go b/validate.go index a64b950c..f878d953 100644 --- a/validate.go +++ b/validate.go @@ -11,7 +11,7 @@ import ( "math/big" "time" - "github.com/btcsuite/btcdb" + "github.com/btcsuite/btcd/database" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcscript" "github.com/btcsuite/btcutil" @@ -627,7 +627,7 @@ func (b *BlockChain) checkBIP0030(node *blockNode, block *btcutil.Block) error { switch txD.Err { // A duplicate transaction was not found. This is the most // common case. - case btcdb.ErrTxShaMissing: + case database.ErrTxShaMissing: continue // A duplicate transaction was found. This is only allowed if From 3f177c98955746df6b8f80dd1ed3592116f28a91 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 30 Jan 2015 12:08:47 -0600 Subject: [PATCH 189/190] Update btcscript import paths to new location. --- checkpoints.go | 6 +++--- scriptval.go | 16 ++++++++-------- validate.go | 20 ++++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/checkpoints.go b/checkpoints.go index 2a1f44cd..394b3fa6 100644 --- a/checkpoints.go +++ b/checkpoints.go @@ -7,8 +7,8 @@ package btcchain import ( "fmt" + "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcnet" - "github.com/btcsuite/btcscript" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" ) @@ -192,8 +192,8 @@ func isNonstandardTransaction(tx *btcutil.Tx) bool { // Check all of the output public key scripts for non-standard scripts. for _, txOut := range tx.MsgTx().TxOut { - scriptClass := btcscript.GetScriptClass(txOut.PkScript) - if scriptClass == btcscript.NonStandardTy { + scriptClass := txscript.GetScriptClass(txOut.PkScript) + if scriptClass == txscript.NonStandardTy { return true } } diff --git a/scriptval.go b/scriptval.go index 20bef703..22d0ea20 100644 --- a/scriptval.go +++ b/scriptval.go @@ -9,7 +9,7 @@ import ( "math" "runtime" - "github.com/btcsuite/btcscript" + "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" ) @@ -29,7 +29,7 @@ type txValidator struct { quitChan chan struct{} resultChan chan error txStore TxStore - flags btcscript.ScriptFlags + flags txscript.ScriptFlags } // sendResult sends the result of a script pair validation on the internal @@ -83,7 +83,7 @@ out: // Create a new script engine for the script pair. sigScript := txIn.SignatureScript pkScript := originMsgTx.TxOut[originTxIndex].PkScript - engine, err := btcscript.NewScript(sigScript, pkScript, + engine, err := txscript.NewScript(sigScript, pkScript, txVI.txInIndex, txVI.tx.MsgTx(), v.flags) if err != nil { str := fmt.Sprintf("failed to parse input "+ @@ -179,7 +179,7 @@ func (v *txValidator) Validate(items []*txValidateItem) error { // newTxValidator returns a new instance of txValidator to be used for // validating transaction scripts asynchronously. -func newTxValidator(txStore TxStore, flags btcscript.ScriptFlags) *txValidator { +func newTxValidator(txStore TxStore, flags txscript.ScriptFlags) *txValidator { return &txValidator{ validateChan: make(chan *txValidateItem), quitChan: make(chan struct{}), @@ -191,7 +191,7 @@ func newTxValidator(txStore TxStore, flags btcscript.ScriptFlags) *txValidator { // ValidateTransactionScripts validates the scripts for the passed transaction // using multiple goroutines. -func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript.ScriptFlags) error { +func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags txscript.ScriptFlags) error { // Collect all of the transaction inputs and required information for // validation. txIns := tx.MsgTx().TxIn @@ -224,9 +224,9 @@ func ValidateTransactionScripts(tx *btcutil.Tx, txStore TxStore, flags btcscript func checkBlockScripts(block *btcutil.Block, txStore TxStore) error { // Setup the script validation flags. Blocks created after the BIP0016 // activation time need to have the pay-to-script-hash checks enabled. - var flags btcscript.ScriptFlags - if block.MsgBlock().Header.Timestamp.After(btcscript.Bip16Activation) { - flags |= btcscript.ScriptBip16 + var flags txscript.ScriptFlags + if block.MsgBlock().Header.Timestamp.After(txscript.Bip16Activation) { + flags |= txscript.ScriptBip16 } // Collect all of the transaction inputs and required information for diff --git a/validate.go b/validate.go index f878d953..488d4b8b 100644 --- a/validate.go +++ b/validate.go @@ -12,8 +12,8 @@ import ( "time" "github.com/btcsuite/btcd/database" + "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcnet" - "github.com/btcsuite/btcscript" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" ) @@ -331,7 +331,7 @@ func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error { // CountSigOps returns the number of signature operations for all transaction // input and output scripts in the provided transaction. This uses the // quicker, but imprecise, signature operation counting mechanism from -// btcscript. +// txscript. func CountSigOps(tx *btcutil.Tx) int { msgTx := tx.MsgTx() @@ -339,14 +339,14 @@ func CountSigOps(tx *btcutil.Tx) int { // inputs. totalSigOps := 0 for _, txIn := range msgTx.TxIn { - numSigOps := btcscript.GetSigOpCount(txIn.SignatureScript) + numSigOps := txscript.GetSigOpCount(txIn.SignatureScript) totalSigOps += numSigOps } // Accumulate the number of signature operations in all transaction // outputs. for _, txOut := range msgTx.TxOut { - numSigOps := btcscript.GetSigOpCount(txOut.PkScript) + numSigOps := txscript.GetSigOpCount(txOut.PkScript) totalSigOps += numSigOps } @@ -355,8 +355,8 @@ func CountSigOps(tx *btcutil.Tx) int { // CountP2SHSigOps returns the number of signature operations for all input // transactions which are of the pay-to-script-hash type. This uses the -// precise, signature operation counting mechanism from btcscript which requires -// access to the input transaction scripts. +// precise, signature operation counting mechanism from the script engine which +// requires access to the input transaction scripts. func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, error) { // Coinbase transactions have no interesting inputs. if isCoinBaseTx { @@ -392,14 +392,14 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e // We're only interested in pay-to-script-hash types, so skip // this input if it's not one. pkScript := originMsgTx.TxOut[originTxIndex].PkScript - if !btcscript.IsPayToScriptHash(pkScript) { + if !txscript.IsPayToScriptHash(pkScript) { continue } // Count the precise number of signature operations in the // referenced public key script. sigScript := txIn.SignatureScript - numSigOps := btcscript.GetPreciseSigOpCount(sigScript, pkScript, + numSigOps := txscript.GetPreciseSigOpCount(sigScript, pkScript, true) // We could potentially overflow the accumulator so check for @@ -817,10 +817,10 @@ func (b *BlockChain) checkConnectBlock(node *blockNode, block *btcutil.Block) er // BIP0016 describes a pay-to-script-hash type that is considered a // "standard" type. The rules for this BIP only apply to transactions - // after the timestamp defined by btcscript.Bip16Activation. See + // after the timestamp defined by txscript.Bip16Activation. See // https://en.bitcoin.it/wiki/BIP_0016 for more details. enforceBIP0016 := false - if node.timestamp.After(btcscript.Bip16Activation) { + if node.timestamp.After(txscript.Bip16Activation) { enforceBIP0016 = true } From b69a849114ea871b49a27bda2ebad36d460f8137 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Fri, 30 Jan 2015 14:54:30 -0600 Subject: [PATCH 190/190] Import btcchain repo into blockchain directory. This commit contains the entire btcchain repository along with several changes needed to move all of the files into the blockchain directory in order to prepare it for merging. This does NOT update btcd or any of the other packages to use the new location as that will be done separately. - All import paths in the old btcchain test files have been changed to the new location - All references to btcchain as the package name have been changed to blockchain --- .gitignore | 28 ----- .travis.yml | 17 --- LICENSE | 13 --- README.md => blockchain/README.md | 40 +++----- accept.go => blockchain/accept.go | 2 +- blocklocator.go => blockchain/blocklocator.go | 2 +- chain.go => blockchain/chain.go | 2 +- chain_test.go => blockchain/chain_test.go | 12 +-- checkpoints.go => blockchain/checkpoints.go | 2 +- common_test.go => blockchain/common_test.go | 14 +-- difficulty.go => blockchain/difficulty.go | 2 +- .../difficulty_test.go | 10 +- doc.go => blockchain/doc.go | 8 +- error.go => blockchain/error.go | 2 +- blockchain/error_test.go | 97 ++++++++++++++++++ example_test.go => blockchain/example_test.go | 14 +-- .../internal_test.go | 11 +- log.go => blockchain/log.go | 2 +- mediantime.go => blockchain/mediantime.go | 2 +- .../mediantime_test.go | 10 +- merkle.go => blockchain/merkle.go | 2 +- merkle_test.go => blockchain/merkle_test.go | 6 +- .../notifications.go | 2 +- process.go => blockchain/process.go | 2 +- .../reorganization_test.go | 10 +- scriptval.go => blockchain/scriptval.go | 2 +- .../scriptval_test.go | 6 +- .../testdata}/277647.dat.bz2 | Bin .../testdata}/277647.txstore.bz2 | Bin .../testdata}/blk_0_to_4.dat.bz2 | Bin .../testdata}/blk_3A.dat.bz2 | Bin .../testdata}/blk_4A.dat.bz2 | Bin .../testdata}/blk_5A.dat.bz2 | Bin .../testdata}/reorgtest.hex | 0 timesorter.go => blockchain/timesorter.go | 2 +- .../timesorter_test.go | 6 +- txlookup.go => blockchain/txlookup.go | 2 +- validate.go => blockchain/validate.go | 2 +- .../validate_test.go | 24 ++--- cov_report.sh | 17 --- error_test.go | 97 ------------------ goclean.sh | 38 ------- test_coverage.txt | 97 ------------------ 43 files changed, 195 insertions(+), 410 deletions(-) delete mode 100644 .gitignore delete mode 100644 .travis.yml delete mode 100644 LICENSE rename README.md => blockchain/README.md (77%) rename accept.go => blockchain/accept.go (99%) rename blocklocator.go => blockchain/blocklocator.go (99%) rename chain.go => blockchain/chain.go (99%) rename chain_test.go => blockchain/chain_test.go (93%) rename checkpoints.go => blockchain/checkpoints.go (99%) rename common_test.go => blockchain/common_test.go (94%) rename difficulty.go => blockchain/difficulty.go (99%) rename difficulty_test.go => blockchain/difficulty_test.go (86%) rename doc.go => blockchain/doc.go (94%) rename error.go => blockchain/error.go (99%) create mode 100644 blockchain/error_test.go rename example_test.go => blockchain/example_test.go (92%) rename internal_test.go => blockchain/internal_test.go (76%) rename log.go => blockchain/log.go (98%) rename mediantime.go => blockchain/mediantime.go (99%) rename mediantime_test.go => blockchain/mediantime_test.go (95%) rename merkle.go => blockchain/merkle.go (99%) rename merkle_test.go => blockchain/merkle_test.go (82%) rename notifications.go => blockchain/notifications.go (99%) rename process.go => blockchain/process.go (99%) rename reorganization_test.go => blockchain/reorganization_test.go (93%) rename scriptval.go => blockchain/scriptval.go (99%) rename scriptval_test.go => blockchain/scriptval_test.go (87%) rename {testdata => blockchain/testdata}/277647.dat.bz2 (100%) rename {testdata => blockchain/testdata}/277647.txstore.bz2 (100%) rename {testdata => blockchain/testdata}/blk_0_to_4.dat.bz2 (100%) rename {testdata => blockchain/testdata}/blk_3A.dat.bz2 (100%) rename {testdata => blockchain/testdata}/blk_4A.dat.bz2 (100%) rename {testdata => blockchain/testdata}/blk_5A.dat.bz2 (100%) rename {testdata => blockchain/testdata}/reorgtest.hex (100%) rename timesorter.go => blockchain/timesorter.go (97%) rename timesorter_test.go => blockchain/timesorter_test.go (93%) rename txlookup.go => blockchain/txlookup.go (99%) rename validate.go => blockchain/validate.go (99%) rename validate_test.go => blockchain/validate_test.go (95%) delete mode 100644 cov_report.sh delete mode 100644 error_test.go delete mode 100755 goclean.sh delete mode 100644 test_coverage.txt diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 5b97dbba..00000000 --- a/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# Temp files -*~ - -# Log files -*.log - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1284c11b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: go -go: - - release - - tip -sudo: false -before_install: - - gotools=golang.org/x/tools - - if [ "$TRAVIS_GO_VERSION" = "release" ]; then gotools=code.google.com/p/go.tools; fi -install: - - go get -d -t -v ./... - - go get -v $gotools/cmd/cover - - go get -v $gotools/cmd/vet - - go get -v github.com/bradfitz/goimports - - go get -v github.com/golang/lint/golint -script: - - export PATH=$PATH:$HOME/gopath/bin - - ./goclean.sh diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 992dd50d..00000000 --- a/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2013-2014 Conformal Systems LLC. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/README.md b/blockchain/README.md similarity index 77% rename from README.md rename to blockchain/README.md index 93164da5..e151756a 100644 --- a/README.md +++ b/blockchain/README.md @@ -1,42 +1,40 @@ -btcchain -======== +blockchain +========== -[![Build Status](http://img.shields.io/travis/btcsuite/btcchain.svg)] -(https://travis-ci.org/btcsuite/btcchain) [![ISC License] +[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)] +(https://travis-ci.org/btcsuite/btcd) [![ISC License] (http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) -Package btcchain implements bitcoin block handling and chain selection rules. +Package blockchain implements bitcoin block handling and chain selection rules. The test coverage is currently only around 60%, but will be increasing over time. See `test_coverage.txt` for the gocov coverage report. Alternatively, if you are running a POSIX OS, you can run the `cov_report.sh` script for a -real-time report. Package btcchain is licensed under the liberal ISC license. +real-time report. Package blockchain is licensed under the liberal ISC license. There is an associated blog post about the release of this package [here](https://blog.conformal.com/btcchain-the-bitcoin-chain-package-from-bctd/). -This package is one of the core packages from btcd, an alternative full-node -implementation of bitcoin which is under active development by Conformal. -Although it was primarily written for btcd, this package has intentionally been -designed so it can be used as a standalone package for any projects needing to -handle processing of blocks into the bitcoin block chain. +This package has intentionally been designed so it can be used as a standalone +package for any projects needing to handle processing of blocks into the bitcoin +block chain. ## Documentation [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] -(http://godoc.org/github.com/btcsuite/btcchain) +(http://godoc.org/github.com/btcsuite/btcd/blockchain) Full `go doc` style documentation for the project can be viewed online without installing this package by using the GoDoc site here: -http://godoc.org/github.com/btcsuite/btcchain +http://godoc.org/github.com/btcsuite/btcd/blockchain You can also view the documentation locally once the package is installed with the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to -http://localhost:6060/pkg/github.com/btcsuite/btcchain +http://localhost:6060/pkg/github.com/btcsuite/btcd/blockchain ## Installation ```bash -$ go get github.com/btcsuite/btcchain +$ go get github.com/btcsuite/btcd/blockchain ``` ## Bitcoin Chain Processing Overview @@ -77,27 +75,23 @@ is by no means exhaustive: ## Examples * [ProcessBlock Example] - (http://godoc.org/github.com/btcsuite/btcchain#example-BlockChain-ProcessBlock) + (http://godoc.org/github.com/btcsuite/btcd/blockchain#example-BlockChain-ProcessBlock) Demonstrates how to create a new chain instance and use ProcessBlock to attempt to attempt add a block to the chain. This example intentionally attempts to insert a duplicate genesis block to illustrate how an invalid block is handled. * [CompactToBig Example] - (http://godoc.org/github.com/btcsuite/btcchain#example-CompactToBig) + (http://godoc.org/github.com/btcsuite/btcd/blockchain#example-CompactToBig) Demonstrates how to convert the compact "bits" in a block header which represent the target difficulty to a big integer and display it using the typical hex notation. * [BigToCompact Example] - (http://godoc.org/github.com/btcsuite/btcchain#example-BigToCompact) + (http://godoc.org/github.com/btcsuite/btcd/blockchain#example-BigToCompact) Demonstrates how to convert how to convert a target difficulty into the compact "bits" in a block header which represent that target difficulty. -## TODO - -- Increase test coverage - ## GPG Verification Key All official release tags are signed by Conformal so users can ensure the code @@ -121,5 +115,5 @@ signature perform the following: ## License -Package btcchain is licensed under the [copyfree](http://copyfree.org) ISC +Package blockchain is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/accept.go b/blockchain/accept.go similarity index 99% rename from accept.go rename to blockchain/accept.go index c4104c55..64cb6d26 100644 --- a/accept.go +++ b/blockchain/accept.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/blocklocator.go b/blockchain/blocklocator.go similarity index 99% rename from blocklocator.go rename to blockchain/blocklocator.go index 544cf72f..a88ccea1 100644 --- a/blocklocator.go +++ b/blockchain/blocklocator.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "github.com/btcsuite/btcwire" diff --git a/chain.go b/blockchain/chain.go similarity index 99% rename from chain.go rename to blockchain/chain.go index c356ee3e..89f9fe58 100644 --- a/chain.go +++ b/blockchain/chain.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "container/list" diff --git a/chain_test.go b/blockchain/chain_test.go similarity index 93% rename from chain_test.go rename to blockchain/chain_test.go index 213979fb..e4349821 100644 --- a/chain_test.go +++ b/blockchain/chain_test.go @@ -2,12 +2,12 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "testing" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" @@ -46,12 +46,12 @@ func TestHaveBlock(t *testing.T) { // Since we're not dealing with the real block chain, disable // checkpoints and set the coinbase maturity to 1. chain.DisableCheckpoints(true) - btcchain.TstSetCoinbaseMaturity(1) + blockchain.TstSetCoinbaseMaturity(1) - timeSource := btcchain.NewMedianTime() + timeSource := blockchain.NewMedianTime() for i := 1; i < len(blocks); i++ { isOrphan, err := chain.ProcessBlock(blocks[i], timeSource, - btcchain.BFNone) + blockchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return @@ -65,7 +65,7 @@ func TestHaveBlock(t *testing.T) { // Insert an orphan block. isOrphan, err := chain.ProcessBlock(btcutil.NewBlock(&Block100000), - timeSource, btcchain.BFNone) + timeSource, blockchain.BFNone) if err != nil { t.Errorf("Unable to process block: %v", err) return diff --git a/checkpoints.go b/blockchain/checkpoints.go similarity index 99% rename from checkpoints.go rename to blockchain/checkpoints.go index 394b3fa6..03d7bfd7 100644 --- a/checkpoints.go +++ b/blockchain/checkpoints.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/common_test.go b/blockchain/common_test.go similarity index 94% rename from common_test.go rename to blockchain/common_test.go index 7b6c692f..651aaff6 100644 --- a/common_test.go +++ b/blockchain/common_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "compress/bzip2" @@ -13,7 +13,7 @@ import ( "path/filepath" "strings" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/database" _ "github.com/btcsuite/btcd/database/ldb" _ "github.com/btcsuite/btcd/database/memdb" @@ -54,7 +54,7 @@ func isSupportedDbType(dbType string) bool { // chainSetup is used to create a new db and chain instance with the genesis // block already inserted. In addition to the new chain instnce, it returns // a teardown function the caller should invoke when done testing to clean up. -func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { +func chainSetup(dbName string) (*blockchain.BlockChain, func(), error) { if !isSupportedDbType(testDbType) { return nil, nil, fmt.Errorf("unsupported db type %v", testDbType) } @@ -116,12 +116,12 @@ func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) { return nil, nil, err } - chain := btcchain.New(db, &btcnet.MainNetParams, nil) + chain := blockchain.New(db, &btcnet.MainNetParams, nil) return chain, teardown, nil } // loadTxStore returns a transaction store loaded from a file. -func loadTxStore(filename string) (btcchain.TxStore, error) { +func loadTxStore(filename string) (blockchain.TxStore, error) { // The txstore file format is: // // @@ -150,10 +150,10 @@ func loadTxStore(filename string) (btcchain.TxStore, error) { return nil, err } - txStore := make(btcchain.TxStore) + txStore := make(blockchain.TxStore) var uintBuf uint32 for height := uint32(0); height < numItems; height++ { - txD := btcchain.TxData{} + txD := blockchain.TxData{} // Serialized transaction length. err = binary.Read(r, binary.LittleEndian, &uintBuf) diff --git a/difficulty.go b/blockchain/difficulty.go similarity index 99% rename from difficulty.go rename to blockchain/difficulty.go index 11bb36ba..0d94eea7 100644 --- a/difficulty.go +++ b/blockchain/difficulty.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/difficulty_test.go b/blockchain/difficulty_test.go similarity index 86% rename from difficulty_test.go rename to blockchain/difficulty_test.go index e3a84454..083d1d31 100644 --- a/difficulty_test.go +++ b/blockchain/difficulty_test.go @@ -2,13 +2,13 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "math/big" "testing" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" ) func TestBigToCompact(t *testing.T) { @@ -22,7 +22,7 @@ func TestBigToCompact(t *testing.T) { for x, test := range tests { n := big.NewInt(test.in) - r := btcchain.BigToCompact(n) + r := blockchain.BigToCompact(n) if r != test.out { t.Errorf("TestBigToCompact test #%d failed: got %d want %d\n", x, r, test.out) @@ -40,7 +40,7 @@ func TestCompactToBig(t *testing.T) { } for x, test := range tests { - n := btcchain.CompactToBig(test.in) + n := blockchain.CompactToBig(test.in) want := big.NewInt(test.out) if n.Cmp(want) != 0 { t.Errorf("TestCompactToBig test #%d failed: got %d want %d\n", @@ -61,7 +61,7 @@ func TestCalcWork(t *testing.T) { for x, test := range tests { bits := uint32(test.in) - r := btcchain.CalcWork(bits) + r := blockchain.CalcWork(bits) if r.Int64() != test.out { t.Errorf("TestCalcWork test #%d failed: got %v want %d\n", x, r.Int64(), test.out) diff --git a/doc.go b/blockchain/doc.go similarity index 94% rename from doc.go rename to blockchain/doc.go index 75a29f8f..69953ad5 100644 --- a/doc.go +++ b/blockchain/doc.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. /* -Package btcchain implements bitcoin block handling and chain selection rules. +Package blockchain implements bitcoin block handling and chain selection rules. The bitcoin block handling and chain selection rules are an integral, and quite likely the most important, part of bitcoin. Unfortunately, at the time of @@ -64,11 +64,11 @@ is by no means exhaustive: Errors Errors returned by this package are either the raw errors provided by underlying -calls or of type btcchain.RuleError. This allows the caller to differentiate +calls or of type blockchain.RuleError. This allows the caller to differentiate between unexpected errors, such as database errors, versus errors due to rule violations through type assertions. In addition, callers can programmatically determine the specific rule violation by examining the ErrorCode field of the -type asserted btcchain.RuleError. +type asserted blockchain.RuleError. Bitcoin Improvement Proposals @@ -78,4 +78,4 @@ This package includes spec changes outlined by the following BIPs: BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) BIP0034 (https://en.bitcoin.it/wiki/BIP_0034) */ -package btcchain +package blockchain diff --git a/error.go b/blockchain/error.go similarity index 99% rename from error.go rename to blockchain/error.go index 31853c59..f96956aa 100644 --- a/error.go +++ b/blockchain/error.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/blockchain/error_test.go b/blockchain/error_test.go new file mode 100644 index 00000000..aeb3d76a --- /dev/null +++ b/blockchain/error_test.go @@ -0,0 +1,97 @@ +// Copyright (c) 2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package blockchain_test + +import ( + "testing" + + "github.com/btcsuite/btcd/blockchain" +) + +// TestErrorCodeStringer tests the stringized output for the ErrorCode type. +func TestErrorCodeStringer(t *testing.T) { + tests := []struct { + in blockchain.ErrorCode + want string + }{ + {blockchain.ErrDuplicateBlock, "ErrDuplicateBlock"}, + {blockchain.ErrBlockTooBig, "ErrBlockTooBig"}, + {blockchain.ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, + {blockchain.ErrInvalidTime, "ErrInvalidTime"}, + {blockchain.ErrTimeTooOld, "ErrTimeTooOld"}, + {blockchain.ErrTimeTooNew, "ErrTimeTooNew"}, + {blockchain.ErrDifficultyTooLow, "ErrDifficultyTooLow"}, + {blockchain.ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, + {blockchain.ErrHighHash, "ErrHighHash"}, + {blockchain.ErrBadMerkleRoot, "ErrBadMerkleRoot"}, + {blockchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, + {blockchain.ErrForkTooOld, "ErrForkTooOld"}, + {blockchain.ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, + {blockchain.ErrNoTransactions, "ErrNoTransactions"}, + {blockchain.ErrTooManyTransactions, "ErrTooManyTransactions"}, + {blockchain.ErrNoTxInputs, "ErrNoTxInputs"}, + {blockchain.ErrNoTxOutputs, "ErrNoTxOutputs"}, + {blockchain.ErrTxTooBig, "ErrTxTooBig"}, + {blockchain.ErrBadTxOutValue, "ErrBadTxOutValue"}, + {blockchain.ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, + {blockchain.ErrBadTxInput, "ErrBadTxInput"}, + {blockchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, + {blockchain.ErrMissingTx, "ErrMissingTx"}, + {blockchain.ErrUnfinalizedTx, "ErrUnfinalizedTx"}, + {blockchain.ErrDuplicateTx, "ErrDuplicateTx"}, + {blockchain.ErrOverwriteTx, "ErrOverwriteTx"}, + {blockchain.ErrImmatureSpend, "ErrImmatureSpend"}, + {blockchain.ErrDoubleSpend, "ErrDoubleSpend"}, + {blockchain.ErrSpendTooHigh, "ErrSpendTooHigh"}, + {blockchain.ErrBadFees, "ErrBadFees"}, + {blockchain.ErrTooManySigOps, "ErrTooManySigOps"}, + {blockchain.ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, + {blockchain.ErrMultipleCoinbases, "ErrMultipleCoinbases"}, + {blockchain.ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, + {blockchain.ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, + {blockchain.ErrMissingCoinbaseHeight, "ErrMissingCoinbaseHeight"}, + {blockchain.ErrBadCoinbaseHeight, "ErrBadCoinbaseHeight"}, + {blockchain.ErrScriptMalformed, "ErrScriptMalformed"}, + {blockchain.ErrScriptValidation, "ErrScriptValidation"}, + {0xffff, "Unknown ErrorCode (65535)"}, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + result := test.in.String() + if result != test.want { + t.Errorf("String #%d\n got: %s want: %s", i, result, + test.want) + continue + } + } +} + +// TestRuleError tests the error output for the RuleError type. +func TestRuleError(t *testing.T) { + tests := []struct { + in blockchain.RuleError + want string + }{ + { + blockchain.RuleError{Description: "duplicate block"}, + "duplicate block", + }, + { + blockchain.RuleError{Description: "human-readable error"}, + "human-readable error", + }, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + result := test.in.Error() + if result != test.want { + t.Errorf("Error #%d\n got: %s want: %s", i, result, + test.want) + continue + } + } +} diff --git a/example_test.go b/blockchain/example_test.go similarity index 92% rename from example_test.go rename to blockchain/example_test.go index 4bbb1248..229b55f1 100644 --- a/example_test.go +++ b/blockchain/example_test.go @@ -2,13 +2,13 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "fmt" "math/big" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/database" _ "github.com/btcsuite/btcd/database/memdb" "github.com/btcsuite/btcnet" @@ -44,18 +44,18 @@ func ExampleBlockChain_ProcessBlock() { // Create a new BlockChain instance using the underlying database for // the main bitcoin network and ignore notifications. - chain := btcchain.New(db, &btcnet.MainNetParams, nil) + chain := blockchain.New(db, &btcnet.MainNetParams, nil) // Create a new median time source that is required by the upcoming // call to ProcessBlock. Ordinarily this would also add time values // obtained from other peers on the network so the local time is // adjusted to be in agreement with other peers. - timeSource := btcchain.NewMedianTime() + timeSource := blockchain.NewMedianTime() // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. - isOrphan, err := chain.ProcessBlock(genesisBlock, timeSource, btcchain.BFNone) + isOrphan, err := chain.ProcessBlock(genesisBlock, timeSource, blockchain.BFNone) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return @@ -72,7 +72,7 @@ func ExampleBlockChain_ProcessBlock() { func ExampleCompactToBig() { // Convert the bits from block 300000 in the main block chain. bits := uint32(419465580) - targetDifficulty := btcchain.CompactToBig(bits) + targetDifficulty := blockchain.CompactToBig(bits) // Display it in hex. fmt.Printf("%064x\n", targetDifficulty.Bytes()) @@ -92,7 +92,7 @@ func ExampleBigToCompact() { fmt.Println("invalid target difficulty") return } - bits := btcchain.BigToCompact(targetDifficulty) + bits := blockchain.BigToCompact(targetDifficulty) fmt.Println(bits) diff --git a/internal_test.go b/blockchain/internal_test.go similarity index 76% rename from internal_test.go rename to blockchain/internal_test.go index 6914fff5..563c7de1 100644 --- a/internal_test.go +++ b/blockchain/internal_test.go @@ -3,13 +3,14 @@ // license that can be found in the LICENSE file. /* -This test file is part of the btcchain package rather than than the -btcchain_test package so it can bridge access to the internals to properly test -cases which are either not possible or can't reliably be tested via the public -interface. The functions are only exported while the tests are being run. +This test file is part of the blockchain package rather than than the +blockchain_test package so it can bridge access to the internals to properly +test cases which are either not possible or can't reliably be tested via the +public interface. The functions are only exported while the tests are being +run. */ -package btcchain +package blockchain import ( "sort" diff --git a/log.go b/blockchain/log.go similarity index 98% rename from log.go rename to blockchain/log.go index 7a79f9e0..bd3b6215 100644 --- a/log.go +++ b/blockchain/log.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "errors" diff --git a/mediantime.go b/blockchain/mediantime.go similarity index 99% rename from mediantime.go rename to blockchain/mediantime.go index 8aa1c28c..f44d8257 100644 --- a/mediantime.go +++ b/blockchain/mediantime.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "math" diff --git a/mediantime_test.go b/blockchain/mediantime_test.go similarity index 95% rename from mediantime_test.go rename to blockchain/mediantime_test.go index 69f543a0..7040017d 100644 --- a/mediantime_test.go +++ b/blockchain/mediantime_test.go @@ -2,14 +2,14 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "strconv" "testing" "time" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" ) // TestMedianTime tests the medianTime implementation. @@ -55,11 +55,11 @@ func TestMedianTime(t *testing.T) { } // Modify the max number of allowed median time entries for these tests. - btcchain.TstSetMaxMedianTimeEntries(10) - defer btcchain.TstSetMaxMedianTimeEntries(200) + blockchain.TstSetMaxMedianTimeEntries(10) + defer blockchain.TstSetMaxMedianTimeEntries(200) for i, test := range tests { - filter := btcchain.NewMedianTime() + filter := blockchain.NewMedianTime() for j, offset := range test.in { id := strconv.Itoa(j) now := time.Unix(time.Now().Unix(), 0) diff --git a/merkle.go b/blockchain/merkle.go similarity index 99% rename from merkle.go rename to blockchain/merkle.go index 83e5acdb..900557ca 100644 --- a/merkle.go +++ b/blockchain/merkle.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "math" diff --git a/merkle_test.go b/blockchain/merkle_test.go similarity index 82% rename from merkle_test.go rename to blockchain/merkle_test.go index f766270f..4f64dbb3 100644 --- a/merkle_test.go +++ b/blockchain/merkle_test.go @@ -2,19 +2,19 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "testing" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcutil" ) // TestMerkle tests the BuildMerkleTreeStore API. func TestMerkle(t *testing.T) { block := btcutil.NewBlock(&Block100000) - merkles := btcchain.BuildMerkleTreeStore(block.Transactions()) + merkles := blockchain.BuildMerkleTreeStore(block.Transactions()) calculatedMerkleRoot := merkles[len(merkles)-1] wantMerkle := &Block100000.Header.MerkleRoot if !wantMerkle.IsEqual(calculatedMerkleRoot) { diff --git a/notifications.go b/blockchain/notifications.go similarity index 99% rename from notifications.go rename to blockchain/notifications.go index 73b63b36..4521d4ed 100644 --- a/notifications.go +++ b/blockchain/notifications.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/process.go b/blockchain/process.go similarity index 99% rename from process.go rename to blockchain/process.go index fce1ee33..2c6dd538 100644 --- a/process.go +++ b/blockchain/process.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/reorganization_test.go b/blockchain/reorganization_test.go similarity index 93% rename from reorganization_test.go rename to blockchain/reorganization_test.go index e52be822..32e00135 100644 --- a/reorganization_test.go +++ b/blockchain/reorganization_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "compress/bzip2" @@ -13,7 +13,7 @@ import ( "strings" "testing" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" ) @@ -56,12 +56,12 @@ func TestReorganization(t *testing.T) { // Since we're not dealing with the real block chain, disable // checkpoints and set the coinbase maturity to 1. chain.DisableCheckpoints(true) - btcchain.TstSetCoinbaseMaturity(1) + blockchain.TstSetCoinbaseMaturity(1) - timeSource := btcchain.NewMedianTime() + timeSource := blockchain.NewMedianTime() expectedOrphans := map[int]struct{}{5: struct{}{}, 6: struct{}{}} for i := 1; i < len(blocks); i++ { - isOrphan, err := chain.ProcessBlock(blocks[i], timeSource, btcchain.BFNone) + isOrphan, err := chain.ProcessBlock(blocks[i], timeSource, blockchain.BFNone) if err != nil { t.Errorf("ProcessBlock fail on block %v: %v\n", i, err) return diff --git a/scriptval.go b/blockchain/scriptval.go similarity index 99% rename from scriptval.go rename to blockchain/scriptval.go index 22d0ea20..1cdf4b8c 100644 --- a/scriptval.go +++ b/blockchain/scriptval.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/scriptval_test.go b/blockchain/scriptval_test.go similarity index 87% rename from scriptval_test.go rename to blockchain/scriptval_test.go index 5dacd826..5b893eb1 100644 --- a/scriptval_test.go +++ b/blockchain/scriptval_test.go @@ -2,14 +2,14 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "fmt" "runtime" "testing" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" ) // TestCheckBlockScripts ensures that validating the all of the scripts in a @@ -35,7 +35,7 @@ func TestCheckBlockScripts(t *testing.T) { return } - if err := btcchain.TstCheckBlockScripts(blocks[0], txStore); err != nil { + if err := blockchain.TstCheckBlockScripts(blocks[0], txStore); err != nil { t.Errorf("Transaction script validation failed: %v\n", err) return diff --git a/testdata/277647.dat.bz2 b/blockchain/testdata/277647.dat.bz2 similarity index 100% rename from testdata/277647.dat.bz2 rename to blockchain/testdata/277647.dat.bz2 diff --git a/testdata/277647.txstore.bz2 b/blockchain/testdata/277647.txstore.bz2 similarity index 100% rename from testdata/277647.txstore.bz2 rename to blockchain/testdata/277647.txstore.bz2 diff --git a/testdata/blk_0_to_4.dat.bz2 b/blockchain/testdata/blk_0_to_4.dat.bz2 similarity index 100% rename from testdata/blk_0_to_4.dat.bz2 rename to blockchain/testdata/blk_0_to_4.dat.bz2 diff --git a/testdata/blk_3A.dat.bz2 b/blockchain/testdata/blk_3A.dat.bz2 similarity index 100% rename from testdata/blk_3A.dat.bz2 rename to blockchain/testdata/blk_3A.dat.bz2 diff --git a/testdata/blk_4A.dat.bz2 b/blockchain/testdata/blk_4A.dat.bz2 similarity index 100% rename from testdata/blk_4A.dat.bz2 rename to blockchain/testdata/blk_4A.dat.bz2 diff --git a/testdata/blk_5A.dat.bz2 b/blockchain/testdata/blk_5A.dat.bz2 similarity index 100% rename from testdata/blk_5A.dat.bz2 rename to blockchain/testdata/blk_5A.dat.bz2 diff --git a/testdata/reorgtest.hex b/blockchain/testdata/reorgtest.hex similarity index 100% rename from testdata/reorgtest.hex rename to blockchain/testdata/reorgtest.hex diff --git a/timesorter.go b/blockchain/timesorter.go similarity index 97% rename from timesorter.go rename to blockchain/timesorter.go index 744726d7..361ccbd6 100644 --- a/timesorter.go +++ b/blockchain/timesorter.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "time" diff --git a/timesorter_test.go b/blockchain/timesorter_test.go similarity index 93% rename from timesorter_test.go rename to blockchain/timesorter_test.go index 297fdb7c..85f5757e 100644 --- a/timesorter_test.go +++ b/blockchain/timesorter_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "reflect" @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" ) // TestTimeSorter tests the timeSorter implementation. @@ -42,7 +42,7 @@ func TestTimeSorter(t *testing.T) { for i, test := range tests { result := make([]time.Time, len(test.in)) copy(result, test.in) - sort.Sort(btcchain.TstTimeSorter(result)) + sort.Sort(blockchain.TstTimeSorter(result)) if !reflect.DeepEqual(result, test.want) { t.Errorf("timeSorter #%d got %v want %v", i, result, test.want) diff --git a/txlookup.go b/blockchain/txlookup.go similarity index 99% rename from txlookup.go rename to blockchain/txlookup.go index 6925ef75..b2ba39e0 100644 --- a/txlookup.go +++ b/blockchain/txlookup.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "fmt" diff --git a/validate.go b/blockchain/validate.go similarity index 99% rename from validate.go rename to blockchain/validate.go index 488d4b8b..b53b8314 100644 --- a/validate.go +++ b/blockchain/validate.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain +package blockchain import ( "encoding/binary" diff --git a/validate_test.go b/blockchain/validate_test.go similarity index 95% rename from validate_test.go rename to blockchain/validate_test.go index c8fde7af..b54112bb 100644 --- a/validate_test.go +++ b/blockchain/validate_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. -package btcchain_test +package blockchain_test import ( "math" @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/btcsuite/btcchain" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcnet" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwire" @@ -46,8 +46,8 @@ func TestCheckConnectBlock(t *testing.T) { func TestCheckBlockSanity(t *testing.T) { powLimit := btcnet.MainNetParams.PowLimit block := btcutil.NewBlock(&Block100000) - timeSource := btcchain.NewMedianTime() - err := btcchain.CheckBlockSanity(block, powLimit, timeSource) + timeSource := blockchain.NewMedianTime() + err := blockchain.CheckBlockSanity(block, powLimit, timeSource) if err != nil { t.Errorf("CheckBlockSanity: %v", err) } @@ -56,7 +56,7 @@ func TestCheckBlockSanity(t *testing.T) { // second fails. timestamp := block.MsgBlock().Header.Timestamp block.MsgBlock().Header.Timestamp = timestamp.Add(time.Nanosecond) - err = btcchain.CheckBlockSanity(block, powLimit, timeSource) + err = blockchain.CheckBlockSanity(block, powLimit, timeSource) if err == nil { t.Errorf("CheckBlockSanity: error is nil when it shouldn't be") } @@ -73,11 +73,11 @@ func TestCheckSerializedHeight(t *testing.T) { coinbaseTx.AddTxIn(btcwire.NewTxIn(coinbaseOutpoint, nil)) // Expected rule errors. - missingHeightError := btcchain.RuleError{ - ErrorCode: btcchain.ErrMissingCoinbaseHeight, + missingHeightError := blockchain.RuleError{ + ErrorCode: blockchain.ErrMissingCoinbaseHeight, } - badHeightError := btcchain.RuleError{ - ErrorCode: btcchain.ErrBadCoinbaseHeight, + badHeightError := blockchain.RuleError{ + ErrorCode: blockchain.ErrBadCoinbaseHeight, } tests := []struct { @@ -109,15 +109,15 @@ func TestCheckSerializedHeight(t *testing.T) { msgTx.TxIn[0].SignatureScript = test.sigScript tx := btcutil.NewTx(msgTx) - err := btcchain.TstCheckSerializedHeight(tx, test.wantHeight) + err := blockchain.TstCheckSerializedHeight(tx, test.wantHeight) if reflect.TypeOf(err) != reflect.TypeOf(test.err) { t.Errorf("checkSerializedHeight #%d wrong error type "+ "got: %v <%T>, want: %T", i, err, err, test.err) continue } - if rerr, ok := err.(btcchain.RuleError); ok { - trerr := test.err.(btcchain.RuleError) + if rerr, ok := err.(blockchain.RuleError); ok { + trerr := test.err.(blockchain.RuleError) if rerr.ErrorCode != trerr.ErrorCode { t.Errorf("checkSerializedHeight #%d wrong "+ "error code got: %v, want: %v", i, diff --git a/cov_report.sh b/cov_report.sh deleted file mode 100644 index 307f05b7..00000000 --- a/cov_report.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -# This script uses gocov to generate a test coverage report. -# The gocov tool my be obtained with the following command: -# go get github.com/axw/gocov/gocov -# -# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH. - -# Check for gocov. -type gocov >/dev/null 2>&1 -if [ $? -ne 0 ]; then - echo >&2 "This script requires the gocov tool." - echo >&2 "You may obtain it with the following command:" - echo >&2 "go get github.com/axw/gocov/gocov" - exit 1 -fi -gocov test | gocov report diff --git a/error_test.go b/error_test.go deleted file mode 100644 index 1962629b..00000000 --- a/error_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2014 Conformal Systems LLC. -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package btcchain_test - -import ( - "testing" - - "github.com/btcsuite/btcchain" -) - -// TestErrorCodeStringer tests the stringized output for the ErrorCode type. -func TestErrorCodeStringer(t *testing.T) { - tests := []struct { - in btcchain.ErrorCode - want string - }{ - {btcchain.ErrDuplicateBlock, "ErrDuplicateBlock"}, - {btcchain.ErrBlockTooBig, "ErrBlockTooBig"}, - {btcchain.ErrBlockVersionTooOld, "ErrBlockVersionTooOld"}, - {btcchain.ErrInvalidTime, "ErrInvalidTime"}, - {btcchain.ErrTimeTooOld, "ErrTimeTooOld"}, - {btcchain.ErrTimeTooNew, "ErrTimeTooNew"}, - {btcchain.ErrDifficultyTooLow, "ErrDifficultyTooLow"}, - {btcchain.ErrUnexpectedDifficulty, "ErrUnexpectedDifficulty"}, - {btcchain.ErrHighHash, "ErrHighHash"}, - {btcchain.ErrBadMerkleRoot, "ErrBadMerkleRoot"}, - {btcchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, - {btcchain.ErrForkTooOld, "ErrForkTooOld"}, - {btcchain.ErrCheckpointTimeTooOld, "ErrCheckpointTimeTooOld"}, - {btcchain.ErrNoTransactions, "ErrNoTransactions"}, - {btcchain.ErrTooManyTransactions, "ErrTooManyTransactions"}, - {btcchain.ErrNoTxInputs, "ErrNoTxInputs"}, - {btcchain.ErrNoTxOutputs, "ErrNoTxOutputs"}, - {btcchain.ErrTxTooBig, "ErrTxTooBig"}, - {btcchain.ErrBadTxOutValue, "ErrBadTxOutValue"}, - {btcchain.ErrDuplicateTxInputs, "ErrDuplicateTxInputs"}, - {btcchain.ErrBadTxInput, "ErrBadTxInput"}, - {btcchain.ErrBadCheckpoint, "ErrBadCheckpoint"}, - {btcchain.ErrMissingTx, "ErrMissingTx"}, - {btcchain.ErrUnfinalizedTx, "ErrUnfinalizedTx"}, - {btcchain.ErrDuplicateTx, "ErrDuplicateTx"}, - {btcchain.ErrOverwriteTx, "ErrOverwriteTx"}, - {btcchain.ErrImmatureSpend, "ErrImmatureSpend"}, - {btcchain.ErrDoubleSpend, "ErrDoubleSpend"}, - {btcchain.ErrSpendTooHigh, "ErrSpendTooHigh"}, - {btcchain.ErrBadFees, "ErrBadFees"}, - {btcchain.ErrTooManySigOps, "ErrTooManySigOps"}, - {btcchain.ErrFirstTxNotCoinbase, "ErrFirstTxNotCoinbase"}, - {btcchain.ErrMultipleCoinbases, "ErrMultipleCoinbases"}, - {btcchain.ErrBadCoinbaseScriptLen, "ErrBadCoinbaseScriptLen"}, - {btcchain.ErrBadCoinbaseValue, "ErrBadCoinbaseValue"}, - {btcchain.ErrMissingCoinbaseHeight, "ErrMissingCoinbaseHeight"}, - {btcchain.ErrBadCoinbaseHeight, "ErrBadCoinbaseHeight"}, - {btcchain.ErrScriptMalformed, "ErrScriptMalformed"}, - {btcchain.ErrScriptValidation, "ErrScriptValidation"}, - {0xffff, "Unknown ErrorCode (65535)"}, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - result := test.in.String() - if result != test.want { - t.Errorf("String #%d\n got: %s want: %s", i, result, - test.want) - continue - } - } -} - -// TestRuleError tests the error output for the RuleError type. -func TestRuleError(t *testing.T) { - tests := []struct { - in btcchain.RuleError - want string - }{ - { - btcchain.RuleError{Description: "duplicate block"}, - "duplicate block", - }, - { - btcchain.RuleError{Description: "human-readable error"}, - "human-readable error", - }, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - result := test.in.Error() - if result != test.want { - t.Errorf("Error #%d\n got: %s want: %s", i, result, - test.want) - continue - } - } -} diff --git a/goclean.sh b/goclean.sh deleted file mode 100755 index 91833320..00000000 --- a/goclean.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# The script does automatic checking on a Go package and its sub-packages, including: -# 1. gofmt (http://golang.org/cmd/gofmt/) -# 2. goimports (https://github.com/bradfitz/goimports) -# 3. golint (https://github.com/golang/lint) -# 4. go vet (http://golang.org/cmd/vet) -# 5. test coverage (http://blog.golang.org/cover) - -set -e - -# Automatic checks -test -z "$(gofmt -l -w . | tee /dev/stderr)" -test -z "$(goimports -l -w . | tee /dev/stderr)" -test -z "$(golint . | tee /dev/stderr)" -go vet ./... -env GORACE="halt_on_error=1" go test -v -race ./... - -# Run test coverage on each subdirectories and merge the coverage profile. - -echo "mode: count" > profile.cov - -# Standard go tooling behavior is to ignore dirs with leading underscores. -for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d); -do -if ls $dir/*.go &> /dev/null; then - go test -covermode=count -coverprofile=$dir/profile.tmp $dir - if [ -f $dir/profile.tmp ]; then - cat $dir/profile.tmp | tail -n +2 >> profile.cov - rm $dir/profile.tmp - fi -fi -done - -go tool cover -func profile.cov - -# To submit the test coverage result to coveralls.io, -# use goveralls (https://github.com/mattn/goveralls) -# goveralls -coverprofile=profile.cov -service=travis-ci diff --git a/test_coverage.txt b/test_coverage.txt deleted file mode 100644 index b07d42c5..00000000 --- a/test_coverage.txt +++ /dev/null @@ -1,97 +0,0 @@ - -github.com/conformal/btcchain/validate.go checkSerializedHeight 100.00% (17/17) -github.com/conformal/btcchain/chain.go BlockChain.removeOrphanBlock 100.00% (16/16) -github.com/conformal/btcchain/txlookup.go disconnectTransactions 100.00% (13/13) -github.com/conformal/btcchain/difficulty.go CompactToBig 100.00% (12/12) -github.com/conformal/btcchain/validate.go CountSigOps 100.00% (9/9) -github.com/conformal/btcchain/chain.go New 100.00% (8/8) -github.com/conformal/btcchain/validate.go BlockChain.CheckConnectBlock 100.00% (7/7) -github.com/conformal/btcchain/difficulty.go ShaHashToBig 100.00% (5/5) -github.com/conformal/btcchain/merkle.go HashMerkleBranches 100.00% (5/5) -github.com/conformal/btcchain/chain.go BlockChain.IsKnownOrphan 100.00% (5/5) -github.com/conformal/btcchain/difficulty.go CalcWork 100.00% (5/5) -github.com/conformal/btcchain/merkle.go nextPowerOfTwo 100.00% (4/4) -github.com/conformal/btcchain/process.go BlockChain.blockExists 100.00% (3/3) -github.com/conformal/btcchain/chain.go newBlockNode 100.00% (3/3) -github.com/conformal/btcchain/error.go ErrorCode.String 100.00% (3/3) -github.com/conformal/btcchain/checkpoints.go newShaHashFromStr 100.00% (2/2) -github.com/conformal/btcchain/log.go init 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go newTxValidator 100.00% (1/1) -github.com/conformal/btcchain/scriptval.go txValidator.sendResult 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Less 100.00% (1/1) -github.com/conformal/btcchain/log.go DisableLog 100.00% (1/1) -github.com/conformal/btcchain/chain.go BlockChain.HaveBlock 100.00% (1/1) -github.com/conformal/btcchain/error.go ruleError 100.00% (1/1) -github.com/conformal/btcchain/checkpoints.go BlockChain.DisableCheckpoints 100.00% (1/1) -github.com/conformal/btcchain/validate.go CheckBlockSanity 100.00% (1/1) -github.com/conformal/btcchain/error.go RuleError.Error 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Len 100.00% (1/1) -github.com/conformal/btcchain/timesorter.go timeSorter.Swap 100.00% (1/1) -github.com/conformal/btcchain/txlookup.go fetchTxStoreMain 95.65% (22/23) -github.com/conformal/btcchain/merkle.go BuildMerkleTreeStore 93.33% (14/15) -github.com/conformal/btcchain/chain.go BlockChain.getReorganizeNodes 92.86% (13/14) -github.com/conformal/btcchain/scriptval.go txValidator.Validate 88.46% (23/26) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchTxStore 86.96% (20/23) -github.com/conformal/btcchain/chain.go BlockChain.connectBestChain 85.71% (30/35) -github.com/conformal/btcchain/validate.go BlockChain.checkBIP0030 85.71% (12/14) -github.com/conformal/btcchain/validate.go IsCoinBase 85.71% (6/7) -github.com/conformal/btcchain/chain.go BlockChain.reorganizeChain 85.29% (29/34) -github.com/conformal/btcchain/process.go BlockChain.processOrphans 84.21% (16/19) -github.com/conformal/btcchain/scriptval.go checkBlockScripts 83.33% (15/18) -github.com/conformal/btcchain/chain.go BlockChain.connectBlock 83.33% (10/12) -github.com/conformal/btcchain/chain.go BlockChain.calcPastMedianTime 82.35% (14/17) -github.com/conformal/btcchain/chain.go BlockChain.isMajorityVersion 80.00% (8/10) -github.com/conformal/btcchain/chain.go BlockChain.addOrphanBlock 77.78% (14/18) -github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromBlock 77.78% (7/9) -github.com/conformal/btcchain/chain.go BlockChain.GenerateInitialIndex 77.27% (17/22) -github.com/conformal/btcchain/chain.go BlockChain.disconnectBlock 76.92% (10/13) -github.com/conformal/btcchain/txlookup.go BlockChain.fetchInputTransactions 75.00% (18/24) -github.com/conformal/btcchain/difficulty.go BigToCompact 75.00% (12/16) -github.com/conformal/btcchain/validate.go isTransactionSpent 75.00% (3/4) -github.com/conformal/btcchain/validate.go BlockChain.checkConnectBlock 71.15% (37/52) -github.com/conformal/btcchain/validate.go checkBlockSanity 67.44% (29/43) -github.com/conformal/btcchain/validate.go CalcBlockSubsidy 66.67% (2/3) -github.com/conformal/btcchain/validate.go isNullOutpoint 66.67% (2/3) -github.com/conformal/btcchain/validate.go CheckTransactionInputs 63.64% (28/44) -github.com/conformal/btcchain/txlookup.go connectTransactions 61.54% (8/13) -github.com/conformal/btcchain/validate.go CheckTransactionSanity 61.11% (22/36) -github.com/conformal/btcchain/validate.go isBIP0030Node 60.00% (3/5) -github.com/conformal/btcchain/validate.go checkProofOfWork 56.25% (9/16) -github.com/conformal/btcchain/accept.go BlockChain.maybeAcceptBlock 55.07% (38/69) -github.com/conformal/btcchain/process.go BlockChain.ProcessBlock 52.27% (23/44) -github.com/conformal/btcchain/chain.go BlockChain.loadBlockNode 52.00% (13/25) -github.com/conformal/btcchain/scriptval.go txValidator.validateHandler 50.00% (16/32) -github.com/conformal/btcchain/chain.go BlockChain.getPrevNodeFromNode 50.00% (4/8) -github.com/conformal/btcchain/checkpoints.go BlockChain.LatestCheckpoint 50.00% (2/4) -github.com/conformal/btcchain/notifications.go BlockChain.sendNotification 50.00% (2/4) -github.com/conformal/btcchain/chain.go BlockChain.pruneBlockNodes 41.18% (7/17) -github.com/conformal/btcchain/validate.go IsFinalizedTransaction 28.57% (4/14) -github.com/conformal/btcchain/checkpoints.go BlockChain.verifyCheckpoint 22.22% (2/9) -github.com/conformal/btcchain/difficulty.go BlockChain.calcNextRequiredDifficulty 11.11% (4/36) -github.com/conformal/btcchain/checkpoints.go BlockChain.findPreviousCheckpoint 4.88% (2/41) -github.com/conformal/btcchain/blocklocator.go BlockChain.BlockLocatorFromHash 0.00% (0/39) -github.com/conformal/btcchain/checkpoints.go BlockChain.IsCheckpointCandidate 0.00% (0/32) -github.com/conformal/btcchain/validate.go CountP2SHSigOps 0.00% (0/26) -github.com/conformal/btcchain/chain.go BlockChain.removeBlockNode 0.00% (0/12) -github.com/conformal/btcchain/difficulty.go BlockChain.calcEasiestDifficulty 0.00% (0/12) -github.com/conformal/btcchain/chain.go BlockChain.GetOrphanRoot 0.00% (0/11) -github.com/conformal/btcchain/scriptval.go ValidateTransactionScripts 0.00% (0/11) -github.com/conformal/btcchain/difficulty.go BlockChain.findPrevTestNetDifficulty 0.00% (0/11) -github.com/conformal/btcchain/log.go SetLogWriter 0.00% (0/10) -github.com/conformal/btcchain/chain.go BlockChain.IsCurrent 0.00% (0/9) -github.com/conformal/btcchain/chain.go removeChildNode 0.00% (0/8) -github.com/conformal/btcchain/txlookup.go BlockChain.FetchTransactionStore 0.00% (0/6) -github.com/conformal/btcchain/blocklocator.go BlockChain.LatestBlockLocator 0.00% (0/6) -github.com/conformal/btcchain/checkpoints.go isNonstandardTransaction 0.00% (0/5) -github.com/conformal/btcchain/checkpoints.go BlockChain.Checkpoints 0.00% (0/3) -github.com/conformal/btcchain/notifications.go NotificationType.String 0.00% (0/3) -github.com/conformal/btcchain/chain.go addChildrenWork 0.00% (0/3) -github.com/conformal/btcchain/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.CalcPastMedianTime 0.00% (0/1) -github.com/conformal/btcchain/chain.go BlockChain.DisableVerify 0.00% (0/1) -github.com/conformal/btcchain/validate.go CheckProofOfWork 0.00% (0/1) -github.com/conformal/btcchain/log.go newLogClosure 0.00% (0/1) -github.com/conformal/btcchain/difficulty.go BlockChain.CalcNextRequiredDifficulty 0.00% (0/1) -github.com/conformal/btcchain/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcchain ------------------------------------- 56.65% (699/1234) -