diff --git a/.travis.yml b/.travis.yml index 8d52cda4..0450edb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,13 +13,18 @@ before_install: # ginkgo golint dep migrate - make installtools - bash ./scripts/install-postgres-10.sh + - npm install -g ganache-cli before_script: - sudo -u postgres createdb vulcanize_private - make migrate NAME=vulcanize_private + - bash ./libraries/maker/start_test_chain.sh script: - make test notifications: email: false + +after_script: + - bash ./libraries/maker/stop_test_chain.sh diff --git a/Gopkg.lock b/Gopkg.lock index b2ead9e6..cca9a777 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -17,7 +17,10 @@ name = "github.com/ethereum/go-ethereum" packages = [ ".", + "accounts", "accounts/abi", + "accounts/abi/bind", + "accounts/keystore", "common", "common/hexutil", "common/math", @@ -33,6 +36,7 @@ "crypto/bn256/cloudflare", "crypto/bn256/google", "crypto/ecies", + "crypto/randentropy", "crypto/secp256k1", "crypto/sha3", "ethclient", @@ -209,12 +213,24 @@ revision = "c893efa28eb45626cdaa76c9f653b62488858837" version = "v1.2.0" +[[projects]] + name = "github.com/pborman/uuid" + packages = ["."] + revision = "e790cca94e6cc75c7064b1332e63811d4aae1a53" + version = "v1.1" + [[projects]] name = "github.com/pelletier/go-toml" packages = ["."] revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8" version = "v1.1.0" +[[projects]] + name = "github.com/rjeczalik/notify" + packages = ["."] + revision = "52ae50d8490436622a8941bd70c3dbe0acdd4bbf" + version = "v0.9.0" + [[projects]] name = "github.com/rs/cors" packages = ["."] @@ -282,7 +298,11 @@ [[projects]] branch = "master" name = "golang.org/x/crypto" - packages = ["ripemd160"] + packages = [ + "pbkdf2", + "ripemd160", + "scrypt" + ] revision = "613d6eafa307c6881a737a3c35c0e312e8d3a8c5" [[projects]] @@ -336,6 +356,16 @@ ] revision = "be25de41fadfae372d6470bda81ca6beb55ef551" +[[projects]] + branch = "master" + name = "golang.org/x/tools" + packages = [ + "go/ast/astutil", + "imports", + "internal/fastwalk" + ] + revision = "8cc4e8a6f4841aa92a8683fca47bc5d64b58875b" + [[projects]] name = "gopkg.in/fatih/set.v0" packages = ["."] @@ -363,6 +393,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "a69d27ddc33f08d7b39242508f04e5c339b52cc65e70596100d17a870b2183a6" + inputs-digest = "2122d1d04fbc67daf75d751e144926e73f0fd838d51711cccf9604eabb46b95b" solver-name = "gps-cdcl" solver-version = 1 diff --git a/README.md b/README.md index 05d450eb..a27532d1 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,16 @@ This command is useful when you want a minimal baseline from which to track targ 2. In a separate terminal start VulcanizeDB: - `./vulcanizedb lightSync --config --starting-block-number ` +## Backfill Auction event logs from light sync +Backfills auction event logs from the configured Ethereum node based on the populated block headers. +This command requires that a light sync (see command above) has previously been run. + +_Since auction contracts have not yet been deployed, this command will need to be run a local blockchain at the moment. As such, a new environment file will need to be added. See `environments/local.toml.example`._ + +1. Start Ethereum node +1. In a separate terminal run the backfill command: + - `./vulcanizedb backfillAuctionLogs --config ` + ## Start full environment in docker by single command ### Geth Rinkeby diff --git a/cmd/backfillAuctionLogs.go b/cmd/backfillAuctionLogs.go new file mode 100644 index 00000000..edcd96fe --- /dev/null +++ b/cmd/backfillAuctionLogs.go @@ -0,0 +1,76 @@ +// Copyright © 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" + "github.com/spf13/cobra" + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/libraries/shared" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/geth" + "github.com/vulcanize/vulcanizedb/pkg/geth/client" + vRpc "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc" + "github.com/vulcanize/vulcanizedb/pkg/geth/node" + "log" +) + +// backfillAuctionLogsCmd represents the backfillAuctionLogs command +var backfillAuctionLogsCmd = &cobra.Command{ + Use: "backfillAuctionLogs", + Short: "Backfill auction event logs", + Long: `Backfills auction event logs based on previously populated block Header records. +vulcanize backfillAuctionLogs --config environments/local.toml + +This command expects a light sync to have been run, and the presence of header records in the Vulcanize database.`, + Run: func(cmd *cobra.Command, args []string) { + backfillAuctionLogs() + }, +} + +func blockChain() *geth.BlockChain { + rawRpcClient, err := rpc.Dial(ipc) + + if err != nil { + log.Fatal(err) + } + rpcClient := client.NewRpcClient(rawRpcClient, ipc) + ethClient := ethclient.NewClient(rawRpcClient) + vdbEthClient := client.NewEthClient(ethClient) + vdbNode := node.MakeNode(rpcClient) + transactionConverter := vRpc.NewRpcTransactionConverter(ethClient) + return geth.NewBlockChain(vdbEthClient, vdbNode, transactionConverter) +} + +func backfillAuctionLogs() { + blockChain := blockChain() + db, err := postgres.NewDB(databaseConfig, blockChain.Node()) + if err != nil { + log.Fatal("Failed to initialize database.") + } + + watcher := shared.Watcher{ + DB: *db, + Blockchain: blockChain, + } + + watcher.AddTransformers(every_block.TransformerInitializers()) + watcher.Execute() +} + +func init() { + rootCmd.AddCommand(backfillAuctionLogsCmd) +} diff --git a/db/migrations/1532468318_create_maker_schema.down.sql b/db/migrations/1532468318_create_maker_schema.down.sql new file mode 100644 index 00000000..cb59a3da --- /dev/null +++ b/db/migrations/1532468318_create_maker_schema.down.sql @@ -0,0 +1 @@ +DROP SCHEMA maker; diff --git a/db/migrations/1532468318_create_maker_schema.up.sql b/db/migrations/1532468318_create_maker_schema.up.sql new file mode 100644 index 00000000..87c8fa51 --- /dev/null +++ b/db/migrations/1532468318_create_maker_schema.up.sql @@ -0,0 +1,2 @@ +CREATE SCHEMA maker; + diff --git a/db/migrations/1532468319_create_flip_kick_table.down.sql b/db/migrations/1532468319_create_flip_kick_table.down.sql new file mode 100644 index 00000000..dbe497b8 --- /dev/null +++ b/db/migrations/1532468319_create_flip_kick_table.down.sql @@ -0,0 +1 @@ +DROP TABLE maker.flip_kick; \ No newline at end of file diff --git a/db/migrations/1532468319_create_flip_kick_table.up.sql b/db/migrations/1532468319_create_flip_kick_table.up.sql new file mode 100644 index 00000000..ad4f672a --- /dev/null +++ b/db/migrations/1532468319_create_flip_kick_table.up.sql @@ -0,0 +1,16 @@ +CREATE TABLE maker.flip_kick ( + db_id SERIAL PRIMARY KEY, + header_id INTEGER NOT NULL REFERENCES headers (id) ON DELETE CASCADE, + id NUMERIC NOT NULL UNIQUE, + mom VARCHAR, + vat VARCHAR, + ilk VARCHAR, + lot NUMERIC, + bid NUMERIC, + guy VARCHAR, + gal VARCHAR, + "end" TIMESTAMP WITH TIME ZONE, + era TIMESTAMP WITH TIME ZONE, + lad VARCHAR, + tab NUMERIC +); diff --git a/db/schema.sql b/db/schema.sql index b9e03a52..6d7203ed 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -15,6 +15,13 @@ SET check_function_bodies = false; SET client_min_messages = warning; SET row_security = off; +-- +-- Name: maker; Type: SCHEMA; Schema: -; Owner: - +-- + +CREATE SCHEMA maker; + + -- -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - -- @@ -33,6 +40,48 @@ SET default_tablespace = ''; SET default_with_oids = false; +-- +-- Name: flip_kick; Type: TABLE; Schema: maker; Owner: - +-- + +CREATE TABLE maker.flip_kick ( + db_id integer NOT NULL, + header_id integer NOT NULL, + id numeric NOT NULL, + mom character varying, + vat character varying, + ilk character varying, + lot numeric, + bid numeric, + guy character varying, + gal character varying, + "end" timestamp with time zone, + era timestamp with time zone, + lad character varying, + tab numeric +); + + +-- +-- Name: flip_kick_db_id_seq; Type: SEQUENCE; Schema: maker; Owner: - +-- + +CREATE SEQUENCE maker.flip_kick_db_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: flip_kick_db_id_seq; Type: SEQUENCE OWNED BY; Schema: maker; Owner: - +-- + +ALTER SEQUENCE maker.flip_kick_db_id_seq OWNED BY maker.flip_kick.db_id; + + -- -- Name: logs; Type: TABLE; Schema: public; Owner: - -- @@ -405,6 +454,13 @@ CREATE VIEW public.watched_event_logs AS WHERE ((((log_filters.topic0)::text = (logs.topic0)::text) OR (log_filters.topic0 IS NULL)) AND (((log_filters.topic1)::text = (logs.topic1)::text) OR (log_filters.topic1 IS NULL)) AND (((log_filters.topic2)::text = (logs.topic2)::text) OR (log_filters.topic2 IS NULL)) AND (((log_filters.topic3)::text = (logs.topic3)::text) OR (log_filters.topic3 IS NULL))); +-- +-- Name: flip_kick db_id; Type: DEFAULT; Schema: maker; Owner: - +-- + +ALTER TABLE ONLY maker.flip_kick ALTER COLUMN db_id SET DEFAULT nextval('maker.flip_kick_db_id_seq'::regclass); + + -- -- Name: blocks id; Type: DEFAULT; Schema: public; Owner: - -- @@ -468,6 +524,22 @@ ALTER TABLE ONLY public.transactions ALTER COLUMN id SET DEFAULT nextval('public ALTER TABLE ONLY public.watched_contracts ALTER COLUMN contract_id SET DEFAULT nextval('public.watched_contracts_contract_id_seq'::regclass); +-- +-- Name: flip_kick flip_kick_id_key; Type: CONSTRAINT; Schema: maker; Owner: - +-- + +ALTER TABLE ONLY maker.flip_kick + ADD CONSTRAINT flip_kick_id_key UNIQUE (id); + + +-- +-- Name: flip_kick flip_kick_pkey; Type: CONSTRAINT; Schema: maker; Owner: - +-- + +ALTER TABLE ONLY maker.flip_kick + ADD CONSTRAINT flip_kick_pkey PRIMARY KEY (db_id); + + -- -- Name: blocks blocks_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -599,6 +671,14 @@ CREATE INDEX tx_from_index ON public.transactions USING btree (tx_from); CREATE INDEX tx_to_index ON public.transactions USING btree (tx_to); +-- +-- Name: flip_kick flip_kick_header_id_fkey; Type: FK CONSTRAINT; Schema: maker; Owner: - +-- + +ALTER TABLE ONLY maker.flip_kick + ADD CONSTRAINT flip_kick_header_id_fkey FOREIGN KEY (header_id) REFERENCES public.headers(id) ON DELETE CASCADE; + + -- -- Name: transactions blocks_fk; Type: FK CONSTRAINT; Schema: public; Owner: - -- diff --git a/environments/local.toml.example b/environments/local.toml.example new file mode 100644 index 00000000..10e51b66 --- /dev/null +++ b/environments/local.toml.example @@ -0,0 +1,7 @@ +[database] +name = "vulcanize_public" +hostname = "localhost" +port = 5432 + +[client] +ipcPath = "http://127.0.0.1:7546" diff --git a/examples/erc20_test_helpers/database.go b/examples/erc20_test_helpers/database.go new file mode 100644 index 00000000..15946db1 --- /dev/null +++ b/examples/erc20_test_helpers/database.go @@ -0,0 +1,27 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package erc20_test_helpers + +type TokenSupplyDBRow struct { + ID int64 + Supply int64 + BlockID int64 `db:"block_id"` + TokenAddress string `db:"token_address"` +} + +type TransferDBRow struct { + ID int64 `db:"id"` + VulcanizeLogID int64 `db:"vulcanize_log_id"` +} diff --git a/examples/mocks/mocks.go b/examples/erc20_test_helpers/mocks/mocks.go similarity index 100% rename from examples/mocks/mocks.go rename to examples/erc20_test_helpers/mocks/mocks.go diff --git a/examples/erc20_watcher/every_block/integration_test.go b/examples/erc20_watcher/every_block/integration_test.go index 52dfa435..53e8154c 100644 --- a/examples/erc20_watcher/every_block/integration_test.go +++ b/examples/erc20_watcher/every_block/integration_test.go @@ -20,11 +20,12 @@ import ( "github.com/vulcanize/vulcanizedb/examples/constants" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" - "github.com/vulcanize/vulcanizedb/examples/test_helpers" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/pkg/fakes" + "github.com/vulcanize/vulcanizedb/pkg/test_helpers" + "github.com/vulcanize/vulcanizedb/examples/erc20_test_helpers" "math/big" "strconv" ) @@ -68,11 +69,11 @@ var _ = Describe("Everyblock transformers", func() { Expect(err).ToNot(HaveOccurred()) Expect(tokenSupplyCount).To(Equal(1)) - var tokenSupply test_helpers.TokenSupplyDBRow + var tokenSupply erc20_test_helpers.TokenSupplyDBRow err = db.Get(&tokenSupply, `SELECT * from token_supply where block_id = $1`, blockId) Expect(err).ToNot(HaveOccurred()) Expect(tokenSupply.BlockID).To(Equal(blockId)) Expect(tokenSupply.TokenAddress).To(Equal(constants.DaiContractAddress)) Expect(tokenSupply.Supply).To(Equal(int64(0))) }) -}) +}) \ No newline at end of file diff --git a/examples/erc20_watcher/every_block/repository_test.go b/examples/erc20_watcher/every_block/repository_test.go index 68372049..da50fc29 100644 --- a/examples/erc20_watcher/every_block/repository_test.go +++ b/examples/erc20_watcher/every_block/repository_test.go @@ -19,12 +19,13 @@ import ( . "github.com/onsi/gomega" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" - "github.com/vulcanize/vulcanizedb/examples/test_helpers" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/test_config" "math/rand" + "github.com/vulcanize/vulcanizedb/pkg/test_helpers" + "github.com/vulcanize/vulcanizedb/examples/erc20_test_helpers" ) var _ = Describe("ERC20 Token Repository", func() { @@ -52,8 +53,8 @@ var _ = Describe("ERC20 Token Repository", func() { err := repository.Create(supply) Expect(err).NotTo(HaveOccurred()) - dbResult := test_helpers.TokenSupplyDBRow{} - expectedTokenSupply := test_helpers.TokenSupplyDBRow{ + dbResult := erc20_test_helpers.TokenSupplyDBRow{} + expectedTokenSupply := erc20_test_helpers.TokenSupplyDBRow{ Supply: int64(100), BlockID: blockId, TokenAddress: testAddress, @@ -112,7 +113,7 @@ var _ = Describe("ERC20 Token Repository", func() { err := node2TokenSupplyRepo.Create(tokenSupply) Expect(err).NotTo(HaveOccurred()) - var tokenSupplies []test_helpers.TokenSupplyDBRow + var tokenSupplies []erc20_test_helpers.TokenSupplyDBRow err = node2TokenSupplyRepo.DB.Select(&tokenSupplies, `SELECT * FROM token_supply`) Expect(err).NotTo(HaveOccurred()) Expect(len(tokenSupplies)).To(Equal(1)) diff --git a/examples/erc20_watcher/every_block/transformer_test.go b/examples/erc20_watcher/every_block/transformer_test.go index a89a5fcc..5e81ea7b 100644 --- a/examples/erc20_watcher/every_block/transformer_test.go +++ b/examples/erc20_watcher/every_block/transformer_test.go @@ -20,7 +20,7 @@ import ( "github.com/vulcanize/vulcanizedb/examples/constants" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" - "github.com/vulcanize/vulcanizedb/examples/mocks" + "github.com/vulcanize/vulcanizedb/examples/erc20_test_helpers/mocks" "github.com/vulcanize/vulcanizedb/pkg/fakes" "math/big" "math/rand" diff --git a/libraries/maker/every_block/config.go b/libraries/maker/every_block/config.go new file mode 100644 index 00000000..93010f08 --- /dev/null +++ b/libraries/maker/every_block/config.go @@ -0,0 +1,31 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +type TransformerConfig struct { + ContractAddress string + ContractAbi string + Topics []string + StartingBlockNumber int64 + EndingBlockNumber int64 +} + +var FlipKickConfig = TransformerConfig{ + ContractAddress: "0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d", //this is a temporary address deployed locally + ContractAbi: FlipperABI, + Topics: []string{FlipKickSignature}, + StartingBlockNumber: 0, + EndingBlockNumber: 100, +} diff --git a/libraries/maker/every_block/constants.go b/libraries/maker/every_block/constants.go new file mode 100644 index 00000000..38d3a962 --- /dev/null +++ b/libraries/maker/every_block/constants.go @@ -0,0 +1,18 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +var FlipperABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"era\",\"outputs\":[{\"name\":\"\",\"type\":\"uint48\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"lad\",\"type\":\"address\"},{\"name\":\"gal\",\"type\":\"address\"},{\"name\":\"tab\",\"type\":\"uint256\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"bid\",\"type\":\"uint256\"}],\"name\":\"kick\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vat\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bids\",\"outputs\":[{\"name\":\"bid\",\"type\":\"uint256\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"guy\",\"type\":\"address\"},{\"name\":\"tic\",\"type\":\"uint48\"},{\"name\":\"end\",\"type\":\"uint48\"},{\"name\":\"lad\",\"type\":\"address\"},{\"name\":\"gal\",\"type\":\"address\"},{\"name\":\"tab\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"bid\",\"type\":\"uint256\"}],\"name\":\"tend\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ttl\",\"outputs\":[{\"name\":\"\",\"type\":\"uint48\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"},{\"name\":\"lot\",\"type\":\"uint256\"},{\"name\":\"bid\",\"type\":\"uint256\"}],\"name\":\"dent\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"beg\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"ilk\",\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"deal\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"tau\",\"outputs\":[{\"name\":\"\",\"type\":\"uint48\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"kicks\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"tick\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"vat_\",\"type\":\"address\"},{\"name\":\"ilk_\",\"type\":\"bytes32\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Move\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"wad\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"act\",\"type\":\"bytes32\"}],\"name\":\"Push\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"what\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"risk\",\"type\":\"int256\"}],\"name\":\"FileIlk\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"what\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"fuss\",\"type\":\"address\"}],\"name\":\"FileFuss\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"what\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"risk\",\"type\":\"int256\"}],\"name\":\"FileInt\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"what\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"risk\",\"type\":\"uint256\"}],\"name\":\"FileUint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"lad\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"gem\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"ink\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"art\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"}],\"name\":\"Frob\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"lad\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"gem\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"ink\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"art\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"tab\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"flip\",\"type\":\"uint256\"}],\"name\":\"Bite\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"lad\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"wad\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"gem\",\"type\":\"int256\"}],\"name\":\"Slip\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"mom\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"vat\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"lot\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"bid\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"gal\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"end\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"lad\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tab\",\"type\":\"uint256\"}],\"name\":\"FlipKick\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"mom\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"pie\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"gem\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"lot\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"bid\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"vow\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"end\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"}],\"name\":\"FlopKick\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"mom\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"pie\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"gem\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"lot\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"bid\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"gal\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"end\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"}],\"name\":\"FlapKick\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"lot\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"bid\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tic\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"}],\"name\":\"Tend\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"lot\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"bid\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"tic\",\"type\":\"uint48\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"}],\"name\":\"Dent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"era\",\"type\":\"uint48\"}],\"name\":\"Deal\",\"type\":\"event\"}]" +var FlipKickSignature = "0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3" diff --git a/libraries/maker/every_block/converter.go b/libraries/maker/every_block/converter.go new file mode 100644 index 00000000..68e4d5f1 --- /dev/null +++ b/libraries/maker/every_block/converter.go @@ -0,0 +1,105 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/vulcanize/vulcanizedb/pkg/geth" + "strings" + "time" + "math/big" + "errors" +) + +type Converter interface { + ToEntity(contractAddress string, contractAbi string, ethLog types.Log) (*FlipKickEntity, error) + ToModel(flipKick FlipKickEntity) (FlipKickModel, error) +} + +type FlipKickConverter struct{} + +func (FlipKickConverter) ToEntity(contractAddress string, contractAbi string, ethLog types.Log) (*FlipKickEntity, error) { + entity := &FlipKickEntity{} + address := common.HexToAddress(contractAddress) + abi, err := geth.ParseAbi(contractAbi) + if err != nil { + return entity, err + } + + contract := bind.NewBoundContract(address, abi, nil, nil, nil) + + err = contract.UnpackLog(entity, "FlipKick", ethLog) + if err != nil { + return entity, err + } + + return entity, nil +} + +func (FlipKickConverter) ToModel(flipKick FlipKickEntity) (FlipKickModel, error) { + //TODO: Confirm if the following values can be/ever will be nil + + if flipKick.Id == nil { + return FlipKickModel{}, errors.New("FlipKick log ID cannot be nil.") + } + + id := flipKick.Id.String() + mom := strings.ToLower(flipKick.Mom.String()) + vat := strings.ToLower(flipKick.Vat.String()) + ilk := strings.ToLower(common.ToHex(flipKick.Ilk[:])) + lot := convertNilToEmptyString(flipKick.Lot.String()) + bid := convertNilToEmptyString(flipKick.Bid.String()) + guy := strings.ToLower(flipKick.Guy.String()) + gal := strings.ToLower(flipKick.Gal.String()) + endValue := convertNilToZeroTimeValue(flipKick.End) + end := time.Unix(endValue, 0) + eraValue := convertNilToZeroTimeValue(flipKick.Era) + era := time.Unix(eraValue, 0) + lad := strings.ToLower(flipKick.Lad.String()) + tab := convertNilToEmptyString(flipKick.Tab.String()) + + return FlipKickModel{ + Id: id, + Mom: mom, + Vat: vat, + Ilk: ilk, + Lot: lot, + Bid: bid, + Guy: guy, + Gal: gal, + End: end, + Era: era, + Lad: lad, + Tab: tab, + }, nil +} + +func convertNilToZeroTimeValue(value *big.Int) int64 { + if value == nil { + return int64(0) + } else { + return value.Int64() + } +} + +func convertNilToEmptyString(value string) string { + if value == "" { + return "" + } else { + return value + } +} diff --git a/libraries/maker/every_block/converter_test.go b/libraries/maker/every_block/converter_test.go new file mode 100644 index 00000000..75bcf347 --- /dev/null +++ b/libraries/maker/every_block/converter_test.go @@ -0,0 +1,109 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/libraries/maker/test_data" + "time" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "math/big" +) + +var _ = Describe("FlipKickEntity Converter", func() { + It("converts an Eth Log to and Entity", func() { + converter := every_block.FlipKickConverter{} + entity, err := converter.ToEntity(test_data.TemporaryFlipAddress, every_block.FlipperABI, test_data.EthFlipKickLog) + + Expect(err).NotTo(HaveOccurred()) + Expect(entity.Id).To(Equal(test_data.FlipKickEntity.Id)) + Expect(entity.Mom).To(Equal(test_data.FlipKickEntity.Mom)) + Expect(entity.Vat).To(Equal(test_data.FlipKickEntity.Vat)) + Expect(entity.Ilk).To(Equal(test_data.FlipKickEntity.Ilk)) + Expect(entity.Lot).To(Equal(test_data.FlipKickEntity.Lot)) + Expect(entity.Bid).To(Equal(test_data.FlipKickEntity.Bid)) + Expect(entity.Guy).To(Equal(test_data.FlipKickEntity.Guy)) + Expect(entity.Gal).To(Equal(test_data.FlipKickEntity.Gal)) + Expect(entity.End).To(Equal(test_data.FlipKickEntity.End)) + Expect(entity.Era).To(Equal(test_data.FlipKickEntity.Era)) + Expect(entity.Lad).To(Equal(test_data.FlipKickEntity.Lad)) + Expect(entity.Tab).To(Equal(test_data.FlipKickEntity.Tab)) + }) + + It("returns an error if converting log to entity fails", func() { + converter := every_block.FlipKickConverter{} + _, err := converter.ToEntity(test_data.TemporaryFlipAddress, "error abi", test_data.EthFlipKickLog) + + Expect(err).To(HaveOccurred()) + }) + + It("converts and Entity to a Model", func() { + converter := every_block.FlipKickConverter{} + model, err := converter.ToModel(test_data.FlipKickEntity) + Expect(err).NotTo(HaveOccurred()) + Expect(model).To(Equal(test_data.FlipKickModel)) + }) + + It("handles nil", func() { + emptyAddressHex := "0x0000000000000000000000000000000000000000" + emptyByteArrayHex := "0x0000000000000000000000000000000000000000000000000000000000000000" + emptyString := "" + emptyTime := time.Unix(0, 0) + converter := every_block.FlipKickConverter{} + emptyEntity := every_block.FlipKickEntity{ + Id: big.NewInt(1), + Mom: common.Address{}, + Vat: common.Address{}, + Ilk: [32]byte{}, + Lot: nil, + Bid: nil, + Guy: common.Address{}, + Gal: common.Address{}, + End: nil, + Era: nil, + Lad: common.Address{}, + Tab: nil, + Raw: types.Log{}, + } + model, err := converter.ToModel(emptyEntity) + + Expect(err).NotTo(HaveOccurred()) + Expect(model.Id).To(Equal("1")) + Expect(model.Mom).To(Equal(emptyAddressHex)) + Expect(model.Vat).To(Equal(emptyAddressHex)) + Expect(model.Ilk).To(Equal(emptyByteArrayHex)) + Expect(model.Lot).To(Equal(emptyString)) + Expect(model.Bid).To(Equal(emptyString)) + Expect(model.Guy).To(Equal(emptyAddressHex)) + Expect(model.Gal).To(Equal(emptyAddressHex)) + Expect(model.End).To(Equal(emptyTime)) + Expect(model.Era).To(Equal(emptyTime)) + Expect(model.Lad).To(Equal(emptyAddressHex)) + Expect(model.Tab).To(Equal(emptyString)) + }) + + It("returns an error of the flip kick event id is nil", func() { + converter := every_block.FlipKickConverter{} + emptyEntity := every_block.FlipKickEntity{} + _, err := converter.ToModel(emptyEntity) + + Expect(err).To(HaveOccurred()) + }) + +}) diff --git a/libraries/maker/every_block/entity.go b/libraries/maker/every_block/entity.go new file mode 100644 index 00000000..485073b8 --- /dev/null +++ b/libraries/maker/every_block/entity.go @@ -0,0 +1,37 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "math/big" +) + +type FlipKickEntity struct { + Id *big.Int + Mom common.Address + Vat common.Address + Ilk [32]byte + Lot *big.Int + Bid *big.Int + Guy common.Address + Gal common.Address + End *big.Int + Era *big.Int + Lad common.Address + Tab *big.Int + Raw types.Log +} diff --git a/libraries/maker/every_block/every_block_suite_test.go b/libraries/maker/every_block/every_block_suite_test.go new file mode 100644 index 00000000..21367c6c --- /dev/null +++ b/libraries/maker/every_block/every_block_suite_test.go @@ -0,0 +1,19 @@ +package every_block_test + +import ( + "io/ioutil" + "log" + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestEveryBlock(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "EveryBlock Suite") +} + +var _ = BeforeSuite(func() { + log.SetOutput(ioutil.Discard) +}) diff --git a/libraries/maker/every_block/fetcher.go b/libraries/maker/every_block/fetcher.go new file mode 100644 index 00000000..21058557 --- /dev/null +++ b/libraries/maker/every_block/fetcher.go @@ -0,0 +1,52 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import ( + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/vulcanize/vulcanizedb/pkg/core" +) + +type LogFetcher interface { + FetchLogs(contractAddress string, topics [][]common.Hash, blockNumber int64) ([]types.Log, error) +} + +type Fetcher struct { + Blockchain core.BlockChain +} + +func NewFetcher(blockchain core.BlockChain) Fetcher { + return Fetcher{ + Blockchain: blockchain, + } +} + +func (f Fetcher) FetchLogs(contractAddress string, topicZeros [][]common.Hash, blockNumber int64) ([]types.Log, error) { + block := big.NewInt(blockNumber) + address := common.HexToAddress(contractAddress) + query := ethereum.FilterQuery{ + FromBlock: block, + ToBlock: block, + Addresses: []common.Address{address}, + Topics: topicZeros, + } + + return f.Blockchain.GetEthLogsWithCustomQuery(query) +} diff --git a/libraries/maker/every_block/fetcher_test.go b/libraries/maker/every_block/fetcher_test.go new file mode 100644 index 00000000..55f32263 --- /dev/null +++ b/libraries/maker/every_block/fetcher_test.go @@ -0,0 +1,62 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block_test + +import ( + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/pkg/fakes" +) + +var _ = Describe("Fetcher", func() { + Describe("FetchLogs", func() { + var blockChain *fakes.MockBlockChain + var fetcher every_block.Fetcher + + BeforeEach(func() { + blockChain = fakes.NewMockBlockChain() + fetcher = every_block.Fetcher{Blockchain: blockChain} + }) + + It("fetches logs based on the given query", func() { + blockNumber := int64(3) + address := "0x4D2" + topicZeros := [][]common.Hash{{common.HexToHash("0x")}} + + query := ethereum.FilterQuery{ + FromBlock: big.NewInt(blockNumber), + ToBlock: big.NewInt(blockNumber), + Addresses: []common.Address{common.HexToAddress(address)}, + Topics: topicZeros, + } + fetcher.FetchLogs(address, topicZeros, blockNumber) + blockChain.AssertGetEthLogsWithCustomQueryCalledWith(query) + + }) + + It("returns an error if fetching the logs fails", func() { + blockChain.SetGetLogsErr(fakes.FakeError) + _, err := fetcher.FetchLogs("", [][]common.Hash{}, int64(1)) + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(fakes.FakeError)) + }) + }) +}) diff --git a/libraries/maker/every_block/integration_test.go b/libraries/maker/every_block/integration_test.go new file mode 100644 index 00000000..5ac55921 --- /dev/null +++ b/libraries/maker/every_block/integration_test.go @@ -0,0 +1,90 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block_test + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/libraries/maker/test_data" + "github.com/vulcanize/vulcanizedb/pkg/geth" + "github.com/vulcanize/vulcanizedb/pkg/geth/client" + rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc" + "github.com/vulcanize/vulcanizedb/pkg/geth/node" +) + +var _ = Describe("Integration tests", func() { + + It("Fetches FlipKickEntity event logs from a local test chain", func() { + ipcPath := "http://127.0.0.1:7545" + + rawRpcClient, err := rpc.Dial(ipcPath) + Expect(err).NotTo(HaveOccurred()) + + rpcClient := client.NewRpcClient(rawRpcClient, ipcPath) + ethClient := ethclient.NewClient(rawRpcClient) + blockChainClient := client.NewEthClient(ethClient) + realNode := node.MakeNode(rpcClient) + transactionConverter := rpc2.NewRpcTransactionConverter(ethClient) + realBlockChain := geth.NewBlockChain(blockChainClient, realNode, transactionConverter) + realFetcher := every_block.NewFetcher(realBlockChain) + topic0 := common.HexToHash(every_block.FlipKickSignature) + topics := [][]common.Hash{{topic0}} + + result, err := realFetcher.FetchLogs(test_data.TemporaryFlipAddress, topics, int64(10)) + Expect(err).NotTo(HaveOccurred()) + + Expect(len(result) > 0).To(BeTrue()) + Expect(result[0].Address).To(Equal(test_data.EthFlipKickLog.Address)) + Expect(result[0].TxHash).To(Equal(test_data.EthFlipKickLog.TxHash)) + Expect(result[0].BlockNumber).To(Equal(test_data.EthFlipKickLog.BlockNumber)) + Expect(result[0].Topics).To(Equal(test_data.EthFlipKickLog.Topics)) + Expect(result[0].Index).To(Equal(test_data.EthFlipKickLog.Index)) + Expect(result[0].Data).To(Equal(test_data.EthFlipKickLog.Data)) + }) + + It("unpacks an event log", func() { + address := common.HexToAddress(test_data.TemporaryFlipAddress) + abi, err := geth.ParseAbi(every_block.FlipperABI) + Expect(err).NotTo(HaveOccurred()) + + contract := bind.NewBoundContract(address, abi, nil, nil, nil) + entity := &every_block.FlipKickEntity{} + + var eventLog = test_data.EthFlipKickLog + + err = contract.UnpackLog(entity, "FlipKick", eventLog) + Expect(err).NotTo(HaveOccurred()) + + expectedEntity := test_data.FlipKickEntity + Expect(entity.Id).To(Equal(expectedEntity.Id)) + Expect(entity.Mom).To(Equal(expectedEntity.Mom)) + Expect(entity.Vat).To(Equal(expectedEntity.Vat)) + Expect(entity.Ilk).To(Equal(expectedEntity.Ilk)) + Expect(entity.Lot).To(Equal(expectedEntity.Lot)) + Expect(entity.Bid.String()).To(Equal(expectedEntity.Bid.String())) //FIXME + Expect(entity.Guy).To(Equal(expectedEntity.Guy)) + Expect(entity.Gal).To(Equal(expectedEntity.Gal)) + Expect(entity.End).To(Equal(expectedEntity.End)) + Expect(entity.Era).To(Equal(expectedEntity.Era)) + Expect(entity.Lad).To(Equal(expectedEntity.Lad)) + Expect(entity.Tab).To(Equal(expectedEntity.Tab)) + }) +}) diff --git a/libraries/maker/every_block/model.go b/libraries/maker/every_block/model.go new file mode 100644 index 00000000..5cf8bdbd --- /dev/null +++ b/libraries/maker/every_block/model.go @@ -0,0 +1,32 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import "time" + +type FlipKickModel struct { + Id string + Mom string + Vat string + Ilk string + Lot string + Bid string + Guy string + Gal string + End time.Time + Era time.Time + Lad string + Tab string +} diff --git a/libraries/maker/every_block/repository.go b/libraries/maker/every_block/repository.go new file mode 100644 index 00000000..e22ef6f5 --- /dev/null +++ b/libraries/maker/every_block/repository.go @@ -0,0 +1,71 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import ( + "fmt" + + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" +) + +type Repository interface { + Create(headerId int64, flipKick FlipKickModel) error + MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) +} + +type FlipKickRepository struct { + DB *postgres.DB +} + +func NewFlipKickRepository(db *postgres.DB) FlipKickRepository { + return FlipKickRepository{DB: db} +} +func (fkr FlipKickRepository) Create(headerId int64, flipKick FlipKickModel) error { + _, err := fkr.DB.Exec( + `INSERT into maker.flip_kick (header_id, id, mom, vat, ilk, lot, bid, guy, gal, "end", era, lad, tab) + VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, + headerId, flipKick.Id, flipKick.Mom, flipKick.Vat, flipKick.Ilk, flipKick.Lot, flipKick.Bid, flipKick.Guy, flipKick.Gal, flipKick.End, flipKick.Era, flipKick.Lad, flipKick.Tab, + ) + + if err != nil { + return err + } + + return nil +} + +func (fkr FlipKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { + var result []core.Header + err := fkr.DB.Select( + &result, + `SELECT headers.id, headers.block_number FROM headers + LEFT JOIN maker.flip_kick on headers.id = header_id + WHERE header_id ISNULL + AND headers.block_number >= $1 + AND headers.block_number <= $2 + AND headers.eth_node_fingerprint = $3`, + startingBlockNumber, + endingBlockNumber, + fkr.DB.Node.ID, + ) + + if err != nil { + fmt.Println("Error:", err) + return result, err + } + + return result, nil +} diff --git a/libraries/maker/every_block/repository_test.go b/libraries/maker/every_block/repository_test.go new file mode 100644 index 00000000..e7e77118 --- /dev/null +++ b/libraries/maker/every_block/repository_test.go @@ -0,0 +1,176 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block_test + +import ( + "math/rand" + + "github.com/ethereum/go-ethereum/common" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/libraries/maker/test_data" + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" + "github.com/vulcanize/vulcanizedb/pkg/test_helpers" + "github.com/vulcanize/vulcanizedb/test_config" +) + +var _ = Describe("FlipKick Repository", func() { + var db *postgres.DB + var flipKickRepository every_block.FlipKickRepository + var headerId int64 + var blockNumber int64 + var flipKick = test_data.FlipKickModel + + BeforeEach(func() { + db = test_helpers.CreateNewDatabase() + flipKickRepository = every_block.FlipKickRepository{DB: db} + blockNumber = rand.Int63() + headerId = createHeader(db, blockNumber) + + _, err := db.Exec(`DELETE from maker.flip_kick;`) + Expect(err).NotTo(HaveOccurred()) + }) + + Describe("Create", func() { + AfterEach(func() { + _, err := db.Exec(`DELETE from headers;`) + Expect(err).NotTo(HaveOccurred()) + }) + + It("persists a flip_kick record", func() { + err := flipKickRepository.Create(headerId, flipKick) + Expect(err).NotTo(HaveOccurred()) + + assertDBRecordCount(db, "maker.flip_kick", 1) + + dbResult := test_data.FlipKickDBRow{} + err = flipKickRepository.DB.QueryRowx(`SELECT * FROM maker.flip_kick`).StructScan(&dbResult) + Expect(err).NotTo(HaveOccurred()) + Expect(dbResult.HeaderId).To(Equal(headerId)) + Expect(dbResult.Id).To(Equal(flipKick.Id)) + Expect(dbResult.Mom).To(Equal(flipKick.Mom)) + Expect(dbResult.Vat).To(Equal(flipKick.Vat)) + Expect(dbResult.Ilk).To(Equal(flipKick.Ilk)) + Expect(dbResult.Lot).To(Equal(flipKick.Lot)) + Expect(dbResult.Bid).To(Equal(flipKick.Bid)) + Expect(dbResult.Guy).To(Equal(flipKick.Guy)) + Expect(dbResult.Gal).To(Equal(flipKick.Gal)) + Expect(dbResult.End.Equal(flipKick.End)).To(BeTrue()) + Expect(dbResult.Era.Equal(flipKick.Era)).To(BeTrue()) + Expect(dbResult.Lad).To(Equal(flipKick.Lad)) + Expect(dbResult.Tab).To(Equal(flipKick.Tab)) + }) + + It("returns an error if inserting the flip_kick record fails", func() { + err := flipKickRepository.Create(headerId, test_data.FlipKickModel) + Expect(err).NotTo(HaveOccurred()) + + err = flipKickRepository.Create(headerId, test_data.FlipKickModel) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) + }) + + It("deletes the flip_kick records if its corresponding header record is deleted", func() { + err := flipKickRepository.Create(headerId, test_data.FlipKickModel) + Expect(err).NotTo(HaveOccurred()) + assertDBRecordCount(db, "maker.flip_kick", 1) + assertDBRecordCount(db, "headers", 1) + + _, err = db.Exec(`DELETE FROM headers where id = $1`, headerId) + Expect(err).NotTo(HaveOccurred()) + + assertDBRecordCount(db, "headers", 0) + assertDBRecordCount(db, "maker.flip_kick", 0) + }) + }) + + Describe("When there are multiple nodes", func() { + var db2 *postgres.DB + var flipKickRepository2 every_block.FlipKickRepository + var headerId2 int64 + + BeforeEach(func() { + //create database for the second node + node2 := core.Node{ + GenesisBlock: "GENESIS", + NetworkID: 1, + ID: "node2", + ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9", + } + db2 = test_config.NewTestDBWithoutDeletingRecords(node2) + flipKickRepository2 = every_block.FlipKickRepository{DB: db2} + headerId2 = createHeader(db2, blockNumber) + + _, err := db2.Exec(`DELETE from maker.flip_kick;`) + Expect(err).NotTo(HaveOccurred()) + }) + + It("only includes missing headers for the current node", func() { + node1missingHeaders, err := flipKickRepository.MissingHeaders(blockNumber, blockNumber) + Expect(err).NotTo(HaveOccurred()) + Expect(len(node1missingHeaders)).To(Equal(1)) + + node2MissingHeaders, err := flipKickRepository2.MissingHeaders(blockNumber, blockNumber) + Expect(err).NotTo(HaveOccurred()) + Expect(len(node2MissingHeaders)).To(Equal(1)) + }) + }) + + Describe("MissingHeaders", func() { + It("returns headers for which there isn't an associated flip_kick record", func() { + startingBlock := blockNumber - 3 + endingBlock := blockNumber + 3 + + err := flipKickRepository.Create(headerId, test_data.FlipKickModel) + Expect(err).NotTo(HaveOccurred()) + + newBlockNumber := blockNumber + 3 + newHeaderId := createHeader(db, newBlockNumber) + createHeader(db, blockNumber+10) //this one is out of the block range and shouldn't be included + headers, err := flipKickRepository.MissingHeaders(startingBlock, endingBlock) + Expect(len(headers)).To(Equal(1)) + Expect(headers[0].Id).To(Equal(newHeaderId)) + Expect(headers[0].BlockNumber).To(Equal(newBlockNumber)) + }) + }) +}) + +func assertDBRecordCount(db *postgres.DB, dbTable string, expectedCount int) { + var count int + query := `SELECT count(*) FROM ` + dbTable + err := db.QueryRow(query).Scan(&count) + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedCount)) +} + +func createHeader(db *postgres.DB, blockNumber int64) (headerId int64) { + headerRepository := repositories.NewHeaderRepository(db) + header := core.Header{ + BlockNumber: blockNumber, + Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(), + Raw: []byte{1, 2, 3, 4, 5}, + } + _, err := headerRepository.CreateOrUpdateHeader(header) + Expect(err).NotTo(HaveOccurred()) + + var dbHeader core.Header + err = db.Get(&dbHeader, `SELECT id, block_number, hash, raw FROM public.headers WHERE block_number = $1 AND eth_node_id = $2`, header.BlockNumber, db.NodeID) + Expect(err).NotTo(HaveOccurred()) + return dbHeader.Id +} diff --git a/libraries/maker/every_block/transformer.go b/libraries/maker/every_block/transformer.go new file mode 100644 index 00000000..e98ce456 --- /dev/null +++ b/libraries/maker/every_block/transformer.go @@ -0,0 +1,126 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import ( + "errors" + "fmt" + "log" + + "github.com/ethereum/go-ethereum/common" + + "github.com/vulcanize/vulcanizedb/libraries/shared" + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" +) + +type FlipKickTransformer struct { + Fetcher LogFetcher + Converter Converter + Repository Repository + Config TransformerConfig +} + +type FlipKickTransformerInitializer struct { + Config TransformerConfig +} + +func (i FlipKickTransformerInitializer) NewFlipKickTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer { + fetcher := NewFetcher(blockChain) + repository := NewFlipKickRepository(db) + transformer := FlipKickTransformer{ + Fetcher: fetcher, + Repository: repository, + Converter: FlipKickConverter{}, + Config: i.Config, + } + + return transformer +} + +func (fkt *FlipKickTransformer) SetConfig(config TransformerConfig) { + fkt.Config = config +} + +const ( + FetcherError = "Error fetching FlipKick log events for block number %d: %s" + LogToEntityError = "Error converting eth log to FlipKick entity for block number %d: %s" + EntityToModelError = "Error converting eth log to FlipKick entity for block number %d: %s" + RepositoryError = "Error creating flip_kick record for block number %d: %s" + TransformerError = "There has been %d error(s) transforming FlipKick event logs, see the logs for more details." +) + +type transformerError struct { + err string + blockNumber int64 + msg string +} + +func (te *transformerError) Error() string { + return fmt.Sprintf(te.msg, te.blockNumber, te.err) +} + +func newTransformerError(err error, blockNumber int64, msg string) error { + e := transformerError{err.Error(), blockNumber, msg} + log.Println(e.Error()) + return &e +} + +func (fkt FlipKickTransformer) Execute() error { + config := fkt.Config + topics := [][]common.Hash{{common.HexToHash(FlipKickSignature)}} + + headers, err := fkt.Repository.MissingHeaders(config.StartingBlockNumber, config.EndingBlockNumber) + if err != nil { + log.Println("Error:", err) + return err + } + + log.Printf("Fetching event logs for %d headers \n", len(headers)) + var resultingErrors []error + for _, header := range headers { + ethLogs, err := fkt.Fetcher.FetchLogs(config.ContractAddress, topics, header.BlockNumber) + if err != nil { + resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, FetcherError)) + } + + for _, ethLog := range ethLogs { + entity, err := fkt.Converter.ToEntity(config.ContractAddress, config.ContractAbi, ethLog) + if err != nil { + resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, LogToEntityError)) + } + model, err := fkt.Converter.ToModel(*entity) + if err != nil { + resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, EntityToModelError)) + } + + err = fkt.Repository.Create(header.Id, model) + if err != nil { + resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, RepositoryError)) + } + } + } + + if len(resultingErrors) > 0 { + for _, err := range resultingErrors { + log.Println(err) + } + + msg := fmt.Sprintf(TransformerError, len(resultingErrors)) + return errors.New(msg) + } + + return nil +} diff --git a/libraries/maker/every_block/transformer_test.go b/libraries/maker/every_block/transformer_test.go new file mode 100644 index 00000000..d7e75360 --- /dev/null +++ b/libraries/maker/every_block/transformer_test.go @@ -0,0 +1,142 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block_test + +import ( + "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/libraries/maker/test_data" + "github.com/vulcanize/vulcanizedb/pkg/core" + "github.com/vulcanize/vulcanizedb/pkg/fakes" +) + +var _ = Describe("FlipKick Transformer", func() { + var transformer every_block.FlipKickTransformer + var fetcher test_data.MockLogFetcher + var converter test_data.MockFlipKickConverter + var repository test_data.MockFlipKickRepository + var testConfig every_block.TransformerConfig + var blockNumber int64 + var headerId int64 + var headers []core.Header + var logs []types.Log + + BeforeEach(func() { + fetcher = test_data.MockLogFetcher{} + converter = test_data.MockFlipKickConverter{} + repository = test_data.MockFlipKickRepository{} + transformer = every_block.FlipKickTransformer{ + Fetcher: &fetcher, + Converter: &converter, + Repository: &repository, + } + + startingBlockNumber := rand.Int63() + testConfig = every_block.TransformerConfig{ + ContractAddress: "0x12345", + ContractAbi: "test abi", + Topics: []string{every_block.FlipKickSignature}, + StartingBlockNumber: startingBlockNumber, + EndingBlockNumber: startingBlockNumber + 5, + } + transformer.SetConfig(testConfig) + + blockNumber = rand.Int63() + headerId = rand.Int63() + headers = []core.Header{{ + Id: headerId, + BlockNumber: blockNumber, + Hash: "0x", + Raw: nil, + }} + + repository.SetHeadersToReturn(headers) + + logs = []types.Log{test_data.EthFlipKickLog} + fetcher.SetFetchedLogs(logs) + }) + + It("fetches logs with the configured contract and topic(s) for each block", func() { + expectedTopics := [][]common.Hash{{common.HexToHash(every_block.FlipKickSignature)}} + + err := transformer.Execute() + Expect(err).NotTo(HaveOccurred()) + + Expect(fetcher.FetchedContractAddress).To(Equal(testConfig.ContractAddress)) + Expect(fetcher.FetchedTopics).To(Equal(expectedTopics)) + Expect(fetcher.FetchedBlocks).To(Equal([]int64{blockNumber})) + }) + + It("returns an error if the fetcher fails", func() { + fetcher.SetFetcherError(fakes.FakeError) + + err := transformer.Execute() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error(s) transforming FlipKick event logs")) + }) + + It("converts the logs", func() { + err := transformer.Execute() + Expect(err).NotTo(HaveOccurred()) + + Expect(converter.ConverterContract).To(Equal(testConfig.ContractAddress)) + Expect(converter.ConverterAbi).To(Equal(testConfig.ContractAbi)) + Expect(converter.LogsToConvert).To(Equal(logs)) + Expect(converter.EntitiesToConvert).To(Equal([]every_block.FlipKickEntity{test_data.FlipKickEntity})) + }) + + It("returns an error if converting the geth log fails", func() { + converter.SetConverterError(fakes.FakeError) + + err := transformer.Execute() + Expect(err).To(HaveOccurred()) + }) + + It("persists a flip_kick record", func() { + err := transformer.Execute() + Expect(err).NotTo(HaveOccurred()) + + Expect(repository.HeaderIds).To(Equal([]int64{headerId})) + Expect(repository.FlipKicksCreated).To(Equal([]every_block.FlipKickModel{test_data.FlipKickModel})) + }) + + It("returns an error if persisting a record fails", func() { + repository.SetCreateRecordError(fakes.FakeError) + + err := transformer.Execute() + Expect(err).To(HaveOccurred()) + }) + + It("returns an error if fetching missing headers fails", func() { + repository.SetMissingHeadersError(fakes.FakeError) + + err := transformer.Execute() + Expect(err).To(HaveOccurred()) + }) + + It("gets missing headers for blocks between the configured block number range", func() { + err := transformer.Execute() + Expect(err).NotTo(HaveOccurred()) + + Expect(repository.StartingBlockNumber).To(Equal(testConfig.StartingBlockNumber)) + Expect(repository.EndingBlockNumber).To(Equal(testConfig.EndingBlockNumber)) + }) +}) diff --git a/libraries/maker/every_block/transformers.go b/libraries/maker/every_block/transformers.go new file mode 100644 index 00000000..87133fa5 --- /dev/null +++ b/libraries/maker/every_block/transformers.go @@ -0,0 +1,27 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package every_block + +import ( + "github.com/vulcanize/vulcanizedb/libraries/shared" +) + +func TransformerInitializers() []shared.TransformerInitializer { + config := FlipKickConfig + initializer := FlipKickTransformerInitializer{Config: config} + return []shared.TransformerInitializer{ + initializer.NewFlipKickTransformer, + } +} diff --git a/libraries/maker/start_test_chain.sh b/libraries/maker/start_test_chain.sh new file mode 100755 index 00000000..c9004043 --- /dev/null +++ b/libraries/maker/start_test_chain.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +MNEMONIC_PHRASE="whisper ordinary mystery awesome wood fox auction february blind volcano spare soft" +PORT=7545 +DATABASE_PATH=libraries/maker/test_data/test_chain/ +echo Starting ganache chain on port $PORT... + +ganache-cli --port $PORT \ + --db $DATABASE_PATH \ + 2>&1 > ganache-output.log & diff --git a/libraries/maker/stop_test_chain.sh b/libraries/maker/stop_test_chain.sh new file mode 100755 index 00000000..ea88d76a --- /dev/null +++ b/libraries/maker/stop_test_chain.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "Stopping ganache chain on port 7545" +ps -ef | grep ganache | grep -v grep | awk '{print $2}' | xargs kill \ No newline at end of file diff --git a/libraries/maker/test_data/flip_kick.go b/libraries/maker/test_data/flip_kick.go new file mode 100644 index 00000000..3de463fc --- /dev/null +++ b/libraries/maker/test_data/flip_kick.go @@ -0,0 +1,98 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test_data + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "math/big" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "time" +) + +var TemporaryFlipAddress = "0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d" +var TemporaryFlipKickTransaction = "0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191" +var Topic0Hex = "0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3" +var TemporaryFlipKickData = "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000008cb6176addcca2e1d1ffe21bee464b72ee4cd8d00000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d922894153be9eef7b7218dc565d1d0ce2a09200000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000005b69b8e7000000000000000000000000000000000000000000000000000000005b607e670000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca0000000000000000000000000000000000000000000000000000000000000032" +var TempBlockNumber = int64(10) +var TemporaryFlipKickBlockNumber = int64(TempBlockNumber) +var TemporaryFlipKickBlockHash = "0x32f8b12023b3a1b4c73f9a46da976931b0355714ada8b8044ebcb2cd295751a9" + +var idString = "1" +var id, _ = new(big.Int).SetString(idString, 10) +var mom = "0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d" +var vat = "0x38219779a699d67d7e7740b8c8f43d3e2dae2182" +var ilk = [32]byte{102, 97, 107, 101, 32, 105, 108, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +var lotString = "100" +var lot, _ = new(big.Int).SetString(lotString, 10) +var bidString = "0" +var bid = new(big.Int).SetBytes([]byte{0}) +var guy = "0x64d922894153be9eef7b7218dc565d1d0ce2a092" +var gal = "0x07fa9ef6609ca7921112231f8f195138ebba2977" +var end = int64(1533655271) +var era = int64(1533050471) +var lad = "0x7340e006f4135ba6970d43bf43d88dcad4e7a8ca" +var tabString = "50" +var tab, _ = new(big.Int).SetString(tabString, 10) + +var EthFlipKickLog = types.Log{ + Address: common.HexToAddress(TemporaryFlipAddress), + Topics: []common.Hash{common.HexToHash(every_block.FlipKickSignature)}, + Data: hexutil.MustDecode(TemporaryFlipKickData), + BlockNumber: uint64(TempBlockNumber), + TxHash: common.HexToHash(TemporaryFlipKickTransaction), + TxIndex: 0, + BlockHash: common.HexToHash(TemporaryFlipKickBlockHash), + Index: 0, + Removed: false, +} + +var FlipKickEntity = every_block.FlipKickEntity{ + Id: id, + Mom: common.HexToAddress(mom), + Vat: common.HexToAddress(vat), + Ilk: ilk, + Lot: lot, + Bid: bid, + Guy: common.HexToAddress(guy), + Gal: common.HexToAddress(gal), + End: big.NewInt(end), + Era: big.NewInt(era), + Lad: common.HexToAddress(lad), + Tab: tab, +} + +var FlipKickModel = every_block.FlipKickModel{ + Id: idString, + Mom: mom, + Vat: vat, + Ilk: "0x" + common.Bytes2Hex(ilk[:]), + Lot: lotString, + Bid: bidString, + Guy: guy, + Gal: gal, + End: time.Unix(end, 0), + Era: time.Unix(era, 0), + Lad: lad, + Tab: tabString, +} + +type FlipKickDBRow struct { + DbID int64 `db:"db_id"` + HeaderId int64 `db:"header_id"` + every_block.FlipKickModel +} diff --git a/libraries/maker/test_data/mocks.go b/libraries/maker/test_data/mocks.go new file mode 100644 index 00000000..a18d2e41 --- /dev/null +++ b/libraries/maker/test_data/mocks.go @@ -0,0 +1,105 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test_data + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/vulcanize/vulcanizedb/libraries/maker/every_block" + "github.com/vulcanize/vulcanizedb/pkg/core" +) + +type MockLogFetcher struct { + FetchedContractAddress string + FetchedTopics [][]common.Hash + FetchedBlocks []int64 + FetcherError error + FetchedLogs []types.Log +} + +func (mlf *MockLogFetcher) FetchLogs(contractAddress string, topics [][]common.Hash, blockNumber int64) ([]types.Log, error) { + mlf.FetchedContractAddress = contractAddress + mlf.FetchedTopics = topics + mlf.FetchedBlocks = append(mlf.FetchedBlocks, blockNumber) + + return mlf.FetchedLogs, mlf.FetcherError +} + +func (mlf *MockLogFetcher) SetFetcherError(err error) { + mlf.FetcherError = err +} + +func (mlf *MockLogFetcher) SetFetchedLogs(logs []types.Log) { + mlf.FetchedLogs = logs +} + +type MockFlipKickConverter struct { + ConverterContract string + ConverterAbi string + LogsToConvert []types.Log + EntitiesToConvert []every_block.FlipKickEntity + ConverterError error +} + +func (mfkc *MockFlipKickConverter) ToEntity(contractAddress string, contractAbi string, ethLog types.Log) (*every_block.FlipKickEntity, error) { + mfkc.ConverterContract = contractAddress + mfkc.ConverterAbi = contractAbi + mfkc.LogsToConvert = append(mfkc.LogsToConvert, ethLog) + return &FlipKickEntity, mfkc.ConverterError +} + +func (mfkc *MockFlipKickConverter) ToModel(flipKick every_block.FlipKickEntity) (every_block.FlipKickModel, error) { + mfkc.EntitiesToConvert = append(mfkc.EntitiesToConvert, flipKick) + return FlipKickModel, nil +} +func (mfkc *MockFlipKickConverter) SetConverterError(err error) { + mfkc.ConverterError = err +} + +type MockFlipKickRepository struct { + HeaderIds []int64 + HeadersToReturn []core.Header + StartingBlockNumber int64 + EndingBlockNumber int64 + FlipKicksCreated []every_block.FlipKickModel + CreateRecordError error + MissingHeadersError error +} + +func (mfkr *MockFlipKickRepository) Create(headerId int64, flipKick every_block.FlipKickModel) error { + mfkr.HeaderIds = append(mfkr.HeaderIds, headerId) + mfkr.FlipKicksCreated = append(mfkr.FlipKicksCreated, flipKick) + + return mfkr.CreateRecordError +} + +func (mfkr *MockFlipKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { + mfkr.StartingBlockNumber = startingBlockNumber + mfkr.EndingBlockNumber = endingBlockNumber + + return mfkr.HeadersToReturn, mfkr.MissingHeadersError +} + +func (mfkr *MockFlipKickRepository) SetHeadersToReturn(headers []core.Header) { + mfkr.HeadersToReturn = headers +} + +func (mfkr *MockFlipKickRepository) SetCreateRecordError(err error) { + mfkr.CreateRecordError = err +} +func (mfkr *MockFlipKickRepository) SetMissingHeadersError(err error) { + mfkr.MissingHeadersError = err +} diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x2c3b96f821a6abe12061036d3f90e3a04f72eb3b06952a1b0d8916bff0103406 b/libraries/maker/test_data/test_chain/!blockHashes!0x2c3b96f821a6abe12061036d3f90e3a04f72eb3b06952a1b0d8916bff0103406 new file mode 100644 index 00000000..e440e5c8 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x2c3b96f821a6abe12061036d3f90e3a04f72eb3b06952a1b0d8916bff0103406 @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44 b/libraries/maker/test_data/test_chain/!blockHashes!0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44 new file mode 100644 index 00000000..f11c82a4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44 @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x4e22a16f36c4579b10db23891796b93ec0452791bf24426836837fc420bec9b7 b/libraries/maker/test_data/test_chain/!blockHashes!0x4e22a16f36c4579b10db23891796b93ec0452791bf24426836837fc420bec9b7 new file mode 100644 index 00000000..c7930257 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x4e22a16f36c4579b10db23891796b93ec0452791bf24426836837fc420bec9b7 @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd b/libraries/maker/test_data/test_chain/!blockHashes!0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd new file mode 100644 index 00000000..9a037142 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x76443e96ab64087485c83dcaf3ed15ad5303b23393957f075901dab7cdefdef8 b/libraries/maker/test_data/test_chain/!blockHashes!0x76443e96ab64087485c83dcaf3ed15ad5303b23393957f075901dab7cdefdef8 new file mode 100644 index 00000000..301160a9 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x76443e96ab64087485c83dcaf3ed15ad5303b23393957f075901dab7cdefdef8 @@ -0,0 +1 @@ +8 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a b/libraries/maker/test_data/test_chain/!blockHashes!0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a new file mode 100644 index 00000000..56a6051c --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789 b/libraries/maker/test_data/test_chain/!blockHashes!0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789 new file mode 100644 index 00000000..bf0d87ab --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789 @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0x92df7e05e7e8c221851b23ef4ce61671ef7b2df3cbd1b5fb0b5b4735803484d2 b/libraries/maker/test_data/test_chain/!blockHashes!0x92df7e05e7e8c221851b23ef4ce61671ef7b2df3cbd1b5fb0b5b4735803484d2 new file mode 100644 index 00000000..c2270834 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0x92df7e05e7e8c221851b23ef4ce61671ef7b2df3cbd1b5fb0b5b4735803484d2 @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a b/libraries/maker/test_data/test_chain/!blockHashes!0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a new file mode 100644 index 00000000..d8263ee9 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0xe3f5f15620f4599a82eba709537542c5db00c2f03f1863646bc2633f80b1a549 b/libraries/maker/test_data/test_chain/!blockHashes!0xe3f5f15620f4599a82eba709537542c5db00c2f03f1863646bc2633f80b1a549 new file mode 100644 index 00000000..7813681f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0xe3f5f15620f4599a82eba709537542c5db00c2f03f1863646bc2633f80b1a549 @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockHashes!0xea660033df6296bce69b24ca2e91556f1d9c5f6c6e9c4ee5ea9877426b6fc893 b/libraries/maker/test_data/test_chain/!blockHashes!0xea660033df6296bce69b24ca2e91556f1d9c5f6c6e9c4ee5ea9877426b6fc893 new file mode 100644 index 00000000..62f94575 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockHashes!0xea660033df6296bce69b24ca2e91556f1d9c5f6c6e9c4ee5ea9877426b6fc893 @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!0 b/libraries/maker/test_data/test_chain/!blockLogs!0 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!0 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!1 b/libraries/maker/test_data/test_chain/!blockLogs!1 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!1 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!10 b/libraries/maker/test_data/test_chain/!blockLogs!10 new file mode 100644 index 00000000..382678ea --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!10 @@ -0,0 +1 @@ +[{"logIndex":"0x0","transactionIndex":"0x0","transactionHash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191","blockHash":"0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd","blockNumber":"0xa","address":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000008cb6176addcca2e1d1ffe21bee464b72ee4cd8d00000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d922894153be9eef7b7218dc565d1d0ce2a09200000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000005b69b8e7000000000000000000000000000000000000000000000000000000005b607e670000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca0000000000000000000000000000000000000000000000000000000000000032","topics":["0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3"],"type":"mined"}] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!2 b/libraries/maker/test_data/test_chain/!blockLogs!2 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!2 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!3 b/libraries/maker/test_data/test_chain/!blockLogs!3 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!3 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!4 b/libraries/maker/test_data/test_chain/!blockLogs!4 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!4 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!5 b/libraries/maker/test_data/test_chain/!blockLogs!5 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!5 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!6 b/libraries/maker/test_data/test_chain/!blockLogs!6 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!6 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!7 b/libraries/maker/test_data/test_chain/!blockLogs!7 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!7 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!8 b/libraries/maker/test_data/test_chain/!blockLogs!8 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!8 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!9 b/libraries/maker/test_data/test_chain/!blockLogs!9 new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!9 @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blockLogs!length b/libraries/maker/test_data/test_chain/!blockLogs!length new file mode 100644 index 00000000..9d607966 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blockLogs!length @@ -0,0 +1 @@ +11 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!0 b/libraries/maker/test_data/test_chain/!blocks!0 new file mode 100644 index 00000000..cce4149d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!0 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0xafc7c6a8161d69dc1b082bbf799d38f88c2f251a7504b87039b2a4f682cbf323","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x","gasLimit":"0x6691b7","gasUsed":"0x","timestamp":"0x5b607bcc","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!1 b/libraries/maker/test_data/test_chain/!blocks!1 new file mode 100644 index 00000000..04ddce2d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!1 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x92df7e05e7e8c221851b23ef4ce61671ef7b2df3cbd1b5fb0b5b4735803484d2","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x1cf5126fea51794b0db1435d14bd933683c230379908b9899391e70c1bdfbe14","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x01","gasLimit":"0x6691b7","gasUsed":"0x043bd6","timestamp":"0x5b607bda","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820167320a3f0aefab2d9d7492779c69a7f6bbea970d8290e17d3631fbed9ad93540029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!10 b/libraries/maker/test_data/test_chain/!blocks!10 new file mode 100644 index 00000000..c5cffa8d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!10 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x50b3886d0b373a1bec1077a101dfbf8cdf97373f7698dc90befabe95a62c18d0","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000020000000000000000080000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000","difficulty":"0x","number":"0x0a","gasLimit":"0x6691b7","gasUsed":"0x027c77","timestamp":"0x5b607e67","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x","gasPrice":"0x01","gasLimit":"0x44aa20","to":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","value":"0x","data":"0x351de6000000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca00000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000","v":"0x1c","r":"0x","s":"0x","from":"0x64d922894153be9eef7b7218dc565d1d0ce2a092","hash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!2 b/libraries/maker/test_data/test_chain/!blocks!2 new file mode 100644 index 00000000..5d96f380 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!2 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x3ad54ef88f031c776dcc858e4339ee689f634fb929d7ac5d9ceec36c15b2779e","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x02","gasLimit":"0x6691b7","gasUsed":"0xa418","timestamp":"0x5b607bda","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x01","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000001","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!3 b/libraries/maker/test_data/test_chain/!blocks!3 new file mode 100644 index 00000000..95e0492b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!3 @@ -0,0 +1 @@ +{"header":{"parentHash":"0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x3ec08de1b6fc2f56324ce3a496f6945898622e7b8e875feb74d0578b18f6730c","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x03","gasLimit":"0x6691b7","gasUsed":"0x010cba","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x02","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820562865e6c1f558e8a54735c0ff54b7f6a1fbc65c540a84c894f17a5fec64110d0029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!4 b/libraries/maker/test_data/test_chain/!blocks!4 new file mode 100644 index 00000000..6b7d2824 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!4 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x2c3b96f821a6abe12061036d3f90e3a04f72eb3b06952a1b0d8916bff0103406","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x014d823cc965c37ad6f570144cfa40059711516c16ac27e18c85f8ba8d41b37a","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x04","gasLimit":"0x6691b7","gasUsed":"0x18b018","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x03","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506116ce806100606000396000f3006080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806311045bee14610101578063143e55e0146101865780632424be5c146101c15780632d61a355146102345780634186706d1461025f578063673c17da146102c45780636c25b3461461032957806371854745146103805780637cdd3fde146103e5578063815d245d14610440578063a4593c5214610489578063b65337df146104ee578063bb35783b14610549578063d9638d36146105b6578063dc42e30914610602578063ebf0c7171461062d578063ee8cd74814610684578063f059212a146106f1575b600080fd5b34801561010d57600080fd5b506101846004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610748565b005b34801561019257600080fd5b5061019b610999565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b3480156101cd57600080fd5b506102106004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109a1565b60405180848152602001838152602001828152602001935050505060405180910390f35b34801561024057600080fd5b506102496109d8565b6040518082815260200191505060405180910390f35b34801561026b57600080fd5b506102ae6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109de565b6040518082815260200191505060405180910390f35b3480156102d057600080fd5b506103136004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a44565b6040518082815260200191505060405180910390f35b34801561033557600080fd5b5061036a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610aaa565b6040518082815260200191505060405180910390f35b34801561038c57600080fd5b506103cf6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ac2565b6040518082815260200191505060405180910390f35b3480156103f157600080fd5b5061043e6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b28565b005b34801561044c57600080fd5b506104876004803603810190808035600019169060200190929190803560001916906020019092919080359060200190929190505050610bf1565b005b34801561049557600080fd5b506104ec6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610c46565b005b3480156104fa57600080fd5b506105476004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eac565b005b34801561055557600080fd5b506105b4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105e565b005b3480156105c257600080fd5b506105e56004803603810190808035600019169060200190929190505050611268565b604051808381526020018281526020019250505060405180910390f35b34801561060e57600080fd5b5061061761128c565b6040518082815260200191505060405180910390f35b34801561063957600080fd5b50610642611292565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561069057600080fd5b506106ef600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506112b7565b005b3480156106fd57600080fd5b50610732600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061157d565b6040518082815260200191505060405180910390f35b60008060046000886000191660001916815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020915060036000886000191660001916815260200190815260200160002090506107d0826001015485611595565b82600101819055506107e6826002015484611595565b82600201819055506107fc816001015484611595565b816001018190555061085a600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546108558360000154866115d6565b61165c565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108b66006546108b18360000154866115d6565b61165c565b6006819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b830866108ed8460000154876115d6565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f6772616200000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a150505050505050565b600042905090565b6004602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154905083565b60065481565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905092915050565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154905092915050565b60016020528060005260406000206000915090505481565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b610b8d60046000856000191660001916815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015482611595565b60046000856000191660001916815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550505050565b7f726174650000000000000000000000000000000000000000000000000000000082600019161415610c415780600360008560001916600019168152602001908152602001600020600001819055505b505050565b60008060046000876000191660001916815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091506003600087600019166000191681526020019081526020016000209050610cce82600001548561165c565b8260000181905550610ce4826001015485611595565b8260010181905550610cfa826002015484611595565b8260020181905550610d10816001015484611595565b8160010181905550610d6e600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d698360000154866115d6565b611595565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dca600554610dc58360000154866115d6565b611595565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b83086610e018460000154876115d6565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f74756e6500000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a1505050505050565b6000806003600086600019166000191681526020019081526020016000209150610eda826000015484611595565b8260000181905550610ef08260010154846115d6565b9050610f3b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611595565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f8a60055482611595565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b8308583604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f666f6c6400000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a15050505050565b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054121515156110ac57600080fd5b6110f5600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611181600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611595565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fdeb3a6837278f6e9914a507e4d73f08e841d8fca434fb97d4307b3b0d3d6b105838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b60036020528060005260406000206000915090508060000154908060010154905082565b60055481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541215151561130557600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541215151561135357600080fd5b806006541215151561136457600080fd5b806005541215151561137557600080fd5b6113be600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061144a600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506114996006548261165c565b6006819055506114ab6005548261165c565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b8308383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f6865616c00000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a1505050565b60026020528060005260406000206000915090505481565b600081830190506000821315806115ab57508281135b15156115b657600080fd5b6000821215806115c557508281125b15156115d057600080fd5b92915050565b6000818302905060008212158061160d57507f80000000000000000000000000000000000000000000000000000000000000008314155b151561161857600080fd5b6000821480611631575082828281151561162e57fe5b05145b151561163c57600080fd5b6b033b2e3c9fd0803ce80000008181151561165357fe5b05905092915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821415151561168d57600080fd5b61169a8383600003611595565b9050929150505600a165627a7a72305820ec063dfa37ad5b689da9bf20703341f9ef9e167b6dfe9adf2920e8eec668cba20029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!5 b/libraries/maker/test_data/test_chain/!blocks!5 new file mode 100644 index 00000000..20cb2710 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!5 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x2755f446d0c4053242e02044d205ff5f10f34d7eada2b8170e32dbe7ce649b54","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x05","gasLimit":"0x6691b7","gasUsed":"0x6980","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x04","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000002","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!6 b/libraries/maker/test_data/test_chain/!blocks!6 new file mode 100644 index 00000000..90ac6bbc --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!6 @@ -0,0 +1 @@ +{"header":{"parentHash":"0xe3f5f15620f4599a82eba709537542c5db00c2f03f1863646bc2633f80b1a549","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x07a4f7534ccd4d1a2893c4233b1addc44ec3a672d7f0fac74c99bfeb7c1e4650","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x06","gasLimit":"0x6691b7","gasUsed":"0x0babc2","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x05","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50604051602080610aca8339810180604052810190808051906020019092919050505080600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff02191690831515021790555050610a2c8061009e6000396000f300608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806336569e77146100885780635a984ded146100df578063815d245d14610124578063957aa58c1461016d5780639be856111461019c578063babe8a3f146101d7578063d9638d3614610202575b600080fd5b34801561009457600080fd5b5061009d61024e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100eb57600080fd5b5061012260048036038101908080356000191690602001909291908035906020019092919080359060200190929190505050610274565b005b34801561013057600080fd5b5061016b60048036038101908080356000191690602001909291908035600019169060200190929190803590602001909291905050506107c3565b005b34801561017957600080fd5b506101826108bf565b604051808215151515815260200191505060405180910390f35b3480156101a857600080fd5b506101d56004803603810190808035600019169060200190929190803590602001909291905050506108d1565b005b3480156101e357600080fd5b506101ec610950565b6040518082815260200191505060405180910390f35b34801561020e57600080fd5b506102316004803603810190808035600019169060200190929190505050610956565b604051808381526020018281526020019250505060405180910390f35b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600080600080600080600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a4593c528e338f8f6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600019166000191681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561036057600080fd5b505af1158015610374573d6000803e3d6000fd5b50505050600260008e600019166000191681526020019081526020016000209950600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d9638d368e6040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600019166000191681526020019150506040805180830381600087803b15801561042d57600080fd5b505af1158015610441573d6000803e3d6000fd5b505050506040513d604081101561045757600080fd5b81019080805190602001909291908051906020019092919050505098509850600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632424be5c8e336040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050606060405180830381600087803b15801561054357600080fd5b505af1158015610557573d6000803e3d6000fd5b505050506040513d606081101561056d57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050965096509650600260008e60001916600019168152602001908152602001600020600101546105c1898b61097a565b131580156106905750600154600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc42e3096040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561065357600080fd5b505af1158015610667573d6000803e3d6000fd5b505050506040513d602081101561067d57600080fd5b8101908080519060200190929190505050125b935060008b1315925060008c121591506106aa858a61097a565b6106b8878c6000015461097a565b1215905083806106c55750825b80156106df57508280156106d65750815b806106de5750805b5b80156106f657506000809054906101000a900460ff165b151561070157600080fd5b6000891415151561071157600080fd5b7f37a20eca2501d96bb978add7bb15556741bede770b8bdf08bac546adfe9e389e8d33898989426040518087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018381526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a150505050505050505050505050565b7f73706f7400000000000000000000000000000000000000000000000000000000826000191614156108135780600260008560001916600019168152602001908152602001600020600001819055505b7f6c696e6500000000000000000000000000000000000000000000000000000000826000191614156108635780600260008560001916600019168152602001908152602001600020600101819055505b7fb80446ca592fac4d11848fd8a1aeb8b3de78791ab4079c424db00ed4547bb8768383836040518084600019166000191681526020018360001916600019168152602001828152602001935050505060405180910390a1505050565b6000809054906101000a900460ff1681565b7f4c696e65000000000000000000000000000000000000000000000000000000008260001916141561090557806001819055505b7f134b2912c1a5fbb942de04eb642d59a9b018427189818dd7c3ff65b7f948562e82826040518083600019166000191681526020018281526020019250505060405180910390a15050565b60015481565b60026020528060005260406000206000915090508060000154908060010154905082565b600081830290506000821215806109b157507f80000000000000000000000000000000000000000000000000000000000000008314155b15156109bc57600080fd5b60008214806109d557508282828115156109d257fe5b05145b15156109e057600080fd5b6b033b2e3c9fd0803ce8000000818115156109f757fe5b059050929150505600a165627a7a72305820ab1131a980e176ca0e098df00dec9b8067466d0d169ca68072ce1c1178e44280002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae2182","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!7 b/libraries/maker/test_data/test_chain/!blocks!7 new file mode 100644 index 00000000..b9cb9eed --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!7 @@ -0,0 +1 @@ +{"header":{"parentHash":"0xea660033df6296bce69b24ca2e91556f1d9c5f6c6e9c4ee5ea9877426b6fc893","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0xbe5e9c050b511a60562962583893f9973c43ce27b29cb8269642240cc817b42a","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x07","gasLimit":"0x6691b7","gasUsed":"0x0fc1e5","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x06","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50604051602080610eb583398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610e32806100836000396000f3006080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305db45381461010157806307a832b41461012c5780630e01198b14610157578063143e55e0146101825780632506855a146101bd57806329ae8114146101ea5780632a1d2b3c1461022557806335aee16f1461025057806349dd5bb21461028557806353cb8def146102b057806364bd7013146102db578063697efb78146103065780637f49edc4146103335780639361266c1461037c578063bbbb0d7b146103a7578063d0adc35f146103d2578063d4e8be83146103fd578063f37ac61c1461044e575b600080fd5b34801561010d57600080fd5b5061011661047b565b6040518082815260200191505060405180910390f35b34801561013857600080fd5b5061014161048d565b6040518082815260200191505060405180910390f35b34801561016357600080fd5b5061016c61058b565b6040518082815260200191505060405180910390f35b34801561018e57600080fd5b506101976106d3565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b3480156101c957600080fd5b506101e8600480360381019080803590602001909291905050506106db565b005b3480156101f657600080fd5b50610223600480360381019080803560001916906020019092919080359060200190929190505050610822565b005b34801561023157600080fd5b5061023a6108d5565b6040518082815260200191505060405180910390f35b34801561025c57600080fd5b50610283600480360381019080803565ffffffffffff1690602001909291905050506108db565b005b34801561029157600080fd5b5061029a61096d565b6040518082815260200191505060405180910390f35b3480156102bc57600080fd5b506102c5610973565b6040518082815260200191505060405180910390f35b3480156102e757600080fd5b506102f0610979565b6040518082815260200191505060405180910390f35b34801561031257600080fd5b506103316004803603810190808035906020019092919050505061097f565b005b34801561033f57600080fd5b50610366600480360381019080803565ffffffffffff1690602001909291905050506109ca565b6040518082815260200191505060405180910390f35b34801561038857600080fd5b506103916109e2565b6040518082815260200191505060405180910390f35b3480156103b357600080fd5b506103bc6109e8565b6040518082815260200191505060405180910390f35b3480156103de57600080fd5b506103e7610b66565b6040518082815260200191505060405180910390f35b34801561040957600080fd5b5061044c6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b6c565b005b34801561045a57600080fd5b5061047960048036038101908080359060200190929190505050610cbf565b005b60006006546005546004540101905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c25b346306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561054b57600080fd5b505af115801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b8101908080519060200190929190505050905090565b600060095460085461059b61047b565b01016105a561048d565b101515156105b257600080fd5b60006005541415156105c357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7e9cd243060085460006040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561069357600080fd5b505af11580156106a7573d6000803e3d6000fd5b505050506040513d60208110156106bd57600080fd5b8101908080519060200190929190505050905090565b600042905090565b60065481111580156106f457506106f061048d565b8111155b15156106ff57600080fd5b806006600082825403925050819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee8cd7483030846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561080757600080fd5b505af115801561081b573d6000803e3d6000fd5b5050505050565b7f6c756d70000000000000000000000000000000000000000000000000000000008260001916141561085657806008819055505b7f70616400000000000000000000000000000000000000000000000000000000008260001916141561088a57806009819055505b7f8a9b1ca0a6295c2e892a579edd3076c4914c2a82a4d5caab9420945c64c7fe4182826040518083600019166000191681526020018281526020019250505060405180910390a15050565b60065481565b600360008265ffffffffffff1665ffffffffffff16815260200190815260200160002054600460008282540392505081905550600360008265ffffffffffff1665ffffffffffff168152602001908152602001600020546005600082825401925050819055506000600360008365ffffffffffff1665ffffffffffff1681526020019081526020016000208190555050565b60055481565b60085481565b60075481565b806003600061098c6106d3565b65ffffffffffff1665ffffffffffff168152602001908152602001600020600082825401925050819055508060046000828254019250508190555050565b60036020528060005260406000206000915090505481565b60095481565b6000600854600554101515156109fd57600080fd5b6000610a0761048d565b141515610a1357600080fd5b600854600560008282540392505081905550600854600660008282540192505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7e9cd24307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6008546040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b158015610b2657600080fd5b505af1158015610b3a573d6000803e3d6000fd5b505050506040513d6020811015610b5057600080fd5b8101908080519060200190929190505050905090565b60045481565b7f666c61700000000000000000000000000000000000000000000000000000000082600019161415610bda5780600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b7f666c6f700000000000000000000000000000000000000000000000000000000082600019161415610c485780600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b7fffca69346a2375c2fc87627e7f186fef2014acdc097e9c22e180b2ae18a04e9682826040518083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b610cc761048d565b8111158015610cd857506005548111155b1515610ce357600080fd5b806005600082825403925050819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee8cd7483030846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610deb57600080fd5b505af1158015610dff573d6000803e3d6000fd5b50505050505600a165627a7a72305820b784bba2324a8daa646152e22c45afdbf26e4f511926cb5a966195539287f629002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae2182","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!8 b/libraries/maker/test_data/test_chain/!blocks!8 new file mode 100644 index 00000000..49d73d40 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!8 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x4e22a16f36c4579b10db23891796b93ec0452791bf24426836837fc420bec9b7","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x1302a403c9b0455ea025bbeed7b513046674ea00905aa34a6e9f7d0d97e86eb1","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x08","gasLimit":"0x6691b7","gasUsed":"0x0e03c1","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x07","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50604051602080610cda83398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610c57806100836000396000f3006080604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b3146100b457806318160ddd1461011957806323b872dd1461014457806336569e77146101c957806370a0823114610220578063a9059cbb14610277578063b753a98c146102dc578063bb35783b14610329578063daea85c514610396578063dd62ed3e146103d9578063f2d5d56b14610450575b600080fd5b3480156100c057600080fd5b506100ff600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061049d565b604051808215151515815260200191505060405180910390f35b34801561012557600080fd5b5061012e6105f4565b6040518082815260200191505060405180910390f35b34801561015057600080fd5b506101af600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106bb565b604051808215151515815260200191505060405180910390f35b3480156101d557600080fd5b506101de610a6a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561022c57600080fd5b50610261600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a8f565b6040518082815260200191505060405180910390f35b34801561028357600080fd5b506102c2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8f565b604051808215151515815260200191505060405180910390f35b3480156102e857600080fd5b50610327600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ba7565b005b34801561033557600080fd5b50610394600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bb7565b005b3480156103a257600080fd5b506103d7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bc8565b005b3480156103e557600080fd5b5061043a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bf6565b6040518082815260200191505060405180910390f35b34801561045c57600080fd5b5061049b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1b565b005b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92533847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8502604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a16001905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc42e3096040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b505050506040513d60208110156106a557600080fd5b8101908080519060200190929190505050905090565b60003373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415801561079557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108b05781600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561082557600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b8585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156109a857600080fd5b505af11580156109bc573d6000803e3d6000fd5b505050507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1600190509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c25b346836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610b4d57600080fd5b505af1158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b81019080805190602001909291905050509050919050565b6000610b9c3384846106bb565b506001905092915050565b610bb23383836106bb565b505050565b610bc28383836106bb565b50505050565b610bf2817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61049d565b5050565b6001602052816000526040600020602052806000526040600020600091509150505481565b610c268233836106bb565b5050505600a165627a7a72305820406d34f0273b216f143451ab1358061466096cfda5c781ea771e8af7828a8517002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae2182","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!9 b/libraries/maker/test_data/test_chain/!blocks!9 new file mode 100644 index 00000000..ddf387b2 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!9 @@ -0,0 +1 @@ +{"header":{"parentHash":"0x76443e96ab64087485c83dcaf3ed15ad5303b23393957f075901dab7cdefdef8","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0xaca22053d89ebbf434c56097fbec7c814822c7113ba4fb6a3eff197356c7b0d0","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x09","gasLimit":"0x6691b7","gasUsed":"0x1e6e49","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x08","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x6080604052670e92596fd6290000600255612a30600360006101000a81548165ffffffffffff021916908365ffffffffffff16021790555062093a80600360066101000a81548165ffffffffffff021916908365ffffffffffff16021790555034801561006b57600080fd5b50604051604080611c2683398101806040528101908080519060200190929190805190602001909291905050508060018160001916905550816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050611b32806100f46000396000f3006080604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063143e55e0146100ca578063351de6001461010557806336569e771461019a5780634423c5f1146101f15780634b43ed12146103075780634e8b1dd5146103485780635ff3a382146103835780637d780d82146103c4578063c5ce281e146103ef578063c959c42b14610422578063cfc4af551461044f578063cfdd33021461048a578063fc7b6aee146104b5575b600080fd5b3480156100d657600080fd5b506100df6104e2565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561011157600080fd5b50610184600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001909291905050506104ea565b6040518082815260200191505060405180910390f35b3480156101a657600080fd5b506101af6108e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101fd57600080fd5b5061021c60048036038101908080359060200190929190505050610907565b604051808981526020018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018665ffffffffffff1665ffffffffffff1681526020018565ffffffffffff1665ffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019850505050505050505060405180910390f35b34801561031357600080fd5b506103466004803603810190808035906020019092919080359060200190929190803590602001909291905050506109d3565b005b34801561035457600080fd5b5061035d611020565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561038f57600080fd5b506103c2600480360381019080803590602001909291908035906020019092919080359060200190929190505050611038565b005b3480156103d057600080fd5b506103d961162c565b6040518082815260200191505060405180910390f35b3480156103fb57600080fd5b50610404611632565b60405180826000191660001916815260200191505060405180910390f35b34801561042e57600080fd5b5061044d60048036038101908080359060200190929190505050611638565b005b34801561045b57600080fd5b50610464611973565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561049657600080fd5b5061049f61198b565b6040518082815260200191505060405180910390f35b3480156104c157600080fd5b506104e060048036038101908080359060200190929190505050611991565b005b600042905090565b6000806004600081546001019190508190559050826005600083815260200190815260200160002060000181905550836005600083815260200190815260200160002060010181905550336005600083815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360069054906101000a900465ffffffffffff166105a66104e2565b0160056000838152602001908152602001600020600201601a6101000a81548165ffffffffffff021916908365ffffffffffff160217905550866005600083815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550856005600083815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460056000838152602001908152602001600020600501819055507fc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b381306000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166001548888338d600560008b8152602001908152602001600020600201601a9054906101000a900465ffffffffffff166107216104e2565b600560008d815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008e815260200190815260200160002060050154604051808d81526020018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a600019166000191681526020018981526020018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018565ffffffffffff1665ffffffffffff1681526020018465ffffffffffff1665ffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019c5050505050505050505050505060405180910390a18091505095945050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60056020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160149054906101000a900465ffffffffffff169080600201601a9054906101000a900465ffffffffffff16908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060050154905088565b60006005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515610a2f57600080fd5b610a376104e2565b65ffffffffffff166005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161180610aac575060006005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16145b1515610ab757600080fd5b610abf6104e2565b65ffffffffffff1660056000858152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff16111515610b0457600080fd5b600560008481526020019081526020016000206001015482141515610b2857600080fd5b60056000848152602001908152602001600020600501548111151515610b4d57600080fd5b600560008481526020019081526020016000206000015481111515610b7157600080fd5b610b936002546005600086815260200190815260200160002060000154611a76565b81101580610bb65750600560008481526020019081526020016000206005015481145b1515610bc157600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000888152602001908152602001600020600001546040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610d0557600080fd5b505af1158015610d19573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008881526020019081526020016000206000015485036040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610e6357600080fd5b505af1158015610e77573d6000803e3d6000fd5b50505050336005600085815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806005600085815260200190815260200160002060000181905550600360009054906101000a900465ffffffffffff16610f086104e2565b016005600085815260200190815260200160002060020160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055507fd4aef477d7912041a69c5b85f2d78b618c76e40a4a92b91122c85ab5b404a64a838383336005600089815260200190815260200160002060020160149054906101000a900465ffffffffffff16610f976104e2565b604051808781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018365ffffffffffff1665ffffffffffff1681526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a1505050565b600360009054906101000a900465ffffffffffff1681565b60006005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561109457600080fd5b61109c6104e2565b65ffffffffffff166005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161180611111575060006005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16145b151561111c57600080fd5b6111246104e2565b65ffffffffffff1660056000858152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff1611151561116957600080fd5b60056000848152602001908152602001600020600001548114151561118d57600080fd5b6005600084815260200190815260200160002060050154811415156111b157600080fd5b6005600084815260200190815260200160002060010154821015156111d557600080fd5b60056000848152602001908152602001600020600101546111f860025484611a76565b1115151561120557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561133357600080fd5b505af1158015611347573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cdd3fde6001546005600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856005600089815260200190815260200160002060010154036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561146f57600080fd5b505af1158015611483573d6000803e3d6000fd5b50505050336005600085815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816005600085815260200190815260200160002060010181905550600360009054906101000a900465ffffffffffff166115146104e2565b016005600085815260200190815260200160002060020160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055507f380cb3bf83f57ec05d0229938aeb5d4fba1de0228097701d1c03379c88cec5d4838383336005600089815260200190815260200160002060020160149054906101000a900465ffffffffffff166115a36104e2565b604051808781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018365ffffffffffff1665ffffffffffff1681526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a1505050565b60025481565b60015481565b6116406104e2565b65ffffffffffff166005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161080156116b7575060006005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff1614155b8061170057506116c56104e2565b65ffffffffffff1660056000838152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff16105b151561170b57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cdd3fde6001546005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000868152602001908152602001600020600101546040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561182d57600080fd5b505af1158015611841573d6000803e3d6000fd5b505050506005600082815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160146101000a81549065ffffffffffff021916905560028201601a6101000a81549065ffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600582016000905550507f9b83ce9ac5e3a4e55a5b95c0e529b8cbe35d29682e2d851f51dd4e0bf9a6d3d1816119446104e2565b604051808381526020018265ffffffffffff1665ffffffffffff1681526020019250505060405180910390a150565b600360069054906101000a900465ffffffffffff1681565b60045481565b6119996104e2565b65ffffffffffff1660056000838152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff161015156119de57600080fd5b60006005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16141515611a1d57600080fd5b600360069054906101000a900465ffffffffffff16611a3a6104e2565b0160056000838152602001908152602001600020600201601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555050565b6000670de0b6b3a7640000611aa8611a8e8585611aba565b6002670de0b6b3a7640000811515611aa257fe5b04611aea565b811515611ab157fe5b04905092915050565b600080821480611ad957508282838502925082811515611ad657fe5b04145b1515611ae457600080fd5b92915050565b60008282840191508110151515611b0057600080fd5b929150505600a165627a7a72305820d6c37b3c03f9212b2651562416a3be7df8798888dec5c1d26a4f7b4d1d9f8864002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b000000000000000000000000000000000000000000000000","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62"}],"uncleHeaders":[]} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!blocks!length b/libraries/maker/test_data/test_chain/!blocks!length new file mode 100644 index 00000000..9d607966 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!blocks!length @@ -0,0 +1 @@ +11 \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62 new file mode 100644 index 00000000..ca5c4c35 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62 @@ -0,0 +1 @@ +{"transactionHash":"0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62","transactionIndex":"0x0","blockHash":"0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44","blockNumber":"0x9","gasUsed":"0x1e6e49","cumulativeGasUsed":"0x1e6e49","contractAddress":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48 new file mode 100644 index 00000000..53be02da --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48 @@ -0,0 +1 @@ +{"transactionHash":"0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48","transactionIndex":"0x0","blockHash":"0xea660033df6296bce69b24ca2e91556f1d9c5f6c6e9c4ee5ea9877426b6fc893","blockNumber":"0x6","gasUsed":"0xbabc2","cumulativeGasUsed":"0xbabc2","contractAddress":"0xff3f2400f1600f3f493a9a92704a29b96795af1a","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49 new file mode 100644 index 00000000..793e7547 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49 @@ -0,0 +1 @@ +{"transactionHash":"0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49","transactionIndex":"0x0","blockHash":"0xe3f5f15620f4599a82eba709537542c5db00c2f03f1863646bc2633f80b1a549","blockNumber":"0x5","gasUsed":"0x6980","cumulativeGasUsed":"0x6980","contractAddress":null,"logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9 new file mode 100644 index 00000000..d4a015e1 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9 @@ -0,0 +1 @@ +{"transactionHash":"0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9","transactionIndex":"0x0","blockHash":"0x4e22a16f36c4579b10db23891796b93ec0452791bf24426836837fc420bec9b7","blockNumber":"0x7","gasUsed":"0xfc1e5","cumulativeGasUsed":"0xfc1e5","contractAddress":"0x76189df410263ad1d9fe2f4af2eab3d24f1b6f41","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191 new file mode 100644 index 00000000..0450a4ba --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191 @@ -0,0 +1 @@ +{"transactionHash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191","transactionIndex":"0x0","blockHash":"0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd","blockNumber":"0xa","gasUsed":"0x27c77","cumulativeGasUsed":"0x27c77","contractAddress":null,"logs":[{"logIndex":"0x0","transactionIndex":"0x0","transactionHash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191","blockHash":"0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd","blockNumber":"0xa","address":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000008cb6176addcca2e1d1ffe21bee464b72ee4cd8d00000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d922894153be9eef7b7218dc565d1d0ce2a09200000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000005b69b8e7000000000000000000000000000000000000000000000000000000005b607e670000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca0000000000000000000000000000000000000000000000000000000000000032","topics":["0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3"],"type":"mined"}],"status":"0x1","logsBloom":"0x00000000000000000020000000000000000080000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172 new file mode 100644 index 00000000..c9212c23 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172 @@ -0,0 +1 @@ +{"transactionHash":"0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172","transactionIndex":"0x0","blockHash":"0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789","blockNumber":"0x4","gasUsed":"0x18b018","cumulativeGasUsed":"0x18b018","contractAddress":"0x38219779a699d67d7e7740b8c8f43d3e2dae2182","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9 b/libraries/maker/test_data/test_chain/!transactionReceipts!0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9 new file mode 100644 index 00000000..187a53da --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9 @@ -0,0 +1 @@ +{"transactionHash":"0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9","transactionIndex":"0x0","blockHash":"0x2c3b96f821a6abe12061036d3f90e3a04f72eb3b06952a1b0d8916bff0103406","blockNumber":"0x3","gasUsed":"0x10cba","cumulativeGasUsed":"0x10cba","contractAddress":"0xa970ed54e41d9db6d91db5e7ff7a9451dad98993","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668 b/libraries/maker/test_data/test_chain/!transactionReceipts!0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668 new file mode 100644 index 00000000..285aa2bf --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668 @@ -0,0 +1 @@ +{"transactionHash":"0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668","transactionIndex":"0x0","blockHash":"0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a","blockNumber":"0x2","gasUsed":"0xa418","cumulativeGasUsed":"0xa418","contractAddress":null,"logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732 b/libraries/maker/test_data/test_chain/!transactionReceipts!0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732 new file mode 100644 index 00000000..8fa62d69 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732 @@ -0,0 +1 @@ +{"transactionHash":"0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732","transactionIndex":"0x0","blockHash":"0x76443e96ab64087485c83dcaf3ed15ad5303b23393957f075901dab7cdefdef8","blockNumber":"0x8","gasUsed":"0xe03c1","cumulativeGasUsed":"0xe03c1","contractAddress":"0x7dbda851034713f899a122f95860eaf707b9f833","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactionReceipts!0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61 b/libraries/maker/test_data/test_chain/!transactionReceipts!0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61 new file mode 100644 index 00000000..2905d844 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactionReceipts!0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61 @@ -0,0 +1 @@ +{"transactionHash":"0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61","transactionIndex":"0x0","blockHash":"0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a","blockNumber":"0x1","gasUsed":"0x43bd6","cumulativeGasUsed":"0x43bd6","contractAddress":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62 b/libraries/maker/test_data/test_chain/!transactions!0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62 new file mode 100644 index 00000000..9325631c --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62 @@ -0,0 +1 @@ +{"nonce":"0x08","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x6080604052670e92596fd6290000600255612a30600360006101000a81548165ffffffffffff021916908365ffffffffffff16021790555062093a80600360066101000a81548165ffffffffffff021916908365ffffffffffff16021790555034801561006b57600080fd5b50604051604080611c2683398101806040528101908080519060200190929190805190602001909291905050508060018160001916905550816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050611b32806100f46000396000f3006080604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063143e55e0146100ca578063351de6001461010557806336569e771461019a5780634423c5f1146101f15780634b43ed12146103075780634e8b1dd5146103485780635ff3a382146103835780637d780d82146103c4578063c5ce281e146103ef578063c959c42b14610422578063cfc4af551461044f578063cfdd33021461048a578063fc7b6aee146104b5575b600080fd5b3480156100d657600080fd5b506100df6104e2565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561011157600080fd5b50610184600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001909291905050506104ea565b6040518082815260200191505060405180910390f35b3480156101a657600080fd5b506101af6108e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101fd57600080fd5b5061021c60048036038101908080359060200190929190505050610907565b604051808981526020018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018665ffffffffffff1665ffffffffffff1681526020018565ffffffffffff1665ffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019850505050505050505060405180910390f35b34801561031357600080fd5b506103466004803603810190808035906020019092919080359060200190929190803590602001909291905050506109d3565b005b34801561035457600080fd5b5061035d611020565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561038f57600080fd5b506103c2600480360381019080803590602001909291908035906020019092919080359060200190929190505050611038565b005b3480156103d057600080fd5b506103d961162c565b6040518082815260200191505060405180910390f35b3480156103fb57600080fd5b50610404611632565b60405180826000191660001916815260200191505060405180910390f35b34801561042e57600080fd5b5061044d60048036038101908080359060200190929190505050611638565b005b34801561045b57600080fd5b50610464611973565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561049657600080fd5b5061049f61198b565b6040518082815260200191505060405180910390f35b3480156104c157600080fd5b506104e060048036038101908080359060200190929190505050611991565b005b600042905090565b6000806004600081546001019190508190559050826005600083815260200190815260200160002060000181905550836005600083815260200190815260200160002060010181905550336005600083815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360069054906101000a900465ffffffffffff166105a66104e2565b0160056000838152602001908152602001600020600201601a6101000a81548165ffffffffffff021916908365ffffffffffff160217905550866005600083815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550856005600083815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460056000838152602001908152602001600020600501819055507fc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b381306000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166001548888338d600560008b8152602001908152602001600020600201601a9054906101000a900465ffffffffffff166107216104e2565b600560008d815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008e815260200190815260200160002060050154604051808d81526020018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a600019166000191681526020018981526020018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018565ffffffffffff1665ffffffffffff1681526020018465ffffffffffff1665ffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019c5050505050505050505050505060405180910390a18091505095945050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60056020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160149054906101000a900465ffffffffffff169080600201601a9054906101000a900465ffffffffffff16908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060050154905088565b60006005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515610a2f57600080fd5b610a376104e2565b65ffffffffffff166005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161180610aac575060006005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16145b1515610ab757600080fd5b610abf6104e2565b65ffffffffffff1660056000858152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff16111515610b0457600080fd5b600560008481526020019081526020016000206001015482141515610b2857600080fd5b60056000848152602001908152602001600020600501548111151515610b4d57600080fd5b600560008481526020019081526020016000206000015481111515610b7157600080fd5b610b936002546005600086815260200190815260200160002060000154611a76565b81101580610bb65750600560008481526020019081526020016000206005015481145b1515610bc157600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000888152602001908152602001600020600001546040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610d0557600080fd5b505af1158015610d19573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008881526020019081526020016000206000015485036040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610e6357600080fd5b505af1158015610e77573d6000803e3d6000fd5b50505050336005600085815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806005600085815260200190815260200160002060000181905550600360009054906101000a900465ffffffffffff16610f086104e2565b016005600085815260200190815260200160002060020160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055507fd4aef477d7912041a69c5b85f2d78b618c76e40a4a92b91122c85ab5b404a64a838383336005600089815260200190815260200160002060020160149054906101000a900465ffffffffffff16610f976104e2565b604051808781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018365ffffffffffff1665ffffffffffff1681526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a1505050565b600360009054906101000a900465ffffffffffff1681565b60006005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561109457600080fd5b61109c6104e2565b65ffffffffffff166005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161180611111575060006005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16145b151561111c57600080fd5b6111246104e2565b65ffffffffffff1660056000858152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff1611151561116957600080fd5b60056000848152602001908152602001600020600001548114151561118d57600080fd5b6005600084815260200190815260200160002060050154811415156111b157600080fd5b6005600084815260200190815260200160002060010154821015156111d557600080fd5b60056000848152602001908152602001600020600101546111f860025484611a76565b1115151561120557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561133357600080fd5b505af1158015611347573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cdd3fde6001546005600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856005600089815260200190815260200160002060010154036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561146f57600080fd5b505af1158015611483573d6000803e3d6000fd5b50505050336005600085815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816005600085815260200190815260200160002060010181905550600360009054906101000a900465ffffffffffff166115146104e2565b016005600085815260200190815260200160002060020160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055507f380cb3bf83f57ec05d0229938aeb5d4fba1de0228097701d1c03379c88cec5d4838383336005600089815260200190815260200160002060020160149054906101000a900465ffffffffffff166115a36104e2565b604051808781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018365ffffffffffff1665ffffffffffff1681526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a1505050565b60025481565b60015481565b6116406104e2565b65ffffffffffff166005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161080156116b7575060006005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff1614155b8061170057506116c56104e2565b65ffffffffffff1660056000838152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff16105b151561170b57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cdd3fde6001546005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000868152602001908152602001600020600101546040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561182d57600080fd5b505af1158015611841573d6000803e3d6000fd5b505050506005600082815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160146101000a81549065ffffffffffff021916905560028201601a6101000a81549065ffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600582016000905550507f9b83ce9ac5e3a4e55a5b95c0e529b8cbe35d29682e2d851f51dd4e0bf9a6d3d1816119446104e2565b604051808381526020018265ffffffffffff1665ffffffffffff1681526020019250505060405180910390a150565b600360069054906101000a900465ffffffffffff1681565b60045481565b6119996104e2565b65ffffffffffff1660056000838152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff161015156119de57600080fd5b60006005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16141515611a1d57600080fd5b600360069054906101000a900465ffffffffffff16611a3a6104e2565b0160056000838152602001908152602001600020600201601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555050565b6000670de0b6b3a7640000611aa8611a8e8585611aba565b6002670de0b6b3a7640000811515611aa257fe5b04611aea565b811515611ab157fe5b04905092915050565b600080821480611ad957508282838502925082811515611ad657fe5b04145b1515611ae457600080fd5b92915050565b60008282840191508110151515611b0057600080fd5b929150505600a165627a7a72305820d6c37b3c03f9212b2651562416a3be7df8798888dec5c1d26a4f7b4d1d9f8864002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b000000000000000000000000000000000000000000000000","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48 b/libraries/maker/test_data/test_chain/!transactions!0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48 new file mode 100644 index 00000000..3f013b8e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48 @@ -0,0 +1 @@ +{"nonce":"0x05","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50604051602080610aca8339810180604052810190808051906020019092919050505080600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016000806101000a81548160ff02191690831515021790555050610a2c8061009e6000396000f300608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806336569e77146100885780635a984ded146100df578063815d245d14610124578063957aa58c1461016d5780639be856111461019c578063babe8a3f146101d7578063d9638d3614610202575b600080fd5b34801561009457600080fd5b5061009d61024e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100eb57600080fd5b5061012260048036038101908080356000191690602001909291908035906020019092919080359060200190929190505050610274565b005b34801561013057600080fd5b5061016b60048036038101908080356000191690602001909291908035600019169060200190929190803590602001909291905050506107c3565b005b34801561017957600080fd5b506101826108bf565b604051808215151515815260200191505060405180910390f35b3480156101a857600080fd5b506101d56004803603810190808035600019169060200190929190803590602001909291905050506108d1565b005b3480156101e357600080fd5b506101ec610950565b6040518082815260200191505060405180910390f35b34801561020e57600080fd5b506102316004803603810190808035600019169060200190929190505050610956565b604051808381526020018281526020019250505060405180910390f35b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600080600080600080600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a4593c528e338f8f6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600019166000191681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561036057600080fd5b505af1158015610374573d6000803e3d6000fd5b50505050600260008e600019166000191681526020019081526020016000209950600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d9638d368e6040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600019166000191681526020019150506040805180830381600087803b15801561042d57600080fd5b505af1158015610441573d6000803e3d6000fd5b505050506040513d604081101561045757600080fd5b81019080805190602001909291908051906020019092919050505098509850600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632424be5c8e336040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050606060405180830381600087803b15801561054357600080fd5b505af1158015610557573d6000803e3d6000fd5b505050506040513d606081101561056d57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050965096509650600260008e60001916600019168152602001908152602001600020600101546105c1898b61097a565b131580156106905750600154600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc42e3096040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561065357600080fd5b505af1158015610667573d6000803e3d6000fd5b505050506040513d602081101561067d57600080fd5b8101908080519060200190929190505050125b935060008b1315925060008c121591506106aa858a61097a565b6106b8878c6000015461097a565b1215905083806106c55750825b80156106df57508280156106d65750815b806106de5750805b5b80156106f657506000809054906101000a900460ff165b151561070157600080fd5b6000891415151561071157600080fd5b7f37a20eca2501d96bb978add7bb15556741bede770b8bdf08bac546adfe9e389e8d33898989426040518087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018381526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a150505050505050505050505050565b7f73706f7400000000000000000000000000000000000000000000000000000000826000191614156108135780600260008560001916600019168152602001908152602001600020600001819055505b7f6c696e6500000000000000000000000000000000000000000000000000000000826000191614156108635780600260008560001916600019168152602001908152602001600020600101819055505b7fb80446ca592fac4d11848fd8a1aeb8b3de78791ab4079c424db00ed4547bb8768383836040518084600019166000191681526020018360001916600019168152602001828152602001935050505060405180910390a1505050565b6000809054906101000a900460ff1681565b7f4c696e65000000000000000000000000000000000000000000000000000000008260001916141561090557806001819055505b7f134b2912c1a5fbb942de04eb642d59a9b018427189818dd7c3ff65b7f948562e82826040518083600019166000191681526020018281526020019250505060405180910390a15050565b60015481565b60026020528060005260406000206000915090508060000154908060010154905082565b600081830290506000821215806109b157507f80000000000000000000000000000000000000000000000000000000000000008314155b15156109bc57600080fd5b60008214806109d557508282828115156109d257fe5b05145b15156109e057600080fd5b6b033b2e3c9fd0803ce8000000818115156109f757fe5b059050929150505600a165627a7a72305820ab1131a980e176ca0e098df00dec9b8067466d0d169ca68072ce1c1178e44280002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae2182","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49 b/libraries/maker/test_data/test_chain/!transactions!0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49 new file mode 100644 index 00000000..b9842790 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49 @@ -0,0 +1 @@ +{"nonce":"0x04","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000002","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9 b/libraries/maker/test_data/test_chain/!transactions!0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9 new file mode 100644 index 00000000..5bfb228a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9 @@ -0,0 +1 @@ +{"nonce":"0x06","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50604051602080610eb583398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610e32806100836000396000f3006080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305db45381461010157806307a832b41461012c5780630e01198b14610157578063143e55e0146101825780632506855a146101bd57806329ae8114146101ea5780632a1d2b3c1461022557806335aee16f1461025057806349dd5bb21461028557806353cb8def146102b057806364bd7013146102db578063697efb78146103065780637f49edc4146103335780639361266c1461037c578063bbbb0d7b146103a7578063d0adc35f146103d2578063d4e8be83146103fd578063f37ac61c1461044e575b600080fd5b34801561010d57600080fd5b5061011661047b565b6040518082815260200191505060405180910390f35b34801561013857600080fd5b5061014161048d565b6040518082815260200191505060405180910390f35b34801561016357600080fd5b5061016c61058b565b6040518082815260200191505060405180910390f35b34801561018e57600080fd5b506101976106d3565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b3480156101c957600080fd5b506101e8600480360381019080803590602001909291905050506106db565b005b3480156101f657600080fd5b50610223600480360381019080803560001916906020019092919080359060200190929190505050610822565b005b34801561023157600080fd5b5061023a6108d5565b6040518082815260200191505060405180910390f35b34801561025c57600080fd5b50610283600480360381019080803565ffffffffffff1690602001909291905050506108db565b005b34801561029157600080fd5b5061029a61096d565b6040518082815260200191505060405180910390f35b3480156102bc57600080fd5b506102c5610973565b6040518082815260200191505060405180910390f35b3480156102e757600080fd5b506102f0610979565b6040518082815260200191505060405180910390f35b34801561031257600080fd5b506103316004803603810190808035906020019092919050505061097f565b005b34801561033f57600080fd5b50610366600480360381019080803565ffffffffffff1690602001909291905050506109ca565b6040518082815260200191505060405180910390f35b34801561038857600080fd5b506103916109e2565b6040518082815260200191505060405180910390f35b3480156103b357600080fd5b506103bc6109e8565b6040518082815260200191505060405180910390f35b3480156103de57600080fd5b506103e7610b66565b6040518082815260200191505060405180910390f35b34801561040957600080fd5b5061044c6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b6c565b005b34801561045a57600080fd5b5061047960048036038101908080359060200190929190505050610cbf565b005b60006006546005546004540101905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c25b346306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561054b57600080fd5b505af115801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b8101908080519060200190929190505050905090565b600060095460085461059b61047b565b01016105a561048d565b101515156105b257600080fd5b60006005541415156105c357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7e9cd243060085460006040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561069357600080fd5b505af11580156106a7573d6000803e3d6000fd5b505050506040513d60208110156106bd57600080fd5b8101908080519060200190929190505050905090565b600042905090565b60065481111580156106f457506106f061048d565b8111155b15156106ff57600080fd5b806006600082825403925050819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee8cd7483030846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561080757600080fd5b505af115801561081b573d6000803e3d6000fd5b5050505050565b7f6c756d70000000000000000000000000000000000000000000000000000000008260001916141561085657806008819055505b7f70616400000000000000000000000000000000000000000000000000000000008260001916141561088a57806009819055505b7f8a9b1ca0a6295c2e892a579edd3076c4914c2a82a4d5caab9420945c64c7fe4182826040518083600019166000191681526020018281526020019250505060405180910390a15050565b60065481565b600360008265ffffffffffff1665ffffffffffff16815260200190815260200160002054600460008282540392505081905550600360008265ffffffffffff1665ffffffffffff168152602001908152602001600020546005600082825401925050819055506000600360008365ffffffffffff1665ffffffffffff1681526020019081526020016000208190555050565b60055481565b60085481565b60075481565b806003600061098c6106d3565b65ffffffffffff1665ffffffffffff168152602001908152602001600020600082825401925050819055508060046000828254019250508190555050565b60036020528060005260406000206000915090505481565b60095481565b6000600854600554101515156109fd57600080fd5b6000610a0761048d565b141515610a1357600080fd5b600854600560008282540392505081905550600854600660008282540192505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7e9cd24307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6008546040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b158015610b2657600080fd5b505af1158015610b3a573d6000803e3d6000fd5b505050506040513d6020811015610b5057600080fd5b8101908080519060200190929190505050905090565b60045481565b7f666c61700000000000000000000000000000000000000000000000000000000082600019161415610bda5780600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b7f666c6f700000000000000000000000000000000000000000000000000000000082600019161415610c485780600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b7fffca69346a2375c2fc87627e7f186fef2014acdc097e9c22e180b2ae18a04e9682826040518083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b610cc761048d565b8111158015610cd857506005548111155b1515610ce357600080fd5b806005600082825403925050819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee8cd7483030846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610deb57600080fd5b505af1158015610dff573d6000803e3d6000fd5b50505050505600a165627a7a72305820b784bba2324a8daa646152e22c45afdbf26e4f511926cb5a966195539287f629002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae2182","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191 b/libraries/maker/test_data/test_chain/!transactions!0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191 new file mode 100644 index 00000000..8ac6b8d1 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191 @@ -0,0 +1 @@ +{"nonce":"0x","gasPrice":"0x01","gasLimit":"0x44aa20","to":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","value":"0x","data":"0x351de6000000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca00000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000","v":"0x1c","r":"0x","s":"0x","from":"0x64d922894153be9eef7b7218dc565d1d0ce2a092","hash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172 b/libraries/maker/test_data/test_chain/!transactions!0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172 new file mode 100644 index 00000000..b64babbb --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172 @@ -0,0 +1 @@ +{"nonce":"0x03","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506116ce806100606000396000f3006080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806311045bee14610101578063143e55e0146101865780632424be5c146101c15780632d61a355146102345780634186706d1461025f578063673c17da146102c45780636c25b3461461032957806371854745146103805780637cdd3fde146103e5578063815d245d14610440578063a4593c5214610489578063b65337df146104ee578063bb35783b14610549578063d9638d36146105b6578063dc42e30914610602578063ebf0c7171461062d578063ee8cd74814610684578063f059212a146106f1575b600080fd5b34801561010d57600080fd5b506101846004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610748565b005b34801561019257600080fd5b5061019b610999565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b3480156101cd57600080fd5b506102106004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109a1565b60405180848152602001838152602001828152602001935050505060405180910390f35b34801561024057600080fd5b506102496109d8565b6040518082815260200191505060405180910390f35b34801561026b57600080fd5b506102ae6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109de565b6040518082815260200191505060405180910390f35b3480156102d057600080fd5b506103136004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a44565b6040518082815260200191505060405180910390f35b34801561033557600080fd5b5061036a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610aaa565b6040518082815260200191505060405180910390f35b34801561038c57600080fd5b506103cf6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ac2565b6040518082815260200191505060405180910390f35b3480156103f157600080fd5b5061043e6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b28565b005b34801561044c57600080fd5b506104876004803603810190808035600019169060200190929190803560001916906020019092919080359060200190929190505050610bf1565b005b34801561049557600080fd5b506104ec6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610c46565b005b3480156104fa57600080fd5b506105476004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eac565b005b34801561055557600080fd5b506105b4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105e565b005b3480156105c257600080fd5b506105e56004803603810190808035600019169060200190929190505050611268565b604051808381526020018281526020019250505060405180910390f35b34801561060e57600080fd5b5061061761128c565b6040518082815260200191505060405180910390f35b34801561063957600080fd5b50610642611292565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561069057600080fd5b506106ef600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506112b7565b005b3480156106fd57600080fd5b50610732600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061157d565b6040518082815260200191505060405180910390f35b60008060046000886000191660001916815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020915060036000886000191660001916815260200190815260200160002090506107d0826001015485611595565b82600101819055506107e6826002015484611595565b82600201819055506107fc816001015484611595565b816001018190555061085a600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546108558360000154866115d6565b61165c565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108b66006546108b18360000154866115d6565b61165c565b6006819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b830866108ed8460000154876115d6565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f6772616200000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a150505050505050565b600042905090565b6004602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154905083565b60065481565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905092915050565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154905092915050565b60016020528060005260406000206000915090505481565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b610b8d60046000856000191660001916815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015482611595565b60046000856000191660001916815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550505050565b7f726174650000000000000000000000000000000000000000000000000000000082600019161415610c415780600360008560001916600019168152602001908152602001600020600001819055505b505050565b60008060046000876000191660001916815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091506003600087600019166000191681526020019081526020016000209050610cce82600001548561165c565b8260000181905550610ce4826001015485611595565b8260010181905550610cfa826002015484611595565b8260020181905550610d10816001015484611595565b8160010181905550610d6e600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d698360000154866115d6565b611595565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dca600554610dc58360000154866115d6565b611595565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b83086610e018460000154876115d6565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f74756e6500000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a1505050505050565b6000806003600086600019166000191681526020019081526020016000209150610eda826000015484611595565b8260000181905550610ef08260010154846115d6565b9050610f3b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611595565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f8a60055482611595565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b8308583604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f666f6c6400000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a15050505050565b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054121515156110ac57600080fd5b6110f5600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611181600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611595565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fdeb3a6837278f6e9914a507e4d73f08e841d8fca434fb97d4307b3b0d3d6b105838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b60036020528060005260406000206000915090508060000154908060010154905082565b60055481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541215151561130557600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541215151561135357600080fd5b806006541215151561136457600080fd5b806005541215151561137557600080fd5b6113be600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061144a600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506114996006548261165c565b6006819055506114ab6005548261165c565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b8308383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f6865616c00000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a1505050565b60026020528060005260406000206000915090505481565b600081830190506000821315806115ab57508281135b15156115b657600080fd5b6000821215806115c557508281125b15156115d057600080fd5b92915050565b6000818302905060008212158061160d57507f80000000000000000000000000000000000000000000000000000000000000008314155b151561161857600080fd5b6000821480611631575082828281151561162e57fe5b05145b151561163c57600080fd5b6b033b2e3c9fd0803ce80000008181151561165357fe5b05905092915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821415151561168d57600080fd5b61169a8383600003611595565b9050929150505600a165627a7a72305820ec063dfa37ad5b689da9bf20703341f9ef9e167b6dfe9adf2920e8eec668cba20029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9 b/libraries/maker/test_data/test_chain/!transactions!0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9 new file mode 100644 index 00000000..46c5b498 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9 @@ -0,0 +1 @@ +{"nonce":"0x02","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820562865e6c1f558e8a54735c0ff54b7f6a1fbc65c540a84c894f17a5fec64110d0029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668 b/libraries/maker/test_data/test_chain/!transactions!0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668 new file mode 100644 index 00000000..d00c29ed --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668 @@ -0,0 +1 @@ +{"nonce":"0x01","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000001","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732 b/libraries/maker/test_data/test_chain/!transactions!0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732 new file mode 100644 index 00000000..8edea4d2 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732 @@ -0,0 +1 @@ +{"nonce":"0x07","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50604051602080610cda83398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610c57806100836000396000f3006080604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b3146100b457806318160ddd1461011957806323b872dd1461014457806336569e77146101c957806370a0823114610220578063a9059cbb14610277578063b753a98c146102dc578063bb35783b14610329578063daea85c514610396578063dd62ed3e146103d9578063f2d5d56b14610450575b600080fd5b3480156100c057600080fd5b506100ff600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061049d565b604051808215151515815260200191505060405180910390f35b34801561012557600080fd5b5061012e6105f4565b6040518082815260200191505060405180910390f35b34801561015057600080fd5b506101af600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106bb565b604051808215151515815260200191505060405180910390f35b3480156101d557600080fd5b506101de610a6a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561022c57600080fd5b50610261600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a8f565b6040518082815260200191505060405180910390f35b34801561028357600080fd5b506102c2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8f565b604051808215151515815260200191505060405180910390f35b3480156102e857600080fd5b50610327600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ba7565b005b34801561033557600080fd5b50610394600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bb7565b005b3480156103a257600080fd5b506103d7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bc8565b005b3480156103e557600080fd5b5061043a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bf6565b6040518082815260200191505060405180910390f35b34801561045c57600080fd5b5061049b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1b565b005b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92533847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8502604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a16001905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc42e3096040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b505050506040513d60208110156106a557600080fd5b8101908080519060200190929190505050905090565b60003373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415801561079557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108b05781600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561082557600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b8585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156109a857600080fd5b505af11580156109bc573d6000803e3d6000fd5b505050507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1600190509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c25b346836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610b4d57600080fd5b505af1158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b81019080805190602001909291905050509050919050565b6000610b9c3384846106bb565b506001905092915050565b610bb23383836106bb565b505050565b610bc28383836106bb565b50505050565b610bf2817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61049d565b5050565b6001602052816000526040600020602052806000526040600020600091509150505481565b610c268233836106bb565b5050505600a165627a7a72305820406d34f0273b216f143451ab1358061466096cfda5c781ea771e8af7828a8517002900000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae2182","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!transactions!0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61 b/libraries/maker/test_data/test_chain/!transactions!0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61 new file mode 100644 index 00000000..a51a93f1 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!transactions!0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61 @@ -0,0 +1 @@ +{"nonce":"0x","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820167320a3f0aefab2d9d7492779c69a7f6bbea970d8290e17d3631fbed9ad93540029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61"} \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x014d823cc965c37ad6f570144cfa40059711516c16ac27e18c85f8ba8d41b37a b/libraries/maker/test_data/test_chain/!trie_db!0x014d823cc965c37ad6f570144cfa40059711516c16ac27e18c85f8ba8d41b37a new file mode 100644 index 00000000..62c3e610 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x014d823cc965c37ad6f570144cfa40059711516c16ac27e18c85f8ba8d41b37a @@ -0,0 +1 @@ +"0xf90131a02b90ac735ccaf20d1204ce987c10f24fa0ecf777dbe99525c0321a58f237aa2380a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca0fdcb675a2fb7395ce85312eeaf38d612251395b4277a958c4a78cea448e07cc1a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0c03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x0580883480974cf8d76b4a4d6eb1a04a3080df15d235779a7318839acd4ec0bb b/libraries/maker/test_data/test_chain/!trie_db!0x0580883480974cf8d76b4a4d6eb1a04a3080df15d235779a7318839acd4ec0bb new file mode 100644 index 00000000..d6291398 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x0580883480974cf8d76b4a4d6eb1a04a3080df15d235779a7318839acd4ec0bb @@ -0,0 +1 @@ +"0xf8f1a0422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f580a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x07a4f7534ccd4d1a2893c4233b1addc44ec3a672d7f0fac74c99bfeb7c1e4650 b/libraries/maker/test_data/test_chain/!trie_db!0x07a4f7534ccd4d1a2893c4233b1addc44ec3a672d7f0fac74c99bfeb7c1e4650 new file mode 100644 index 00000000..24de751d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x07a4f7534ccd4d1a2893c4233b1addc44ec3a672d7f0fac74c99bfeb7c1e4650 @@ -0,0 +1 @@ +"0xf90131a080b4053526aa3f9eeead723f413de9449aa4066e6d54c701ac5bd5a05db08bf980a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca0b8a4ccd79e4c55573c4c1909205f8a64815b241b68749290e126968a01a55296a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x0e1adb36bae65d3155a1a7f0ab1f18cb8bd59db49e62cdebf6705b13116e15ca b/libraries/maker/test_data/test_chain/!trie_db!0x0e1adb36bae65d3155a1a7f0ab1f18cb8bd59db49e62cdebf6705b13116e15ca new file mode 100644 index 00000000..2625a687 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x0e1adb36bae65d3155a1a7f0ab1f18cb8bd59db49e62cdebf6705b13116e15ca @@ -0,0 +1 @@ +"0xf85120b84ef84c80887d705cb8966c4000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x0f6ebbd43b6a851db54d9cc542488786e9042bb4e8f6521d6f29c455c388f159 b/libraries/maker/test_data/test_chain/!trie_db!0x0f6ebbd43b6a851db54d9cc542488786e9042bb4e8f6521d6f29c455c388f159 new file mode 100644 index 00000000..7fcefd0f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x0f6ebbd43b6a851db54d9cc542488786e9042bb4e8f6521d6f29c455c388f159 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d05890568f5064263e60000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x10becc474a25f7d0d67dd3130916e6486ec73cd6c0e3d9c3354f22544dfc0a90 b/libraries/maker/test_data/test_chain/!trie_db!0x10becc474a25f7d0d67dd3130916e6486ec73cd6c0e3d9c3354f22544dfc0a90 new file mode 100644 index 00000000..493be66f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x10becc474a25f7d0d67dd3130916e6486ec73cd6c0e3d9c3354f22544dfc0a90 @@ -0,0 +1 @@ +"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a034d4377e4f0dee74f4a49f6c09d66f6d4ff253d260d052e8d5ffe022965d6ffc808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1302a403c9b0455ea025bbeed7b513046674ea00905aa34a6e9f7d0d97e86eb1 b/libraries/maker/test_data/test_chain/!trie_db!0x1302a403c9b0455ea025bbeed7b513046674ea00905aa34a6e9f7d0d97e86eb1 new file mode 100644 index 00000000..df19595a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1302a403c9b0455ea025bbeed7b513046674ea00905aa34a6e9f7d0d97e86eb1 @@ -0,0 +1 @@ +"0xf90131a0e471b75d1693dfa4458588ca431b54af9320eca119ece050d55e1b05a94bad2480a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0d35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919a0ab6df9bdf417e2156e3d5b8fe119c9f9366e0fb63b6e79c6840068695a6d3b47a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x14a96b69c2eef02d5e6634d7934993c4b23d133a8f96001f6a03a9664c02f758 b/libraries/maker/test_data/test_chain/!trie_db!0x14a96b69c2eef02d5e6634d7934993c4b23d133a8f96001f6a03a9664c02f758 new file mode 100644 index 00000000..4ddd4421 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x14a96b69c2eef02d5e6634d7934993c4b23d133a8f96001f6a03a9664c02f758 @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a066c5d0a6016165e537ac63b121df2d074c649a16b50ca7a2839abc5eb3894a9a" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1561a115b24603945911a073663c023089180aa738afe551ae06a21d98132b77 b/libraries/maker/test_data/test_chain/!trie_db!0x1561a115b24603945911a073663c023089180aa738afe551ae06a21d98132b77 new file mode 100644 index 00000000..8ba216dc --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1561a115b24603945911a073663c023089180aa738afe551ae06a21d98132b77 @@ -0,0 +1 @@ +"0xf90111a08202796f16ed68ec4c55687dd91c9eaf8eb1506c93c66179b72255e15104f292a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x157933e4f44b7ff7eb5b84bec2e32e7809151518a104fbff813500b0c235ab7c b/libraries/maker/test_data/test_chain/!trie_db!0x157933e4f44b7ff7eb5b84bec2e32e7809151518a104fbff813500b0c235ab7c new file mode 100644 index 00000000..8e43ee90 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x157933e4f44b7ff7eb5b84bec2e32e7809151518a104fbff813500b0c235ab7c @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a0fb53e64824f62daa3a1598b6864c077c8b3feafa8d6f93bb5185dcd52a55f4b5" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x160b20504872ea0c821139a14ec305c50928dbc5612ff1f0b1a58484a9e5e1e2 b/libraries/maker/test_data/test_chain/!trie_db!0x160b20504872ea0c821139a14ec305c50928dbc5612ff1f0b1a58484a9e5e1e2 new file mode 100644 index 00000000..00890517 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x160b20504872ea0c821139a14ec305c50928dbc5612ff1f0b1a58484a9e5e1e2 @@ -0,0 +1 @@ +"0x6080604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063143e55e0146100ca578063351de6001461010557806336569e771461019a5780634423c5f1146101f15780634b43ed12146103075780634e8b1dd5146103485780635ff3a382146103835780637d780d82146103c4578063c5ce281e146103ef578063c959c42b14610422578063cfc4af551461044f578063cfdd33021461048a578063fc7b6aee146104b5575b600080fd5b3480156100d657600080fd5b506100df6104e2565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561011157600080fd5b50610184600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803590602001909291905050506104ea565b6040518082815260200191505060405180910390f35b3480156101a657600080fd5b506101af6108e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156101fd57600080fd5b5061021c60048036038101908080359060200190929190505050610907565b604051808981526020018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018665ffffffffffff1665ffffffffffff1681526020018565ffffffffffff1665ffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019850505050505050505060405180910390f35b34801561031357600080fd5b506103466004803603810190808035906020019092919080359060200190929190803590602001909291905050506109d3565b005b34801561035457600080fd5b5061035d611020565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561038f57600080fd5b506103c2600480360381019080803590602001909291908035906020019092919080359060200190929190505050611038565b005b3480156103d057600080fd5b506103d961162c565b6040518082815260200191505060405180910390f35b3480156103fb57600080fd5b50610404611632565b60405180826000191660001916815260200191505060405180910390f35b34801561042e57600080fd5b5061044d60048036038101908080359060200190929190505050611638565b005b34801561045b57600080fd5b50610464611973565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b34801561049657600080fd5b5061049f61198b565b6040518082815260200191505060405180910390f35b3480156104c157600080fd5b506104e060048036038101908080359060200190929190505050611991565b005b600042905090565b6000806004600081546001019190508190559050826005600083815260200190815260200160002060000181905550836005600083815260200190815260200160002060010181905550336005600083815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360069054906101000a900465ffffffffffff166105a66104e2565b0160056000838152602001908152602001600020600201601a6101000a81548165ffffffffffff021916908365ffffffffffff160217905550866005600083815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550856005600083815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508460056000838152602001908152602001600020600501819055507fc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b381306000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166001548888338d600560008b8152602001908152602001600020600201601a9054906101000a900465ffffffffffff166107216104e2565b600560008d815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008e815260200190815260200160002060050154604051808d81526020018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018a600019166000191681526020018981526020018881526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018565ffffffffffff1665ffffffffffff1681526020018465ffffffffffff1665ffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019c5050505050505050505050505060405180910390a18091505095945050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60056020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160149054906101000a900465ffffffffffff169080600201601a9054906101000a900465ffffffffffff16908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060050154905088565b60006005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515610a2f57600080fd5b610a376104e2565b65ffffffffffff166005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161180610aac575060006005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16145b1515610ab757600080fd5b610abf6104e2565b65ffffffffffff1660056000858152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff16111515610b0457600080fd5b600560008481526020019081526020016000206001015482141515610b2857600080fd5b60056000848152602001908152602001600020600501548111151515610b4d57600080fd5b600560008481526020019081526020016000206000015481111515610b7157600080fd5b610b936002546005600086815260200190815260200160002060000154611a76565b81101580610bb65750600560008481526020019081526020016000206005015481145b1515610bc157600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000888152602001908152602001600020600001546040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610d0557600080fd5b505af1158015610d19573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600560008881526020019081526020016000206000015485036040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610e6357600080fd5b505af1158015610e77573d6000803e3d6000fd5b50505050336005600085815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806005600085815260200190815260200160002060000181905550600360009054906101000a900465ffffffffffff16610f086104e2565b016005600085815260200190815260200160002060020160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055507fd4aef477d7912041a69c5b85f2d78b618c76e40a4a92b91122c85ab5b404a64a838383336005600089815260200190815260200160002060020160149054906101000a900465ffffffffffff16610f976104e2565b604051808781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018365ffffffffffff1665ffffffffffff1681526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a1505050565b600360009054906101000a900465ffffffffffff1681565b60006005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561109457600080fd5b61109c6104e2565b65ffffffffffff166005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161180611111575060006005600085815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16145b151561111c57600080fd5b6111246104e2565b65ffffffffffff1660056000858152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff1611151561116957600080fd5b60056000848152602001908152602001600020600001548114151561118d57600080fd5b6005600084815260200190815260200160002060050154811415156111b157600080fd5b6005600084815260200190815260200160002060010154821015156111d557600080fd5b60056000848152602001908152602001600020600101546111f860025484611a76565b1115151561120557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b336005600087815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561133357600080fd5b505af1158015611347573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cdd3fde6001546005600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856005600089815260200190815260200160002060010154036040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561146f57600080fd5b505af1158015611483573d6000803e3d6000fd5b50505050336005600085815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816005600085815260200190815260200160002060010181905550600360009054906101000a900465ffffffffffff166115146104e2565b016005600085815260200190815260200160002060020160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055507f380cb3bf83f57ec05d0229938aeb5d4fba1de0228097701d1c03379c88cec5d4838383336005600089815260200190815260200160002060020160149054906101000a900465ffffffffffff166115a36104e2565b604051808781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018365ffffffffffff1665ffffffffffff1681526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a1505050565b60025481565b60015481565b6116406104e2565b65ffffffffffff166005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff161080156116b7575060006005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff1614155b8061170057506116c56104e2565b65ffffffffffff1660056000838152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff16105b151561170b57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cdd3fde6001546005600085815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660056000868152602001908152602001600020600101546040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561182d57600080fd5b505af1158015611841573d6000803e3d6000fd5b505050506005600082815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160146101000a81549065ffffffffffff021916905560028201601a6101000a81549065ffffffffffff02191690556003820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556004820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600582016000905550507f9b83ce9ac5e3a4e55a5b95c0e529b8cbe35d29682e2d851f51dd4e0bf9a6d3d1816119446104e2565b604051808381526020018265ffffffffffff1665ffffffffffff1681526020019250505060405180910390a150565b600360069054906101000a900465ffffffffffff1681565b60045481565b6119996104e2565b65ffffffffffff1660056000838152602001908152602001600020600201601a9054906101000a900465ffffffffffff1665ffffffffffff161015156119de57600080fd5b60006005600083815260200190815260200160002060020160149054906101000a900465ffffffffffff1665ffffffffffff16141515611a1d57600080fd5b600360069054906101000a900465ffffffffffff16611a3a6104e2565b0160056000838152602001908152602001600020600201601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555050565b6000670de0b6b3a7640000611aa8611a8e8585611aba565b6002670de0b6b3a7640000811515611aa257fe5b04611aea565b811515611ab157fe5b04905092915050565b600080821480611ad957508282838502925082811515611ad657fe5b04145b1515611ae457600080fd5b92915050565b60008282840191508110151515611b0057600080fd5b929150505600a165627a7a72305820d6c37b3c03f9212b2651562416a3be7df8798888dec5c1d26a4f7b4d1d9f88640029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x193d91e77927d4dd6888eb3cd28c6c3570cef82bd0ce193d6d78a420d076988f b/libraries/maker/test_data/test_chain/!trie_db!0x193d91e77927d4dd6888eb3cd28c6c3570cef82bd0ce193d6d78a420d076988f new file mode 100644 index 00000000..0c6f689c --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x193d91e77927d4dd6888eb3cd28c6c3570cef82bd0ce193d6d78a420d076988f @@ -0,0 +1 @@ +"0xf85fd720959438219779a699d67d7e7740b8c8f43d3e2dae2182a0bd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428bcb2089880e92596fd6290000cc208a89093a80000000002a3080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1ae66f56e80b6ce3f6dd2c657d165248c788005cbee34e61ff0a5459edae1722 b/libraries/maker/test_data/test_chain/!trie_db!0x1ae66f56e80b6ce3f6dd2c657d165248c788005cbee34e61ff0a5459edae1722 new file mode 100644 index 00000000..2ef1809b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1ae66f56e80b6ce3f6dd2c657d165248c788005cbee34e61ff0a5459edae1722 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d0189056b64cb27c8321000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2 b/libraries/maker/test_data/test_chain/!trie_db!0x1b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2 new file mode 100644 index 00000000..d52787c7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2 @@ -0,0 +1 @@ +"0xf866943463dbb283c08844ebc2aa38c225e3ebc6a0c4e4b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1b9fc114e1505a2ebf1b4ddc24cbc7831547495eda32e440e6708345d85e5bc0 b/libraries/maker/test_data/test_chain/!trie_db!0x1b9fc114e1505a2ebf1b4ddc24cbc7831547495eda32e440e6708345d85e5bc0 new file mode 100644 index 00000000..8fca3d29 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1b9fc114e1505a2ebf1b4ddc24cbc7831547495eda32e440e6708345d85e5bc0 @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a03692ebfcca6c72d823f2edef1158597c3c964404792d86cbd9b4027f828a022f" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1c178169738ade34156345610b0dbb907e6bdf72dcf5ad63422ba2e21f59f3ff b/libraries/maker/test_data/test_chain/!trie_db!0x1c178169738ade34156345610b0dbb907e6bdf72dcf5ad63422ba2e21f59f3ff new file mode 100644 index 00000000..c77274bd --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1c178169738ade34156345610b0dbb907e6bdf72dcf5ad63422ba2e21f59f3ff @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d078905667668ad058ca800a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1cf5126fea51794b0db1435d14bd933683c230379908b9899391e70c1bdfbe14 b/libraries/maker/test_data/test_chain/!trie_db!0x1cf5126fea51794b0db1435d14bd933683c230379908b9899391e70c1bdfbe14 new file mode 100644 index 00000000..6f1cfe63 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1cf5126fea51794b0db1435d14bd933683c230379908b9899391e70c1bdfbe14 @@ -0,0 +1 @@ +"0xf90111a01e566933d70b71a726f5cc492316cd71fe8ee35d224575d33e29280c409c3c8d80a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca01ae66f56e80b6ce3f6dd2c657d165248c788005cbee34e61ff0a5459edae1722a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde280808080a04e8bf0d45a3147eac8fc230cd9711ccec2dae78beadfdcf290c11b5ad5f0702a80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d b/libraries/maker/test_data/test_chain/!trie_db!0x1dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d new file mode 100644 index 00000000..7d8ab804 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d @@ -0,0 +1 @@ +"0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820167320a3f0aefab2d9d7492779c69a7f6bbea970d8290e17d3631fbed9ad93540029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x1e566933d70b71a726f5cc492316cd71fe8ee35d224575d33e29280c409c3c8d b/libraries/maker/test_data/test_chain/!trie_db!0x1e566933d70b71a726f5cc492316cd71fe8ee35d224575d33e29280c409c3c8d new file mode 100644 index 00000000..99ae3694 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x1e566933d70b71a726f5cc492316cd71fe8ee35d224575d33e29280c409c3c8d @@ -0,0 +1 @@ +"0xf871a0157933e4f44b7ff7eb5b84bec2e32e7809151518a104fbff813500b0c235ab7c808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x21844edeb0c63d6c416c3ac4ccf639034227a206e8d39e76dadd463b61e5508b b/libraries/maker/test_data/test_chain/!trie_db!0x21844edeb0c63d6c416c3ac4ccf639034227a206e8d39e76dadd463b61e5508b new file mode 100644 index 00000000..61aa46a6 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x21844edeb0c63d6c416c3ac4ccf639034227a206e8d39e76dadd463b61e5508b @@ -0,0 +1 @@ +"0xf85120b84ef84c80882a04b7209109f000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x2214fc392a3915c339364267b8fb9e17ab479f98d5f927e218df7171ae2fa22e b/libraries/maker/test_data/test_chain/!trie_db!0x2214fc392a3915c339364267b8fb9e17ab479f98d5f927e218df7171ae2fa22e new file mode 100644 index 00000000..9dda297d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x2214fc392a3915c339364267b8fb9e17ab479f98d5f927e218df7171ae2fa22e @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a07641a0ead83074c914ca25a99e4532ee4f35f55fe2c150517568b9040d83eb7f" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x22bb72309f6e88672f57b0adbf6eddd953d4050a6bcb736a9bae44ccb639bfa0 b/libraries/maker/test_data/test_chain/!trie_db!0x22bb72309f6e88672f57b0adbf6eddd953d4050a6bcb736a9bae44ccb639bfa0 new file mode 100644 index 00000000..3333c1c4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x22bb72309f6e88672f57b0adbf6eddd953d4050a6bcb736a9bae44ccb639bfa0 @@ -0,0 +1 @@ +"0xf3808080808080808080808080c22064a0f2bf1441ea4a8c925cf68ab80ed63d86d61ded11b1f08d633a16a808be066864808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x25fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577b b/libraries/maker/test_data/test_chain/!trie_db!0x25fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577b new file mode 100644 index 00000000..ce895faa --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x25fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577b @@ -0,0 +1 @@ +"0xf8669433086347c52a8878af71bb818509d484c6a2e1bfb84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x2755f446d0c4053242e02044d205ff5f10f34d7eada2b8170e32dbe7ce649b54 b/libraries/maker/test_data/test_chain/!trie_db!0x2755f446d0c4053242e02044d205ff5f10f34d7eada2b8170e32dbe7ce649b54 new file mode 100644 index 00000000..d8e2b87d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x2755f446d0c4053242e02044d205ff5f10f34d7eada2b8170e32dbe7ce649b54 @@ -0,0 +1 @@ +"0xf90131a054141933fa63670d278c0d533f96e09dba2150247a9c4a4e71fdf0b0dd0c8c2b80a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca00f6ebbd43b6a851db54d9cc542488786e9042bb4e8f6521d6f29c455c388f159a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a02b3927b8275f057efa8d7be266f32e70895c4474d6e5319d70b5e3ed8c24722c80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x27dfbb598caaf84884996f663f33b11b4260c4b8e4b9acea7464641ee98c176c b/libraries/maker/test_data/test_chain/!trie_db!0x27dfbb598caaf84884996f663f33b11b4260c4b8e4b9acea7464641ee98c176c new file mode 100644 index 00000000..fbc82a84 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x27dfbb598caaf84884996f663f33b11b4260c4b8e4b9acea7464641ee98c176c @@ -0,0 +1 @@ +"0xf85d94203f2400f1600f3f493a9a92704a29b96795af1ab846f8440180a06b41508fe01ac4fe9d58179885bf0e9127fa6eda02f7692fcbc6987adb041151a05cd303b71add8faa7c8cf60e3117b6b32f756742a4026aec069402d2dfe9cc25" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x294e0688e78b8ebe45c45e778e11e00302f5dc9d735569c1b5a4a0cf48b848e2 b/libraries/maker/test_data/test_chain/!trie_db!0x294e0688e78b8ebe45c45e778e11e00302f5dc9d735569c1b5a4a0cf48b848e2 new file mode 100644 index 00000000..caed1053 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x294e0688e78b8ebe45c45e778e11e00302f5dc9d735569c1b5a4a0cf48b848e2 @@ -0,0 +1 @@ +"0xea808080808080808080808080c22064d720959464d922894153be9eef7b7218dc565d1d0ce2a092808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x2ac25c8b39e9ba3a99e3983a69cc607e6b2a4f04adbe1abb9167b8b5d454056e b/libraries/maker/test_data/test_chain/!trie_db!0x2ac25c8b39e9ba3a99e3983a69cc607e6b2a4f04adbe1abb9167b8b5d454056e new file mode 100644 index 00000000..4de3996c --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x2ac25c8b39e9ba3a99e3983a69cc607e6b2a4f04adbe1abb9167b8b5d454056e @@ -0,0 +1 @@ +"0xf86694207bee5fcfd8028cf7b00876c5b1421c800561a6b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x2b3927b8275f057efa8d7be266f32e70895c4474d6e5319d70b5e3ed8c24722c b/libraries/maker/test_data/test_chain/!trie_db!0x2b3927b8275f057efa8d7be266f32e70895c4474d6e5319d70b5e3ed8c24722c new file mode 100644 index 00000000..11909483 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x2b3927b8275f057efa8d7be266f32e70895c4474d6e5319d70b5e3ed8c24722c @@ -0,0 +1 @@ +"0xf85d943c0ba85028256ef48f5ba64dd65dc258988955f6b846f8440180a0db0af948d55394775495207faf2541a5432ef2b567e0f6faccb7e193d64d48cfa01dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x2b90ac735ccaf20d1204ce987c10f24fa0ecf777dbe99525c0321a58f237aa23 b/libraries/maker/test_data/test_chain/!trie_db!0x2b90ac735ccaf20d1204ce987c10f24fa0ecf777dbe99525c0321a58f237aa23 new file mode 100644 index 00000000..74964e88 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x2b90ac735ccaf20d1204ce987c10f24fa0ecf777dbe99525c0321a58f237aa23 @@ -0,0 +1 @@ +"0xf871a05179412bdf3b1fdc681506fcf02a48f3c350619ac1beba18d698453faad284b0808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x315b6170f8978b4fce756cb2479b0b0ed256aaf4266920068c34aafec49bb2b1 b/libraries/maker/test_data/test_chain/!trie_db!0x315b6170f8978b4fce756cb2479b0b0ed256aaf4266920068c34aafec49bb2b1 new file mode 100644 index 00000000..accba8ee --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x315b6170f8978b4fce756cb2479b0b0ed256aaf4266920068c34aafec49bb2b1 @@ -0,0 +1 @@ +"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a03aeb3aa806a152ccfd51ab85640ba5dac102913e3782cbe2af8310a1247c5aa3808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x34d4377e4f0dee74f4a49f6c09d66f6d4ff253d260d052e8d5ffe022965d6ffc b/libraries/maker/test_data/test_chain/!trie_db!0x34d4377e4f0dee74f4a49f6c09d66f6d4ff253d260d052e8d5ffe022965d6ffc new file mode 100644 index 00000000..c6104dea --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x34d4377e4f0dee74f4a49f6c09d66f6d4ff253d260d052e8d5ffe022965d6ffc @@ -0,0 +1 @@ +"0xf842a000471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017a0bda48a1d334a501c0161da23c7ac8c5061abc0d5a8c87532b0588f57df6e26db" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3692ebfcca6c72d823f2edef1158597c3c964404792d86cbd9b4027f828a022f b/libraries/maker/test_data/test_chain/!trie_db!0x3692ebfcca6c72d823f2edef1158597c3c964404792d86cbd9b4027f828a022f new file mode 100644 index 00000000..49cffe0e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3692ebfcca6c72d823f2edef1158597c3c964404792d86cbd9b4027f828a022f @@ -0,0 +1 @@ +"0xf90111a0595254cf7b611ccf8a5ec65e448f532364805c5bf22aac6b84662e0883539de2a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x372afacecb5d397370430cfa7481601253172b63d77e80278ab3d4895b20001b b/libraries/maker/test_data/test_chain/!trie_db!0x372afacecb5d397370430cfa7481601253172b63d77e80278ab3d4895b20001b new file mode 100644 index 00000000..7941daad --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x372afacecb5d397370430cfa7481601253172b63d77e80278ab3d4895b20001b @@ -0,0 +1 @@ +"0xf8f180a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef2 b/libraries/maker/test_data/test_chain/!trie_db!0x3900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef2 new file mode 100644 index 00000000..cbb9c849 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef2 @@ -0,0 +1 @@ +"0xf866942040e006f4135ba6970d43bf43d88dcad4e7a8cab84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x39eb45844be0763684b87dbae75783d4c8373f2b79041c5deec61cc33bc0ac32 b/libraries/maker/test_data/test_chain/!trie_db!0x39eb45844be0763684b87dbae75783d4c8373f2b79041c5deec61cc33bc0ac32 new file mode 100644 index 00000000..1622cdd8 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x39eb45844be0763684b87dbae75783d4c8373f2b79041c5deec61cc33bc0ac32 @@ -0,0 +1 @@ +"0xf85c933da851034713f899a122f95860eaf707b9f833b846f8440180a0fdc8e630564f657910187c9eb1d7bf01e04231d016528da0062c123203eb1c79a087f40f40a31bbcb0abcacfa9b6e1e3504ae122fcb443c2a174a3c443be9e9288" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3a1b09fce6390882d7322ddbe543253cd6da427a07bf45dc8909180bbe48183e b/libraries/maker/test_data/test_chain/!trie_db!0x3a1b09fce6390882d7322ddbe543253cd6da427a07bf45dc8909180bbe48183e new file mode 100644 index 00000000..9978e7a5 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3a1b09fce6390882d7322ddbe543253cd6da427a07bf45dc8909180bbe48183e @@ -0,0 +1 @@ +"0xf85220b84ff84d80890128bff23d18b75800a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3ad54ef88f031c776dcc858e4339ee689f634fb929d7ac5d9ceec36c15b2779e b/libraries/maker/test_data/test_chain/!trie_db!0x3ad54ef88f031c776dcc858e4339ee689f634fb929d7ac5d9ceec36c15b2779e new file mode 100644 index 00000000..e9a0a16e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3ad54ef88f031c776dcc858e4339ee689f634fb929d7ac5d9ceec36c15b2779e @@ -0,0 +1 @@ +"0xf90111a0aa9f11e9216645caffc0b16ba04465953bbe7a9d5c1e321f1f022d21d86bc13880a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca0bea5ac5b5b294572a69eeb79ac50511dad8558456cbd1f0f99342215d69d141ca025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde280808080a0c03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3aeb3aa806a152ccfd51ab85640ba5dac102913e3782cbe2af8310a1247c5aa3 b/libraries/maker/test_data/test_chain/!trie_db!0x3aeb3aa806a152ccfd51ab85640ba5dac102913e3782cbe2af8310a1247c5aa3 new file mode 100644 index 00000000..645f51f9 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3aeb3aa806a152ccfd51ab85640ba5dac102913e3782cbe2af8310a1247c5aa3 @@ -0,0 +1 @@ +"0xf842a000471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017a022bb72309f6e88672f57b0adbf6eddd953d4050a6bcb736a9bae44ccb639bfa0" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3cc1c317257fc0571bcb469d8893b7329aaa0c7fd79852e6879c17327e31659b b/libraries/maker/test_data/test_chain/!trie_db!0x3cc1c317257fc0571bcb469d8893b7329aaa0c7fd79852e6879c17327e31659b new file mode 100644 index 00000000..9d1e80c7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3cc1c317257fc0571bcb469d8893b7329aaa0c7fd79852e6879c17327e31659b @@ -0,0 +1 @@ +"0xf842a000471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017a0a5d0993717b2edefc64e653c2b1f69222ac351f6f051bc010b3ae77a7a82cd8e" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3e9dee0a3894a2bd8b3ff56f496055d9c66346b4810abcf8ecc2f1ab13483e89 b/libraries/maker/test_data/test_chain/!trie_db!0x3e9dee0a3894a2bd8b3ff56f496055d9c66346b4810abcf8ecc2f1ab13483e89 new file mode 100644 index 00000000..6308c405 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3e9dee0a3894a2bd8b3ff56f496055d9c66346b4810abcf8ecc2f1ab13483e89 @@ -0,0 +1 @@ +"0xf90111a054ea506fbfef710a7ac83211106487c3920b195e7fc316d9e489de5bd09c77b2a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3ec08de1b6fc2f56324ce3a496f6945898622e7b8e875feb74d0578b18f6730c b/libraries/maker/test_data/test_chain/!trie_db!0x3ec08de1b6fc2f56324ce3a496f6945898622e7b8e875feb74d0578b18f6730c new file mode 100644 index 00000000..72d09895 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3ec08de1b6fc2f56324ce3a496f6945898622e7b8e875feb74d0578b18f6730c @@ -0,0 +1 @@ +"0xf90111a0cf2759c659bd860d34b51ade81828c957ccf8622569c2cb25a546bd325a84a2580a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca048bef2949d1b9e743c3372264d49e8811a5e316cc7eb8a0eb12cc91159e9bc89a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0c03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x3f5286f5cae259e122279b4ad4a24c5f98f82ec5b90976e8467e3d3e6445947e b/libraries/maker/test_data/test_chain/!trie_db!0x3f5286f5cae259e122279b4ad4a24c5f98f82ec5b90976e8467e3d3e6445947e new file mode 100644 index 00000000..b7b81870 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x3f5286f5cae259e122279b4ad4a24c5f98f82ec5b90976e8467e3d3e6445947e @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a0193d91e77927d4dd6888eb3cd28c6c3570cef82bd0ce193d6d78a420d076988f" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f b/libraries/maker/test_data/test_chain/!trie_db!0x406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f new file mode 100644 index 00000000..082efd67 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f @@ -0,0 +1 @@ +"0xf8669420243e26db94b5426032e6dfa6007802dea2a614b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f5 b/libraries/maker/test_data/test_chain/!trie_db!0x422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f5 new file mode 100644 index 00000000..3b24e60e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f5 @@ -0,0 +1 @@ +"0xf871a062ab8b4e7f7569eb032e637fcdcfd5b561442347326a3ffca40ae225d0029d4c808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4269a0201e3ae680b579c725e9bf6276dcd03776ad56573f386b24c7bd65a10b b/libraries/maker/test_data/test_chain/!trie_db!0x4269a0201e3ae680b579c725e9bf6276dcd03776ad56573f386b24c7bd65a10b new file mode 100644 index 00000000..239f80e7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4269a0201e3ae680b579c725e9bf6276dcd03776ad56573f386b24c7bd65a10b @@ -0,0 +1 @@ +"0xf891808080a03900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef280a0b2aea4b00c6faa6890b6e8256dcb98b86808a19ab61c59994ab8b8bdf9acfa4da07f7b46c4c5746aa251ed9a7453743bcd033f304dd1b8877087453f36a598018e808080808080a02ac25c8b39e9ba3a99e3983a69cc607e6b2a4f04adbe1abb9167b8b5d454056e808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x429b0f28e1011b174b50343f41f0d9cb6707fa8659ba6f0e93ff298b0f94cb49 b/libraries/maker/test_data/test_chain/!trie_db!0x429b0f28e1011b174b50343f41f0d9cb6707fa8659ba6f0e93ff298b0f94cb49 new file mode 100644 index 00000000..03c6fc4f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x429b0f28e1011b174b50343f41f0d9cb6707fa8659ba6f0e93ff298b0f94cb49 @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a03e9dee0a3894a2bd8b3ff56f496055d9c66346b4810abcf8ecc2f1ab13483e89" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x44feb02352f8a94bfdbaf401bf7044483059864224a8e2c0b3abfb4d56f17264 b/libraries/maker/test_data/test_chain/!trie_db!0x44feb02352f8a94bfdbaf401bf7044483059864224a8e2c0b3abfb4d56f17264 new file mode 100644 index 00000000..baca1fb4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x44feb02352f8a94bfdbaf401bf7044483059864224a8e2c0b3abfb4d56f17264 @@ -0,0 +1 @@ +"0xf85180808080808080a0cfe663a029b4580a64c6b23d74e9c54a7fb03d16ed52c503bf8dbd2ea0332a47808080a039eb45844be0763684b87dbae75783d4c8373f2b79041c5deec61cc33bc0ac328080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4584397d16a79dc5e2ad22b1c31aff4d5324e2208a73ca65e3a28b93adc85a8f b/libraries/maker/test_data/test_chain/!trie_db!0x4584397d16a79dc5e2ad22b1c31aff4d5324e2208a73ca65e3a28b93adc85a8f new file mode 100644 index 00000000..96b44d08 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4584397d16a79dc5e2ad22b1c31aff4d5324e2208a73ca65e3a28b93adc85a8f @@ -0,0 +1 @@ +"0xf871a054b4a1c61e5ad24ffdd1fbd8ad1e2a94b7af053151a44e0484166c0cd1581be9808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x46d92709b24bf67da10cef933a4d84948ada50b8ec963de13493518a0411bf5e b/libraries/maker/test_data/test_chain/!trie_db!0x46d92709b24bf67da10cef933a4d84948ada50b8ec963de13493518a0411bf5e new file mode 100644 index 00000000..12e54e15 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x46d92709b24bf67da10cef933a4d84948ada50b8ec963de13493518a0411bf5e @@ -0,0 +1 @@ +"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a0c454a94697819d0ce89be4706b7aef962fe14083d38e0f45b7cf3a7d3d24b032808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x48bef2949d1b9e743c3372264d49e8811a5e316cc7eb8a0eb12cc91159e9bc89 b/libraries/maker/test_data/test_chain/!trie_db!0x48bef2949d1b9e743c3372264d49e8811a5e316cc7eb8a0eb12cc91159e9bc89 new file mode 100644 index 00000000..9446d601 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x48bef2949d1b9e743c3372264d49e8811a5e316cc7eb8a0eb12cc91159e9bc89 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d0389056b3d6dc5af27c000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4a620dd91dbe73f56ca2fbac126a6d98f36699888043bee37beaa2efd72f32d8 b/libraries/maker/test_data/test_chain/!trie_db!0x4a620dd91dbe73f56ca2fbac126a6d98f36699888043bee37beaa2efd72f32d8 new file mode 100644 index 00000000..695305a4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4a620dd91dbe73f56ca2fbac126a6d98f36699888043bee37beaa2efd72f32d8 @@ -0,0 +1 @@ +"0xf8d1a0b849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df77080a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a280808080a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4cbd41e3ae7174e6b1850aa829299243d2c45d31ba72e5da22cb6fb5ded89eda b/libraries/maker/test_data/test_chain/!trie_db!0x4cbd41e3ae7174e6b1850aa829299243d2c45d31ba72e5da22cb6fb5ded89eda new file mode 100644 index 00000000..7c19faec --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4cbd41e3ae7174e6b1850aa829299243d2c45d31ba72e5da22cb6fb5ded89eda @@ -0,0 +1 @@ +"0xf85d94200ba85028256ef48f5ba64dd65dc258988955f6b846f8440180a0db0af948d55394775495207faf2541a5432ef2b567e0f6faccb7e193d64d48cfa01dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4e8bf0d45a3147eac8fc230cd9711ccec2dae78beadfdcf290c11b5ad5f0702a b/libraries/maker/test_data/test_chain/!trie_db!0x4e8bf0d45a3147eac8fc230cd9711ccec2dae78beadfdcf290c11b5ad5f0702a new file mode 100644 index 00000000..f8ce7e4e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4e8bf0d45a3147eac8fc230cd9711ccec2dae78beadfdcf290c11b5ad5f0702a @@ -0,0 +1 @@ +"0xf85d943c0ba85028256ef48f5ba64dd65dc258988955f6b846f8440180a0af884a3280efc05cbccc0c8e2fbf065aaa4165652efa1d89d174d440c96e25cfa01dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4ef305cd67b97b743669faa6b70fab3c29d545df173e5798da1a3bef0efeb5d9 b/libraries/maker/test_data/test_chain/!trie_db!0x4ef305cd67b97b743669faa6b70fab3c29d545df173e5798da1a3bef0efeb5d9 new file mode 100644 index 00000000..b0cc304a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4ef305cd67b97b743669faa6b70fab3c29d545df173e5798da1a3bef0efeb5d9 @@ -0,0 +1 @@ +"0xf6940000000000000000000000000000000000000000a0372afacecb5d397370430cfa7481601253172b63d77e80278ab3d4895b20001b" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x4fa6053972ef0f71dfeca3ad2c42ef1471f7597831c1b4cda4508d211e1e5fe7 b/libraries/maker/test_data/test_chain/!trie_db!0x4fa6053972ef0f71dfeca3ad2c42ef1471f7597831c1b4cda4508d211e1e5fe7 new file mode 100644 index 00000000..b9a6ea75 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x4fa6053972ef0f71dfeca3ad2c42ef1471f7597831c1b4cda4508d211e1e5fe7 @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a07ac0c41c0d80d8e020f83ae1b7f6bf62c1a5eca81c5d618a9512114809b884cb" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x5072a6c1e2e016ff4e5b6b35caf68673a43b7a13bb1fa82f2643bad3e4d1c253 b/libraries/maker/test_data/test_chain/!trie_db!0x5072a6c1e2e016ff4e5b6b35caf68673a43b7a13bb1fa82f2643bad3e4d1c253 new file mode 100644 index 00000000..d711d7bd --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x5072a6c1e2e016ff4e5b6b35caf68673a43b7a13bb1fa82f2643bad3e4d1c253 @@ -0,0 +1 @@ +"0xf8d180a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a80808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x50b3886d0b373a1bec1077a101dfbf8cdf97373f7698dc90befabe95a62c18d0 b/libraries/maker/test_data/test_chain/!trie_db!0x50b3886d0b373a1bec1077a101dfbf8cdf97373f7698dc90befabe95a62c18d0 new file mode 100644 index 00000000..0965e58d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x50b3886d0b373a1bec1077a101dfbf8cdf97373f7698dc90befabe95a62c18d0 @@ -0,0 +1 @@ +"0xf90131a0dc29fc9d85a41d5f7586954e84a9702e33d52ab2b78dbc8a4110bc4ab980592680a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a062b7219819310966c2f08a76b3b5915232be4e619fc829f4a1882a54200f8f94a0d35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919a0a3f2cd2ba5bc1fb673062bb9b6a68e54880eacdec18ffa1656ad572976b752cca025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x50c257a83e805b0c15f7dcdac955e22e29b2c6a89be444e7b996602c26dfc4c6 b/libraries/maker/test_data/test_chain/!trie_db!0x50c257a83e805b0c15f7dcdac955e22e29b2c6a89be444e7b996602c26dfc4c6 new file mode 100644 index 00000000..7f9b2ada --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x50c257a83e805b0c15f7dcdac955e22e29b2c6a89be444e7b996602c26dfc4c6 @@ -0,0 +1 @@ +"0xf8f1a0422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f580a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0c34b6254fe0b63fd193c05815394207384070546c321e43b2c8fe77c7d2f909da051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x5179412bdf3b1fdc681506fcf02a48f3c350619ac1beba18d698453faad284b0 b/libraries/maker/test_data/test_chain/!trie_db!0x5179412bdf3b1fdc681506fcf02a48f3c350619ac1beba18d698453faad284b0 new file mode 100644 index 00000000..c96340b0 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x5179412bdf3b1fdc681506fcf02a48f3c350619ac1beba18d698453faad284b0 @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a0b36069e00f14f31f6af8179ab19fc5c4e750959d0d6135c010c23f3bbc37bfd8" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x51e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194 b/libraries/maker/test_data/test_chain/!trie_db!0x51e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194 new file mode 100644 index 00000000..19381344 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x51e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x526dd67231b9088dffafec9d83e93dd46d770db9ada1151883868cf1192b59f5 b/libraries/maker/test_data/test_chain/!trie_db!0x526dd67231b9088dffafec9d83e93dd46d770db9ada1151883868cf1192b59f5 new file mode 100644 index 00000000..e453428e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x526dd67231b9088dffafec9d83e93dd46d770db9ada1151883868cf1192b59f5 @@ -0,0 +1 @@ +"0xf85220b84ff84d80890153a8643fc5404000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x54141933fa63670d278c0d533f96e09dba2150247a9c4a4e71fdf0b0dd0c8c2b b/libraries/maker/test_data/test_chain/!trie_db!0x54141933fa63670d278c0d533f96e09dba2150247a9c4a4e71fdf0b0dd0c8c2b new file mode 100644 index 00000000..69fd09cb --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x54141933fa63670d278c0d533f96e09dba2150247a9c4a4e71fdf0b0dd0c8c2b @@ -0,0 +1 @@ +"0xf871a02214fc392a3915c339364267b8fb9e17ab479f98d5f927e218df7171ae2fa22e808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x54350d30b48d6984395cf168b20e31952619100e01a31e619f91393e34d80ab5 b/libraries/maker/test_data/test_chain/!trie_db!0x54350d30b48d6984395cf168b20e31952619100e01a31e619f91393e34d80ab5 new file mode 100644 index 00000000..d244c1c9 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x54350d30b48d6984395cf168b20e31952619100e01a31e619f91393e34d80ab5 @@ -0,0 +1 @@ +"0xf85e95200000000000000000000000000000000000000001b846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x54b4a1c61e5ad24ffdd1fbd8ad1e2a94b7af053151a44e0484166c0cd1581be9 b/libraries/maker/test_data/test_chain/!trie_db!0x54b4a1c61e5ad24ffdd1fbd8ad1e2a94b7af053151a44e0484166c0cd1581be9 new file mode 100644 index 00000000..7272e020 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x54b4a1c61e5ad24ffdd1fbd8ad1e2a94b7af053151a44e0484166c0cd1581be9 @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a0faa013dc69cc994058701503d6e2bfc0e77581a8233aac88928620af541b9fbd" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x54ea506fbfef710a7ac83211106487c3920b195e7fc316d9e489de5bd09c77b2 b/libraries/maker/test_data/test_chain/!trie_db!0x54ea506fbfef710a7ac83211106487c3920b195e7fc316d9e489de5bd09c77b2 new file mode 100644 index 00000000..4a2dabef --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x54ea506fbfef710a7ac83211106487c3920b195e7fc316d9e489de5bd09c77b2 @@ -0,0 +1 @@ +"0xf85120b84ef84c808853b5c7d67efbb000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x5911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a b/libraries/maker/test_data/test_chain/!trie_db!0x5911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a new file mode 100644 index 00000000..73bd6fef --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x5911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a @@ -0,0 +1 @@ +"0xf84920b846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x59199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b0455 b/libraries/maker/test_data/test_chain/!trie_db!0x59199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b0455 new file mode 100644 index 00000000..149edfe4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x59199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b0455 @@ -0,0 +1 @@ +"0xf8669420fa9ef6609ca7921112231f8f195138ebba2977b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x595254cf7b611ccf8a5ec65e448f532364805c5bf22aac6b84662e0883539de2 b/libraries/maker/test_data/test_chain/!trie_db!0x595254cf7b611ccf8a5ec65e448f532364805c5bf22aac6b84662e0883539de2 new file mode 100644 index 00000000..f9951604 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x595254cf7b611ccf8a5ec65e448f532364805c5bf22aac6b84662e0883539de2 @@ -0,0 +1 @@ +"0xf85220b84ff84d808901a9b1322ba332e477a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x5cd303b71add8faa7c8cf60e3117b6b32f756742a4026aec069402d2dfe9cc25 b/libraries/maker/test_data/test_chain/!trie_db!0x5cd303b71add8faa7c8cf60e3117b6b32f756742a4026aec069402d2dfe9cc25 new file mode 100644 index 00000000..db37ced4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x5cd303b71add8faa7c8cf60e3117b6b32f756742a4026aec069402d2dfe9cc25 @@ -0,0 +1 @@ +"0x608060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806336569e77146100885780635a984ded146100df578063815d245d14610124578063957aa58c1461016d5780639be856111461019c578063babe8a3f146101d7578063d9638d3614610202575b600080fd5b34801561009457600080fd5b5061009d61024e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100eb57600080fd5b5061012260048036038101908080356000191690602001909291908035906020019092919080359060200190929190505050610274565b005b34801561013057600080fd5b5061016b60048036038101908080356000191690602001909291908035600019169060200190929190803590602001909291905050506107c3565b005b34801561017957600080fd5b506101826108bf565b604051808215151515815260200191505060405180910390f35b3480156101a857600080fd5b506101d56004803603810190808035600019169060200190929190803590602001909291905050506108d1565b005b3480156101e357600080fd5b506101ec610950565b6040518082815260200191505060405180910390f35b34801561020e57600080fd5b506102316004803603810190808035600019169060200190929190505050610956565b604051808381526020018281526020019250505060405180910390f35b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600080600080600080600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a4593c528e338f8f6040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600019166000191681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001945050505050600060405180830381600087803b15801561036057600080fd5b505af1158015610374573d6000803e3d6000fd5b50505050600260008e600019166000191681526020019081526020016000209950600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d9638d368e6040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600019166000191681526020019150506040805180830381600087803b15801561042d57600080fd5b505af1158015610441573d6000803e3d6000fd5b505050506040513d604081101561045757600080fd5b81019080805190602001909291908051906020019092919050505098509850600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632424be5c8e336040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050606060405180830381600087803b15801561054357600080fd5b505af1158015610557573d6000803e3d6000fd5b505050506040513d606081101561056d57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050965096509650600260008e60001916600019168152602001908152602001600020600101546105c1898b61097a565b131580156106905750600154600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc42e3096040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561065357600080fd5b505af1158015610667573d6000803e3d6000fd5b505050506040513d602081101561067d57600080fd5b8101908080519060200190929190505050125b935060008b1315925060008c121591506106aa858a61097a565b6106b8878c6000015461097a565b1215905083806106c55750825b80156106df57508280156106d65750815b806106de5750805b5b80156106f657506000809054906101000a900460ff165b151561070157600080fd5b6000891415151561071157600080fd5b7f37a20eca2501d96bb978add7bb15556741bede770b8bdf08bac546adfe9e389e8d33898989426040518087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018481526020018381526020018265ffffffffffff1665ffffffffffff168152602001965050505050505060405180910390a150505050505050505050505050565b7f73706f7400000000000000000000000000000000000000000000000000000000826000191614156108135780600260008560001916600019168152602001908152602001600020600001819055505b7f6c696e6500000000000000000000000000000000000000000000000000000000826000191614156108635780600260008560001916600019168152602001908152602001600020600101819055505b7fb80446ca592fac4d11848fd8a1aeb8b3de78791ab4079c424db00ed4547bb8768383836040518084600019166000191681526020018360001916600019168152602001828152602001935050505060405180910390a1505050565b6000809054906101000a900460ff1681565b7f4c696e65000000000000000000000000000000000000000000000000000000008260001916141561090557806001819055505b7f134b2912c1a5fbb942de04eb642d59a9b018427189818dd7c3ff65b7f948562e82826040518083600019166000191681526020018281526020019250505060405180910390a15050565b60015481565b60026020528060005260406000206000915090508060000154908060010154905082565b600081830290506000821215806109b157507f80000000000000000000000000000000000000000000000000000000000000008314155b15156109bc57600080fd5b60008214806109d557508282828115156109d257fe5b05145b15156109e057600080fd5b6b033b2e3c9fd0803ce8000000818115156109f757fe5b059050929150505600a165627a7a72305820ab1131a980e176ca0e098df00dec9b8067466d0d169ca68072ce1c1178e442800029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x5e287c9213b0dcabfdf484092e2b6133f6826e045c391501e80374760de69320 b/libraries/maker/test_data/test_chain/!trie_db!0x5e287c9213b0dcabfdf484092e2b6133f6826e045c391501e80374760de69320 new file mode 100644 index 00000000..bb473d2c --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x5e287c9213b0dcabfdf484092e2b6133f6826e045c391501e80374760de69320 @@ -0,0 +1 @@ +"0xf85180a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a8080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x60b37e6a056ee52545c169ae2074181fda1f14f9abb6363e4d9a152fd9f07c90 b/libraries/maker/test_data/test_chain/!trie_db!0x60b37e6a056ee52545c169ae2074181fda1f14f9abb6363e4d9a152fd9f07c90 new file mode 100644 index 00000000..10321f0b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x60b37e6a056ee52545c169ae2074181fda1f14f9abb6363e4d9a152fd9f07c90 @@ -0,0 +1 @@ +"0xead72095948e84a1e068d77059cbe263c43ad0cdc130863313c22002808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x62ab8b4e7f7569eb032e637fcdcfd5b561442347326a3ffca40ae225d0029d4c b/libraries/maker/test_data/test_chain/!trie_db!0x62ab8b4e7f7569eb032e637fcdcfd5b561442347326a3ffca40ae225d0029d4c new file mode 100644 index 00000000..f81615a6 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x62ab8b4e7f7569eb032e637fcdcfd5b561442347326a3ffca40ae225d0029d4c @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a0372afacecb5d397370430cfa7481601253172b63d77e80278ab3d4895b20001b" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x62b7219819310966c2f08a76b3b5915232be4e619fc829f4a1882a54200f8f94 b/libraries/maker/test_data/test_chain/!trie_db!0x62b7219819310966c2f08a76b3b5915232be4e619fc829f4a1882a54200f8f94 new file mode 100644 index 00000000..d0e51c08 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x62b7219819310966c2f08a76b3b5915232be4e619fc829f4a1882a54200f8f94 @@ -0,0 +1 @@ +"0xf8669434d922894153be9eef7b7218dc565d1d0ce2a092b84ff84d0189056bc75e2d630d8389a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x63a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2 b/libraries/maker/test_data/test_chain/!trie_db!0x63a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2 new file mode 100644 index 00000000..6308bd9f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x63a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2 @@ -0,0 +1 @@ +"0xf8669433e37186e017747dba34042e83e3f76ad3cce9b0b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x66c5d0a6016165e537ac63b121df2d074c649a16b50ca7a2839abc5eb3894a9a b/libraries/maker/test_data/test_chain/!trie_db!0x66c5d0a6016165e537ac63b121df2d074c649a16b50ca7a2839abc5eb3894a9a new file mode 100644 index 00000000..fa0eb94b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x66c5d0a6016165e537ac63b121df2d074c649a16b50ca7a2839abc5eb3894a9a @@ -0,0 +1 @@ +"0xe88080cb2089880e92596fd6290000cc208a89093a80000000002a3080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x67bcaf1d60f75a22d49b037c88c00e44733094250664cbfc9d9bbf9eda3ca745 b/libraries/maker/test_data/test_chain/!trie_db!0x67bcaf1d60f75a22d49b037c88c00e44733094250664cbfc9d9bbf9eda3ca745 new file mode 100644 index 00000000..aa17b399 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x67bcaf1d60f75a22d49b037c88c00e44733094250664cbfc9d9bbf9eda3ca745 @@ -0,0 +1 @@ +"0xf6941000000000000000000000000000000000000000a0fe3d828c2803bd586bc34641752157c205a391ec9a1b730031bccc77a9276b02" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x6b41508fe01ac4fe9d58179885bf0e9127fa6eda02f7692fcbc6987adb041151 b/libraries/maker/test_data/test_chain/!trie_db!0x6b41508fe01ac4fe9d58179885bf0e9127fa6eda02f7692fcbc6987adb041151 new file mode 100644 index 00000000..26351032 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x6b41508fe01ac4fe9d58179885bf0e9127fa6eda02f7692fcbc6987adb041151 @@ -0,0 +1 @@ +"0xf839a1200000000000000000000000000000000000000000000000000000000000000000969538219779a699d67d7e7740b8c8f43d3e2dae218201" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x6cebfe106ade0f88e6b68581d9f8b4def74d71d0cbf3ec3c5039ce6d0d2c35ae b/libraries/maker/test_data/test_chain/!trie_db!0x6cebfe106ade0f88e6b68581d9f8b4def74d71d0cbf3ec3c5039ce6d0d2c35ae new file mode 100644 index 00000000..f9035fff --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x6cebfe106ade0f88e6b68581d9f8b4def74d71d0cbf3ec3c5039ce6d0d2c35ae @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a0a855e7870075f22bca3187c9fcf5f0ae0f9bcf0bc40aba289d2876006140eada" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x74952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03 b/libraries/maker/test_data/test_chain/!trie_db!0x74952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03 new file mode 100644 index 00000000..4464d064 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x74952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03 @@ -0,0 +1 @@ +"0xf8669434d922894153be9eef7b7218dc565d1d0ce2a092b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x7604b45506a0b39430208425bde0a01f3705f6c9b1756f6c93fdc09248227c94 b/libraries/maker/test_data/test_chain/!trie_db!0x7604b45506a0b39430208425bde0a01f3705f6c9b1756f6c93fdc09248227c94 new file mode 100644 index 00000000..c99a82e8 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x7604b45506a0b39430208425bde0a01f3705f6c9b1756f6c93fdc09248227c94 @@ -0,0 +1 @@ +"0xf8b1a0b849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df77080a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a280808080a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c19480a063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x7641a0ead83074c914ca25a99e4532ee4f35f55fe2c150517568b9040d83eb7f b/libraries/maker/test_data/test_chain/!trie_db!0x7641a0ead83074c914ca25a99e4532ee4f35f55fe2c150517568b9040d83eb7f new file mode 100644 index 00000000..20757ad7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x7641a0ead83074c914ca25a99e4532ee4f35f55fe2c150517568b9040d83eb7f @@ -0,0 +1 @@ +"0xf90111a08f45dc1a11f3098f0ed77769955e86ec99632f505cabf3b3f3db6c1a72a4c7f4a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x77ecddca419c697a6aae21fa9a02f85475aaa5b109d41dc35f1893dc5bb3cf72 b/libraries/maker/test_data/test_chain/!trie_db!0x77ecddca419c697a6aae21fa9a02f85475aaa5b109d41dc35f1893dc5bb3cf72 new file mode 100644 index 00000000..292c5e8d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x77ecddca419c697a6aae21fa9a02f85475aaa5b109d41dc35f1893dc5bb3cf72 @@ -0,0 +1 @@ +"0xf6941000000000000000000000000000000000000000a0372afacecb5d397370430cfa7481601253172b63d77e80278ab3d4895b20001b" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x7876d09d07838d1e8aa713fdcb1da8149ab4fe2240dfa1ce57ec821d5b18c981 b/libraries/maker/test_data/test_chain/!trie_db!0x7876d09d07838d1e8aa713fdcb1da8149ab4fe2240dfa1ce57ec821d5b18c981 new file mode 100644 index 00000000..e684bfd4 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x7876d09d07838d1e8aa713fdcb1da8149ab4fe2240dfa1ce57ec821d5b18c981 @@ -0,0 +1 @@ +"0xf851a04ef305cd67b97b743669faa6b70fab3c29d545df173e5798da1a3bef0efeb5d980808080808080a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c1948080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x78e21e7abc575f28a786c1d79ca9cdf554979bddd265f772a5540fddbab91ef9 b/libraries/maker/test_data/test_chain/!trie_db!0x78e21e7abc575f28a786c1d79ca9cdf554979bddd265f772a5540fddbab91ef9 new file mode 100644 index 00000000..6f4172e2 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x78e21e7abc575f28a786c1d79ca9cdf554979bddd265f772a5540fddbab91ef9 @@ -0,0 +1 @@ +"0xf85120b84ef84c8088fdaeecb51345d000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x79b9aa7f3bfc53dde3d5f06102bce3649bc358aa26ea150ada9053e81bf7f579 b/libraries/maker/test_data/test_chain/!trie_db!0x79b9aa7f3bfc53dde3d5f06102bce3649bc358aa26ea150ada9053e81bf7f579 new file mode 100644 index 00000000..18f79cc9 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x79b9aa7f3bfc53dde3d5f06102bce3649bc358aa26ea150ada9053e81bf7f579 @@ -0,0 +1 @@ +"0xf84880a0bd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428bcb2089880e92596fd6290000cc208a89093a80000000002a3080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x7ac0c41c0d80d8e020f83ae1b7f6bf62c1a5eca81c5d618a9512114809b884cb b/libraries/maker/test_data/test_chain/!trie_db!0x7ac0c41c0d80d8e020f83ae1b7f6bf62c1a5eca81c5d618a9512114809b884cb new file mode 100644 index 00000000..91f556ab --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x7ac0c41c0d80d8e020f83ae1b7f6bf62c1a5eca81c5d618a9512114809b884cb @@ -0,0 +1 @@ +"0xe18080cb2089880e92596fd6290000c52083822a3080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x7f58526de3503c41aa43ef3fb1891a4f45c21d7b16f3f99f4e558a33436f1f76 b/libraries/maker/test_data/test_chain/!trie_db!0x7f58526de3503c41aa43ef3fb1891a4f45c21d7b16f3f99f4e558a33436f1f76 new file mode 100644 index 00000000..350683ec --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x7f58526de3503c41aa43ef3fb1891a4f45c21d7b16f3f99f4e558a33436f1f76 @@ -0,0 +1 @@ +"0xf8669420e37186e017747dba34042e83e3f76ad3cce9b0b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x7f7b46c4c5746aa251ed9a7453743bcd033f304dd1b8877087453f36a598018e b/libraries/maker/test_data/test_chain/!trie_db!0x7f7b46c4c5746aa251ed9a7453743bcd033f304dd1b8877087453f36a598018e new file mode 100644 index 00000000..93dba751 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x7f7b46c4c5746aa251ed9a7453743bcd033f304dd1b8877087453f36a598018e @@ -0,0 +1 @@ +"0xf85d9420189df410263ad1d9fe2f4af2eab3d24f1b6f41b846f8440180a0fdc8e630564f657910187c9eb1d7bf01e04231d016528da0062c123203eb1c79a08ee1bc00a0fdef60abe39832c2fbbb1590d1835ede9c484a98c742db028aa1c9" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x80b4053526aa3f9eeead723f413de9449aa4066e6d54c701ac5bd5a05db08bf9 b/libraries/maker/test_data/test_chain/!trie_db!0x80b4053526aa3f9eeead723f413de9449aa4066e6d54c701ac5bd5a05db08bf9 new file mode 100644 index 00000000..c89e9c46 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x80b4053526aa3f9eeead723f413de9449aa4066e6d54c701ac5bd5a05db08bf9 @@ -0,0 +1 @@ +"0xf871a0cdf03fdc6d63c3530d16f913b78ddc858ba8a78466e187b640d05ee1b307c52e808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8202796f16ed68ec4c55687dd91c9eaf8eb1506c93c66179b72255e15104f292 b/libraries/maker/test_data/test_chain/!trie_db!0x8202796f16ed68ec4c55687dd91c9eaf8eb1506c93c66179b72255e15104f292 new file mode 100644 index 00000000..1faea03d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8202796f16ed68ec4c55687dd91c9eaf8eb1506c93c66179b72255e15104f292 @@ -0,0 +1 @@ +"0xf85220b84ff84d808901800f0e10ad046800a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x83097864ebee0be81925b10976490ab2c71a0643e9f16e16807811b7112ed032 b/libraries/maker/test_data/test_chain/!trie_db!0x83097864ebee0be81925b10976490ab2c71a0643e9f16e16807811b7112ed032 new file mode 100644 index 00000000..fe96610e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x83097864ebee0be81925b10976490ab2c71a0643e9f16e16807811b7112ed032 @@ -0,0 +1 @@ +"0xf6941000000000000000000000000000000000000000a098ad39fb8468cbcb93a0990018ded196413ef989c0062341ff886889f39ab41b" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x87f40f40a31bbcb0abcacfa9b6e1e3504ae122fcb443c2a174a3c443be9e9288 b/libraries/maker/test_data/test_chain/!trie_db!0x87f40f40a31bbcb0abcacfa9b6e1e3504ae122fcb443c2a174a3c443be9e9288 new file mode 100644 index 00000000..806d3e75 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x87f40f40a31bbcb0abcacfa9b6e1e3504ae122fcb443c2a174a3c443be9e9288 @@ -0,0 +1 @@ +"0x6080604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b3146100b457806318160ddd1461011957806323b872dd1461014457806336569e77146101c957806370a0823114610220578063a9059cbb14610277578063b753a98c146102dc578063bb35783b14610329578063daea85c514610396578063dd62ed3e146103d9578063f2d5d56b14610450575b600080fd5b3480156100c057600080fd5b506100ff600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061049d565b604051808215151515815260200191505060405180910390f35b34801561012557600080fd5b5061012e6105f4565b6040518082815260200191505060405180910390f35b34801561015057600080fd5b506101af600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106bb565b604051808215151515815260200191505060405180910390f35b3480156101d557600080fd5b506101de610a6a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561022c57600080fd5b50610261600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a8f565b6040518082815260200191505060405180910390f35b34801561028357600080fd5b506102c2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8f565b604051808215151515815260200191505060405180910390f35b3480156102e857600080fd5b50610327600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610ba7565b005b34801561033557600080fd5b50610394600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bb7565b005b3480156103a257600080fd5b506103d7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bc8565b005b3480156103e557600080fd5b5061043a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bf6565b6040518082815260200191505060405180910390f35b34801561045c57600080fd5b5061049b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c1b565b005b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92533847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8502604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a16001905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc42e3096040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b505050506040513d60208110156106a557600080fd5b8101908080519060200190929190505050905090565b60003373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415801561079557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108b05781600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561082557600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb35783b8585856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156109a857600080fd5b505af11580156109bc573d6000803e3d6000fd5b505050507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1600190509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c25b346836040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015610b4d57600080fd5b505af1158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b81019080805190602001909291905050509050919050565b6000610b9c3384846106bb565b506001905092915050565b610bb23383836106bb565b505050565b610bc28383836106bb565b50505050565b610bf2817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61049d565b5050565b6001602052816000526040600020602052806000526040600020600091509150505481565b610c268233836106bb565b5050505600a165627a7a72305820406d34f0273b216f143451ab1358061466096cfda5c781ea771e8af7828a85170029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x87ff3bbe1430ed5cc0f2cc2ad5b75f139955ef1aa3d618d17cef880433e70dc6 b/libraries/maker/test_data/test_chain/!trie_db!0x87ff3bbe1430ed5cc0f2cc2ad5b75f139955ef1aa3d618d17cef880433e70dc6 new file mode 100644 index 00000000..d967f810 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x87ff3bbe1430ed5cc0f2cc2ad5b75f139955ef1aa3d618d17cef880433e70dc6 @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a0c10146e60c892a940009077be47b47625f3ca8023e92cc10bf73329a699933ad" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8a083a05cf77f2f36f6c055ac468fc88ab99335759bb47d22b0947229f0b170a b/libraries/maker/test_data/test_chain/!trie_db!0x8a083a05cf77f2f36f6c055ac468fc88ab99335759bb47d22b0947229f0b170a new file mode 100644 index 00000000..d1b4951e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8a083a05cf77f2f36f6c055ac468fc88ab99335759bb47d22b0947229f0b170a @@ -0,0 +1 @@ +"0xf6941000000000000000000000000000000000000000a05e287c9213b0dcabfdf484092e2b6133f6826e045c391501e80374760de69320" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8ac88fd296fe71814c119087c21bae16a9e5809241b5bd5a36845a5f5d357a6e b/libraries/maker/test_data/test_chain/!trie_db!0x8ac88fd296fe71814c119087c21bae16a9e5809241b5bd5a36845a5f5d357a6e new file mode 100644 index 00000000..3326d915 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8ac88fd296fe71814c119087c21bae16a9e5809241b5bd5a36845a5f5d357a6e @@ -0,0 +1 @@ +"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a0ed89ce8c7b8d2657d679fd3eb25076b5d12bd24ecfd91f2b19891722703a43e2808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8b1ba0894221f78d2d10aa32895e2d402fe71d272af2994483bb9b56e2f1b6ca b/libraries/maker/test_data/test_chain/!trie_db!0x8b1ba0894221f78d2d10aa32895e2d402fe71d272af2994483bb9b56e2f1b6ca new file mode 100644 index 00000000..54729896 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8b1ba0894221f78d2d10aa32895e2d402fe71d272af2994483bb9b56e2f1b6ca @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a0c2509c936c6a49946f4d1f8ea285ba22df97bb1283f3b5a8326d7ee1b2ba2ed2" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8e7e25bae88ad50ddb83a7aa4aff24663004533b92d8ef1947a6fd621b5c028f b/libraries/maker/test_data/test_chain/!trie_db!0x8e7e25bae88ad50ddb83a7aa4aff24663004533b92d8ef1947a6fd621b5c028f new file mode 100644 index 00000000..9c5aa306 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8e7e25bae88ad50ddb83a7aa4aff24663004533b92d8ef1947a6fd621b5c028f @@ -0,0 +1 @@ +"0x6080604052600080fd00a165627a7a72305820562865e6c1f558e8a54735c0ff54b7f6a1fbc65c540a84c894f17a5fec64110d0029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8ee1bc00a0fdef60abe39832c2fbbb1590d1835ede9c484a98c742db028aa1c9 b/libraries/maker/test_data/test_chain/!trie_db!0x8ee1bc00a0fdef60abe39832c2fbbb1590d1835ede9c484a98c742db028aa1c9 new file mode 100644 index 00000000..b2ae391d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8ee1bc00a0fdef60abe39832c2fbbb1590d1835ede9c484a98c742db028aa1c9 @@ -0,0 +1 @@ +"0x6080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305db45381461010157806307a832b41461012c5780630e01198b14610157578063143e55e0146101825780632506855a146101bd57806329ae8114146101ea5780632a1d2b3c1461022557806335aee16f1461025057806349dd5bb21461028557806353cb8def146102b057806364bd7013146102db578063697efb78146103065780637f49edc4146103335780639361266c1461037c578063bbbb0d7b146103a7578063d0adc35f146103d2578063d4e8be83146103fd578063f37ac61c1461044e575b600080fd5b34801561010d57600080fd5b5061011661047b565b6040518082815260200191505060405180910390f35b34801561013857600080fd5b5061014161048d565b6040518082815260200191505060405180910390f35b34801561016357600080fd5b5061016c61058b565b6040518082815260200191505060405180910390f35b34801561018e57600080fd5b506101976106d3565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b3480156101c957600080fd5b506101e8600480360381019080803590602001909291905050506106db565b005b3480156101f657600080fd5b50610223600480360381019080803560001916906020019092919080359060200190929190505050610822565b005b34801561023157600080fd5b5061023a6108d5565b6040518082815260200191505060405180910390f35b34801561025c57600080fd5b50610283600480360381019080803565ffffffffffff1690602001909291905050506108db565b005b34801561029157600080fd5b5061029a61096d565b6040518082815260200191505060405180910390f35b3480156102bc57600080fd5b506102c5610973565b6040518082815260200191505060405180910390f35b3480156102e757600080fd5b506102f0610979565b6040518082815260200191505060405180910390f35b34801561031257600080fd5b506103316004803603810190808035906020019092919050505061097f565b005b34801561033f57600080fd5b50610366600480360381019080803565ffffffffffff1690602001909291905050506109ca565b6040518082815260200191505060405180910390f35b34801561038857600080fd5b506103916109e2565b6040518082815260200191505060405180910390f35b3480156103b357600080fd5b506103bc6109e8565b6040518082815260200191505060405180910390f35b3480156103de57600080fd5b506103e7610b66565b6040518082815260200191505060405180910390f35b34801561040957600080fd5b5061044c6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b6c565b005b34801561045a57600080fd5b5061047960048036038101908080359060200190929190505050610cbf565b005b60006006546005546004540101905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636c25b346306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561054b57600080fd5b505af115801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b8101908080519060200190929190505050905090565b600060095460085461059b61047b565b01016105a561048d565b101515156105b257600080fd5b60006005541415156105c357600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7e9cd243060085460006040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561069357600080fd5b505af11580156106a7573d6000803e3d6000fd5b505050506040513d60208110156106bd57600080fd5b8101908080519060200190929190505050905090565b600042905090565b60065481111580156106f457506106f061048d565b8111155b15156106ff57600080fd5b806006600082825403925050819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee8cd7483030846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b15801561080757600080fd5b505af115801561081b573d6000803e3d6000fd5b5050505050565b7f6c756d70000000000000000000000000000000000000000000000000000000008260001916141561085657806008819055505b7f70616400000000000000000000000000000000000000000000000000000000008260001916141561088a57806009819055505b7f8a9b1ca0a6295c2e892a579edd3076c4914c2a82a4d5caab9420945c64c7fe4182826040518083600019166000191681526020018281526020019250505060405180910390a15050565b60065481565b600360008265ffffffffffff1665ffffffffffff16815260200190815260200160002054600460008282540392505081905550600360008265ffffffffffff1665ffffffffffff168152602001908152602001600020546005600082825401925050819055506000600360008365ffffffffffff1665ffffffffffff1681526020019081526020016000208190555050565b60055481565b60085481565b60075481565b806003600061098c6106d3565b65ffffffffffff1665ffffffffffff168152602001908152602001600020600082825401925050819055508060046000828254019250508190555050565b60036020528060005260406000206000915090505481565b60095481565b6000600854600554101515156109fd57600080fd5b6000610a0761048d565b141515610a1357600080fd5b600854600560008282540392505081905550600854600660008282540192505081905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b7e9cd24307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6008546040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b158015610b2657600080fd5b505af1158015610b3a573d6000803e3d6000fd5b505050506040513d6020811015610b5057600080fd5b8101908080519060200190929190505050905090565b60045481565b7f666c61700000000000000000000000000000000000000000000000000000000082600019161415610bda5780600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b7f666c6f700000000000000000000000000000000000000000000000000000000082600019161415610c485780600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b7fffca69346a2375c2fc87627e7f186fef2014acdc097e9c22e180b2ae18a04e9682826040518083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b610cc761048d565b8111158015610cd857506005548111155b1515610ce357600080fd5b806005600082825403925050819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee8cd7483030846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b158015610deb57600080fd5b505af1158015610dff573d6000803e3d6000fd5b50505050505600a165627a7a72305820b784bba2324a8daa646152e22c45afdbf26e4f511926cb5a966195539287f6290029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x8f45dc1a11f3098f0ed77769955e86ec99632f505cabf3b3f3db6c1a72a4c7f4 b/libraries/maker/test_data/test_chain/!trie_db!0x8f45dc1a11f3098f0ed77769955e86ec99632f505cabf3b3f3db6c1a72a4c7f4 new file mode 100644 index 00000000..0cf2f219 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x8f45dc1a11f3098f0ed77769955e86ec99632f505cabf3b3f3db6c1a72a4c7f4 @@ -0,0 +1 @@ +"0xf85120b84ef84c8088d2fd0c71ce060000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x907b9cb17ed4afdf1e49593aa2a077f3019a7e851ec9faf4b21ad72aea963675 b/libraries/maker/test_data/test_chain/!trie_db!0x907b9cb17ed4afdf1e49593aa2a077f3019a7e851ec9faf4b21ad72aea963675 new file mode 100644 index 00000000..db2835f0 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x907b9cb17ed4afdf1e49593aa2a077f3019a7e851ec9faf4b21ad72aea963675 @@ -0,0 +1 @@ +"0xf842a000471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017a0294e0688e78b8ebe45c45e778e11e00302f5dc9d735569c1b5a4a0cf48b848e2" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x96378ad746eed1418f76252c71aceef69fd13c10e815107467ebf53c1644bbc0 b/libraries/maker/test_data/test_chain/!trie_db!0x96378ad746eed1418f76252c71aceef69fd13c10e815107467ebf53c1644bbc0 new file mode 100644 index 00000000..1472a531 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x96378ad746eed1418f76252c71aceef69fd13c10e815107467ebf53c1644bbc0 @@ -0,0 +1 @@ +"0xf90111a078e21e7abc575f28a786c1d79ca9cdf554979bddd265f772a5540fddbab91ef9a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x977f3e78fd927245d850c04695f06db28c3c19f59f40e67ad6e7558c31669a10 b/libraries/maker/test_data/test_chain/!trie_db!0x977f3e78fd927245d850c04695f06db28c3c19f59f40e67ad6e7558c31669a10 new file mode 100644 index 00000000..bf6c3305 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x977f3e78fd927245d850c04695f06db28c3c19f59f40e67ad6e7558c31669a10 @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a079b9aa7f3bfc53dde3d5f06102bce3649bc358aa26ea150ada9053e81bf7f579" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x98ad39fb8468cbcb93a0990018ded196413ef989c0062341ff886889f39ab41b b/libraries/maker/test_data/test_chain/!trie_db!0x98ad39fb8468cbcb93a0990018ded196413ef989c0062341ff886889f39ab41b new file mode 100644 index 00000000..43f3b84b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x98ad39fb8468cbcb93a0990018ded196413ef989c0062341ff886889f39ab41b @@ -0,0 +1 @@ +"0xf8b180a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a8080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0x9d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa3 b/libraries/maker/test_data/test_chain/!trie_db!0x9d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa3 new file mode 100644 index 00000000..374731e8 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0x9d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa3 @@ -0,0 +1 @@ +"0xf85d9438219779a699d67d7e7740b8c8f43d3e2dae2182b846f8440180a0af884a3280efc05cbccc0c8e2fbf065aaa4165652efa1d89d174d440c96e25cfa0af5f20f6426af3e166955afda7cf465726738ab7ebb44fe0879a9029b4aa582f" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xa3f2cd2ba5bc1fb673062bb9b6a68e54880eacdec18ffa1656ad572976b752cc b/libraries/maker/test_data/test_chain/!trie_db!0xa3f2cd2ba5bc1fb673062bb9b6a68e54880eacdec18ffa1656ad572976b752cc new file mode 100644 index 00000000..03914864 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xa3f2cd2ba5bc1fb673062bb9b6a68e54880eacdec18ffa1656ad572976b752cc @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d098905626b950f5d979800a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xa5d0993717b2edefc64e653c2b1f69222ac351f6f051bc010b3ae77a7a82cd8e b/libraries/maker/test_data/test_chain/!trie_db!0xa5d0993717b2edefc64e653c2b1f69222ac351f6f051bc010b3ae77a7a82cd8e new file mode 100644 index 00000000..a8e5cadd --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xa5d0993717b2edefc64e653c2b1f69222ac351f6f051bc010b3ae77a7a82cd8e @@ -0,0 +1 @@ +"0xf84a808080808080808080808080c22064a0f2bf1441ea4a8c925cf68ab80ed63d86d61ded11b1f08d633a16a808be066864d72095947340e006f4135ba6970d43bf43d88dcad4e7a8ca8080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xa7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963 b/libraries/maker/test_data/test_chain/!trie_db!0xa7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963 new file mode 100644 index 00000000..e38f5866 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xa7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963 @@ -0,0 +1 @@ +"0xf866943d7bee5fcfd8028cf7b00876c5b1421c800561a6b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xa855e7870075f22bca3187c9fcf5f0ae0f9bcf0bc40aba289d2876006140eada b/libraries/maker/test_data/test_chain/!trie_db!0xa855e7870075f22bca3187c9fcf5f0ae0f9bcf0bc40aba289d2876006140eada new file mode 100644 index 00000000..ae84baf0 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xa855e7870075f22bca3187c9fcf5f0ae0f9bcf0bc40aba289d2876006140eada @@ -0,0 +1 @@ +"0xf861d720959438219779a699d67d7e7740b8c8f43d3e2dae2182a0bd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428bcb2089880e92596fd6290000cc208a89093a80000000002a30c22001808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xa965142b2b0f0b1fb2701ad3f57fad2d56471e0605fe795a4c1779c7f90b8650 b/libraries/maker/test_data/test_chain/!trie_db!0xa965142b2b0f0b1fb2701ad3f57fad2d56471e0605fe795a4c1779c7f90b8650 new file mode 100644 index 00000000..f9aea237 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xa965142b2b0f0b1fb2701ad3f57fad2d56471e0605fe795a4c1779c7f90b8650 @@ -0,0 +1 @@ +"0xf380808080808080a0bda48a1d334a501c0161da23c7ac8c5061abc0d5a8c87532b0588f57df6e26dbc230328080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xa9bfb1f25d67b7e48433ab939937886bcd21eb6f358949eeb9aa781747cd12f0 b/libraries/maker/test_data/test_chain/!trie_db!0xa9bfb1f25d67b7e48433ab939937886bcd21eb6f358949eeb9aa781747cd12f0 new file mode 100644 index 00000000..2ebeaf27 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xa9bfb1f25d67b7e48433ab939937886bcd21eb6f358949eeb9aa781747cd12f0 @@ -0,0 +1 @@ +"0xf839a1200000000000000000000000000000000000000000000000000000000000000000969538219779a699d67d7e7740b8c8f43d3e2dae218200" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xaa9f11e9216645caffc0b16ba04465953bbe7a9d5c1e321f1f022d21d86bc138 b/libraries/maker/test_data/test_chain/!trie_db!0xaa9f11e9216645caffc0b16ba04465953bbe7a9d5c1e321f1f022d21d86bc138 new file mode 100644 index 00000000..a729c897 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xaa9f11e9216645caffc0b16ba04465953bbe7a9d5c1e321f1f022d21d86bc138 @@ -0,0 +1 @@ +"0xf871a0429b0f28e1011b174b50343f41f0d9cb6707fa8659ba6f0e93ff298b0f94cb49808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xab6df9bdf417e2156e3d5b8fe119c9f9366e0fb63b6e79c6840068695a6d3b47 b/libraries/maker/test_data/test_chain/!trie_db!0xab6df9bdf417e2156e3d5b8fe119c9f9366e0fb63b6e79c6840068695a6d3b47 new file mode 100644 index 00000000..4dbf9c5d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xab6df9bdf417e2156e3d5b8fe119c9f9366e0fb63b6e79c6840068695a6d3b47 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d08890565301ac54f2fc000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xababfa40a16a76228f9c9289d3598e99571cd4f0fec9f550a211febe9215be1d b/libraries/maker/test_data/test_chain/!trie_db!0xababfa40a16a76228f9c9289d3598e99571cd4f0fec9f550a211febe9215be1d new file mode 100644 index 00000000..b9f395fe --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xababfa40a16a76228f9c9289d3598e99571cd4f0fec9f550a211febe9215be1d @@ -0,0 +1 @@ +"0xf85d9420cb6176addcca2e1d1ffe21bee464b72ee4cd8db846f8440180a046d92709b24bf67da10cef933a4d84948ada50b8ec963de13493518a0411bf5ea0160b20504872ea0c821139a14ec305c50928dbc5612ff1f0b1a58484a9e5e1e2" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xaca22053d89ebbf434c56097fbec7c814822c7113ba4fb6a3eff197356c7b0d0 b/libraries/maker/test_data/test_chain/!trie_db!0xaca22053d89ebbf434c56097fbec7c814822c7113ba4fb6a3eff197356c7b0d0 new file mode 100644 index 00000000..e1a75e5f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xaca22053d89ebbf434c56097fbec7c814822c7113ba4fb6a3eff197356c7b0d0 @@ -0,0 +1 @@ +"0xf90131a0b093ce9bfa6db5d783bab7a68d3db7dc0fa8ad95b1f8fe5e4f66df8b0a369b1480a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0d35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919a0a3f2cd2ba5bc1fb673062bb9b6a68e54880eacdec18ffa1656ad572976b752cca025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xae1c3ba42b6c8f2a271b7f56459c2add5676ba26e637d77963fd933a2108b7aa b/libraries/maker/test_data/test_chain/!trie_db!0xae1c3ba42b6c8f2a271b7f56459c2add5676ba26e637d77963fd933a2108b7aa new file mode 100644 index 00000000..94b549e1 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xae1c3ba42b6c8f2a271b7f56459c2add5676ba26e637d77963fd933a2108b7aa @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a0ef07ff19a8b934da7c4809afe1dc5b3548bf27bc66900c8e118c9187767cb85d" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xaf5f20f6426af3e166955afda7cf465726738ab7ebb44fe0879a9029b4aa582f b/libraries/maker/test_data/test_chain/!trie_db!0xaf5f20f6426af3e166955afda7cf465726738ab7ebb44fe0879a9029b4aa582f new file mode 100644 index 00000000..65198e40 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xaf5f20f6426af3e166955afda7cf465726738ab7ebb44fe0879a9029b4aa582f @@ -0,0 +1 @@ +"0x6080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806311045bee14610101578063143e55e0146101865780632424be5c146101c15780632d61a355146102345780634186706d1461025f578063673c17da146102c45780636c25b3461461032957806371854745146103805780637cdd3fde146103e5578063815d245d14610440578063a4593c5214610489578063b65337df146104ee578063bb35783b14610549578063d9638d36146105b6578063dc42e30914610602578063ebf0c7171461062d578063ee8cd74814610684578063f059212a146106f1575b600080fd5b34801561010d57600080fd5b506101846004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610748565b005b34801561019257600080fd5b5061019b610999565b604051808265ffffffffffff1665ffffffffffff16815260200191505060405180910390f35b3480156101cd57600080fd5b506102106004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109a1565b60405180848152602001838152602001828152602001935050505060405180910390f35b34801561024057600080fd5b506102496109d8565b6040518082815260200191505060405180910390f35b34801561026b57600080fd5b506102ae6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109de565b6040518082815260200191505060405180910390f35b3480156102d057600080fd5b506103136004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a44565b6040518082815260200191505060405180910390f35b34801561033557600080fd5b5061036a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610aaa565b6040518082815260200191505060405180910390f35b34801561038c57600080fd5b506103cf6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ac2565b6040518082815260200191505060405180910390f35b3480156103f157600080fd5b5061043e6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b28565b005b34801561044c57600080fd5b506104876004803603810190808035600019169060200190929190803560001916906020019092919080359060200190929190505050610bf1565b005b34801561049557600080fd5b506104ec6004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610c46565b005b3480156104fa57600080fd5b506105476004803603810190808035600019169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eac565b005b34801561055557600080fd5b506105b4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105e565b005b3480156105c257600080fd5b506105e56004803603810190808035600019169060200190929190505050611268565b604051808381526020018281526020019250505060405180910390f35b34801561060e57600080fd5b5061061761128c565b6040518082815260200191505060405180910390f35b34801561063957600080fd5b50610642611292565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561069057600080fd5b506106ef600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506112b7565b005b3480156106fd57600080fd5b50610732600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061157d565b6040518082815260200191505060405180910390f35b60008060046000886000191660001916815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020915060036000886000191660001916815260200190815260200160002090506107d0826001015485611595565b82600101819055506107e6826002015484611595565b82600201819055506107fc816001015484611595565b816001018190555061085a600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546108558360000154866115d6565b61165c565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108b66006546108b18360000154866115d6565b61165c565b6006819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b830866108ed8460000154876115d6565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f6772616200000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a150505050505050565b600042905090565b6004602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154905083565b60065481565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905092915050565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154905092915050565b60016020528060005260406000206000915090505481565b600060046000846000191660001916815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b610b8d60046000856000191660001916815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015482611595565b60046000856000191660001916815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550505050565b7f726174650000000000000000000000000000000000000000000000000000000082600019161415610c415780600360008560001916600019168152602001908152602001600020600001819055505b505050565b60008060046000876000191660001916815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091506003600087600019166000191681526020019081526020016000209050610cce82600001548561165c565b8260000181905550610ce4826001015485611595565b8260010181905550610cfa826002015484611595565b8260020181905550610d10816001015484611595565b8160010181905550610d6e600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d698360000154866115d6565b611595565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dca600554610dc58360000154866115d6565b611595565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b83086610e018460000154876115d6565b604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f74756e6500000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a1505050505050565b6000806003600086600019166000191681526020019081526020016000209150610eda826000015484611595565b8260000181905550610ef08260010154846115d6565b9050610f3b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611595565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f8a60055482611595565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b8308583604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f666f6c6400000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a15050505050565b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054121515156110ac57600080fd5b6110f5600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611181600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482611595565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fdeb3a6837278f6e9914a507e4d73f08e841d8fca434fb97d4307b3b0d3d6b105838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b60036020528060005260406000206000915090508060000154908060010154905082565b60055481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541215151561130557600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541215151561135357600080fd5b806006541215151561136457600080fd5b806005541215151561137557600080fd5b6113be600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061144a600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548261165c565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506114996006548261165c565b6006819055506114ab6005548261165c565b6005819055507fd7176cd3481e210e438a7a7ebd026b079f7009a955df920778ee60eb0a2fa1b8308383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001807f6865616c00000000000000000000000000000000000000000000000000000000815250602001935050505060405180910390a1505050565b60026020528060005260406000206000915090505481565b600081830190506000821315806115ab57508281135b15156115b657600080fd5b6000821215806115c557508281125b15156115d057600080fd5b92915050565b6000818302905060008212158061160d57507f80000000000000000000000000000000000000000000000000000000000000008314155b151561161857600080fd5b6000821480611631575082828281151561162e57fe5b05145b151561163c57600080fd5b6b033b2e3c9fd0803ce80000008181151561165357fe5b05905092915050565b60007f8000000000000000000000000000000000000000000000000000000000000000821415151561168d57600080fd5b61169a8383600003611595565b9050929150505600a165627a7a72305820ec063dfa37ad5b689da9bf20703341f9ef9e167b6dfe9adf2920e8eec668cba20029" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xaf884a3280efc05cbccc0c8e2fbf065aaa4165652efa1d89d174d440c96e25cf b/libraries/maker/test_data/test_chain/!trie_db!0xaf884a3280efc05cbccc0c8e2fbf065aaa4165652efa1d89d174d440c96e25cf new file mode 100644 index 00000000..51d299f7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xaf884a3280efc05cbccc0c8e2fbf065aaa4165652efa1d89d174d440c96e25cf @@ -0,0 +1 @@ +"0xf838a120000000000000000000000000000000000000000000000000000000000000000095948e84a1e068d77059cbe263c43ad0cdc130863313" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xafc7c6a8161d69dc1b082bbf799d38f88c2f251a7504b87039b2a4f682cbf323 b/libraries/maker/test_data/test_chain/!trie_db!0xafc7c6a8161d69dc1b082bbf799d38f88c2f251a7504b87039b2a4f682cbf323 new file mode 100644 index 00000000..37b70ed5 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xafc7c6a8161d69dc1b082bbf799d38f88c2f251a7504b87039b2a4f682cbf323 @@ -0,0 +1 @@ +"0xf8f1a0422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f580a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab3 b/libraries/maker/test_data/test_chain/!trie_db!0xb07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab3 new file mode 100644 index 00000000..151cae0f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab3 @@ -0,0 +1 @@ +"0xf851808080808080808080808080a04cbd41e3ae7174e6b1850aa829299243d2c45d31ba72e5da22cb6fb5ded89eda8080a027dfbb598caaf84884996f663f33b11b4260c4b8e4b9acea7464641ee98c176c80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb093ce9bfa6db5d783bab7a68d3db7dc0fa8ad95b1f8fe5e4f66df8b0a369b14 b/libraries/maker/test_data/test_chain/!trie_db!0xb093ce9bfa6db5d783bab7a68d3db7dc0fa8ad95b1f8fe5e4f66df8b0a369b14 new file mode 100644 index 00000000..f66a49a7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb093ce9bfa6db5d783bab7a68d3db7dc0fa8ad95b1f8fe5e4f66df8b0a369b14 @@ -0,0 +1 @@ +"0xf891a0c81d5533ce94ec680095939e45ba3d6a775b7c067a2f1fb1966bce0da728835a808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b0455a0c5efe80126d2f4bb222c3d78e5ee3769d04d971e0cae935a09538cacde59d972808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb2409e30945c4de021f839faad355d13a20bec9382d722959b2dd34cc06f7956 b/libraries/maker/test_data/test_chain/!trie_db!0xb2409e30945c4de021f839faad355d13a20bec9382d722959b2dd34cc06f7956 new file mode 100644 index 00000000..838b887c --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb2409e30945c4de021f839faad355d13a20bec9382d722959b2dd34cc06f7956 @@ -0,0 +1 @@ +"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a03cc1c317257fc0571bcb469d8893b7329aaa0c7fd79852e6879c17327e31659b808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb2aea4b00c6faa6890b6e8256dcb98b86808a19ab61c59994ab8b8bdf9acfa4d b/libraries/maker/test_data/test_chain/!trie_db!0xb2aea4b00c6faa6890b6e8256dcb98b86808a19ab61c59994ab8b8bdf9acfa4d new file mode 100644 index 00000000..24ce005a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb2aea4b00c6faa6890b6e8256dcb98b86808a19ab61c59994ab8b8bdf9acfa4d @@ -0,0 +1 @@ +"0xf866942026eb4f95e2a1394797cb38a921fb1eba09291bb84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb36069e00f14f31f6af8179ab19fc5c4e750959d0d6135c010c23f3bbc37bfd8 b/libraries/maker/test_data/test_chain/!trie_db!0xb36069e00f14f31f6af8179ab19fc5c4e750959d0d6135c010c23f3bbc37bfd8 new file mode 100644 index 00000000..d71615fa --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb36069e00f14f31f6af8179ab19fc5c4e750959d0d6135c010c23f3bbc37bfd8 @@ -0,0 +1 @@ +"0xf90111a0b53a58d1f1f96b20865f6c8c8090467201e6cb399f8506276bb47064462610c9a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb53a58d1f1f96b20865f6c8c8090467201e6cb399f8506276bb47064462610c9 b/libraries/maker/test_data/test_chain/!trie_db!0xb53a58d1f1f96b20865f6c8c8090467201e6cb399f8506276bb47064462610c9 new file mode 100644 index 00000000..ccc9ef05 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb53a58d1f1f96b20865f6c8c8090467201e6cb399f8506276bb47064462610c9 @@ -0,0 +1 @@ +"0xf85120b84ef84c8088a9514ff9d73e0000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df770 b/libraries/maker/test_data/test_chain/!trie_db!0xb849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df770 new file mode 100644 index 00000000..4f3a51a7 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df770 @@ -0,0 +1 @@ +"0xf851a062ab8b4e7f7569eb032e637fcdcfd5b561442347326a3ffca40ae225d0029d4c8080808080808080808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb8a4ccd79e4c55573c4c1909205f8a64815b241b68749290e126968a01a55296 b/libraries/maker/test_data/test_chain/!trie_db!0xb8a4ccd79e4c55573c4c1909205f8a64815b241b68749290e126968a01a55296 new file mode 100644 index 00000000..9008b2ca --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb8a4ccd79e4c55573c4c1909205f8a64815b241b68749290e126968a01a55296 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d06890567e54a1a14d23000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xb9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a b/libraries/maker/test_data/test_chain/!trie_db!0xb9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a new file mode 100644 index 00000000..b28feb1b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xb9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a @@ -0,0 +1 @@ +"0xf851808080a07f58526de3503c41aa43ef3fb1891a4f45c21d7b16f3f99f4e558a33436f1f768080808080a0e76d776e0fd3e779b1154f656e88a16b2303744aa3fc59034662092c8e68856980808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xbd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428b b/libraries/maker/test_data/test_chain/!trie_db!0xbd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428b new file mode 100644 index 00000000..45790c52 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xbd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428b @@ -0,0 +1 @@ +"0xe320a1a066616b6520696c6b000000000000000000000000000000000000000000000000" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xbda48a1d334a501c0161da23c7ac8c5061abc0d5a8c87532b0588f57df6e26db b/libraries/maker/test_data/test_chain/!trie_db!0xbda48a1d334a501c0161da23c7ac8c5061abc0d5a8c87532b0588f57df6e26db new file mode 100644 index 00000000..ee24a6b8 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xbda48a1d334a501c0161da23c7ac8c5061abc0d5a8c87532b0588f57df6e26db @@ -0,0 +1 @@ +"0xf861808080808080808080808080c22064a0f2bf1441ea4a8c925cf68ab80ed63d86d61ded11b1f08d633a16a808be066864d72095947340e006f4135ba6970d43bf43d88dcad4e7a8cad720959407fa9ef6609ca7921112231f8f195138ebba297780" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xbe5e9c050b511a60562962583893f9973c43ce27b29cb8269642240cc817b42a b/libraries/maker/test_data/test_chain/!trie_db!0xbe5e9c050b511a60562962583893f9973c43ce27b29cb8269642240cc817b42a new file mode 100644 index 00000000..f3ac1cc2 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xbe5e9c050b511a60562962583893f9973c43ce27b29cb8269642240cc817b42a @@ -0,0 +1 @@ +"0xf90131a04584397d16a79dc5e2ad22b1c31aff4d5324e2208a73ca65e3a28b93adc85a8f80a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a04269a0201e3ae680b579c725e9bf6276dcd03776ad56573f386b24c7bd65a10ba01c178169738ade34156345610b0dbb907e6bdf72dcf5ad63422ba2e21f59f3ffa025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xbea5ac5b5b294572a69eeb79ac50511dad8558456cbd1f0f99342215d69d141c b/libraries/maker/test_data/test_chain/!trie_db!0xbea5ac5b5b294572a69eeb79ac50511dad8558456cbd1f0f99342215d69d141c new file mode 100644 index 00000000..8d8c07ed --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xbea5ac5b5b294572a69eeb79ac50511dad8558456cbd1f0f99342215d69d141c @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d0289056b55de8cd06c5000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca b/libraries/maker/test_data/test_chain/!trie_db!0xc03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca new file mode 100644 index 00000000..5f411f24 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca @@ -0,0 +1 @@ +"0xf85d943c0ba85028256ef48f5ba64dd65dc258988955f6b846f8440180a08b1ba0894221f78d2d10aa32895e2d402fe71d272af2994483bb9b56e2f1b6caa01dd53620e42fc2cb4123bb7f46ba314f34ed23ca34f9fa01dab86cf82353983d" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc10146e60c892a940009077be47b47625f3ca8023e92cc10bf73329a699933ad b/libraries/maker/test_data/test_chain/!trie_db!0xc10146e60c892a940009077be47b47625f3ca8023e92cc10bf73329a699933ad new file mode 100644 index 00000000..ff6ffcd5 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc10146e60c892a940009077be47b47625f3ca8023e92cc10bf73329a699933ad @@ -0,0 +1 @@ +"0xf90111a00e1adb36bae65d3155a1a7f0ab1f18cb8bd59db49e62cdebf6705b13116e15caa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc2509c936c6a49946f4d1f8ea285ba22df97bb1283f3b5a8326d7ee1b2ba2ed2 b/libraries/maker/test_data/test_chain/!trie_db!0xc2509c936c6a49946f4d1f8ea285ba22df97bb1283f3b5a8326d7ee1b2ba2ed2 new file mode 100644 index 00000000..e9daf740 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc2509c936c6a49946f4d1f8ea285ba22df97bb1283f3b5a8326d7ee1b2ba2ed2 @@ -0,0 +1 @@ +"0xead72095948e84a1e068d77059cbe263c43ad0cdc130863313c22001808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc34b6254fe0b63fd193c05815394207384070546c321e43b2c8fe77c7d2f909d b/libraries/maker/test_data/test_chain/!trie_db!0xc34b6254fe0b63fd193c05815394207384070546c321e43b2c8fe77c7d2f909d new file mode 100644 index 00000000..f91726c0 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc34b6254fe0b63fd193c05815394207384070546c321e43b2c8fe77c7d2f909d @@ -0,0 +1 @@ +"0xf851808080a03900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef2808080808080808080a02ac25c8b39e9ba3a99e3983a69cc607e6b2a4f04adbe1abb9167b8b5d454056e808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc454a94697819d0ce89be4706b7aef962fe14083d38e0f45b7cf3a7d3d24b032 b/libraries/maker/test_data/test_chain/!trie_db!0xc454a94697819d0ce89be4706b7aef962fe14083d38e0f45b7cf3a7d3d24b032 new file mode 100644 index 00000000..0f067929 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc454a94697819d0ce89be4706b7aef962fe14083d38e0f45b7cf3a7d3d24b032 @@ -0,0 +1 @@ +"0xf8419f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd8101a0a965142b2b0f0b1fb2701ad3f57fad2d56471e0605fe795a4c1779c7f90b8650" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc4f6a1f0b681632674246c126fd0b2eb33764bdb3ec5763b93968f205314944c b/libraries/maker/test_data/test_chain/!trie_db!0xc4f6a1f0b681632674246c126fd0b2eb33764bdb3ec5763b93968f205314944c new file mode 100644 index 00000000..4ce9496e --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc4f6a1f0b681632674246c126fd0b2eb33764bdb3ec5763b93968f205314944c @@ -0,0 +1 @@ +"0xf6941000000000000000000000000000000000000000a0c74b55ae25b522915216f62ea6ffcd436f6c6d4fe14a771042f7d4cea5cfa92f" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc5efe80126d2f4bb222c3d78e5ee3769d04d971e0cae935a09538cacde59d972 b/libraries/maker/test_data/test_chain/!trie_db!0xc5efe80126d2f4bb222c3d78e5ee3769d04d971e0cae935a09538cacde59d972 new file mode 100644 index 00000000..d5e17f7a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc5efe80126d2f4bb222c3d78e5ee3769d04d971e0cae935a09538cacde59d972 @@ -0,0 +1 @@ +"0xf85d9420cb6176addcca2e1d1ffe21bee464b72ee4cd8db846f8440180a03f5286f5cae259e122279b4ad4a24c5f98f82ec5b90976e8467e3d3e6445947ea0160b20504872ea0c821139a14ec305c50928dbc5612ff1f0b1a58484a9e5e1e2" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc74b55ae25b522915216f62ea6ffcd436f6c6d4fe14a771042f7d4cea5cfa92f b/libraries/maker/test_data/test_chain/!trie_db!0xc74b55ae25b522915216f62ea6ffcd436f6c6d4fe14a771042f7d4cea5cfa92f new file mode 100644 index 00000000..3c3d65f2 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc74b55ae25b522915216f62ea6ffcd436f6c6d4fe14a771042f7d4cea5cfa92f @@ -0,0 +1 @@ +"0xf89180a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xc81d5533ce94ec680095939e45ba3d6a775b7c067a2f1fb1966bce0da728835a b/libraries/maker/test_data/test_chain/!trie_db!0xc81d5533ce94ec680095939e45ba3d6a775b7c067a2f1fb1966bce0da728835a new file mode 100644 index 00000000..8abfcecc --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xc81d5533ce94ec680095939e45ba3d6a775b7c067a2f1fb1966bce0da728835a @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a01561a115b24603945911a073663c023089180aa738afe551ae06a21d98132b77" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xcdf03fdc6d63c3530d16f913b78ddc858ba8a78466e187b640d05ee1b307c52e b/libraries/maker/test_data/test_chain/!trie_db!0xcdf03fdc6d63c3530d16f913b78ddc858ba8a78466e187b640d05ee1b307c52e new file mode 100644 index 00000000..4ff61373 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xcdf03fdc6d63c3530d16f913b78ddc858ba8a78466e187b640d05ee1b307c52e @@ -0,0 +1 @@ +"0xf59310000000000000000000000000000000000000a096378ad746eed1418f76252c71aceef69fd13c10e815107467ebf53c1644bbc0" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xcf2759c659bd860d34b51ade81828c957ccf8622569c2cb25a546bd325a84a25 b/libraries/maker/test_data/test_chain/!trie_db!0xcf2759c659bd860d34b51ade81828c957ccf8622569c2cb25a546bd325a84a25 new file mode 100644 index 00000000..2c05cb1f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xcf2759c659bd860d34b51ade81828c957ccf8622569c2cb25a546bd325a84a25 @@ -0,0 +1 @@ +"0xf871a087ff3bbe1430ed5cc0f2cc2ad5b75f139955ef1aa3d618d17cef880433e70dc6808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xcfe663a029b4580a64c6b23d74e9c54a7fb03d16ed52c503bf8dbd2ea0332a47 b/libraries/maker/test_data/test_chain/!trie_db!0xcfe663a029b4580a64c6b23d74e9c54a7fb03d16ed52c503bf8dbd2ea0332a47 new file mode 100644 index 00000000..e167aa8d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xcfe663a029b4580a64c6b23d74e9c54a7fb03d16ed52c503bf8dbd2ea0332a47 @@ -0,0 +1 @@ +"0xf865933bee5fcfd8028cf7b00876c5b1421c800561a6b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xd167b284cd9e648f2508afc91308534ad0c1c0b77bb37c4abab7043a4f758ef2 b/libraries/maker/test_data/test_chain/!trie_db!0xd167b284cd9e648f2508afc91308534ad0c1c0b77bb37c4abab7043a4f758ef2 new file mode 100644 index 00000000..e1c27f19 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xd167b284cd9e648f2508afc91308534ad0c1c0b77bb37c4abab7043a4f758ef2 @@ -0,0 +1 @@ +"0xf891a0b849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df770808080808080a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c19480a063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xd35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919 b/libraries/maker/test_data/test_chain/!trie_db!0xd35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919 new file mode 100644 index 00000000..8e2636cd --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xd35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919 @@ -0,0 +1 @@ +"0xf891808080a03900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef280a0b2aea4b00c6faa6890b6e8256dcb98b86808a19ab61c59994ab8b8bdf9acfa4da07f7b46c4c5746aa251ed9a7453743bcd033f304dd1b8877087453f36a598018e808080808080a044feb02352f8a94bfdbaf401bf7044483059864224a8e2c0b3abfb4d56f17264808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xd8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57 b/libraries/maker/test_data/test_chain/!trie_db!0xd8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57 new file mode 100644 index 00000000..3baac13b --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xd8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57 @@ -0,0 +1 @@ +"0xf842a00000000000000000000000000000000000000000000000000000000000000000a0a855e7870075f22bca3187c9fcf5f0ae0f9bcf0bc40aba289d2876006140eada" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xdb0af948d55394775495207faf2541a5432ef2b567e0f6faccb7e193d64d48cf b/libraries/maker/test_data/test_chain/!trie_db!0xdb0af948d55394775495207faf2541a5432ef2b567e0f6faccb7e193d64d48cf new file mode 100644 index 00000000..0a2ac18a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xdb0af948d55394775495207faf2541a5432ef2b567e0f6faccb7e193d64d48cf @@ -0,0 +1 @@ +"0xf842a01000000000000000000000000000000000000000000000000000000000000000a060b37e6a056ee52545c169ae2074181fda1f14f9abb6363e4d9a152fd9f07c90" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xdc29fc9d85a41d5f7586954e84a9702e33d52ab2b78dbc8a4110bc4ab9805926 b/libraries/maker/test_data/test_chain/!trie_db!0xdc29fc9d85a41d5f7586954e84a9702e33d52ab2b78dbc8a4110bc4ab9805926 new file mode 100644 index 00000000..b8c630c3 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xdc29fc9d85a41d5f7586954e84a9702e33d52ab2b78dbc8a4110bc4ab9805926 @@ -0,0 +1 @@ +"0xf891a01b9fc114e1505a2ebf1b4ddc24cbc7831547495eda32e440e6708345d85e5bc0808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b0455a0ababfa40a16a76228f9c9289d3598e99571cd4f0fec9f550a211febe9215be1d808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xe471b75d1693dfa4458588ca431b54af9320eca119ece050d55e1b05a94bad24 b/libraries/maker/test_data/test_chain/!trie_db!0xe471b75d1693dfa4458588ca431b54af9320eca119ece050d55e1b05a94bad24 new file mode 100644 index 00000000..517c15f2 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xe471b75d1693dfa4458588ca431b54af9320eca119ece050d55e1b05a94bad24 @@ -0,0 +1 @@ +"0xf871a0ae1c3ba42b6c8f2a271b7f56459c2add5676ba26e637d77963fd933a2108b7aa808080808080a059199de3c5812d70d26226c5f0ab999758a19b72cbf7c4eff6d930525a8b045580808080808080a0406d82bbf3ff8b6eb8bce99f947723566e0e73bd4730e6482500142bcff67d1f80" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xe76d776e0fd3e779b1154f656e88a16b2303744aa3fc59034662092c8e688569 b/libraries/maker/test_data/test_chain/!trie_db!0xe76d776e0fd3e779b1154f656e88a16b2303744aa3fc59034662092c8e688569 new file mode 100644 index 00000000..48423d70 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xe76d776e0fd3e779b1154f656e88a16b2303744aa3fc59034662092c8e688569 @@ -0,0 +1 @@ +"0xf85d942070ed54e41d9db6d91db5e7ff7a9451dad98993b846f8440180a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a08e7e25bae88ad50ddb83a7aa4aff24663004533b92d8ef1947a6fd621b5c028f" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xed57d93087e1a79ee9e3f6eadfc3d2affdb420d73dc4ecf07c5a21b22a221a98 b/libraries/maker/test_data/test_chain/!trie_db!0xed57d93087e1a79ee9e3f6eadfc3d2affdb420d73dc4ecf07c5a21b22a221a98 new file mode 100644 index 00000000..0f4ee6f9 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xed57d93087e1a79ee9e3f6eadfc3d2affdb420d73dc4ecf07c5a21b22a221a98 @@ -0,0 +1 @@ +"0xf6941000000000000000000000000000000000000000a05072a6c1e2e016ff4e5b6b35caf68673a43b7a13bb1fa82f2643bad3e4d1c253" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xed89ce8c7b8d2657d679fd3eb25076b5d12bd24ecfd91f2b19891722703a43e2 b/libraries/maker/test_data/test_chain/!trie_db!0xed89ce8c7b8d2657d679fd3eb25076b5d12bd24ecfd91f2b19891722703a43e2 new file mode 100644 index 00000000..8ba33368 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xed89ce8c7b8d2657d679fd3eb25076b5d12bd24ecfd91f2b19891722703a43e2 @@ -0,0 +1 @@ +"0xe2a03471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017c64" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xef07ff19a8b934da7c4809afe1dc5b3548bf27bc66900c8e118c9187767cb85d b/libraries/maker/test_data/test_chain/!trie_db!0xef07ff19a8b934da7c4809afe1dc5b3548bf27bc66900c8e118c9187767cb85d new file mode 100644 index 00000000..ea1555d3 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xef07ff19a8b934da7c4809afe1dc5b3548bf27bc66900c8e118c9187767cb85d @@ -0,0 +1 @@ +"0xf90111a0526dd67231b9088dffafec9d83e93dd46d770db9ada1151883868cf1192b59f5a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xf16e2c7b466b113f3159a527a5f17bce3863cc3cda8b21f0da41228f0be40e75 b/libraries/maker/test_data/test_chain/!trie_db!0xf16e2c7b466b113f3159a527a5f17bce3863cc3cda8b21f0da41228f0be40e75 new file mode 100644 index 00000000..04adb4ac --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xf16e2c7b466b113f3159a527a5f17bce3863cc3cda8b21f0da41228f0be40e75 @@ -0,0 +1 @@ +"0xeca120000000000000000000000000000000000000000000000000000000000000000289880e92596fd6290000" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xf2bf1441ea4a8c925cf68ab80ed63d86d61ded11b1f08d633a16a808be066864 b/libraries/maker/test_data/test_chain/!trie_db!0xf2bf1441ea4a8c925cf68ab80ed63d86d61ded11b1f08d633a16a808be066864 new file mode 100644 index 00000000..50827ddc --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xf2bf1441ea4a8c925cf68ab80ed63d86d61ded11b1f08d633a16a808be066864 @@ -0,0 +1 @@ +"0xe1209f9e5b69b8e700000000000064d922894153be9eef7b7218dc565d1d0ce2a092" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xf39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80c b/libraries/maker/test_data/test_chain/!trie_db!0xf39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80c new file mode 100644 index 00000000..96b68d3d --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xf39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80c @@ -0,0 +1 @@ +"0xf871808080a03900e16f35744fd8e6732d9253866e50977eb123efb7ecb3ae0508b5d72afef280a0b2aea4b00c6faa6890b6e8256dcb98b86808a19ab61c59994ab8b8bdf9acfa4d80808080808080a02ac25c8b39e9ba3a99e3983a69cc607e6b2a4f04adbe1abb9167b8b5d454056e808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xf5bc46da5777e39236ea19c82191f7ff73ee8b732b3652ae6864c8bc2e2688e0 b/libraries/maker/test_data/test_chain/!trie_db!0xf5bc46da5777e39236ea19c82191f7ff73ee8b732b3652ae6864c8bc2e2688e0 new file mode 100644 index 00000000..b90a2d7f --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xf5bc46da5777e39236ea19c82191f7ff73ee8b732b3652ae6864c8bc2e2688e0 @@ -0,0 +1 @@ +"0xf871a04ef305cd67b97b743669faa6b70fab3c29d545df173e5798da1a3bef0efeb5d9808080808080a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c1948080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xf5ee2d5a1e72de4b5a1e2af94497ed2082c0874454d5419cbdb0037f105e882a b/libraries/maker/test_data/test_chain/!trie_db!0xf5ee2d5a1e72de4b5a1e2af94497ed2082c0874454d5419cbdb0037f105e882a new file mode 100644 index 00000000..8562ec9a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xf5ee2d5a1e72de4b5a1e2af94497ed2082c0874454d5419cbdb0037f105e882a @@ -0,0 +1 @@ +"0xf8f1a0b849d833c3c299ab14d40e9dda4d67a6f2e7a5ec13ec49680683cdc24a3df77080a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xf809a0ce500223d176d587be8c6a89aea88a70d80394f7eda04d8e4b1c17cc4e b/libraries/maker/test_data/test_chain/!trie_db!0xf809a0ce500223d176d587be8c6a89aea88a70d80394f7eda04d8e4b1c17cc4e new file mode 100644 index 00000000..efcdb266 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xf809a0ce500223d176d587be8c6a89aea88a70d80394f7eda04d8e4b1c17cc4e @@ -0,0 +1 @@ +"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a0907b9cb17ed4afdf1e49593aa2a077f3019a7e851ec9faf4b21ad72aea963675808080808080808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xfaa013dc69cc994058701503d6e2bfc0e77581a8233aac88928620af541b9fbd b/libraries/maker/test_data/test_chain/!trie_db!0xfaa013dc69cc994058701503d6e2bfc0e77581a8233aac88928620af541b9fbd new file mode 100644 index 00000000..6a79ee2a --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xfaa013dc69cc994058701503d6e2bfc0e77581a8233aac88928620af541b9fbd @@ -0,0 +1 @@ +"0xf90111a03a1b09fce6390882d7322ddbe543253cd6da427a07bf45dc8909180bbe48183ea05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xfb53e64824f62daa3a1598b6864c077c8b3feafa8d6f93bb5185dcd52a55f4b5 b/libraries/maker/test_data/test_chain/!trie_db!0xfb53e64824f62daa3a1598b6864c077c8b3feafa8d6f93bb5185dcd52a55f4b5 new file mode 100644 index 00000000..c515d8ef --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xfb53e64824f62daa3a1598b6864c077c8b3feafa8d6f93bb5185dcd52a55f4b5 @@ -0,0 +1 @@ +"0xf90111a021844edeb0c63d6c416c3ac4ccf639034227a206e8d39e76dadd463b61e5508ba05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xfc06e3f1445bb4688f0502c46231fc72da5d44c6419ee71c47be24fbf1928fcf b/libraries/maker/test_data/test_chain/!trie_db!0xfc06e3f1445bb4688f0502c46231fc72da5d44c6419ee71c47be24fbf1928fcf new file mode 100644 index 00000000..ea12be77 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xfc06e3f1445bb4688f0502c46231fc72da5d44c6419ee71c47be24fbf1928fcf @@ -0,0 +1 @@ +"0xf891a04ef305cd67b97b743669faa6b70fab3c29d545df173e5798da1a3bef0efeb5d9808080808080a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c19480a063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xfdc8e630564f657910187c9eb1d7bf01e04231d016528da0062c123203eb1c79 b/libraries/maker/test_data/test_chain/!trie_db!0xfdc8e630564f657910187c9eb1d7bf01e04231d016528da0062c123203eb1c79 new file mode 100644 index 00000000..00bb3bb3 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xfdc8e630564f657910187c9eb1d7bf01e04231d016528da0062c123203eb1c79 @@ -0,0 +1 @@ +"0xf838a1200000000000000000000000000000000000000000000000000000000000000000959438219779a699d67d7e7740b8c8f43d3e2dae2182" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xfdcb675a2fb7395ce85312eeaf38d612251395b4277a958c4a78cea448e07cc1 b/libraries/maker/test_data/test_chain/!trie_db!0xfdcb675a2fb7395ce85312eeaf38d612251395b4277a958c4a78cea448e07cc1 new file mode 100644 index 00000000..2492ae95 --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xfdcb675a2fb7395ce85312eeaf38d612251395b4277a958c4a78cea448e07cc1 @@ -0,0 +1 @@ +"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d04890568fe9e9f64820000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" \ No newline at end of file diff --git a/libraries/maker/test_data/test_chain/!trie_db!0xfe3d828c2803bd586bc34641752157c205a391ec9a1b730031bccc77a9276b02 b/libraries/maker/test_data/test_chain/!trie_db!0xfe3d828c2803bd586bc34641752157c205a391ec9a1b730031bccc77a9276b02 new file mode 100644 index 00000000..19ee58cc --- /dev/null +++ b/libraries/maker/test_data/test_chain/!trie_db!0xfe3d828c2803bd586bc34641752157c205a391ec9a1b730031bccc77a9276b02 @@ -0,0 +1 @@ +"0xf87180a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a80808080808080808080808080" \ No newline at end of file diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index fb56e96a..e5b01ff2 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1,12 +1,17 @@ package core -import "math/big" +import ( + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/core/types" + "math/big" +) type BlockChain interface { ContractDataFetcher GetBlockByNumber(blockNumber int64) (Block, error) GetHeaderByNumber(blockNumber int64) (Header, error) GetLogs(contract Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]Log, error) + GetEthLogsWithCustomQuery(query ethereum.FilterQuery) ([]types.Log, error) LastBlock() *big.Int Node() Node } diff --git a/pkg/core/header.go b/pkg/core/header.go index 21335b6f..e8d90efd 100644 --- a/pkg/core/header.go +++ b/pkg/core/header.go @@ -1,6 +1,7 @@ package core type Header struct { + Id int64 BlockNumber int64 `db:"block_number"` Hash string Raw []byte diff --git a/pkg/core/node_info.go b/pkg/core/node_info.go index 56876453..e63faeba 100644 --- a/pkg/core/node_info.go +++ b/pkg/core/node_info.go @@ -10,6 +10,7 @@ const ( GETH NodeType = iota PARITY INFURA + GANACHE ) type Node struct { diff --git a/pkg/fakes/mock_blockchain.go b/pkg/fakes/mock_blockchain.go index bd543106..1c12bdf9 100644 --- a/pkg/fakes/mock_blockchain.go +++ b/pkg/fakes/mock_blockchain.go @@ -5,6 +5,8 @@ import ( . "github.com/onsi/gomega" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/core/types" "github.com/vulcanize/vulcanizedb/pkg/core" ) @@ -17,6 +19,8 @@ type MockBlockChain struct { fetchContractDataPassedResult interface{} fetchContractDataPassedBlockNumber int64 getBlockByNumberErr error + logQuery ethereum.FilterQuery + logQueryErr error lastBlock *big.Int node core.Node } @@ -39,6 +43,15 @@ func (blockChain *MockBlockChain) SetGetBlockByNumberErr(err error) { blockChain.getBlockByNumberErr = err } +func (blockChain *MockBlockChain) SetGetLogsErr(err error) { + blockChain.logQueryErr = err +} + +func (blockChain *MockBlockChain) GetEthLogsWithCustomQuery(query ethereum.FilterQuery) ([]types.Log, error) { + blockChain.logQuery = query + return []types.Log{}, blockChain.logQueryErr +} + func (blockChain *MockBlockChain) GetHeaderByNumber(blockNumber int64) (core.Header, error) { return core.Header{BlockNumber: blockNumber}, nil } @@ -81,3 +94,7 @@ func (blockChain *MockBlockChain) AssertFetchContractDataCalledWith(abiJSON stri Expect(blockChain.fetchContractDataPassedResult).To(Equal(result)) Expect(blockChain.fetchContractDataPassedBlockNumber).To(Equal(blockNumber)) } + +func (blockChain *MockBlockChain) AssertGetEthLogsWithCustomQueryCalledWith(query ethereum.FilterQuery) { + Expect(blockChain.logQuery).To(Equal(query)) +} diff --git a/pkg/fakes/mock_rpc_client.go b/pkg/fakes/mock_rpc_client.go index d4cbf9b1..dc370c16 100644 --- a/pkg/fakes/mock_rpc_client.go +++ b/pkg/fakes/mock_rpc_client.go @@ -8,18 +8,15 @@ import ( ) type MockRpcClient struct { - ipcPath string - nodeType core.NodeType + ipcPath string + nodeType core.NodeType + supportedModules map[string]string } func NewMockRpcClient() *MockRpcClient { return &MockRpcClient{} } -func (client *MockRpcClient) SetNodeType(nodeType core.NodeType) { - client.nodeType = nodeType -} - func (client *MockRpcClient) SetIpcPath(ipcPath string) { client.ipcPath = ipcPath } @@ -65,9 +62,9 @@ func (client *MockRpcClient) IpcPath() string { } func (client *MockRpcClient) SupportedModules() (map[string]string, error) { - result := make(map[string]string) - if client.nodeType == core.GETH { - result["admin"] = "ok" - } - return result, nil + return client.supportedModules, nil } + +func (client *MockRpcClient) SetSupporedModules(supportedModules map[string]string) { + client.supportedModules = supportedModules +} \ No newline at end of file diff --git a/pkg/geth/blockchain.go b/pkg/geth/blockchain.go index a6d9193d..a772cc32 100644 --- a/pkg/geth/blockchain.go +++ b/pkg/geth/blockchain.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "golang.org/x/net/context" + "github.com/ethereum/go-ethereum/core/types" "github.com/vulcanize/vulcanizedb/pkg/core" vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common" ) @@ -53,7 +54,7 @@ func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumbe ToBlock: endingBlockNumber, Addresses: []common.Address{contractAddress}, } - gethLogs, err := blockChain.client.FilterLogs(context.Background(), fc) + gethLogs, err := blockChain.GetEthLogsWithCustomQuery(fc) if err != nil { return []core.Log{}, err } @@ -61,6 +62,14 @@ func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumbe return logs, nil } +func (blockChain *BlockChain) GetEthLogsWithCustomQuery(query ethereum.FilterQuery) ([]types.Log, error) { + gethLogs, err := blockChain.client.FilterLogs(context.Background(), query) + if err != nil { + return []types.Log{}, err + } + return gethLogs, nil +} + func (blockChain *BlockChain) LastBlock() *big.Int { block, _ := blockChain.client.HeaderByNumber(context.Background(), nil) return block.Number diff --git a/pkg/geth/blockchain_test.go b/pkg/geth/blockchain_test.go index 69f04e3b..c48e8c9a 100644 --- a/pkg/geth/blockchain_test.go +++ b/pkg/geth/blockchain_test.go @@ -17,12 +17,18 @@ import ( ) var _ = Describe("Geth blockchain", func() { + var mockClient *fakes.MockEthClient + var blockChain *geth.BlockChain + + BeforeEach(func() { + mockClient = fakes.NewMockEthClient() + node := vulcCore.Node{} + blockChain = geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) + }) + Describe("getting a block", func() { It("fetches block from client", func() { - mockClient := fakes.NewMockEthClient() mockClient.SetBlockByNumberReturnBlock(types.NewBlockWithHeader(&types.Header{})) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) blockNumber := int64(100) _, err := blockChain.GetBlockByNumber(blockNumber) @@ -32,10 +38,7 @@ var _ = Describe("Geth blockchain", func() { }) It("returns err if client returns err", func() { - mockClient := fakes.NewMockEthClient() mockClient.SetBlockByNumberErr(fakes.FakeError) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) _, err := blockChain.GetBlockByNumber(100) @@ -46,11 +49,8 @@ var _ = Describe("Geth blockchain", func() { Describe("getting a header", func() { It("fetches header from client", func() { - mockClient := fakes.NewMockEthClient() blockNumber := int64(100) mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)}) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) _, err := blockChain.GetHeaderByNumber(blockNumber) @@ -59,10 +59,7 @@ var _ = Describe("Geth blockchain", func() { }) It("returns err if client returns err", func() { - mockClient := fakes.NewMockEthClient() mockClient.SetHeaderByNumberErr(fakes.FakeError) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) _, err := blockChain.GetHeaderByNumber(100) @@ -71,12 +68,9 @@ var _ = Describe("Geth blockchain", func() { }) }) - Describe("getting logs", func() { + Describe("getting logs with default FilterQuery", func() { It("fetches logs from client", func() { - mockClient := fakes.NewMockEthClient() mockClient.SetFilterLogsReturnLogs([]types.Log{{}}) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()} startingBlockNumber := big.NewInt(1) endingBlockNumber := big.NewInt(2) @@ -93,10 +87,39 @@ var _ = Describe("Geth blockchain", func() { }) It("returns err if client returns err", func() { - mockClient := fakes.NewMockEthClient() mockClient.SetFilterLogsErr(fakes.FakeError) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) + contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()} + startingBlockNumber := big.NewInt(1) + endingBlockNumber := big.NewInt(2) + + _, err := blockChain.GetLogs(contract, startingBlockNumber, endingBlockNumber) + + Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(fakes.FakeError)) + }) + }) + + Describe("getting logs with a custom FilterQuery", func() { + It("fetches logs from client", func() { + mockClient.SetFilterLogsReturnLogs([]types.Log{{}}) + address := common.HexToAddress("0x") + startingBlockNumber := big.NewInt(1) + endingBlockNumber := big.NewInt(2) + topic := common.HexToHash("0x") + query := ethereum.FilterQuery{ + FromBlock: startingBlockNumber, + ToBlock: endingBlockNumber, + Addresses: []common.Address{address}, + Topics: [][]common.Hash{{topic}}, + } + _, err := blockChain.GetEthLogsWithCustomQuery(query) + + Expect(err).NotTo(HaveOccurred()) + mockClient.AssertFilterLogsCalledWith(context.Background(), query) + }) + + It("returns err if client returns err", func() { + mockClient.SetFilterLogsErr(fakes.FakeError) contract := vulcCore.Contract{Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex()} startingBlockNumber := big.NewInt(1) endingBlockNumber := big.NewInt(2) @@ -110,11 +133,8 @@ var _ = Describe("Geth blockchain", func() { Describe("getting the most recent block number", func() { It("fetches latest header from client", func() { - mockClient := fakes.NewMockEthClient() blockNumber := int64(100) mockClient.SetHeaderByNumberReturnHeader(&types.Header{Number: big.NewInt(blockNumber)}) - node := vulcCore.Node{} - blockChain := geth.NewBlockChain(mockClient, node, cold_db.NewColdDbTransactionConverter()) result := blockChain.LastBlock() diff --git a/pkg/geth/client/rpc_client.go b/pkg/geth/client/rpc_client.go index 46b3f80f..bbaf26a2 100644 --- a/pkg/geth/client/rpc_client.go +++ b/pkg/geth/client/rpc_client.go @@ -18,7 +18,14 @@ func NewRpcClient(client *rpc.Client, ipcPath string) RpcClient { } func (client RpcClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { - return client.client.CallContext(ctx, result, method, args) + //If an empty interface (or other nil object) is passed to CallContext, when the JSONRPC message is created the params will + //be interpreted as [null]. This seems to work fine for most of the ethereum clients (which presumably ignore a null parameter. + //Ganache however does not ignore it, and throws an 'Incorrect number of arguments' error. + if args == nil { + return client.client.CallContext(ctx, result, method) + } else { + return client.client.CallContext(ctx, result, method, args) + } } func (client RpcClient) IpcPath() string { diff --git a/pkg/geth/node/node.go b/pkg/geth/node/node.go index 33459e8f..ae70ada0 100644 --- a/pkg/geth/node/node.go +++ b/pkg/geth/node/node.go @@ -37,6 +37,10 @@ type InfuraClient struct { PropertiesReader } +type GanacheClient struct { + PropertiesReader +} + func MakeNode(rpcClient core.RpcClient) core.Node { pr := makePropertiesReader(rpcClient) id, name := pr.NodeInfo() @@ -56,6 +60,8 @@ func makePropertiesReader(client core.RpcClient) IPropertiesReader { return ParityClient{PropertiesReader: PropertiesReader{client: client}} case core.INFURA: return InfuraClient{PropertiesReader: PropertiesReader{client: client}} + case core.GANACHE: + return GanacheClient{PropertiesReader: PropertiesReader{client: client}} default: return PropertiesReader{client: client} } @@ -65,6 +71,9 @@ func getNodeType(client core.RpcClient) core.NodeType { if strings.Contains(client.IpcPath(), "infura") { return core.INFURA } + if strings.Contains(client.IpcPath(), "127.0.0.1") || strings.Contains(client.IpcPath(), "localhost") { + return core.GANACHE + } modules, _ := client.SupportedModules() if _, ok := modules["admin"]; ok { return core.GETH @@ -106,6 +115,10 @@ func (client InfuraClient) NodeInfo() (string, string) { return "infura", "infura" } +func (client GanacheClient) NodeInfo() (string, string) { + return "ganache", "ganache" +} + func (client ParityClient) parityNodeInfo() string { var nodeInfo core.ParityNodeInfo client.client.CallContext(context.Background(), &nodeInfo, "parity_versionInfo") diff --git a/pkg/geth/node/node_test.go b/pkg/geth/node/node_test.go index ec557369..7c9d4f28 100644 --- a/pkg/geth/node/node_test.go +++ b/pkg/geth/node/node_test.go @@ -1,23 +1,22 @@ package node_test import ( - "encoding/json" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/fakes" "github.com/vulcanize/vulcanizedb/pkg/geth/node" + "encoding/json" ) var EmpytHeaderHash = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" -var _ = Describe("Parity Node Info", func() { - - It("verifies parity_versionInfo can be unmarshalled into ParityNodeInfo", func() { - var parityNodeInfo core.ParityNodeInfo - nodeInfoJSON := []byte( - `{ +var _ = Describe("Node Info", func() { + Describe("Parity Node Info", func() { + It("verifies parity_versionInfo can be unmarshalled into ParityNodeInfo", func() { + var parityNodeInfo core.ParityNodeInfo + nodeInfoJSON := []byte( + `{ "hash": "0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0", "track": "null", "version": { @@ -26,25 +25,34 @@ var _ = Describe("Parity Node Info", func() { "patch": 0 } }`) - json.Unmarshal(nodeInfoJSON, &parityNodeInfo) - Expect(parityNodeInfo.Hash).To(Equal("0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0")) - Expect(parityNodeInfo.Track).To(Equal("null")) - Expect(parityNodeInfo.Major).To(Equal(1)) - Expect(parityNodeInfo.Minor).To(Equal(6)) - Expect(parityNodeInfo.Patch).To(Equal(0)) - }) + json.Unmarshal(nodeInfoJSON, &parityNodeInfo) + Expect(parityNodeInfo.Hash).To(Equal("0x2ae8b4ca278dd7b896090366615fef81cbbbc0e0")) + Expect(parityNodeInfo.Track).To(Equal("null")) + Expect(parityNodeInfo.Major).To(Equal(1)) + Expect(parityNodeInfo.Minor).To(Equal(6)) + Expect(parityNodeInfo.Patch).To(Equal(0)) + }) - It("Creates client string", func() { - parityNodeInfo := core.ParityNodeInfo{ - Track: "null", - ParityVersion: core.ParityVersion{ - Major: 1, - Minor: 6, - Patch: 0, - }, - Hash: "0x1232144j", - } - Expect(parityNodeInfo.String()).To(Equal("Parity/v1.6.0/")) + It("Creates client string", func() { + parityNodeInfo := core.ParityNodeInfo{ + Track: "null", + ParityVersion: core.ParityVersion{ + Major: 1, + Minor: 6, + Patch: 0, + }, + Hash: "0x1232144j", + } + Expect(parityNodeInfo.String()).To(Equal("Parity/v1.6.0/")) + }) + + It("returns parity ID and client name for parity node", func() { + client := fakes.NewMockRpcClient() + + n := node.MakeNode(client) + Expect(n.ID).To(Equal("ParityNode")) + Expect(n.ClientName).To(Equal("Parity/v1.2.3/")) + }) }) It("returns the genesis block for any client", func() { @@ -59,17 +67,12 @@ var _ = Describe("Parity Node Info", func() { Expect(n.NetworkID).To(Equal(float64(1234))) }) - It("returns parity ID and client name for parity node", func() { - client := fakes.NewMockRpcClient() - client.SetNodeType(core.PARITY) - n := node.MakeNode(client) - Expect(n.ID).To(Equal("ParityNode")) - Expect(n.ClientName).To(Equal("Parity/v1.2.3/")) - }) - It("returns geth ID and client name for geth node", func() { client := fakes.NewMockRpcClient() - client.SetNodeType(core.GETH) + supportedModules := make(map[string]string) + supportedModules["admin"] = "ok" + client.SetSupporedModules(supportedModules) + n := node.MakeNode(client) Expect(n.ID).To(Equal("enode://GethNode@172.17.0.1:30303")) Expect(n.ClientName).To(Equal("Geth/v1.7")) @@ -77,10 +80,22 @@ var _ = Describe("Parity Node Info", func() { It("returns infura ID and client name for infura node", func() { client := fakes.NewMockRpcClient() - client.SetNodeType(core.INFURA) client.SetIpcPath("infura/path") n := node.MakeNode(client) Expect(n.ID).To(Equal("infura")) Expect(n.ClientName).To(Equal("infura")) }) + + It("returns local id and client name for Local node", func() { + client := fakes.NewMockRpcClient() + client.SetIpcPath("127.0.0.1") + n := node.MakeNode(client) + Expect(n.ID).To(Equal("ganache")) + Expect(n.ClientName).To(Equal("ganache")) + + client.SetIpcPath("localhost") + n = node.MakeNode(client) + Expect(n.ID).To(Equal("ganache")) + Expect(n.ClientName).To(Equal("ganache")) + }) }) diff --git a/examples/test_helpers/database.go b/pkg/test_helpers/database.go similarity index 85% rename from examples/test_helpers/database.go rename to pkg/test_helpers/database.go index d4d5e9ad..a3671b92 100644 --- a/examples/test_helpers/database.go +++ b/pkg/test_helpers/database.go @@ -16,25 +16,12 @@ package test_helpers import ( . "github.com/onsi/gomega" - "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/test_config" ) -type TokenSupplyDBRow struct { - ID int64 - Supply int64 - BlockID int64 `db:"block_id"` - TokenAddress string `db:"token_address"` -} - -type TransferDBRow struct { - ID int64 `db:"id"` - VulcanizeLogID int64 `db:"vulcanize_log_id"` -} - func CreateNewDatabase() *postgres.DB { var node core.Node node = core.Node{ diff --git a/vendor/github.com/pborman/uuid/.travis.yml b/vendor/github.com/pborman/uuid/.travis.yml new file mode 100644 index 00000000..d8156a60 --- /dev/null +++ b/vendor/github.com/pborman/uuid/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.4.3 + - 1.5.3 + - tip + +script: + - go test -v ./... diff --git a/vendor/github.com/pborman/uuid/CONTRIBUTING.md b/vendor/github.com/pborman/uuid/CONTRIBUTING.md new file mode 100644 index 00000000..04fdf09f --- /dev/null +++ b/vendor/github.com/pborman/uuid/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# How to contribute + +We definitely welcome patches and contribution to this project! + +### Legal requirements + +In order to protect both you and ourselves, you will need to sign the +[Contributor License Agreement](https://cla.developers.google.com/clas). + +You may have already signed it for other Google projects. diff --git a/vendor/github.com/pborman/uuid/CONTRIBUTORS b/vendor/github.com/pborman/uuid/CONTRIBUTORS new file mode 100644 index 00000000..b382a04e --- /dev/null +++ b/vendor/github.com/pborman/uuid/CONTRIBUTORS @@ -0,0 +1 @@ +Paul Borman diff --git a/vendor/github.com/pborman/uuid/LICENSE b/vendor/github.com/pborman/uuid/LICENSE new file mode 100644 index 00000000..5dc68268 --- /dev/null +++ b/vendor/github.com/pborman/uuid/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009,2014 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pborman/uuid/README.md b/vendor/github.com/pborman/uuid/README.md new file mode 100644 index 00000000..b0396b27 --- /dev/null +++ b/vendor/github.com/pborman/uuid/README.md @@ -0,0 +1,13 @@ +This project was automatically exported from code.google.com/p/go-uuid + +# uuid ![build status](https://travis-ci.org/pborman/uuid.svg?branch=master) +The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services. + +###### Install +`go get github.com/pborman/uuid` + +###### Documentation +[![GoDoc](https://godoc.org/github.com/pborman/uuid?status.svg)](http://godoc.org/github.com/pborman/uuid) + +Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: +http://godoc.org/github.com/pborman/uuid diff --git a/vendor/github.com/pborman/uuid/dce.go b/vendor/github.com/pborman/uuid/dce.go new file mode 100644 index 00000000..50a0f2d0 --- /dev/null +++ b/vendor/github.com/pborman/uuid/dce.go @@ -0,0 +1,84 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "fmt" + "os" +) + +// A Domain represents a Version 2 domain +type Domain byte + +// Domain constants for DCE Security (Version 2) UUIDs. +const ( + Person = Domain(0) + Group = Domain(1) + Org = Domain(2) +) + +// NewDCESecurity returns a DCE Security (Version 2) UUID. +// +// The domain should be one of Person, Group or Org. +// On a POSIX system the id should be the users UID for the Person +// domain and the users GID for the Group. The meaning of id for +// the domain Org or on non-POSIX systems is site defined. +// +// For a given domain/id pair the same token may be returned for up to +// 7 minutes and 10 seconds. +func NewDCESecurity(domain Domain, id uint32) UUID { + uuid := NewUUID() + if uuid != nil { + uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 + uuid[9] = byte(domain) + binary.BigEndian.PutUint32(uuid[0:], id) + } + return uuid +} + +// NewDCEPerson returns a DCE Security (Version 2) UUID in the person +// domain with the id returned by os.Getuid. +// +// NewDCEPerson(Person, uint32(os.Getuid())) +func NewDCEPerson() UUID { + return NewDCESecurity(Person, uint32(os.Getuid())) +} + +// NewDCEGroup returns a DCE Security (Version 2) UUID in the group +// domain with the id returned by os.Getgid. +// +// NewDCEGroup(Group, uint32(os.Getgid())) +func NewDCEGroup() UUID { + return NewDCESecurity(Group, uint32(os.Getgid())) +} + +// Domain returns the domain for a Version 2 UUID or false. +func (uuid UUID) Domain() (Domain, bool) { + if v, _ := uuid.Version(); v != 2 { + return 0, false + } + return Domain(uuid[9]), true +} + +// Id returns the id for a Version 2 UUID or false. +func (uuid UUID) Id() (uint32, bool) { + if v, _ := uuid.Version(); v != 2 { + return 0, false + } + return binary.BigEndian.Uint32(uuid[0:4]), true +} + +func (d Domain) String() string { + switch d { + case Person: + return "Person" + case Group: + return "Group" + case Org: + return "Org" + } + return fmt.Sprintf("Domain%d", int(d)) +} diff --git a/vendor/github.com/pborman/uuid/doc.go b/vendor/github.com/pborman/uuid/doc.go new file mode 100644 index 00000000..d8bd013e --- /dev/null +++ b/vendor/github.com/pborman/uuid/doc.go @@ -0,0 +1,8 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The uuid package generates and inspects UUIDs. +// +// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services. +package uuid diff --git a/vendor/github.com/pborman/uuid/hash.go b/vendor/github.com/pborman/uuid/hash.go new file mode 100644 index 00000000..a0420c1e --- /dev/null +++ b/vendor/github.com/pborman/uuid/hash.go @@ -0,0 +1,53 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "crypto/md5" + "crypto/sha1" + "hash" +) + +// Well known Name Space IDs and UUIDs +var ( + NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8") + NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8") + NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8") + NIL = Parse("00000000-0000-0000-0000-000000000000") +) + +// NewHash returns a new UUID derived from the hash of space concatenated with +// data generated by h. The hash should be at least 16 byte in length. The +// first 16 bytes of the hash are used to form the UUID. The version of the +// UUID will be the lower 4 bits of version. NewHash is used to implement +// NewMD5 and NewSHA1. +func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { + h.Reset() + h.Write(space) + h.Write([]byte(data)) + s := h.Sum(nil) + uuid := make([]byte, 16) + copy(uuid, s) + uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) + uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant + return uuid +} + +// NewMD5 returns a new MD5 (Version 3) UUID based on the +// supplied name space and data. +// +// NewHash(md5.New(), space, data, 3) +func NewMD5(space UUID, data []byte) UUID { + return NewHash(md5.New(), space, data, 3) +} + +// NewSHA1 returns a new SHA1 (Version 5) UUID based on the +// supplied name space and data. +// +// NewHash(sha1.New(), space, data, 5) +func NewSHA1(space UUID, data []byte) UUID { + return NewHash(sha1.New(), space, data, 5) +} diff --git a/vendor/github.com/pborman/uuid/marshal.go b/vendor/github.com/pborman/uuid/marshal.go new file mode 100644 index 00000000..6621dd54 --- /dev/null +++ b/vendor/github.com/pborman/uuid/marshal.go @@ -0,0 +1,83 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "errors" + "fmt" +) + +// MarshalText implements encoding.TextMarshaler. +func (u UUID) MarshalText() ([]byte, error) { + if len(u) != 16 { + return nil, nil + } + var js [36]byte + encodeHex(js[:], u) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (u *UUID) UnmarshalText(data []byte) error { + if len(data) == 0 { + return nil + } + id := Parse(string(data)) + if id == nil { + return errors.New("invalid UUID") + } + *u = id + return nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (u UUID) MarshalBinary() ([]byte, error) { + return u[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (u *UUID) UnmarshalBinary(data []byte) error { + if len(data) == 0 { + return nil + } + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + var id [16]byte + copy(id[:], data) + *u = id[:] + return nil +} + +// MarshalText implements encoding.TextMarshaler. +func (u Array) MarshalText() ([]byte, error) { + var js [36]byte + encodeHex(js[:], u[:]) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (u *Array) UnmarshalText(data []byte) error { + id := Parse(string(data)) + if id == nil { + return errors.New("invalid UUID") + } + *u = id.Array() + return nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (u Array) MarshalBinary() ([]byte, error) { + return u[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (u *Array) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(u[:], data) + return nil +} diff --git a/vendor/github.com/pborman/uuid/marshal_test.go b/vendor/github.com/pborman/uuid/marshal_test.go new file mode 100644 index 00000000..4e85b6ba --- /dev/null +++ b/vendor/github.com/pborman/uuid/marshal_test.go @@ -0,0 +1,124 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "encoding/json" + "reflect" + "testing" +) + +var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") +var testArray = testUUID.Array() + +func TestJSON(t *testing.T) { + type S struct { + ID1 UUID + ID2 UUID + } + s1 := S{ID1: testUUID} + data, err := json.Marshal(&s1) + if err != nil { + t.Fatal(err) + } + var s2 S + if err := json.Unmarshal(data, &s2); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(&s1, &s2) { + t.Errorf("got %#v, want %#v", s2, s1) + } +} + +func TestJSONArray(t *testing.T) { + type S struct { + ID1 Array + ID2 Array + } + s1 := S{ID1: testArray} + data, err := json.Marshal(&s1) + if err != nil { + t.Fatal(err) + } + var s2 S + if err := json.Unmarshal(data, &s2); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(&s1, &s2) { + t.Errorf("got %#v, want %#v", s2, s1) + } +} + +func TestMarshal(t *testing.T) { + data, err := testUUID.MarshalBinary() + if err != nil { + t.Fatalf("MarhsalBinary returned unexpected error %v", err) + } + if !bytes.Equal(data, testUUID) { + t.Fatalf("MarhsalBinary returns %x, want %x", data, testUUID) + } + var u UUID + u.UnmarshalBinary(data) + if !Equal(data, u) { + t.Fatalf("UnmarhsalBinary returns %v, want %v", u, testUUID) + } +} + +func TestMarshalArray(t *testing.T) { + data, err := testArray.MarshalBinary() + if err != nil { + t.Fatalf("MarhsalBinary returned unexpected error %v", err) + } + if !bytes.Equal(data, testUUID) { + t.Fatalf("MarhsalBinary returns %x, want %x", data, testUUID) + } + var a Array + a.UnmarshalBinary(data) + if a != testArray { + t.Fatalf("UnmarhsalBinary returns %v, want %v", a, testArray) + } +} + +func TestMarshalTextArray(t *testing.T) { + data, err := testArray.MarshalText() + if err != nil { + t.Fatalf("MarhsalText returned unexpected error %v", err) + } + var a Array + a.UnmarshalText(data) + if a != testArray { + t.Fatalf("UnmarhsalText returns %v, want %v", a, testArray) + } +} + +func BenchmarkUUID_MarshalJSON(b *testing.B) { + x := &struct { + UUID UUID `json:"uuid"` + }{} + x.UUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if x.UUID == nil { + b.Fatal("invalid uuid") + } + for i := 0; i < b.N; i++ { + js, err := json.Marshal(x) + if err != nil { + b.Fatalf("marshal json: %#v (%v)", js, err) + } + } +} + +func BenchmarkUUID_UnmarshalJSON(b *testing.B) { + js := []byte(`{"uuid":"f47ac10b-58cc-0372-8567-0e02b2c3d479"}`) + var x *struct { + UUID UUID `json:"uuid"` + } + for i := 0; i < b.N; i++ { + err := json.Unmarshal(js, &x) + if err != nil { + b.Fatalf("marshal json: %#v (%v)", js, err) + } + } +} diff --git a/vendor/github.com/pborman/uuid/node.go b/vendor/github.com/pborman/uuid/node.go new file mode 100644 index 00000000..42d60da8 --- /dev/null +++ b/vendor/github.com/pborman/uuid/node.go @@ -0,0 +1,117 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "net" + "sync" +) + +var ( + nodeMu sync.Mutex + interfaces []net.Interface // cached list of interfaces + ifname string // name of interface being used + nodeID []byte // hardware for version 1 UUIDs +) + +// NodeInterface returns the name of the interface from which the NodeID was +// derived. The interface "user" is returned if the NodeID was set by +// SetNodeID. +func NodeInterface() string { + defer nodeMu.Unlock() + nodeMu.Lock() + return ifname +} + +// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. +// If name is "" then the first usable interface found will be used or a random +// Node ID will be generated. If a named interface cannot be found then false +// is returned. +// +// SetNodeInterface never fails when name is "". +func SetNodeInterface(name string) bool { + defer nodeMu.Unlock() + nodeMu.Lock() + return setNodeInterface(name) +} + +func setNodeInterface(name string) bool { + if interfaces == nil { + var err error + interfaces, err = net.Interfaces() + if err != nil && name != "" { + return false + } + } + + for _, ifs := range interfaces { + if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { + if setNodeID(ifs.HardwareAddr) { + ifname = ifs.Name + return true + } + } + } + + // We found no interfaces with a valid hardware address. If name + // does not specify a specific interface generate a random Node ID + // (section 4.1.6) + if name == "" { + if nodeID == nil { + nodeID = make([]byte, 6) + } + randomBits(nodeID) + return true + } + return false +} + +// NodeID returns a slice of a copy of the current Node ID, setting the Node ID +// if not already set. +func NodeID() []byte { + defer nodeMu.Unlock() + nodeMu.Lock() + if nodeID == nil { + setNodeInterface("") + } + nid := make([]byte, 6) + copy(nid, nodeID) + return nid +} + +// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes +// of id are used. If id is less than 6 bytes then false is returned and the +// Node ID is not set. +func SetNodeID(id []byte) bool { + defer nodeMu.Unlock() + nodeMu.Lock() + if setNodeID(id) { + ifname = "user" + return true + } + return false +} + +func setNodeID(id []byte) bool { + if len(id) < 6 { + return false + } + if nodeID == nil { + nodeID = make([]byte, 6) + } + copy(nodeID, id) + return true +} + +// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is +// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) NodeID() []byte { + if len(uuid) != 16 { + return nil + } + node := make([]byte, 6) + copy(node, uuid[10:]) + return node +} diff --git a/vendor/github.com/pborman/uuid/seq_test.go b/vendor/github.com/pborman/uuid/seq_test.go new file mode 100644 index 00000000..3b3d1430 --- /dev/null +++ b/vendor/github.com/pborman/uuid/seq_test.go @@ -0,0 +1,66 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "flag" + "runtime" + "testing" + "time" +) + +// This test is only run when --regressions is passed on the go test line. +var regressions = flag.Bool("regressions", false, "run uuid regression tests") + +// TestClockSeqRace tests for a particular race condition of returning two +// identical Version1 UUIDs. The duration of 1 minute was chosen as the race +// condition, before being fixed, nearly always occured in under 30 seconds. +func TestClockSeqRace(t *testing.T) { + if !*regressions { + t.Skip("skipping regression tests") + } + duration := time.Minute + + done := make(chan struct{}) + defer close(done) + + ch := make(chan UUID, 10000) + ncpu := runtime.NumCPU() + switch ncpu { + case 0, 1: + // We can't run the test effectively. + t.Skip("skipping race test, only one CPU detected") + return + default: + runtime.GOMAXPROCS(ncpu) + } + for i := 0; i < ncpu; i++ { + go func() { + for { + select { + case <-done: + return + case ch <- NewUUID(): + } + } + }() + } + + uuids := make(map[string]bool) + cnt := 0 + start := time.Now() + for u := range ch { + s := u.String() + if uuids[s] { + t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s) + return + } + uuids[s] = true + if time.Since(start) > duration { + return + } + cnt++ + } +} diff --git a/vendor/github.com/pborman/uuid/sql.go b/vendor/github.com/pborman/uuid/sql.go new file mode 100644 index 00000000..d015bfd1 --- /dev/null +++ b/vendor/github.com/pborman/uuid/sql.go @@ -0,0 +1,66 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "database/sql/driver" + "errors" + "fmt" +) + +// Scan implements sql.Scanner so UUIDs can be read from databases transparently +// Currently, database types that map to string and []byte are supported. Please +// consult database-specific driver documentation for matching types. +func (uuid *UUID) Scan(src interface{}) error { + switch src.(type) { + case string: + // if an empty UUID comes from a table, we return a null UUID + if src.(string) == "" { + return nil + } + + // see uuid.Parse for required string format + parsed := Parse(src.(string)) + + if parsed == nil { + return errors.New("Scan: invalid UUID format") + } + + *uuid = parsed + case []byte: + b := src.([]byte) + + // if an empty UUID comes from a table, we return a null UUID + if len(b) == 0 { + return nil + } + + // assumes a simple slice of bytes if 16 bytes + // otherwise attempts to parse + if len(b) == 16 { + *uuid = UUID(b) + } else { + u := Parse(string(b)) + + if u == nil { + return errors.New("Scan: invalid UUID format") + } + + *uuid = u + } + + default: + return fmt.Errorf("Scan: unable to scan type %T into UUID", src) + } + + return nil +} + +// Value implements sql.Valuer so that UUIDs can be written to databases +// transparently. Currently, UUIDs map to strings. Please consult +// database-specific driver documentation for matching types. +func (uuid UUID) Value() (driver.Value, error) { + return uuid.String(), nil +} diff --git a/vendor/github.com/pborman/uuid/sql_test.go b/vendor/github.com/pborman/uuid/sql_test.go new file mode 100644 index 00000000..10309515 --- /dev/null +++ b/vendor/github.com/pborman/uuid/sql_test.go @@ -0,0 +1,96 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "strings" + "testing" +) + +func TestScan(t *testing.T) { + var stringTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d479" + var byteTest []byte = Parse(stringTest) + var badTypeTest int = 6 + var invalidTest string = "f47ac10b-58cc-0372-8567-0e02b2c3d4" + + // sunny day tests + + var uuid UUID + err := (&uuid).Scan(stringTest) + if err != nil { + t.Fatal(err) + } + + err = (&uuid).Scan([]byte(stringTest)) + if err != nil { + t.Fatal(err) + } + + err = (&uuid).Scan(byteTest) + if err != nil { + t.Fatal(err) + } + + // bad type tests + + err = (&uuid).Scan(badTypeTest) + if err == nil { + t.Error("int correctly parsed and shouldn't have") + } + if !strings.Contains(err.Error(), "unable to scan type") { + t.Error("attempting to parse an int returned an incorrect error message") + } + + // invalid/incomplete uuids + + err = (&uuid).Scan(invalidTest) + if err == nil { + t.Error("invalid uuid was parsed without error") + } + if !strings.Contains(err.Error(), "invalid UUID") { + t.Error("attempting to parse an invalid UUID returned an incorrect error message") + } + + err = (&uuid).Scan(byteTest[:len(byteTest)-2]) + if err == nil { + t.Error("invalid byte uuid was parsed without error") + } + if !strings.Contains(err.Error(), "invalid UUID") { + t.Error("attempting to parse an invalid byte UUID returned an incorrect error message") + } + + // empty tests + + uuid = nil + var emptySlice []byte + err = (&uuid).Scan(emptySlice) + if err != nil { + t.Fatal(err) + } + + if uuid != nil { + t.Error("UUID was not nil after scanning empty byte slice") + } + + uuid = nil + var emptyString string + err = (&uuid).Scan(emptyString) + if err != nil { + t.Fatal(err) + } + + if uuid != nil { + t.Error("UUID was not nil after scanning empty string") + } +} + +func TestValue(t *testing.T) { + stringTest := "f47ac10b-58cc-0372-8567-0e02b2c3d479" + uuid := Parse(stringTest) + val, _ := uuid.Value() + if val != stringTest { + t.Error("Value() did not return expected string") + } +} diff --git a/vendor/github.com/pborman/uuid/time.go b/vendor/github.com/pborman/uuid/time.go new file mode 100644 index 00000000..eedf2421 --- /dev/null +++ b/vendor/github.com/pborman/uuid/time.go @@ -0,0 +1,132 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "sync" + "time" +) + +// A Time represents a time as the number of 100's of nanoseconds since 15 Oct +// 1582. +type Time int64 + +const ( + lillian = 2299160 // Julian day of 15 Oct 1582 + unix = 2440587 // Julian day of 1 Jan 1970 + epoch = unix - lillian // Days between epochs + g1582 = epoch * 86400 // seconds between epochs + g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs +) + +var ( + timeMu sync.Mutex + lasttime uint64 // last time we returned + clock_seq uint16 // clock sequence for this run + + timeNow = time.Now // for testing +) + +// UnixTime converts t the number of seconds and nanoseconds using the Unix +// epoch of 1 Jan 1970. +func (t Time) UnixTime() (sec, nsec int64) { + sec = int64(t - g1582ns100) + nsec = (sec % 10000000) * 100 + sec /= 10000000 + return sec, nsec +} + +// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and +// clock sequence as well as adjusting the clock sequence as needed. An error +// is returned if the current time cannot be determined. +func GetTime() (Time, uint16, error) { + defer timeMu.Unlock() + timeMu.Lock() + return getTime() +} + +func getTime() (Time, uint16, error) { + t := timeNow() + + // If we don't have a clock sequence already, set one. + if clock_seq == 0 { + setClockSequence(-1) + } + now := uint64(t.UnixNano()/100) + g1582ns100 + + // If time has gone backwards with this clock sequence then we + // increment the clock sequence + if now <= lasttime { + clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000 + } + lasttime = now + return Time(now), clock_seq, nil +} + +// ClockSequence returns the current clock sequence, generating one if not +// already set. The clock sequence is only used for Version 1 UUIDs. +// +// The uuid package does not use global static storage for the clock sequence or +// the last time a UUID was generated. Unless SetClockSequence a new random +// clock sequence is generated the first time a clock sequence is requested by +// ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated +// for +func ClockSequence() int { + defer timeMu.Unlock() + timeMu.Lock() + return clockSequence() +} + +func clockSequence() int { + if clock_seq == 0 { + setClockSequence(-1) + } + return int(clock_seq & 0x3fff) +} + +// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to +// -1 causes a new sequence to be generated. +func SetClockSequence(seq int) { + defer timeMu.Unlock() + timeMu.Lock() + setClockSequence(seq) +} + +func setClockSequence(seq int) { + if seq == -1 { + var b [2]byte + randomBits(b[:]) // clock sequence + seq = int(b[0])<<8 | int(b[1]) + } + old_seq := clock_seq + clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant + if old_seq != clock_seq { + lasttime = 0 + } +} + +// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in +// uuid. It returns false if uuid is not valid. The time is only well defined +// for version 1 and 2 UUIDs. +func (uuid UUID) Time() (Time, bool) { + if len(uuid) != 16 { + return 0, false + } + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + return Time(time), true +} + +// ClockSequence returns the clock sequence encoded in uuid. It returns false +// if uuid is not valid. The clock sequence is only well defined for version 1 +// and 2 UUIDs. +func (uuid UUID) ClockSequence() (int, bool) { + if len(uuid) != 16 { + return 0, false + } + return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true +} diff --git a/vendor/github.com/pborman/uuid/util.go b/vendor/github.com/pborman/uuid/util.go new file mode 100644 index 00000000..fc8e052c --- /dev/null +++ b/vendor/github.com/pborman/uuid/util.go @@ -0,0 +1,43 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// randomBits completely fills slice b with random data. +func randomBits(b []byte) { + if _, err := io.ReadFull(rander, b); err != nil { + panic(err.Error()) // rand should never fail + } +} + +// xvalues returns the value of a byte as a hexadecimal digit or 255. +var xvalues = [256]byte{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +} + +// xtob converts the the first two hex bytes of x into a byte. +func xtob(x string) (byte, bool) { + b1 := xvalues[x[0]] + b2 := xvalues[x[1]] + return (b1 << 4) | b2, b1 != 255 && b2 != 255 +} diff --git a/vendor/github.com/pborman/uuid/uuid.go b/vendor/github.com/pborman/uuid/uuid.go new file mode 100644 index 00000000..7c643cf0 --- /dev/null +++ b/vendor/github.com/pborman/uuid/uuid.go @@ -0,0 +1,201 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "fmt" + "io" + "strings" +) + +// Array is a pass-by-value UUID that can be used as an effecient key in a map. +type Array [16]byte + +// UUID converts uuid into a slice. +func (uuid Array) UUID() UUID { + return uuid[:] +} + +// String returns the string representation of uuid, +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. +func (uuid Array) String() string { + return uuid.UUID().String() +} + +// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC +// 4122. +type UUID []byte + +// A Version represents a UUIDs version. +type Version byte + +// A Variant represents a UUIDs variant. +type Variant byte + +// Constants returned by Variant. +const ( + Invalid = Variant(iota) // Invalid UUID + RFC4122 // The variant specified in RFC4122 + Reserved // Reserved, NCS backward compatibility. + Microsoft // Reserved, Microsoft Corporation backward compatibility. + Future // Reserved for future definition. +) + +var rander = rand.Reader // random function + +// New returns a new random (version 4) UUID as a string. It is a convenience +// function for NewRandom().String(). +func New() string { + return NewRandom().String() +} + +// Parse decodes s into a UUID or returns nil. Both the UUID form of +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded. +func Parse(s string) UUID { + if len(s) == 36+9 { + if strings.ToLower(s[:9]) != "urn:uuid:" { + return nil + } + s = s[9:] + } else if len(s) != 36 { + return nil + } + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return nil + } + var uuid [16]byte + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + if v, ok := xtob(s[x:]); !ok { + return nil + } else { + uuid[i] = v + } + } + return uuid[:] +} + +// Equal returns true if uuid1 and uuid2 are equal. +func Equal(uuid1, uuid2 UUID) bool { + return bytes.Equal(uuid1, uuid2) +} + +// Array returns an array representation of uuid that can be used as a map key. +// Array panics if uuid is not valid. +func (uuid UUID) Array() Array { + if len(uuid) != 16 { + panic("invalid uuid") + } + var a Array + copy(a[:], uuid) + return a +} + +// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// , or "" if uuid is invalid. +func (uuid UUID) String() string { + if len(uuid) != 16 { + return "" + } + var buf [36]byte + encodeHex(buf[:], uuid) + return string(buf[:]) +} + +// URN returns the RFC 2141 URN form of uuid, +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. +func (uuid UUID) URN() string { + if len(uuid) != 16 { + return "" + } + var buf [36 + 9]byte + copy(buf[:], "urn:uuid:") + encodeHex(buf[9:], uuid) + return string(buf[:]) +} + +func encodeHex(dst []byte, uuid UUID) { + hex.Encode(dst[:], uuid[:4]) + dst[8] = '-' + hex.Encode(dst[9:13], uuid[4:6]) + dst[13] = '-' + hex.Encode(dst[14:18], uuid[6:8]) + dst[18] = '-' + hex.Encode(dst[19:23], uuid[8:10]) + dst[23] = '-' + hex.Encode(dst[24:], uuid[10:]) +} + +// Variant returns the variant encoded in uuid. It returns Invalid if +// uuid is invalid. +func (uuid UUID) Variant() Variant { + if len(uuid) != 16 { + return Invalid + } + switch { + case (uuid[8] & 0xc0) == 0x80: + return RFC4122 + case (uuid[8] & 0xe0) == 0xc0: + return Microsoft + case (uuid[8] & 0xe0) == 0xe0: + return Future + default: + return Reserved + } +} + +// Version returns the version of uuid. It returns false if uuid is not +// valid. +func (uuid UUID) Version() (Version, bool) { + if len(uuid) != 16 { + return 0, false + } + return Version(uuid[6] >> 4), true +} + +func (v Version) String() string { + if v > 15 { + return fmt.Sprintf("BAD_VERSION_%d", v) + } + return fmt.Sprintf("VERSION_%d", v) +} + +func (v Variant) String() string { + switch v { + case RFC4122: + return "RFC4122" + case Reserved: + return "Reserved" + case Microsoft: + return "Microsoft" + case Future: + return "Future" + case Invalid: + return "Invalid" + } + return fmt.Sprintf("BadVariant%d", int(v)) +} + +// SetRand sets the random number generator to r, which implements io.Reader. +// If r.Read returns an error when the package requests random data then +// a panic will be issued. +// +// Calling SetRand with nil sets the random number generator to the default +// generator. +func SetRand(r io.Reader) { + if r == nil { + rander = rand.Reader + return + } + rander = r +} diff --git a/vendor/github.com/pborman/uuid/uuid_test.go b/vendor/github.com/pborman/uuid/uuid_test.go new file mode 100644 index 00000000..03872396 --- /dev/null +++ b/vendor/github.com/pborman/uuid/uuid_test.go @@ -0,0 +1,543 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "fmt" + "os" + "strings" + "testing" + "time" +) + +type test struct { + in string + version Version + variant Variant + isuuid bool +} + +var tests = []test{ + {"f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, RFC4122, true}, + {"f47ac10b-58cc-1372-8567-0e02b2c3d479", 1, RFC4122, true}, + {"f47ac10b-58cc-2372-8567-0e02b2c3d479", 2, RFC4122, true}, + {"f47ac10b-58cc-3372-8567-0e02b2c3d479", 3, RFC4122, true}, + {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true}, + {"f47ac10b-58cc-5372-8567-0e02b2c3d479", 5, RFC4122, true}, + {"f47ac10b-58cc-6372-8567-0e02b2c3d479", 6, RFC4122, true}, + {"f47ac10b-58cc-7372-8567-0e02b2c3d479", 7, RFC4122, true}, + {"f47ac10b-58cc-8372-8567-0e02b2c3d479", 8, RFC4122, true}, + {"f47ac10b-58cc-9372-8567-0e02b2c3d479", 9, RFC4122, true}, + {"f47ac10b-58cc-a372-8567-0e02b2c3d479", 10, RFC4122, true}, + {"f47ac10b-58cc-b372-8567-0e02b2c3d479", 11, RFC4122, true}, + {"f47ac10b-58cc-c372-8567-0e02b2c3d479", 12, RFC4122, true}, + {"f47ac10b-58cc-d372-8567-0e02b2c3d479", 13, RFC4122, true}, + {"f47ac10b-58cc-e372-8567-0e02b2c3d479", 14, RFC4122, true}, + {"f47ac10b-58cc-f372-8567-0e02b2c3d479", 15, RFC4122, true}, + + {"urn:uuid:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, + {"URN:UUID:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-1567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-2567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-3567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-4567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-5567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-6567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-7567-0e02b2c3d479", 4, Reserved, true}, + {"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true}, + {"f47ac10b-58cc-4372-9567-0e02b2c3d479", 4, RFC4122, true}, + {"f47ac10b-58cc-4372-a567-0e02b2c3d479", 4, RFC4122, true}, + {"f47ac10b-58cc-4372-b567-0e02b2c3d479", 4, RFC4122, true}, + {"f47ac10b-58cc-4372-c567-0e02b2c3d479", 4, Microsoft, true}, + {"f47ac10b-58cc-4372-d567-0e02b2c3d479", 4, Microsoft, true}, + {"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true}, + {"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true}, + + {"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false}, + {"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false}, + {"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false}, + {"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false}, + {"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false}, + {"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false}, +} + +var constants = []struct { + c interface{} + name string +}{ + {Person, "Person"}, + {Group, "Group"}, + {Org, "Org"}, + {Invalid, "Invalid"}, + {RFC4122, "RFC4122"}, + {Reserved, "Reserved"}, + {Microsoft, "Microsoft"}, + {Future, "Future"}, + {Domain(17), "Domain17"}, + {Variant(42), "BadVariant42"}, +} + +func testTest(t *testing.T, in string, tt test) { + uuid := Parse(in) + if ok := (uuid != nil); ok != tt.isuuid { + t.Errorf("Parse(%s) got %v expected %v\b", in, ok, tt.isuuid) + } + if uuid == nil { + return + } + + if v := uuid.Variant(); v != tt.variant { + t.Errorf("Variant(%s) got %d expected %d\b", in, v, tt.variant) + } + if v, _ := uuid.Version(); v != tt.version { + t.Errorf("Version(%s) got %d expected %d\b", in, v, tt.version) + } +} + +func TestUUID(t *testing.T) { + for _, tt := range tests { + testTest(t, tt.in, tt) + testTest(t, strings.ToUpper(tt.in), tt) + } +} + +func TestConstants(t *testing.T) { + for x, tt := range constants { + v, ok := tt.c.(fmt.Stringer) + if !ok { + t.Errorf("%x: %v: not a stringer", x, v) + } else if s := v.String(); s != tt.name { + v, _ := tt.c.(int) + t.Errorf("%x: Constant %T:%d gives %q, expected %q", x, tt.c, v, s, tt.name) + } + } +} + +func TestRandomUUID(t *testing.T) { + m := make(map[string]bool) + for x := 1; x < 32; x++ { + uuid := NewRandom() + s := uuid.String() + if m[s] { + t.Errorf("NewRandom returned duplicated UUID %s", s) + } + m[s] = true + if v, _ := uuid.Version(); v != 4 { + t.Errorf("Random UUID of version %s", v) + } + if uuid.Variant() != RFC4122 { + t.Errorf("Random UUID is variant %d", uuid.Variant()) + } + } +} + +func TestNew(t *testing.T) { + m := make(map[string]bool) + for x := 1; x < 32; x++ { + s := New() + if m[s] { + t.Errorf("New returned duplicated UUID %s", s) + } + m[s] = true + uuid := Parse(s) + if uuid == nil { + t.Errorf("New returned %q which does not decode", s) + continue + } + if v, _ := uuid.Version(); v != 4 { + t.Errorf("Random UUID of version %s", v) + } + if uuid.Variant() != RFC4122 { + t.Errorf("Random UUID is variant %d", uuid.Variant()) + } + } +} + +func clockSeq(t *testing.T, uuid UUID) int { + seq, ok := uuid.ClockSequence() + if !ok { + t.Fatalf("%s: invalid clock sequence", uuid) + } + return seq +} + +func TestClockSeq(t *testing.T) { + // Fake time.Now for this test to return a monotonically advancing time; restore it at end. + defer func(orig func() time.Time) { timeNow = orig }(timeNow) + monTime := time.Now() + timeNow = func() time.Time { + monTime = monTime.Add(1 * time.Second) + return monTime + } + + SetClockSequence(-1) + uuid1 := NewUUID() + uuid2 := NewUUID() + + if clockSeq(t, uuid1) != clockSeq(t, uuid2) { + t.Errorf("clock sequence %d != %d", clockSeq(t, uuid1), clockSeq(t, uuid2)) + } + + SetClockSequence(-1) + uuid2 = NewUUID() + + // Just on the very off chance we generated the same sequence + // two times we try again. + if clockSeq(t, uuid1) == clockSeq(t, uuid2) { + SetClockSequence(-1) + uuid2 = NewUUID() + } + if clockSeq(t, uuid1) == clockSeq(t, uuid2) { + t.Errorf("Duplicate clock sequence %d", clockSeq(t, uuid1)) + } + + SetClockSequence(0x1234) + uuid1 = NewUUID() + if seq := clockSeq(t, uuid1); seq != 0x1234 { + t.Errorf("%s: expected seq 0x1234 got 0x%04x", uuid1, seq) + } +} + +func TestCoding(t *testing.T) { + text := "7d444840-9dc0-11d1-b245-5ffdce74fad2" + urn := "urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2" + data := UUID{ + 0x7d, 0x44, 0x48, 0x40, + 0x9d, 0xc0, + 0x11, 0xd1, + 0xb2, 0x45, + 0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2, + } + if v := data.String(); v != text { + t.Errorf("%x: encoded to %s, expected %s", data, v, text) + } + if v := data.URN(); v != urn { + t.Errorf("%x: urn is %s, expected %s", data, v, urn) + } + + uuid := Parse(text) + if !Equal(uuid, data) { + t.Errorf("%s: decoded to %s, expected %s", text, uuid, data) + } +} + +func TestVersion1(t *testing.T) { + uuid1 := NewUUID() + uuid2 := NewUUID() + + if Equal(uuid1, uuid2) { + t.Errorf("%s:duplicate uuid", uuid1) + } + if v, _ := uuid1.Version(); v != 1 { + t.Errorf("%s: version %s expected 1", uuid1, v) + } + if v, _ := uuid2.Version(); v != 1 { + t.Errorf("%s: version %s expected 1", uuid2, v) + } + n1 := uuid1.NodeID() + n2 := uuid2.NodeID() + if !bytes.Equal(n1, n2) { + t.Errorf("Different nodes %x != %x", n1, n2) + } + t1, ok := uuid1.Time() + if !ok { + t.Errorf("%s: invalid time", uuid1) + } + t2, ok := uuid2.Time() + if !ok { + t.Errorf("%s: invalid time", uuid2) + } + q1, ok := uuid1.ClockSequence() + if !ok { + t.Errorf("%s: invalid clock sequence", uuid1) + } + q2, ok := uuid2.ClockSequence() + if !ok { + t.Errorf("%s: invalid clock sequence", uuid2) + } + + switch { + case t1 == t2 && q1 == q2: + t.Error("time stopped") + case t1 > t2 && q1 == q2: + t.Error("time reversed") + case t1 < t2 && q1 != q2: + t.Error("clock sequence chaned unexpectedly") + } +} + +func TestNode(t *testing.T) { + // This test is mostly to make sure we don't leave nodeMu locked. + ifname = "" + if ni := NodeInterface(); ni != "" { + t.Errorf("NodeInterface got %q, want %q", ni, "") + } + if SetNodeInterface("xyzzy") { + t.Error("SetNodeInterface succeeded on a bad interface name") + } + if !SetNodeInterface("") { + t.Error("SetNodeInterface failed") + } + if ni := NodeInterface(); ni == "" { + t.Error("NodeInterface returned an empty string") + } + + ni := NodeID() + if len(ni) != 6 { + t.Errorf("ni got %d bytes, want 6", len(ni)) + } + hasData := false + for _, b := range ni { + if b != 0 { + hasData = true + } + } + if !hasData { + t.Error("nodeid is all zeros") + } + + id := []byte{1, 2, 3, 4, 5, 6, 7, 8} + SetNodeID(id) + ni = NodeID() + if !bytes.Equal(ni, id[:6]) { + t.Errorf("got nodeid %v, want %v", ni, id[:6]) + } + + if ni := NodeInterface(); ni != "user" { + t.Errorf("got inteface %q, want %q", ni, "user") + } +} + +func TestNodeAndTime(t *testing.T) { + // Time is February 5, 1998 12:30:23.136364800 AM GMT + + uuid := Parse("7d444840-9dc0-11d1-b245-5ffdce74fad2") + node := []byte{0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2} + + ts, ok := uuid.Time() + if ok { + c := time.Unix(ts.UnixTime()) + want := time.Date(1998, 2, 5, 0, 30, 23, 136364800, time.UTC) + if !c.Equal(want) { + t.Errorf("Got time %v, want %v", c, want) + } + } else { + t.Errorf("%s: bad time", uuid) + } + if !bytes.Equal(node, uuid.NodeID()) { + t.Errorf("Expected node %v got %v", node, uuid.NodeID()) + } +} + +func TestMD5(t *testing.T) { + uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String() + want := "6fa459ea-ee8a-3ca4-894e-db77e160355e" + if uuid != want { + t.Errorf("MD5: got %q expected %q", uuid, want) + } +} + +func TestSHA1(t *testing.T) { + uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String() + want := "886313e1-3b8a-5372-9b90-0c9aee199e5d" + if uuid != want { + t.Errorf("SHA1: got %q expected %q", uuid, want) + } +} + +func TestNodeID(t *testing.T) { + nid := []byte{1, 2, 3, 4, 5, 6} + SetNodeInterface("") + s := NodeInterface() + if s == "" || s == "user" { + t.Errorf("NodeInterface %q after SetInteface", s) + } + node1 := NodeID() + if node1 == nil { + t.Error("NodeID nil after SetNodeInterface", s) + } + SetNodeID(nid) + s = NodeInterface() + if s != "user" { + t.Errorf("Expected NodeInterface %q got %q", "user", s) + } + node2 := NodeID() + if node2 == nil { + t.Error("NodeID nil after SetNodeID", s) + } + if bytes.Equal(node1, node2) { + t.Error("NodeID not changed after SetNodeID", s) + } else if !bytes.Equal(nid, node2) { + t.Errorf("NodeID is %x, expected %x", node2, nid) + } +} + +func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) { + if uuid == nil { + t.Errorf("%s failed", name) + return + } + if v, _ := uuid.Version(); v != 2 { + t.Errorf("%s: %s: expected version 2, got %s", name, uuid, v) + return + } + if v, ok := uuid.Domain(); !ok || v != domain { + if !ok { + t.Errorf("%s: %d: Domain failed", name, uuid) + } else { + t.Errorf("%s: %s: expected domain %d, got %d", name, uuid, domain, v) + } + } + if v, ok := uuid.Id(); !ok || v != id { + if !ok { + t.Errorf("%s: %d: Id failed", name, uuid) + } else { + t.Errorf("%s: %s: expected id %d, got %d", name, uuid, id, v) + } + } +} + +func TestDCE(t *testing.T) { + testDCE(t, "NewDCESecurity", NewDCESecurity(42, 12345678), 42, 12345678) + testDCE(t, "NewDCEPerson", NewDCEPerson(), Person, uint32(os.Getuid())) + testDCE(t, "NewDCEGroup", NewDCEGroup(), Group, uint32(os.Getgid())) +} + +type badRand struct{} + +func (r badRand) Read(buf []byte) (int, error) { + for i, _ := range buf { + buf[i] = byte(i) + } + return len(buf), nil +} + +func TestBadRand(t *testing.T) { + SetRand(badRand{}) + uuid1 := New() + uuid2 := New() + if uuid1 != uuid2 { + t.Errorf("expected duplicates, got %q and %q", uuid1, uuid2) + } + SetRand(nil) + uuid1 = New() + uuid2 = New() + if uuid1 == uuid2 { + t.Errorf("unexpected duplicates, got %q", uuid1) + } +} + +func TestUUID_Array(t *testing.T) { + expect := Array{ + 0xf4, 0x7a, 0xc1, 0x0b, + 0x58, 0xcc, + 0x03, 0x72, + 0x85, 0x67, + 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79, + } + uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if uuid == nil { + t.Fatal("invalid uuid") + } + if uuid.Array() != expect { + t.Fatal("invalid array") + } +} + +func TestArray_UUID(t *testing.T) { + array := Array{ + 0xf4, 0x7a, 0xc1, 0x0b, + 0x58, 0xcc, + 0x03, 0x72, + 0x85, 0x67, + 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79, + } + expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if expect == nil { + t.Fatal("invalid uuid") + } + if !bytes.Equal(array.UUID(), expect) { + t.Fatal("invalid uuid") + } +} + +func BenchmarkParse(b *testing.B) { + for i := 0; i < b.N; i++ { + uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if uuid == nil { + b.Fatal("invalid uuid") + } + } +} + +func BenchmarkNew(b *testing.B) { + for i := 0; i < b.N; i++ { + New() + } +} + +func BenchmarkUUID_String(b *testing.B) { + uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if uuid == nil { + b.Fatal("invalid uuid") + } + for i := 0; i < b.N; i++ { + if uuid.String() == "" { + b.Fatal("invalid uuid") + } + } +} + +func BenchmarkUUID_URN(b *testing.B) { + uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if uuid == nil { + b.Fatal("invalid uuid") + } + for i := 0; i < b.N; i++ { + if uuid.URN() == "" { + b.Fatal("invalid uuid") + } + } +} + +func BenchmarkUUID_Array(b *testing.B) { + expect := Array{ + 0xf4, 0x7a, 0xc1, 0x0b, + 0x58, 0xcc, + 0x03, 0x72, + 0x85, 0x67, + 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79, + } + uuid := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if uuid == nil { + b.Fatal("invalid uuid") + } + for i := 0; i < b.N; i++ { + if uuid.Array() != expect { + b.Fatal("invalid array") + } + } +} + +func BenchmarkArray_UUID(b *testing.B) { + array := Array{ + 0xf4, 0x7a, 0xc1, 0x0b, + 0x58, 0xcc, + 0x03, 0x72, + 0x85, 0x67, + 0x0e, 0x02, 0xb2, 0xc3, 0xd4, 0x79, + } + expect := Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + if expect == nil { + b.Fatal("invalid uuid") + } + for i := 0; i < b.N; i++ { + if !bytes.Equal(array.UUID(), expect) { + b.Fatal("invalid uuid") + } + } +} diff --git a/vendor/github.com/pborman/uuid/version1.go b/vendor/github.com/pborman/uuid/version1.go new file mode 100644 index 00000000..0127eacf --- /dev/null +++ b/vendor/github.com/pborman/uuid/version1.go @@ -0,0 +1,41 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" +) + +// NewUUID returns a Version 1 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewUUID returns nil. If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewUUID returns nil. +func NewUUID() UUID { + if nodeID == nil { + SetNodeInterface("") + } + + now, seq, err := GetTime() + if err != nil { + return nil + } + + uuid := make([]byte, 16) + + time_low := uint32(now & 0xffffffff) + time_mid := uint16((now >> 32) & 0xffff) + time_hi := uint16((now >> 48) & 0x0fff) + time_hi |= 0x1000 // Version 1 + + binary.BigEndian.PutUint32(uuid[0:], time_low) + binary.BigEndian.PutUint16(uuid[4:], time_mid) + binary.BigEndian.PutUint16(uuid[6:], time_hi) + binary.BigEndian.PutUint16(uuid[8:], seq) + copy(uuid[10:], nodeID) + + return uuid +} diff --git a/vendor/github.com/pborman/uuid/version4.go b/vendor/github.com/pborman/uuid/version4.go new file mode 100644 index 00000000..b3d4a368 --- /dev/null +++ b/vendor/github.com/pborman/uuid/version4.go @@ -0,0 +1,25 @@ +// Copyright 2011 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +// Random returns a Random (Version 4) UUID or panics. +// +// The strength of the UUIDs is based on the strength of the crypto/rand +// package. +// +// A note about uniqueness derived from from the UUID Wikipedia entry: +// +// Randomly generated UUIDs have 122 random bits. One's annual risk of being +// hit by a meteorite is estimated to be one chance in 17 billion, that +// means the probability is about 0.00000000006 (6 × 10−11), +// equivalent to the odds of creating a few tens of trillions of UUIDs in a +// year and having one duplicate. +func NewRandom() UUID { + uuid := make([]byte, 16) + randomBits([]byte(uuid)) + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid +} diff --git a/vendor/github.com/rjeczalik/notify/.gitignore b/vendor/github.com/rjeczalik/notify/.gitignore new file mode 100644 index 00000000..32c6eb98 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/.gitignore @@ -0,0 +1,92 @@ +# Created by https://www.gitignore.io + +### OSX ### +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### Windows ### +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + + +### Linux ### +*~ + +# KDE directory preferences +.directory + + +### Go ### +# 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 +*.test +*.prof + + +### vim ### +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ + +### JetBrains files ### +.idea/ +*.iml \ No newline at end of file diff --git a/vendor/github.com/rjeczalik/notify/.travis.yml b/vendor/github.com/rjeczalik/notify/.travis.yml new file mode 100644 index 00000000..0c0b66dd --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/.travis.yml @@ -0,0 +1,31 @@ +language: go + +go: + - 1.7.5 + - tip + +os: + - linux + - osx + +matrix: + include: + - os: osx + go: 1.7.5 + env: + - GOFLAGS="-tags kqueue" + allow_failures: + - go: tip + +env: + global: + - GOBIN=$HOME/bin + - PATH=$HOME/bin:$PATH + +install: + - go get -t -v ./... + +script: + - "(go version | grep -q 1.4) || go tool vet -all ." + - go install $GOFLAGS ./... + - go test -v -timeout 60s -race $GOFLAGS ./... diff --git a/vendor/github.com/rjeczalik/notify/AUTHORS b/vendor/github.com/rjeczalik/notify/AUTHORS new file mode 100644 index 00000000..9262eae6 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/AUTHORS @@ -0,0 +1,10 @@ +# List of individuals who contributed to the Notify package. +# +# The up-to-date list of the authors one may obtain with: +# +# ~ $ git shortlog -es | cut -f2 | rev | uniq -f1 | rev +# + +Pawel Blaszczyk +Pawel Knap +Rafal Jeczalik diff --git a/vendor/github.com/rjeczalik/notify/LICENSE b/vendor/github.com/rjeczalik/notify/LICENSE new file mode 100644 index 00000000..3e678817 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015 The Notify Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/rjeczalik/notify/README.md b/vendor/github.com/rjeczalik/notify/README.md new file mode 100644 index 00000000..ad743b2a --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/README.md @@ -0,0 +1,22 @@ +notify [![GoDoc](https://godoc.org/github.com/rjeczalik/notify?status.svg)](https://godoc.org/github.com/rjeczalik/notify) [![Build Status](https://img.shields.io/travis/rjeczalik/notify/master.svg)](https://travis-ci.org/rjeczalik/notify "inotify + FSEvents + kqueue") [![Build status](https://img.shields.io/appveyor/ci/rjeczalik/notify-246.svg)](https://ci.appveyor.com/project/rjeczalik/notify-246 "ReadDirectoryChangesW") [![Coverage Status](https://img.shields.io/coveralls/rjeczalik/notify/master.svg)](https://coveralls.io/r/rjeczalik/notify?branch=master) +====== + +Filesystem event notification library on steroids. (under active development) + +*Documentation* + +[godoc.org/github.com/rjeczalik/notify](https://godoc.org/github.com/rjeczalik/notify) + +*Installation* + +``` +~ $ go get -u github.com/rjeczalik/notify +``` + +*Projects using notify* + +- [github.com/rjeczalik/cmd/notify](https://godoc.org/github.com/rjeczalik/cmd/notify) +- [github.com/cortesi/devd](https://github.com/cortesi/devd) +- [github.com/cortesi/modd](https://github.com/cortesi/modd) +- [github.com/syncthing/syncthing-inotify](https://github.com/syncthing/syncthing-inotify) +- [github.com/OrlovEvgeny/TinyJPG](https://github.com/OrlovEvgeny/TinyJPG) diff --git a/vendor/github.com/rjeczalik/notify/appveyor.yml b/vendor/github.com/rjeczalik/notify/appveyor.yml new file mode 100644 index 00000000..a495bd7c --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/appveyor.yml @@ -0,0 +1,23 @@ +version: "{build}" + +os: Windows Server 2012 R2 + +clone_folder: c:\projects\src\github.com\rjeczalik\notify + +environment: + PATH: c:\projects\bin;%PATH% + GOPATH: c:\projects + NOTIFY_TIMEOUT: 5s + +install: + - go version + - go get -v -t ./... + +build_script: + - go tool vet -all . + - go build ./... + - go test -v -timeout 60s -race ./... + +test: off + +deploy: off diff --git a/vendor/github.com/rjeczalik/notify/debug.go b/vendor/github.com/rjeczalik/notify/debug.go new file mode 100644 index 00000000..2a3eb337 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/debug.go @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "log" + "os" + "runtime" + "strings" +) + +var dbgprint func(...interface{}) + +var dbgprintf func(string, ...interface{}) + +var dbgcallstack func(max int) []string + +func init() { + if _, ok := os.LookupEnv("NOTIFY_DEBUG"); ok || debugTag { + log.SetOutput(os.Stdout) + log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) + dbgprint = func(v ...interface{}) { + v = append([]interface{}{"[D] "}, v...) + log.Println(v...) + } + dbgprintf = func(format string, v ...interface{}) { + format = "[D] " + format + log.Printf(format, v...) + } + dbgcallstack = func(max int) []string { + pc, stack := make([]uintptr, max), make([]string, 0, max) + runtime.Callers(2, pc) + for _, pc := range pc { + if f := runtime.FuncForPC(pc); f != nil { + fname := f.Name() + idx := strings.LastIndex(fname, string(os.PathSeparator)) + if idx != -1 { + stack = append(stack, fname[idx+1:]) + } else { + stack = append(stack, fname) + } + } + } + return stack + } + return + } + dbgprint = func(v ...interface{}) {} + dbgprintf = func(format string, v ...interface{}) {} + dbgcallstack = func(max int) []string { return nil } +} diff --git a/vendor/github.com/rjeczalik/notify/debug_debug.go b/vendor/github.com/rjeczalik/notify/debug_debug.go new file mode 100644 index 00000000..9d234ced --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/debug_debug.go @@ -0,0 +1,9 @@ +// Copyright (c) 2014-2018 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build debug + +package notify + +var debugTag = true diff --git a/vendor/github.com/rjeczalik/notify/debug_nodebug.go b/vendor/github.com/rjeczalik/notify/debug_nodebug.go new file mode 100644 index 00000000..9ebf880d --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/debug_nodebug.go @@ -0,0 +1,9 @@ +// Copyright (c) 2014-2018 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build !debug + +package notify + +var debugTag = false diff --git a/vendor/github.com/rjeczalik/notify/doc.go b/vendor/github.com/rjeczalik/notify/doc.go new file mode 100644 index 00000000..60543c08 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/doc.go @@ -0,0 +1,43 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// Package notify implements access to filesystem events. +// +// Notify is a high-level abstraction over filesystem watchers like inotify, +// kqueue, FSEvents, FEN or ReadDirectoryChangesW. Watcher implementations are +// split into two groups: ones that natively support recursive notifications +// (FSEvents and ReadDirectoryChangesW) and ones that do not (inotify, kqueue, FEN). +// For more details see watcher and recursiveWatcher interfaces in watcher.go +// source file. +// +// On top of filesystem watchers notify maintains a watchpoint tree, which provides +// a strategy for creating and closing filesystem watches and dispatching filesystem +// events to user channels. +// +// An event set is just an event list joint using bitwise OR operator +// into a single event value. +// Both the platform-independent (see Constants) and specific events can be used. +// Refer to the event_*.go source files for information about the available +// events. +// +// A filesystem watch or just a watch is platform-specific entity which represents +// a single path registered for notifications for specific event set. Setting a watch +// means using platform-specific API calls for creating / initializing said watch. +// For each watcher the API call is: +// +// - FSEvents: FSEventStreamCreate +// - inotify: notify_add_watch +// - kqueue: kevent +// - ReadDirectoryChangesW: CreateFile+ReadDirectoryChangesW +// - FEN: port_get +// +// To rewatch means to either shrink or expand an event set that was previously +// registered during watch operation for particular filesystem watch. +// +// A watchpoint is a list of user channel and event set pairs for particular +// path (watchpoint tree's node). A single watchpoint can contain multiple +// different user channels registered to listen for one or more events. A single +// user channel can be registered in one or more watchpoints, recursive and +// non-recursive ones as well. +package notify diff --git a/vendor/github.com/rjeczalik/notify/event.go b/vendor/github.com/rjeczalik/notify/event.go new file mode 100644 index 00000000..c1288419 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event.go @@ -0,0 +1,143 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "fmt" + "strings" +) + +// Event represents the type of filesystem action. +// +// Number of available event values is dependent on the target system or the +// watcher implmenetation used (e.g. it's possible to use either kqueue or +// FSEvents on Darwin). +// +// Please consult documentation for your target platform to see list of all +// available events. +type Event uint32 + +// Create, Remove, Write and Rename are the only event values guaranteed to be +// present on all platforms. +const ( + Create = osSpecificCreate + Remove = osSpecificRemove + Write = osSpecificWrite + Rename = osSpecificRename + + // All is handful alias for all platform-independent event values. + All = Create | Remove | Write | Rename +) + +const internal = recursive | omit + +// String implements fmt.Stringer interface. +func (e Event) String() string { + var s []string + for _, strmap := range []map[Event]string{estr, osestr} { + for ev, str := range strmap { + if e&ev == ev { + s = append(s, str) + } + } + } + return strings.Join(s, "|") +} + +// EventInfo describes an event reported by the underlying filesystem notification +// subsystem. +// +// It always describes single event, even if the OS reported a coalesced action. +// Reported path is absolute and clean. +// +// For non-recursive watchpoints its base is always equal to the path passed +// to corresponding Watch call. +// +// The value of Sys if system-dependent and can be nil. +// +// Sys +// +// Under Darwin (FSEvents) Sys() always returns a non-nil *notify.FSEvent value, +// which is defined as: +// +// type FSEvent struct { +// Path string // real path of the file or directory +// ID uint64 // ID of the event (FSEventStreamEventId) +// Flags uint32 // joint FSEvents* flags (FSEventStreamEventFlags) +// } +// +// For possible values of Flags see Darwin godoc for notify or FSEvents +// documentation for FSEventStreamEventFlags constants: +// +// https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamEventFlags +// +// Under Linux (inotify) Sys() always returns a non-nil *unix.InotifyEvent +// value, defined as: +// +// type InotifyEvent struct { +// Wd int32 // Watch descriptor +// Mask uint32 // Mask describing event +// Cookie uint32 // Unique cookie associating related events (for rename(2)) +// Len uint32 // Size of name field +// Name [0]uint8 // Optional null-terminated name +// } +// +// More information about inotify masks and the usage of inotify_event structure +// can be found at: +// +// http://man7.org/linux/man-pages/man7/inotify.7.html +// +// Under Darwin, DragonFlyBSD, FreeBSD, NetBSD, OpenBSD (kqueue) Sys() always +// returns a non-nil *notify.Kevent value, which is defined as: +// +// type Kevent struct { +// Kevent *syscall.Kevent_t // Kevent is a kqueue specific structure +// FI os.FileInfo // FI describes file/dir +// } +// +// More information about syscall.Kevent_t can be found at: +// +// https://www.freebsd.org/cgi/man.cgi?query=kqueue +// +// Under Windows (ReadDirectoryChangesW) Sys() always returns nil. The documentation +// of watcher's WinAPI function can be found at: +// +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx +type EventInfo interface { + Event() Event // event value for the filesystem action + Path() string // real path of the file or directory + Sys() interface{} // underlying data source (can return nil) +} + +type isDirer interface { + isDir() (bool, error) +} + +var _ fmt.Stringer = (*event)(nil) +var _ isDirer = (*event)(nil) + +// String implements fmt.Stringer interface. +func (e *event) String() string { + return e.Event().String() + `: "` + e.Path() + `"` +} + +var estr = map[Event]string{ + Create: "notify.Create", + Remove: "notify.Remove", + Write: "notify.Write", + Rename: "notify.Rename", + // Display name for recursive event is added only for debugging + // purposes. It's an internal event after all and won't be exposed to the + // user. Having Recursive event printable is helpful, e.g. for reading + // testing failure messages: + // + // --- FAIL: TestWatchpoint (0.00 seconds) + // watchpoint_test.go:64: want diff=[notify.Remove notify.Create|notify.Remove]; + // got [notify.Remove notify.Remove|notify.Create] (i=1) + // + // Yup, here the diff have Recursive event inside. Go figure. + recursive: "recursive", + omit: "omit", +} diff --git a/vendor/github.com/rjeczalik/notify/event_fen.go b/vendor/github.com/rjeczalik/notify/event_fen.go new file mode 100644 index 00000000..767f04fa --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_fen.go @@ -0,0 +1,57 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build solaris + +package notify + +const ( + osSpecificCreate Event = 0x00000100 << iota + osSpecificRemove + osSpecificWrite + osSpecificRename + // internal + // recursive is used to distinguish recursive eventsets from non-recursive ones + recursive + // omit is used for dispatching internal events; only those events are sent + // for which both the event and the watchpoint has omit in theirs event sets. + omit +) + +const ( + // FileAccess is an event reported when monitored file/directory was accessed. + FileAccess = fileAccess + // FileModified is an event reported when monitored file/directory was modified. + FileModified = fileModified + // FileAttrib is an event reported when monitored file/directory's ATTRIB + // was changed. + FileAttrib = fileAttrib + // FileDelete is an event reported when monitored file/directory was deleted. + FileDelete = fileDelete + // FileRenameTo to is an event reported when monitored file/directory was renamed. + FileRenameTo = fileRenameTo + // FileRenameFrom is an event reported when monitored file/directory was renamed. + FileRenameFrom = fileRenameFrom + // FileTrunc is an event reported when monitored file/directory was truncated. + FileTrunc = fileTrunc + // FileNoFollow is an flag to indicate not to follow symbolic links. + FileNoFollow = fileNoFollow + // Unmounted is an event reported when monitored filesystem was unmounted. + Unmounted = unmounted + // MountedOver is an event reported when monitored file/directory was mounted on. + MountedOver = mountedOver +) + +var osestr = map[Event]string{ + FileAccess: "notify.FileAccess", + FileModified: "notify.FileModified", + FileAttrib: "notify.FileAttrib", + FileDelete: "notify.FileDelete", + FileRenameTo: "notify.FileRenameTo", + FileRenameFrom: "notify.FileRenameFrom", + FileTrunc: "notify.FileTrunc", + FileNoFollow: "notify.FileNoFollow", + Unmounted: "notify.Unmounted", + MountedOver: "notify.MountedOver", +} diff --git a/vendor/github.com/rjeczalik/notify/event_fsevents.go b/vendor/github.com/rjeczalik/notify/event_fsevents.go new file mode 100644 index 00000000..6ded80b2 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_fsevents.go @@ -0,0 +1,71 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,!kqueue + +package notify + +const ( + osSpecificCreate = Event(FSEventsCreated) + osSpecificRemove = Event(FSEventsRemoved) + osSpecificWrite = Event(FSEventsModified) + osSpecificRename = Event(FSEventsRenamed) + // internal = Event(0x100000) + // recursive is used to distinguish recursive eventsets from non-recursive ones + recursive = Event(0x200000) + // omit is used for dispatching internal events; only those events are sent + // for which both the event and the watchpoint has omit in theirs event sets. + omit = Event(0x400000) +) + +// FSEvents specific event values. +const ( + FSEventsMustScanSubDirs Event = 0x00001 + FSEventsUserDropped = 0x00002 + FSEventsKernelDropped = 0x00004 + FSEventsEventIdsWrapped = 0x00008 + FSEventsHistoryDone = 0x00010 + FSEventsRootChanged = 0x00020 + FSEventsMount = 0x00040 + FSEventsUnmount = 0x00080 + FSEventsCreated = 0x00100 + FSEventsRemoved = 0x00200 + FSEventsInodeMetaMod = 0x00400 + FSEventsRenamed = 0x00800 + FSEventsModified = 0x01000 + FSEventsFinderInfoMod = 0x02000 + FSEventsChangeOwner = 0x04000 + FSEventsXattrMod = 0x08000 + FSEventsIsFile = 0x10000 + FSEventsIsDir = 0x20000 + FSEventsIsSymlink = 0x40000 +) + +var osestr = map[Event]string{ + FSEventsMustScanSubDirs: "notify.FSEventsMustScanSubDirs", + FSEventsUserDropped: "notify.FSEventsUserDropped", + FSEventsKernelDropped: "notify.FSEventsKernelDropped", + FSEventsEventIdsWrapped: "notify.FSEventsEventIdsWrapped", + FSEventsHistoryDone: "notify.FSEventsHistoryDone", + FSEventsRootChanged: "notify.FSEventsRootChanged", + FSEventsMount: "notify.FSEventsMount", + FSEventsUnmount: "notify.FSEventsUnmount", + FSEventsInodeMetaMod: "notify.FSEventsInodeMetaMod", + FSEventsFinderInfoMod: "notify.FSEventsFinderInfoMod", + FSEventsChangeOwner: "notify.FSEventsChangeOwner", + FSEventsXattrMod: "notify.FSEventsXattrMod", + FSEventsIsFile: "notify.FSEventsIsFile", + FSEventsIsDir: "notify.FSEventsIsDir", + FSEventsIsSymlink: "notify.FSEventsIsSymlink", +} + +type event struct { + fse FSEvent + event Event +} + +func (ei *event) Event() Event { return ei.event } +func (ei *event) Path() string { return ei.fse.Path } +func (ei *event) Sys() interface{} { return &ei.fse } +func (ei *event) isDir() (bool, error) { return ei.fse.Flags&FSEventsIsDir != 0, nil } diff --git a/vendor/github.com/rjeczalik/notify/event_inotify.go b/vendor/github.com/rjeczalik/notify/event_inotify.go new file mode 100644 index 00000000..1f32bb73 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_inotify.go @@ -0,0 +1,75 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build linux + +package notify + +import "golang.org/x/sys/unix" + +// Platform independent event values. +const ( + osSpecificCreate Event = 0x100000 << iota + osSpecificRemove + osSpecificWrite + osSpecificRename + // internal + // recursive is used to distinguish recursive eventsets from non-recursive ones + recursive + // omit is used for dispatching internal events; only those events are sent + // for which both the event and the watchpoint has omit in theirs event sets. + omit +) + +// Inotify specific masks are legal, implemented events that are guaranteed to +// work with notify package on linux-based systems. +const ( + InAccess = Event(unix.IN_ACCESS) // File was accessed + InModify = Event(unix.IN_MODIFY) // File was modified + InAttrib = Event(unix.IN_ATTRIB) // Metadata changed + InCloseWrite = Event(unix.IN_CLOSE_WRITE) // Writtable file was closed + InCloseNowrite = Event(unix.IN_CLOSE_NOWRITE) // Unwrittable file closed + InOpen = Event(unix.IN_OPEN) // File was opened + InMovedFrom = Event(unix.IN_MOVED_FROM) // File was moved from X + InMovedTo = Event(unix.IN_MOVED_TO) // File was moved to Y + InCreate = Event(unix.IN_CREATE) // Subfile was created + InDelete = Event(unix.IN_DELETE) // Subfile was deleted + InDeleteSelf = Event(unix.IN_DELETE_SELF) // Self was deleted + InMoveSelf = Event(unix.IN_MOVE_SELF) // Self was moved +) + +var osestr = map[Event]string{ + InAccess: "notify.InAccess", + InModify: "notify.InModify", + InAttrib: "notify.InAttrib", + InCloseWrite: "notify.InCloseWrite", + InCloseNowrite: "notify.InCloseNowrite", + InOpen: "notify.InOpen", + InMovedFrom: "notify.InMovedFrom", + InMovedTo: "notify.InMovedTo", + InCreate: "notify.InCreate", + InDelete: "notify.InDelete", + InDeleteSelf: "notify.InDeleteSelf", + InMoveSelf: "notify.InMoveSelf", +} + +// Inotify behavior events are not **currently** supported by notify package. +const ( + inDontFollow = Event(unix.IN_DONT_FOLLOW) + inExclUnlink = Event(unix.IN_EXCL_UNLINK) + inMaskAdd = Event(unix.IN_MASK_ADD) + inOneshot = Event(unix.IN_ONESHOT) + inOnlydir = Event(unix.IN_ONLYDIR) +) + +type event struct { + sys unix.InotifyEvent + path string + event Event +} + +func (e *event) Event() Event { return e.event } +func (e *event) Path() string { return e.path } +func (e *event) Sys() interface{} { return &e.sys } +func (e *event) isDir() (bool, error) { return e.sys.Mask&unix.IN_ISDIR != 0, nil } diff --git a/vendor/github.com/rjeczalik/notify/event_kqueue.go b/vendor/github.com/rjeczalik/notify/event_kqueue.go new file mode 100644 index 00000000..422ac87f --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_kqueue.go @@ -0,0 +1,59 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,kqueue dragonfly freebsd netbsd openbsd + +package notify + +import "syscall" + +// TODO(pblaszczyk): ensure in runtime notify built-in event values do not +// overlap with platform-defined ones. + +// Platform independent event values. +const ( + osSpecificCreate Event = 0x0100 << iota + osSpecificRemove + osSpecificWrite + osSpecificRename + // internal + // recursive is used to distinguish recursive eventsets from non-recursive ones + recursive + // omit is used for dispatching internal events; only those events are sent + // for which both the event and the watchpoint has omit in theirs event sets. + omit +) + +const ( + // NoteDelete is an event reported when the unlink() system call was called + // on the file referenced by the descriptor. + NoteDelete = Event(syscall.NOTE_DELETE) + // NoteWrite is an event reported when a write occurred on the file + // referenced by the descriptor. + NoteWrite = Event(syscall.NOTE_WRITE) + // NoteExtend is an event reported when the file referenced by the + // descriptor was extended. + NoteExtend = Event(syscall.NOTE_EXTEND) + // NoteAttrib is an event reported when the file referenced + // by the descriptor had its attributes changed. + NoteAttrib = Event(syscall.NOTE_ATTRIB) + // NoteLink is an event reported when the link count on the file changed. + NoteLink = Event(syscall.NOTE_LINK) + // NoteRename is an event reported when the file referenced + // by the descriptor was renamed. + NoteRename = Event(syscall.NOTE_RENAME) + // NoteRevoke is an event reported when access to the file was revoked via + // revoke(2) or the underlying file system was unmounted. + NoteRevoke = Event(syscall.NOTE_REVOKE) +) + +var osestr = map[Event]string{ + NoteDelete: "notify.NoteDelete", + NoteWrite: "notify.NoteWrite", + NoteExtend: "notify.NoteExtend", + NoteAttrib: "notify.NoteAttrib", + NoteLink: "notify.NoteLink", + NoteRename: "notify.NoteRename", + NoteRevoke: "notify.NoteRevoke", +} diff --git a/vendor/github.com/rjeczalik/notify/event_readdcw.go b/vendor/github.com/rjeczalik/notify/event_readdcw.go new file mode 100644 index 00000000..f7b82de0 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_readdcw.go @@ -0,0 +1,118 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify + +import ( + "os" + "path/filepath" + "syscall" +) + +// Platform independent event values. +const ( + osSpecificCreate Event = 1 << (20 + iota) + osSpecificRemove + osSpecificWrite + osSpecificRename + // recursive is used to distinguish recursive eventsets from non-recursive ones + recursive + // omit is used for dispatching internal events; only those events are sent + // for which both the event and the watchpoint has omit in theirs event sets. + omit + // dirmarker TODO(pknap) + dirmarker +) + +// ReadDirectoryChangesW filters +// On Windows the following events can be passed to Watch. A different set of +// events (see actions below) are received on the channel passed to Watch. +// For more information refer to +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx +const ( + FileNotifyChangeFileName = Event(syscall.FILE_NOTIFY_CHANGE_FILE_NAME) + FileNotifyChangeDirName = Event(syscall.FILE_NOTIFY_CHANGE_DIR_NAME) + FileNotifyChangeAttributes = Event(syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES) + FileNotifyChangeSize = Event(syscall.FILE_NOTIFY_CHANGE_SIZE) + FileNotifyChangeLastWrite = Event(syscall.FILE_NOTIFY_CHANGE_LAST_WRITE) + FileNotifyChangeLastAccess = Event(syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS) + FileNotifyChangeCreation = Event(syscall.FILE_NOTIFY_CHANGE_CREATION) + FileNotifyChangeSecurity = Event(syscallFileNotifyChangeSecurity) +) + +const ( + fileNotifyChangeAll = 0x17f // logical sum of all FileNotifyChange* events. + fileNotifyChangeModified = fileNotifyChangeAll &^ (FileNotifyChangeFileName | FileNotifyChangeDirName) +) + +// according to: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx +// this flag should be declared in: http://golang.org/src/pkg/syscall/ztypes_windows.go +const syscallFileNotifyChangeSecurity = 0x00000100 + +// ReadDirectoryChangesW actions +// The following events are returned on the channel passed to Watch, but cannot +// be passed to Watch itself (see filters above). You can find a table showing +// the relation between actions and filteres at +// https://github.com/rjeczalik/notify/issues/10#issuecomment-66179535 +// The msdn documentation on actions is part of +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364391(v=vs.85).aspx +const ( + FileActionAdded = Event(syscall.FILE_ACTION_ADDED) << 12 + FileActionRemoved = Event(syscall.FILE_ACTION_REMOVED) << 12 + FileActionModified = Event(syscall.FILE_ACTION_MODIFIED) << 14 + FileActionRenamedOldName = Event(syscall.FILE_ACTION_RENAMED_OLD_NAME) << 15 + FileActionRenamedNewName = Event(syscall.FILE_ACTION_RENAMED_NEW_NAME) << 16 +) + +const fileActionAll = 0x7f000 // logical sum of all FileAction* events. + +var osestr = map[Event]string{ + FileNotifyChangeFileName: "notify.FileNotifyChangeFileName", + FileNotifyChangeDirName: "notify.FileNotifyChangeDirName", + FileNotifyChangeAttributes: "notify.FileNotifyChangeAttributes", + FileNotifyChangeSize: "notify.FileNotifyChangeSize", + FileNotifyChangeLastWrite: "notify.FileNotifyChangeLastWrite", + FileNotifyChangeLastAccess: "notify.FileNotifyChangeLastAccess", + FileNotifyChangeCreation: "notify.FileNotifyChangeCreation", + FileNotifyChangeSecurity: "notify.FileNotifyChangeSecurity", + + FileActionAdded: "notify.FileActionAdded", + FileActionRemoved: "notify.FileActionRemoved", + FileActionModified: "notify.FileActionModified", + FileActionRenamedOldName: "notify.FileActionRenamedOldName", + FileActionRenamedNewName: "notify.FileActionRenamedNewName", +} + +const ( + fTypeUnknown uint8 = iota + fTypeFile + fTypeDirectory +) + +// TODO(ppknap) : doc. +type event struct { + pathw []uint16 + name string + ftype uint8 + action uint32 + filter uint32 + e Event +} + +func (e *event) Event() Event { return e.e } +func (e *event) Path() string { return filepath.Join(syscall.UTF16ToString(e.pathw), e.name) } +func (e *event) Sys() interface{} { return e.ftype } + +func (e *event) isDir() (bool, error) { + if e.ftype != fTypeUnknown { + return e.ftype == fTypeDirectory, nil + } + fi, err := os.Stat(e.Path()) + if err != nil { + return false, err + } + return fi.IsDir(), nil +} diff --git a/vendor/github.com/rjeczalik/notify/event_stub.go b/vendor/github.com/rjeczalik/notify/event_stub.go new file mode 100644 index 00000000..faac7c7c --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_stub.go @@ -0,0 +1,31 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build !darwin,!linux,!freebsd,!dragonfly,!netbsd,!openbsd,!windows +// +build !kqueue,!solaris + +package notify + +// Platform independent event values. +const ( + osSpecificCreate Event = 1 << iota + osSpecificRemove + osSpecificWrite + osSpecificRename + // internal + // recursive is used to distinguish recursive eventsets from non-recursive ones + recursive + // omit is used for dispatching internal events; only those events are sent + // for which both the event and the watchpoint has omit in theirs event sets. + omit +) + +var osestr = map[Event]string{} + +type event struct{} + +func (e *event) Event() (_ Event) { return } +func (e *event) Path() (_ string) { return } +func (e *event) Sys() (_ interface{}) { return } +func (e *event) isDir() (_ bool, _ error) { return } diff --git a/vendor/github.com/rjeczalik/notify/event_test.go b/vendor/github.com/rjeczalik/notify/event_test.go new file mode 100644 index 00000000..2803509f --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_test.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "sort" + "strings" + "testing" +) + +// S is a workaround for random event strings concatenation order. +func s(s string) string { + z := strings.Split(s, "|") + sort.StringSlice(z).Sort() + return strings.Join(z, "|") +} + +// This test is not safe to run in parallel with others. +func TestEventString(t *testing.T) { + cases := map[Event]string{ + Create: "notify.Create", + Create | Remove: "notify.Create|notify.Remove", + Create | Remove | Write: "notify.Create|notify.Remove|notify.Write", + Create | Write | Rename: "notify.Create|notify.Rename|notify.Write", + } + for e, str := range cases { + if s := s(e.String()); s != str { + t.Errorf("want s=%s; got %s (e=%#x)", str, s, e) + } + } +} diff --git a/vendor/github.com/rjeczalik/notify/event_trigger.go b/vendor/github.com/rjeczalik/notify/event_trigger.go new file mode 100644 index 00000000..94470fd3 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/event_trigger.go @@ -0,0 +1,22 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,kqueue dragonfly freebsd netbsd openbsd solaris + +package notify + +type event struct { + p string + e Event + d bool + pe interface{} +} + +func (e *event) Event() Event { return e.e } + +func (e *event) Path() string { return e.p } + +func (e *event) Sys() interface{} { return e.pe } + +func (e *event) isDir() (bool, error) { return e.d, nil } diff --git a/vendor/github.com/rjeczalik/notify/example_fsevents_test.go b/vendor/github.com/rjeczalik/notify/example_fsevents_test.go new file mode 100644 index 00000000..53d1b342 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/example_fsevents_test.go @@ -0,0 +1,128 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,!kqueue + +package notify_test + +import ( + "log" + + "github.com/rjeczalik/notify" +) + +// This example shows how to use FSEvents-specifc event values. +func ExampleWatch_darwin() { + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 1) + + // Set up a watchpoint listening for FSEvents-specific events within a + // current working directory. Dispatch each FSEventsChangeOwner and FSEventsMount + // events separately to c. + if err := notify.Watch(".", c, notify.FSEventsChangeOwner, notify.FSEventsMount); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + // Block until an event is received. + switch ei := <-c; ei.Event() { + case notify.FSEventsChangeOwner: + log.Println("The owner of", ei.Path(), "has changed.") + case notify.FSEventsMount: + log.Println("The path", ei.Path(), "has been mounted.") + } +} + +// This example shows how to work with EventInfo's underlying FSEvent struct. +// Investigating notify.(*FSEvent).Flags field we are able to say whether +// the event's path is a file or a directory and many more. +func ExampleWatch_darwinDirFileSymlink() { + var must = func(err error) { + if err != nil { + log.Fatal(err) + } + } + var stop = func(c ...chan<- notify.EventInfo) { + for _, c := range c { + notify.Stop(c) + } + } + + // Make the channels buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + dir := make(chan notify.EventInfo, 1) + file := make(chan notify.EventInfo, 1) + symlink := make(chan notify.EventInfo, 1) + all := make(chan notify.EventInfo, 1) + + // Set up a single watchpoint listening for FSEvents-specific events on + // multiple user-provided channels. + must(notify.Watch(".", dir, notify.FSEventsIsDir)) + must(notify.Watch(".", file, notify.FSEventsIsFile)) + must(notify.Watch(".", symlink, notify.FSEventsIsSymlink)) + must(notify.Watch(".", all, notify.All)) + defer stop(dir, file, symlink, all) + + // Block until an event is received. + select { + case ei := <-dir: + log.Println("The directory", ei.Path(), "has changed") + case ei := <-file: + log.Println("The file", ei.Path(), "has changed") + case ei := <-symlink: + log.Println("The symlink", ei.Path(), "has changed") + case ei := <-all: + var kind string + + // Investigate underlying *notify.FSEvent struct to access more + // information about the event. + switch flags := ei.Sys().(*notify.FSEvent).Flags; { + case flags¬ify.FSEventsIsFile != 0: + kind = "file" + case flags¬ify.FSEventsIsDir != 0: + kind = "dir" + case flags¬ify.FSEventsIsSymlink != 0: + kind = "symlink" + } + + log.Printf("The %s under path %s has been %sd\n", kind, ei.Path(), ei.Event()) + } +} + +// FSEvents may report multiple filesystem actions with one, coalesced event. +// Notify unscoalesces such event and dispatches series of single events +// back to the user. +// +// This example shows how to coalesce events by investigating notify.(*FSEvent).ID +// field, for the science. +func ExampleWatch_darwinCoalesce() { + // Make the channels buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 4) + + // Set up a watchpoint listetning for events within current working directory. + // Dispatch all platform-independent separately to c. + if err := notify.Watch(".", c, notify.All); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + var id uint64 + var coalesced []notify.EventInfo + + for ei := range c { + switch n := ei.Sys().(*notify.FSEvent).ID; { + case id == 0: + id = n + coalesced = []notify.EventInfo{ei} + case id == n: + coalesced = append(coalesced, ei) + default: + log.Printf("FSEvents reported a filesystem action with the following"+ + " coalesced events %v groupped by %d ID\n", coalesced, id) + return + } + } +} diff --git a/vendor/github.com/rjeczalik/notify/example_inotify_test.go b/vendor/github.com/rjeczalik/notify/example_inotify_test.go new file mode 100644 index 00000000..e386012c --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/example_inotify_test.go @@ -0,0 +1,84 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build linux + +package notify_test + +import ( + "log" + + "golang.org/x/sys/unix" + + "github.com/rjeczalik/notify" +) + +// This example shows how to watch changes made on file-system by text editor +// when saving a file. Usually, either InCloseWrite or InMovedTo (when swapping +// with a temporary file) event is created. +func ExampleWatch_linux() { + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 1) + + // Set up a watchpoint listening for inotify-specific events within a + // current working directory. Dispatch each InCloseWrite and InMovedTo + // events separately to c. + if err := notify.Watch(".", c, notify.InCloseWrite, notify.InMovedTo); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + // Block until an event is received. + switch ei := <-c; ei.Event() { + case notify.InCloseWrite: + log.Println("Editing of", ei.Path(), "file is done.") + case notify.InMovedTo: + log.Println("File", ei.Path(), "was swapped/moved into the watched directory.") + } +} + +// This example shows how to use Sys() method from EventInfo interface to tie +// two separate events generated by rename(2) function. +func ExampleWatch_linuxMove() { + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 2) + + // Set up a watchpoint listening for inotify-specific events within a + // current working directory. Dispatch each InMovedFrom and InMovedTo + // events separately to c. + if err := notify.Watch(".", c, notify.InMovedFrom, notify.InMovedTo); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + // Inotify reports move filesystem action by sending two events tied with + // unique cookie value (uint32): one of the events is of InMovedFrom type + // carrying move source path, while the second one is of InMoveTo type + // carrying move destination path. + moves := make(map[uint32]struct { + From string + To string + }) + + // Wait for moves. + for ei := range c { + cookie := ei.Sys().(*unix.InotifyEvent).Cookie + + info := moves[cookie] + switch ei.Event() { + case notify.InMovedFrom: + info.From = ei.Path() + case notify.InMovedTo: + info.To = ei.Path() + } + moves[cookie] = info + + if cookie != 0 && info.From != "" && info.To != "" { + log.Println("File:", info.From, "was renamed to", info.To) + delete(moves, cookie) + } + } +} diff --git a/vendor/github.com/rjeczalik/notify/example_readdcw_test.go b/vendor/github.com/rjeczalik/notify/example_readdcw_test.go new file mode 100644 index 00000000..e9e05bef --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/example_readdcw_test.go @@ -0,0 +1,40 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify_test + +import ( + "log" + + "github.com/rjeczalik/notify" +) + +// This example shows how to watch directory-name changes in the working directory subtree. +func ExampleWatch_windows() { + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 4) + + // Since notify package behaves exactly like ReadDirectoryChangesW function, + // we must register notify.FileNotifyChangeDirName filter and wait for one + // of FileAction* events. + if err := notify.Watch("./...", c, notify.FileNotifyChangeDirName); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + // Wait for actions. + for ei := range c { + switch ei.Event() { + case notify.FileActionAdded, notify.FileActionRenamedNewName: + log.Println("Created:", ei.Path()) + case notify.FileActionRemoved, notify.FileActionRenamedOldName: + log.Println("Removed:", ei.Path()) + case notify.FileActionModified: + panic("notify: unexpected action") + } + } +} diff --git a/vendor/github.com/rjeczalik/notify/example_test.go b/vendor/github.com/rjeczalik/notify/example_test.go new file mode 100644 index 00000000..3c8df71d --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/example_test.go @@ -0,0 +1,87 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify_test + +import ( + "log" + "path/filepath" + "time" + + "github.com/rjeczalik/notify" +) + +// This is a basic example showing how to work with notify.Watch function. +func ExampleWatch() { + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 1) + + // Set up a watchpoint listening on events within current working directory. + // Dispatch each create and remove events separately to c. + if err := notify.Watch(".", c, notify.Create, notify.Remove); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + // Block until an event is received. + ei := <-c + log.Println("Got event:", ei) +} + +// This example shows how to set up a recursive watchpoint. +func ExampleWatch_recursive() { + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + c := make(chan notify.EventInfo, 1) + + // Set up a watchpoint listening for events within a directory tree rooted + // at current working directory. Dispatch remove events to c. + if err := notify.Watch("./...", c, notify.Remove); err != nil { + log.Fatal(err) + } + defer notify.Stop(c) + + // Block until an event is received. + ei := <-c + log.Println("Got event:", ei) +} + +// This example shows why it is important to not create leaks by stoping +// a channel when it's no longer being used. +func ExampleStop() { + waitfor := func(path string, e notify.Event, timeout time.Duration) bool { + dir, file := filepath.Split(path) + c := make(chan notify.EventInfo, 1) + + if err := notify.Watch(dir, c, e); err != nil { + log.Fatal(err) + } + // Clean up watchpoint associated with c. If Stop was not called upon + // return the channel would be leaked as notify holds the only reference + // to it and does not release it on its own. + defer notify.Stop(c) + + t := time.After(timeout) + + for { + select { + case ei := <-c: + if filepath.Base(ei.Path()) == file { + return true + } + case <-t: + return false + } + } + } + + if waitfor("index.lock", notify.Create, 5*time.Second) { + log.Println("The git repository was locked") + } + + if waitfor("index.lock", notify.Remove, 5*time.Second) { + log.Println("The git repository was unlocked") + } +} diff --git a/vendor/github.com/rjeczalik/notify/node.go b/vendor/github.com/rjeczalik/notify/node.go new file mode 100644 index 00000000..aced8b9c --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/node.go @@ -0,0 +1,275 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "errors" + "io/ioutil" + "os" + "path/filepath" +) + +var errSkip = errors.New("notify: skip") + +type walkPathFunc func(nd node, isbase bool) error + +type walkFunc func(node) error + +func errnotexist(name string) error { + return &os.PathError{ + Op: "Node", + Path: name, + Err: os.ErrNotExist, + } +} + +type node struct { + Name string + Watch watchpoint + Child map[string]node +} + +func newnode(name string) node { + return node{ + Name: name, + Watch: make(watchpoint), + Child: make(map[string]node), + } +} + +func (nd node) addchild(name, base string) node { + child, ok := nd.Child[base] + if !ok { + child = newnode(name) + nd.Child[base] = child + } + return child +} + +func (nd node) Add(name string) node { + i := indexbase(nd.Name, name) + if i == -1 { + return node{} + } + for j := indexSep(name[i:]); j != -1; j = indexSep(name[i:]) { + nd = nd.addchild(name[:i+j], name[i:i+j]) + i += j + 1 + } + return nd.addchild(name, name[i:]) +} + +func (nd node) AddDir(fn walkFunc) error { + stack := []node{nd} +Traverse: + for n := len(stack); n != 0; n = len(stack) { + nd, stack = stack[n-1], stack[:n-1] + switch err := fn(nd); err { + case nil: + case errSkip: + continue Traverse + default: + return &os.PathError{ + Op: "error while traversing", + Path: nd.Name, + Err: err, + } + } + // TODO(rjeczalik): tolerate open failures - add failed names to + // AddDirError and notify users which names are not added to the tree. + fi, err := ioutil.ReadDir(nd.Name) + if err != nil { + return err + } + for _, fi := range fi { + if fi.Mode()&(os.ModeSymlink|os.ModeDir) == os.ModeDir { + name := filepath.Join(nd.Name, fi.Name()) + stack = append(stack, nd.addchild(name, name[len(nd.Name)+1:])) + } + } + } + return nil +} + +func (nd node) Get(name string) (node, error) { + i := indexbase(nd.Name, name) + if i == -1 { + return node{}, errnotexist(name) + } + ok := false + for j := indexSep(name[i:]); j != -1; j = indexSep(name[i:]) { + if nd, ok = nd.Child[name[i:i+j]]; !ok { + return node{}, errnotexist(name) + } + i += j + 1 + } + if nd, ok = nd.Child[name[i:]]; !ok { + return node{}, errnotexist(name) + } + return nd, nil +} + +func (nd node) Del(name string) error { + i := indexbase(nd.Name, name) + if i == -1 { + return errnotexist(name) + } + stack := []node{nd} + ok := false + for j := indexSep(name[i:]); j != -1; j = indexSep(name[i:]) { + if nd, ok = nd.Child[name[i:i+j]]; !ok { + return errnotexist(name[:i+j]) + } + stack = append(stack, nd) + } + if nd, ok = nd.Child[name[i:]]; !ok { + return errnotexist(name) + } + nd.Child = nil + nd.Watch = nil + for name, i = base(nd.Name), len(stack); i != 0; name, i = base(nd.Name), i-1 { + nd = stack[i-1] + if nd := nd.Child[name]; len(nd.Watch) > 1 || len(nd.Child) != 0 { + break + } else { + nd.Child = nil + nd.Watch = nil + } + delete(nd.Child, name) + } + return nil +} + +func (nd node) Walk(fn walkFunc) error { + stack := []node{nd} +Traverse: + for n := len(stack); n != 0; n = len(stack) { + nd, stack = stack[n-1], stack[:n-1] + switch err := fn(nd); err { + case nil: + case errSkip: + continue Traverse + default: + return err + } + for name, nd := range nd.Child { + if name == "" { + // Node storing inactive watchpoints has empty name, skip it + // form traversing. Root node has also an empty name, but it + // never has a parent node. + continue + } + stack = append(stack, nd) + } + } + return nil +} + +func (nd node) WalkPath(name string, fn walkPathFunc) error { + i := indexbase(nd.Name, name) + if i == -1 { + return errnotexist(name) + } + ok := false + for j := indexSep(name[i:]); j != -1; j = indexSep(name[i:]) { + switch err := fn(nd, false); err { + case nil: + case errSkip: + return nil + default: + return err + } + if nd, ok = nd.Child[name[i:i+j]]; !ok { + return errnotexist(name[:i+j]) + } + i += j + 1 + } + switch err := fn(nd, false); err { + case nil: + case errSkip: + return nil + default: + return err + } + if nd, ok = nd.Child[name[i:]]; !ok { + return errnotexist(name) + } + switch err := fn(nd, true); err { + case nil, errSkip: + return nil + default: + return err + } +} + +type root struct { + nd node +} + +func (r root) addroot(name string) node { + if vol := filepath.VolumeName(name); vol != "" { + root, ok := r.nd.Child[vol] + if !ok { + root = r.nd.addchild(vol, vol) + } + return root + } + return r.nd +} + +func (r root) root(name string) (node, error) { + if vol := filepath.VolumeName(name); vol != "" { + nd, ok := r.nd.Child[vol] + if !ok { + return node{}, errnotexist(name) + } + return nd, nil + } + return r.nd, nil +} + +func (r root) Add(name string) node { + return r.addroot(name).Add(name) +} + +func (r root) AddDir(dir string, fn walkFunc) error { + return r.Add(dir).AddDir(fn) +} + +func (r root) Del(name string) error { + nd, err := r.root(name) + if err != nil { + return err + } + return nd.Del(name) +} + +func (r root) Get(name string) (node, error) { + nd, err := r.root(name) + if err != nil { + return node{}, err + } + if nd.Name != name { + if nd, err = nd.Get(name); err != nil { + return node{}, err + } + } + return nd, nil +} + +func (r root) Walk(name string, fn walkFunc) error { + nd, err := r.Get(name) + if err != nil { + return err + } + return nd.Walk(fn) +} + +func (r root) WalkPath(name string, fn walkPathFunc) error { + nd, err := r.root(name) + if err != nil { + return err + } + return nd.WalkPath(name, fn) +} diff --git a/vendor/github.com/rjeczalik/notify/notify.go b/vendor/github.com/rjeczalik/notify/notify.go new file mode 100644 index 00000000..7d2eec3a --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/notify.go @@ -0,0 +1,74 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// BUG(rjeczalik): Notify does not collect watchpoints, when underlying watches +// were removed by their os-specific watcher implementations. Instead users are +// advised to listen on persistent paths to have guarantee they receive events +// for the whole lifetime of their applications (to discuss see #69). + +// BUG(ppknap): Linux (inotify) does not support watcher behavior masks like +// InOneshot, InOnlydir etc. Instead users are advised to perform the filtering +// themselves (to discuss see #71). + +// BUG(ppknap): Notify was not tested for short path name support under Windows +// (ReadDirectoryChangesW). + +// BUG(ppknap): Windows (ReadDirectoryChangesW) cannot recognize which notification +// triggers FileActionModified event. (to discuss see #75). + +package notify + +var defaultTree = newTree() + +// Watch sets up a watchpoint on path listening for events given by the events +// argument. +// +// File or directory given by the path must exist, otherwise Watch will fail +// with non-nil error. Notify resolves, for its internal purpose, any symlinks +// the provided path may contain, so it may fail if the symlinks form a cycle. +// It does so, since not all watcher implementations treat passed paths as-is. +// E.g. FSEvents reports a real path for every event, setting a watchpoint +// on /tmp will report events with paths rooted at /private/tmp etc. +// +// The c almost always is a buffered channel. Watch will not block sending to c +// - the caller must ensure that c has sufficient buffer space to keep up with +// the expected event rate. +// +// It is allowed to pass the same channel multiple times with different event +// list or different paths. Calling Watch with different event lists for a single +// watchpoint expands its event set. The only way to shrink it, is to call +// Stop on its channel. +// +// Calling Watch with empty event list does expand nor shrink watchpoint's event +// set. If c is the first channel to listen for events on the given path, Watch +// will seamlessly create a watch on the filesystem. +// +// Notify dispatches copies of single filesystem event to all channels registered +// for each path. If a single filesystem event contains multiple coalesced events, +// each of them is dispatched separately. E.g. the following filesystem change: +// +// ~ $ echo Hello > Notify.txt +// +// dispatches two events - notify.Create and notify.Write. However, it may depend +// on the underlying watcher implementation whether OS reports both of them. +// +// Windows and recursive watches +// +// If a directory which path was used to create recursive watch under Windows +// gets deleted, the OS will not report such event. It is advised to keep in +// mind this limitation while setting recursive watchpoints for your application, +// e.g. use persistent paths like %userprofile% or watch additionally parent +// directory of a recursive watchpoint in order to receive delete events for it. +func Watch(path string, c chan<- EventInfo, events ...Event) error { + return defaultTree.Watch(path, c, events...) +} + +// Stop removes all watchpoints registered for c. All underlying watches are +// also removed, for which c was the last channel listening for events. +// +// Stop does not close c. When Stop returns, it is guaranteed that c will +// receive no more signals. +func Stop(c chan<- EventInfo) { + defaultTree.Stop(c) +} diff --git a/vendor/github.com/rjeczalik/notify/notify_inotify_test.go b/vendor/github.com/rjeczalik/notify/notify_inotify_test.go new file mode 100644 index 00000000..c5984d33 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/notify_inotify_test.go @@ -0,0 +1,37 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build linux + +package notify + +import "testing" + +func TestNotifySystemAndGlobalMix(t *testing.T) { + n := NewNotifyTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(2) + + n.Watch("src/github.com/rjeczalik/fs", ch[0], Create) + n.Watch("src/github.com/rjeczalik/fs", ch[1], InCreate) + + cases := []NCase{ + { + Event: icreate(n.W(), "src/github.com/rjeczalik/fs/.main.cc.swr"), + Receiver: Chans{ch[0], ch[1]}, + }, + } + + n.ExpectNotifyEvents(cases, ch) +} + +func TestUnknownEvent(t *testing.T) { + n := NewNotifyTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(1) + + n.WatchErr("src/github.com/rjeczalik/fs", ch[0], nil, inExclUnlink) +} diff --git a/vendor/github.com/rjeczalik/notify/notify_readdcw_test.go b/vendor/github.com/rjeczalik/notify/notify_readdcw_test.go new file mode 100644 index 00000000..944b5338 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/notify_readdcw_test.go @@ -0,0 +1,60 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify + +import "testing" + +func TestNotifySystemSpecificEvent(t *testing.T) { + n := NewNotifyTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(1) + + n.Watch("src/github.com/rjeczalik/fs", ch[0], FileNotifyChangeFileName, FileNotifyChangeSize) + + cases := []NCase{ + { + Event: rremove(n.W(), "src/github.com/rjeczalik/fs/fs.go"), + Receiver: Chans{ch[0]}, + }, + { + Event: rwrite(n.W(), "src/github.com/rjeczalik/fs/README.md", []byte("XD")), + Receiver: Chans{ch[0]}, + }, + } + + n.ExpectNotifyEvents(cases, ch) +} + +func TestUnknownEvent(t *testing.T) { + n := NewNotifyTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(1) + + n.WatchErr("src/github.com/rjeczalik/fs", ch[0], nil, FileActionAdded) +} + +func TestNotifySystemAndGlobalMix(t *testing.T) { + n := NewNotifyTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(3) + + n.Watch("src/github.com/rjeczalik/fs", ch[0], Create) + n.Watch("src/github.com/rjeczalik/fs", ch[1], FileNotifyChangeFileName) + n.Watch("src/github.com/rjeczalik/fs", ch[2], FileNotifyChangeDirName) + + cases := []NCase{ + { + Event: rcreate(n.W(), "src/github.com/rjeczalik/fs/.main.cc.swr"), + Receiver: Chans{ch[0], ch[1]}, + }, + } + + n.ExpectNotifyEvents(cases, ch) +} diff --git a/vendor/github.com/rjeczalik/notify/notify_test.go b/vendor/github.com/rjeczalik/notify/notify_test.go new file mode 100644 index 00000000..58c6ae75 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/notify_test.go @@ -0,0 +1,103 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin linux freebsd dragonfly netbsd openbsd windows solaris + +package notify + +import "testing" + +func TestNotifyExample(t *testing.T) { + n := NewNotifyTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(3) + + // Watch-points can be set explicitly via Watch/Stop calls... + n.Watch("src/github.com/rjeczalik/fs", ch[0], Write) + n.Watch("src/github.com/pblaszczyk/qttu", ch[0], Write) + n.Watch("src/github.com/pblaszczyk/qttu/...", ch[1], Create) + n.Watch("src/github.com/rjeczalik/fs/cmd/...", ch[2], Remove) + + cases := []NCase{ + // i=0 + { + Event: write(n.W(), "src/github.com/rjeczalik/fs/fs.go", []byte("XD")), + Receiver: Chans{ch[0]}, + }, + // TODO(rjeczalik): #62 + // i=1 + // { + // Event: write(n.W(), "src/github.com/pblaszczyk/qttu/README.md", []byte("XD")), + // Receiver: Chans{ch[0]}, + // }, + // i=2 + { + Event: write(n.W(), "src/github.com/rjeczalik/fs/cmd/gotree/go.go", []byte("XD")), + Receiver: nil, + }, + // i=3 + { + Event: create(n.W(), "src/github.com/pblaszczyk/qttu/src/.main.cc.swp"), + Receiver: Chans{ch[1]}, + }, + // i=4 + { + Event: create(n.W(), "src/github.com/pblaszczyk/qttu/src/.main.cc.swo"), + Receiver: Chans{ch[1]}, + }, + // i=5 + { + Event: remove(n.W(), "src/github.com/rjeczalik/fs/cmd/gotree/go.go"), + Receiver: Chans{ch[2]}, + }, + } + + n.ExpectNotifyEvents(cases, ch) + + // ...or using Call structures. + stops := [...]Call{ + // i=0 + { + F: FuncStop, + C: ch[0], + }, + // i=1 + { + F: FuncStop, + C: ch[1], + }, + } + + n.Call(stops[:]...) + + cases = []NCase{ + // i=0 + { + Event: write(n.W(), "src/github.com/rjeczalik/fs/fs.go", []byte("XD")), + Receiver: nil, + }, + // i=1 + { + Event: write(n.W(), "src/github.com/pblaszczyk/qttu/README.md", []byte("XD")), + Receiver: nil, + }, + // i=2 + { + Event: create(n.W(), "src/github.com/pblaszczyk/qttu/src/.main.cc.swr"), + Receiver: nil, + }, + // i=3 + { + Event: remove(n.W(), "src/github.com/rjeczalik/fs/cmd/gotree/main.go"), + Receiver: Chans{ch[2]}, + }, + } + + n.ExpectNotifyEvents(cases, ch) +} + +func TestStop(t *testing.T) { + t.Skip("TODO(rjeczalik)") +} diff --git a/vendor/github.com/rjeczalik/notify/sync_readdcw_test.go b/vendor/github.com/rjeczalik/notify/sync_readdcw_test.go new file mode 100644 index 00000000..f2997543 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/sync_readdcw_test.go @@ -0,0 +1,33 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify + +import ( + "syscall" + "time" + "unsafe" +) + +var modkernel32 = syscall.NewLazyDLL("kernel32.dll") +var procSetSystemFileCacheSize = modkernel32.NewProc("SetSystemFileCacheSize") +var zero = uintptr(1<<(unsafe.Sizeof(uintptr(0))*8) - 1) + +func Sync() { + // TODO(pknap): does not work without admin privileges, but I'm going + // to hack it. + // r, _, err := procSetSystemFileCacheSize.Call(none, none, 0) + // if r == 0 { + // dbgprint("SetSystemFileCacheSize error:", err) + // } +} + +// UpdateWait pauses the program for some minimal amount of time. This function +// is required only by implementations which work asynchronously. It gives +// watcher structure time to update its internal state. +func UpdateWait() { + time.Sleep(50 * time.Millisecond) +} diff --git a/vendor/github.com/rjeczalik/notify/sync_unix_test.go b/vendor/github.com/rjeczalik/notify/sync_unix_test.go new file mode 100644 index 00000000..5e2c5dde --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/sync_unix_test.go @@ -0,0 +1,18 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build !windows + +package notify + +import "golang.org/x/sys/unix" + +func Sync() { + unix.Sync() +} + +// UpdateWait is required only by windows watcher implementation. On other +// platforms this function is no-op. +func UpdateWait() { +} diff --git a/vendor/github.com/rjeczalik/notify/testdata/vfs.txt b/vendor/github.com/rjeczalik/notify/testdata/vfs.txt new file mode 100644 index 00000000..88afbc6e --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/testdata/vfs.txt @@ -0,0 +1,56 @@ +src/github.com/pblaszczyk/qttu/.travis.yml +src/github.com/pblaszczyk/qttu/include/qttu/detail/registrator.hh +src/github.com/pblaszczyk/qttu/include/qttu/detail/registry.hh +src/github.com/pblaszczyk/qttu/include/qttu/runner.hh +src/github.com/pblaszczyk/qttu/LICENSE +src/github.com/pblaszczyk/qttu/qttu.pri +src/github.com/pblaszczyk/qttu/qttu.pro +src/github.com/pblaszczyk/qttu/README.md +src/github.com/pblaszczyk/qttu/src/main.cc +src/github.com/pblaszczyk/qttu/src/reg.cc +src/github.com/ppknap/link/.travis.yml +src/github.com/ppknap/link/include/coost/link/definitions.hpp +src/github.com/ppknap/link/include/coost/link/detail/bundle.hpp +src/github.com/ppknap/link/include/coost/link/detail/container_invoker.hpp +src/github.com/ppknap/link/include/coost/link/detail/container_value_trait.hpp +src/github.com/ppknap/link/include/coost/link/detail/dummy_type.hpp +src/github.com/ppknap/link/include/coost/link/detail/function_trait.hpp +src/github.com/ppknap/link/include/coost/link/detail/immediate_invoker.hpp +src/github.com/ppknap/link/include/coost/link/detail/stdhelpers/always_same.hpp +src/github.com/ppknap/link/include/coost/link/detail/stdhelpers/make_unique.hpp +src/github.com/ppknap/link/include/coost/link/detail/vertex.hpp +src/github.com/ppknap/link/include/coost/link/detail/wire.hpp +src/github.com/ppknap/link/include/coost/link/link.hpp +src/github.com/ppknap/link/include/coost/link.hpp +src/github.com/ppknap/link/Jamroot.jam +src/github.com/ppknap/link/LICENSE.md +src/github.com/ppknap/link/README.md +src/github.com/ppknap/link/test/counter_helper.hpp +src/github.com/ppknap/link/test/Jamfile.jam +src/github.com/ppknap/link/test/test_circular_calls.cpp +src/github.com/ppknap/link/test/test_container.cpp +src/github.com/ppknap/link/test/test_copy.cpp +src/github.com/ppknap/link/test/test_destructor.cpp +src/github.com/ppknap/link/test/test_immediate.cpp +src/github.com/ppknap/link/test/test_initialize.cpp +src/github.com/rjeczalik/fs/.travis.yml +src/github.com/rjeczalik/fs/appveyor.yml +src/github.com/rjeczalik/fs/cmd/gotree/go.go +src/github.com/rjeczalik/fs/cmd/gotree/main.go +src/github.com/rjeczalik/fs/cmd/mktree/main.go +src/github.com/rjeczalik/fs/fs.go +src/github.com/rjeczalik/fs/fsutil/fixture_test.go +src/github.com/rjeczalik/fs/fsutil/fsutil.go +src/github.com/rjeczalik/fs/fsutil/fsutil_test.go +src/github.com/rjeczalik/fs/fsutil/rel.go +src/github.com/rjeczalik/fs/fsutil/rel_test.go +src/github.com/rjeczalik/fs/fsutil/tee.go +src/github.com/rjeczalik/fs/fsutil/tee_test.go +src/github.com/rjeczalik/fs/LICENSE +src/github.com/rjeczalik/fs/memfs/memfs.go +src/github.com/rjeczalik/fs/memfs/memfs_test.go +src/github.com/rjeczalik/fs/memfs/tree.go +src/github.com/rjeczalik/fs/memfs/tree_test.go +src/github.com/rjeczalik/fs/memfs/util.go +src/github.com/rjeczalik/fs/memfs/util_test.go +src/github.com/rjeczalik/fs/README.md diff --git a/vendor/github.com/rjeczalik/notify/testing_test.go b/vendor/github.com/rjeczalik/notify/testing_test.go new file mode 100644 index 00000000..62e8c28c --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/testing_test.go @@ -0,0 +1,955 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "bufio" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "testing" + "time" +) + +// NOTE(rjeczalik): some useful environment variables: +// +// - NOTIFY_DEBUG gives some extra information about generated events +// - NOTIFY_TIMEOUT allows for changing default wait time for watcher's +// events +// - NOTIFY_TMP allows for changing location of temporary directory trees +// created for test purpose + +var wd string + +func init() { + var err error + if wd, err = os.Getwd(); err != nil { + panic("Getwd()=" + err.Error()) + } +} + +func timeout() time.Duration { + if s := os.Getenv("NOTIFY_TIMEOUT"); s != "" { + if t, err := time.ParseDuration(s); err == nil { + return t + } + } + return 2 * time.Second +} + +func vfs() (string, string) { + if s := os.Getenv("NOTIFY_TMP"); s != "" { + return filepath.Split(s) + } + return "testdata", "" +} + +func isDir(path string) bool { + r := path[len(path)-1] + return r == '\\' || r == '/' +} + +func tmpcreateall(tmp string, path string) error { + isdir := isDir(path) + path = filepath.Join(tmp, filepath.FromSlash(path)) + if isdir { + if err := os.MkdirAll(path, 0755); err != nil { + return err + } + } else { + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + f, err := os.Create(path) + if err != nil { + return err + } + if err := nonil(f.Sync(), f.Close()); err != nil { + return err + } + } + return nil +} + +func tmpcreate(root, path string) (bool, error) { + isdir := isDir(path) + path = filepath.Join(root, filepath.FromSlash(path)) + if isdir { + if err := os.Mkdir(path, 0755); err != nil { + return false, err + } + } else { + f, err := os.Create(path) + if err != nil { + return false, err + } + if err := nonil(f.Sync(), f.Close()); err != nil { + return false, err + } + } + return isdir, nil +} + +func tmptree(root, list string) (string, error) { + f, err := os.Open(list) + if err != nil { + return "", err + } + defer f.Close() + if root == "" { + if root, err = ioutil.TempDir(vfs()); err != nil { + return "", err + } + } + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if err := tmpcreateall(root, scanner.Text()); err != nil { + return "", err + } + } + if err := scanner.Err(); err != nil { + return "", err + } + return root, nil +} + +func callern(n int) string { + _, file, line, ok := runtime.Caller(n) + if !ok { + return "" + } + return filepath.Base(file) + ":" + strconv.Itoa(line) +} + +func caller() string { + return callern(3) +} + +type WCase struct { + Action func() + Events []EventInfo +} + +func (cas WCase) String() string { + s := make([]string, 0, len(cas.Events)) + for _, ei := range cas.Events { + s = append(s, "Event("+ei.Event().String()+")@"+filepath.FromSlash(ei.Path())) + } + return strings.Join(s, ", ") +} + +type W struct { + Watcher watcher + C chan EventInfo + Timeout time.Duration + + t *testing.T + root string +} + +func newWatcherTest(t *testing.T, tree string) *W { + root, err := tmptree("", filepath.FromSlash(tree)) + if err != nil { + t.Fatalf(`tmptree("", %q)=%v`, tree, err) + } + root, _, err = cleanpath(root) + if err != nil { + t.Fatalf(`cleanpath(%q)=%v`, root, err) + } + Sync() + return &W{ + t: t, + root: root, + } +} + +func NewWatcherTest(t *testing.T, tree string, events ...Event) *W { + w := newWatcherTest(t, tree) + if len(events) == 0 { + events = []Event{Create, Remove, Write, Rename} + } + if rw, ok := w.watcher().(recursiveWatcher); ok { + if err := rw.RecursiveWatch(w.root, joinevents(events)); err != nil { + t.Fatalf("RecursiveWatch(%q, All)=%v", w.root, err) + } + } else { + fn := func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + if fi.IsDir() { + if err := w.watcher().Watch(path, joinevents(events)); err != nil { + return err + } + } + return nil + } + if err := filepath.Walk(w.root, fn); err != nil { + t.Fatalf("Walk(%q, fn)=%v", w.root, err) + } + } + drainall(w.C) + return w +} + +func (w *W) clean(path string) string { + path, isrec, err := cleanpath(filepath.Join(w.root, path)) + if err != nil { + w.Fatalf("cleanpath(%q)=%v", path, err) + } + if isrec { + path = path + "..." + } + return path +} + +func (w *W) Fatal(v interface{}) { + w.t.Fatalf("%s: %v", caller(), v) +} + +func (w *W) Fatalf(format string, v ...interface{}) { + w.t.Fatalf("%s: %s", caller(), fmt.Sprintf(format, v...)) +} + +func (w *W) Watch(path string, e Event) { + if err := w.watcher().Watch(w.clean(path), e); err != nil { + w.Fatalf("Watch(%s, %v)=%v", path, e, err) + } +} + +func (w *W) Rewatch(path string, olde, newe Event) { + if err := w.watcher().Rewatch(w.clean(path), olde, newe); err != nil { + w.Fatalf("Rewatch(%s, %v, %v)=%v", path, olde, newe, err) + } +} + +func (w *W) Unwatch(path string) { + if err := w.watcher().Unwatch(w.clean(path)); err != nil { + w.Fatalf("Unwatch(%s)=%v", path, err) + } +} + +func (w *W) RecursiveWatch(path string, e Event) { + rw, ok := w.watcher().(recursiveWatcher) + if !ok { + w.Fatal("watcher does not implement recursive watching on this platform") + } + if err := rw.RecursiveWatch(w.clean(path), e); err != nil { + w.Fatalf("RecursiveWatch(%s, %v)=%v", path, e, err) + } +} + +func (w *W) RecursiveRewatch(oldp, newp string, olde, newe Event) { + rw, ok := w.watcher().(recursiveWatcher) + if !ok { + w.Fatal("watcher does not implement recursive watching on this platform") + } + if err := rw.RecursiveRewatch(w.clean(oldp), w.clean(newp), olde, newe); err != nil { + w.Fatalf("RecursiveRewatch(%s, %s, %v, %v)=%v", oldp, newp, olde, newe, err) + } +} + +func (w *W) RecursiveUnwatch(path string) { + rw, ok := w.watcher().(recursiveWatcher) + if !ok { + w.Fatal("watcher does not implement recursive watching on this platform") + } + if err := rw.RecursiveUnwatch(w.clean(path)); err != nil { + w.Fatalf("RecursiveUnwatch(%s)=%v", path, err) + } +} + +func (w *W) initwatcher(buffer int) { + c := make(chan EventInfo, buffer) + w.Watcher = newWatcher(c) + w.C = c +} + +func (w *W) watcher() watcher { + if w.Watcher == nil { + w.initwatcher(512) + } + return w.Watcher +} + +func (w *W) c() chan EventInfo { + if w.C == nil { + w.initwatcher(512) + } + return w.C +} + +func (w *W) timeout() time.Duration { + if w.Timeout != 0 { + return w.Timeout + } + return timeout() +} + +func (w *W) Close() error { + defer os.RemoveAll(w.root) + if err := w.watcher().Close(); err != nil { + w.Fatalf("w.Watcher.Close()=%v", err) + } + return nil +} + +func EqualEventInfo(want, got EventInfo) error { + if got.Event() != want.Event() { + return fmt.Errorf("want Event()=%v; got %v (path=%s)", want.Event(), + got.Event(), want.Path()) + } + path := strings.TrimRight(filepath.FromSlash(want.Path()), `/\`) + if !strings.HasSuffix(got.Path(), path) { + return fmt.Errorf("want Path()=%s; got %s (event=%v)", path, got.Path(), + want.Event()) + } + return nil +} + +func HasEventInfo(want, got Event, p string) error { + if got&want != want { + return fmt.Errorf("want Event=%v; got %v (path=%s)", want, + got, p) + } + return nil +} + +func EqualCall(want, got Call) error { + if want.F != got.F { + return fmt.Errorf("want F=%v; got %v (want.P=%q, got.P=%q)", want.F, got.F, want.P, got.P) + } + if got.E != want.E { + return fmt.Errorf("want E=%v; got %v (want.P=%q, got.P=%q)", want.E, got.E, want.P, got.P) + } + if got.NE != want.NE { + return fmt.Errorf("want NE=%v; got %v (want.P=%q, got.P=%q)", want.NE, got.NE, want.P, got.P) + } + if want.C != got.C { + return fmt.Errorf("want C=%p; got %p (want.P=%q, got.P=%q)", want.C, got.C, want.P, got.P) + } + if want := filepath.FromSlash(want.P); !strings.HasSuffix(got.P, want) { + return fmt.Errorf("want P=%s; got %s", want, got.P) + } + if want := filepath.FromSlash(want.NP); !strings.HasSuffix(got.NP, want) { + return fmt.Errorf("want NP=%s; got %s", want, got.NP) + } + return nil +} + +func create(w *W, path string) WCase { + return WCase{ + Action: func() { + isdir, err := tmpcreate(w.root, filepath.FromSlash(path)) + if err != nil { + w.Fatalf("tmpcreate(%q, %q)=%v", w.root, path, err) + } + if isdir { + dbgprintf("[FS] os.Mkdir(%q)\n", path) + } else { + dbgprintf("[FS] os.Create(%q)\n", path) + } + }, + Events: []EventInfo{ + &Call{P: path, E: Create}, + }, + } +} + +func remove(w *W, path string) WCase { + return WCase{ + Action: func() { + if err := os.RemoveAll(filepath.Join(w.root, filepath.FromSlash(path))); err != nil { + w.Fatal(err) + } + dbgprintf("[FS] os.Remove(%q)\n", path) + }, + Events: []EventInfo{ + &Call{P: path, E: Remove}, + }, + } +} + +func rename(w *W, oldpath, newpath string) WCase { + return WCase{ + Action: func() { + err := os.Rename(filepath.Join(w.root, filepath.FromSlash(oldpath)), + filepath.Join(w.root, filepath.FromSlash(newpath))) + if err != nil { + w.Fatal(err) + } + dbgprintf("[FS] os.Rename(%q, %q)\n", oldpath, newpath) + }, + Events: []EventInfo{ + &Call{P: newpath, E: Rename}, + }, + } +} + +func write(w *W, path string, p []byte) WCase { + return WCase{ + Action: func() { + f, err := os.OpenFile(filepath.Join(w.root, filepath.FromSlash(path)), + os.O_WRONLY, 0644) + if err != nil { + w.Fatalf("OpenFile(%q)=%v", path, err) + } + if _, err := f.Write(p); err != nil { + w.Fatalf("Write(%q)=%v", path, err) + } + if err := nonil(f.Sync(), f.Close()); err != nil { + w.Fatalf("Sync(%q)/Close(%q)=%v", path, path, err) + } + dbgprintf("[FS] Write(%q)\n", path) + }, + Events: []EventInfo{ + &Call{P: path, E: Write}, + }, + } +} + +func drainall(c chan EventInfo) (ei []EventInfo) { + time.Sleep(50 * time.Millisecond) + for { + select { + case e := <-c: + ei = append(ei, e) + runtime.Gosched() + default: + return + } + } +} + +type WCaseFunc func(i int, cas WCase, ei EventInfo) error + +func (w *W) ExpectAnyFunc(cases []WCase, fn WCaseFunc) { + UpdateWait() // Wait some time before starting the test. +Test: + for i, cas := range cases { + dbgprintf("ExpectAny: i=%d\n", i) + cas.Action() + Sync() + switch cas.Events { + case nil: + if ei := drainall(w.C); len(ei) != 0 { + w.Fatalf("unexpected dangling events: %v (i=%d)", ei, i) + } + default: + select { + case ei := <-w.C: + dbgprintf("received: path=%q, event=%v, sys=%v (i=%d)", ei.Path(), + ei.Event(), ei.Sys(), i) + for j, want := range cas.Events { + if err := EqualEventInfo(want, ei); err != nil { + dbgprint(err, j) + continue + } + if fn != nil { + if err := fn(i, cas, ei); err != nil { + w.Fatalf("ExpectAnyFunc(%d, %v)=%v", i, ei, err) + } + } + drainall(w.C) // TODO(rjeczalik): revisit + continue Test + } + w.Fatalf("ExpectAny received an event which does not match any of "+ + "the expected ones (i=%d): want one of %v; got %v", i, cas.Events, ei) + case <-time.After(w.timeout()): + w.Fatalf("timed out after %v waiting for one of %v (i=%d)", w.timeout(), + cas.Events, i) + } + drainall(w.C) // TODO(rjeczalik): revisit + } + } +} + +func (w *W) ExpectAny(cases []WCase) { + w.ExpectAnyFunc(cases, nil) +} + +func (w *W) aggregate(ei []EventInfo, pf string) (evs map[string]Event) { + evs = make(map[string]Event) + for _, cas := range ei { + p := cas.Path() + if pf != "" { + p = filepath.Join(pf, p) + } + evs[p] |= cas.Event() + } + return +} + +func (w *W) ExpectAllFunc(cases []WCase) { + UpdateWait() // Wait some time before starting the test. + for i, cas := range cases { + exp := w.aggregate(cas.Events, w.root) + dbgprintf("ExpectAll: i=%d\n", i) + cas.Action() + Sync() + got := w.aggregate(drainall(w.C), "") + for ep, ee := range exp { + ge, ok := got[ep] + if !ok { + w.Fatalf("missing events for %q (%v)", ep, ee) + continue + } + delete(got, ep) + if err := HasEventInfo(ee, ge, ep); err != nil { + w.Fatalf("ExpectAll received an event which does not match "+ + "the expected ones for %q: want %v; got %v", ep, ee, ge) + continue + } + } + if len(got) != 0 { + w.Fatalf("ExpectAll received unexpected events: %v", got) + } + } +} + +// ExpectAll requires all requested events to be send. +// It does not require events to be send in the same order or in the same +// chunks (e.g. NoteWrite and NoteExtend reported as independent events are +// treated the same as one NoteWrite|NoteExtend event). +func (w *W) ExpectAll(cases []WCase) { + w.ExpectAllFunc(cases) +} + +// FuncType represents enums for Watcher interface. +type FuncType string + +const ( + FuncWatch = FuncType("Watch") + FuncUnwatch = FuncType("Unwatch") + FuncRewatch = FuncType("Rewatch") + FuncRecursiveWatch = FuncType("RecursiveWatch") + FuncRecursiveUnwatch = FuncType("RecursiveUnwatch") + FuncRecursiveRewatch = FuncType("RecursiveRewatch") + FuncStop = FuncType("Stop") +) + +type Chans []chan EventInfo + +func NewChans(n int) Chans { + ch := make([]chan EventInfo, n) + for i := range ch { + ch[i] = make(chan EventInfo, buffer) + } + return ch +} + +func (c Chans) Foreach(fn func(chan<- EventInfo, node)) { + for i, ch := range c { + fn(ch, node{Name: strconv.Itoa(i)}) + } +} + +func (c Chans) Drain() (ei []EventInfo) { + n := len(c) + stop := make(chan struct{}) + eich := make(chan EventInfo, n*buffer) + go func() { + defer close(eich) + cases := make([]reflect.SelectCase, n+1) + for i := range c { + cases[i].Chan = reflect.ValueOf(c[i]) + cases[i].Dir = reflect.SelectRecv + } + cases[n].Chan = reflect.ValueOf(stop) + cases[n].Dir = reflect.SelectRecv + for { + i, v, ok := reflect.Select(cases) + if i == n { + return + } + if !ok { + panic("(Chans).Drain(): unexpected chan close") + } + eich <- v.Interface().(EventInfo) + } + }() + <-time.After(50 * time.Duration(n) * time.Millisecond) + close(stop) + for e := range eich { + ei = append(ei, e) + } + return +} + +// Call represents single call to Watcher issued by the Tree +// and recorded by a spy Watcher mock. +type Call struct { + F FuncType // denotes type of function to call, for both watcher and notifier interface + C chan EventInfo // user channel being an argument to either Watch or Stop function + P string // regular Path argument and old path from RecursiveRewatch call + NP string // new Path argument from RecursiveRewatch call + E Event // regular Event argument and old Event from a Rewatch call + NE Event // new Event argument from Rewatch call + S interface{} // when Call is used as EventInfo, S is a value of Sys() + Dir bool // when Call is used as EventInfo, Dir is a value of isDir() +} + +// Call implements the EventInfo interface. +func (c *Call) Event() Event { return c.E } +func (c *Call) Path() string { return c.P } +func (c *Call) String() string { return fmt.Sprintf("%#v", c) } +func (c *Call) Sys() interface{} { return c.S } +func (c *Call) isDir() (bool, error) { return c.Dir, nil } + +// CallSlice is a convenient wrapper for a slice of Call values, which allows +// to sort them in ascending order. +type CallSlice []Call + +// CallSlice implements sort.Interface inteface. +func (cs CallSlice) Len() int { return len(cs) } +func (cs CallSlice) Less(i, j int) bool { return cs[i].P < cs[j].P } +func (cs CallSlice) Swap(i, j int) { cs[i], cs[j] = cs[j], cs[i] } +func (cs CallSlice) Sort() { sort.Sort(cs) } + +// Spy is a mock for Watcher interface, which records every call. +type Spy []Call + +func (s *Spy) Close() (_ error) { return } + +func (s *Spy) Watch(p string, e Event) (_ error) { + dbgprintf("%s: (*Spy).Watch(%q, %v)", caller(), p, e) + *s = append(*s, Call{F: FuncWatch, P: p, E: e}) + return +} + +func (s *Spy) Unwatch(p string) (_ error) { + dbgprintf("%s: (*Spy).Unwatch(%q)", caller(), p) + *s = append(*s, Call{F: FuncUnwatch, P: p}) + return +} + +func (s *Spy) Rewatch(p string, olde, newe Event) (_ error) { + dbgprintf("%s: (*Spy).Rewatch(%q, %v, %v)", caller(), p, olde, newe) + *s = append(*s, Call{F: FuncRewatch, P: p, E: olde, NE: newe}) + return +} + +func (s *Spy) RecursiveWatch(p string, e Event) (_ error) { + dbgprintf("%s: (*Spy).RecursiveWatch(%q, %v)", caller(), p, e) + *s = append(*s, Call{F: FuncRecursiveWatch, P: p, E: e}) + return +} + +func (s *Spy) RecursiveUnwatch(p string) (_ error) { + dbgprintf("%s: (*Spy).RecursiveUnwatch(%q)", caller(), p) + *s = append(*s, Call{F: FuncRecursiveUnwatch, P: p}) + return +} + +func (s *Spy) RecursiveRewatch(oldp, newp string, olde, newe Event) (_ error) { + dbgprintf("%s: (*Spy).RecursiveRewatch(%q, %q, %v, %v)", caller(), oldp, newp, olde, newe) + *s = append(*s, Call{F: FuncRecursiveRewatch, P: oldp, NP: newp, E: olde, NE: newe}) + return +} + +type RCase struct { + Call Call + Record []Call +} + +type TCase struct { + Event Call + Receiver Chans +} + +type NCase struct { + Event WCase + Receiver Chans +} + +type N struct { + Timeout time.Duration + + t *testing.T + tree tree + w *W + spy *Spy + c chan EventInfo + j int // spy offset + + realroot string +} + +func newN(t *testing.T, tree string) *N { + n := &N{ + t: t, + w: newWatcherTest(t, tree), + } + realroot, err := canonical(n.w.root) + if err != nil { + t.Fatalf("%s: unexpected fixture failure: %v", caller(), err) + } + n.realroot = realroot + return n +} + +func newTreeN(t *testing.T, tree string) *N { + c := make(chan EventInfo, buffer) + n := newN(t, tree) + n.spy = &Spy{} + n.w.Watcher = n.spy + n.w.C = c + n.c = c + return n +} + +func NewNotifyTest(t *testing.T, tree string) *N { + n := newN(t, tree) + if rw, ok := n.w.watcher().(recursiveWatcher); ok { + n.tree = newRecursiveTree(rw, n.w.c()) + } else { + n.tree = newNonrecursiveTree(n.w.watcher(), n.w.c(), nil) + } + return n +} + +func NewRecursiveTreeTest(t *testing.T, tree string) *N { + n := newTreeN(t, tree) + n.tree = newRecursiveTree(n.spy, n.c) + return n +} + +func NewNonrecursiveTreeTest(t *testing.T, tree string) *N { + n := newTreeN(t, tree) + n.tree = newNonrecursiveTree(n.spy, n.c, nil) + return n +} + +func NewNonrecursiveTreeTestC(t *testing.T, tree string) (*N, chan EventInfo) { + rec := make(chan EventInfo, buffer) + recinternal := make(chan EventInfo, buffer) + recuser := make(chan EventInfo, buffer) + go func() { + for ei := range rec { + select { + case recinternal <- ei: + default: + t.Fatalf("failed to send ei to recinternal: not ready") + } + select { + case recuser <- ei: + default: + t.Fatalf("failed to send ei to recuser: not ready") + } + } + }() + n := newTreeN(t, tree) + tr := newNonrecursiveTree(n.spy, n.c, recinternal) + tr.rec = rec + n.tree = tr + return n, recuser +} + +func (n *N) timeout() time.Duration { + if n.Timeout != 0 { + return n.Timeout + } + return n.w.timeout() +} + +func (n *N) W() *W { + return n.w +} + +func (n *N) Close() error { + defer os.RemoveAll(n.w.root) + if err := n.tree.Close(); err != nil { + n.w.Fatalf("(notifier).Close()=%v", err) + } + return nil +} + +func (n *N) Watch(path string, c chan<- EventInfo, events ...Event) { + UpdateWait() // we need to wait on Windows because of its asynchronous watcher. + path = filepath.Join(n.w.root, path) + if err := n.tree.Watch(path, c, events...); err != nil { + n.t.Errorf("Watch(%s, %p, %v)=%v", path, c, events, err) + } +} + +func (n *N) WatchErr(path string, c chan<- EventInfo, err error, events ...Event) { + path = filepath.Join(n.w.root, path) + switch e := n.tree.Watch(path, c, events...); { + case err == nil && e == nil: + n.t.Errorf("Watch(%s, %p, %v)=nil", path, c, events) + case err != nil && e != err: + n.t.Errorf("Watch(%s, %p, %v)=%v != %v", path, c, events, e, err) + } +} + +func (n *N) Stop(c chan<- EventInfo) { + n.tree.Stop(c) +} + +func (n *N) Call(calls ...Call) { + for i := range calls { + switch calls[i].F { + case FuncWatch: + n.Watch(calls[i].P, calls[i].C, calls[i].E) + case FuncStop: + n.Stop(calls[i].C) + default: + panic("unsupported call type: " + string(calls[i].F)) + } + } +} + +func (n *N) expectDry(ch Chans, i int) { + if ei := ch.Drain(); len(ei) != 0 { + n.w.Fatalf("unexpected dangling events: %v (i=%d)", ei, i) + } +} + +func (n *N) ExpectRecordedCalls(cases []RCase) { + for i, cas := range cases { + dbgprintf("ExpectRecordedCalls: i=%d\n", i) + n.Call(cas.Call) + record := (*n.spy)[n.j:] + if len(cas.Record) == 0 && len(record) == 0 { + continue + } + n.j = len(*n.spy) + if len(record) != len(cas.Record) { + n.t.Fatalf("%s: want len(record)=%d; got %d [%+v] (i=%d)", caller(), + len(cas.Record), len(record), record, i) + } + CallSlice(record).Sort() + for j := range cas.Record { + if err := EqualCall(cas.Record[j], record[j]); err != nil { + n.t.Fatalf("%s: %v (i=%d, j=%d)", caller(), err, i, j) + } + } + } +} + +func (n *N) collect(ch Chans) <-chan []EventInfo { + done := make(chan []EventInfo) + go func() { + cases := make([]reflect.SelectCase, len(ch)) + unique := make(map[<-chan EventInfo]EventInfo, len(ch)) + for i := range ch { + cases[i].Chan = reflect.ValueOf(ch[i]) + cases[i].Dir = reflect.SelectRecv + } + for i := len(cases); i != 0; i = len(cases) { + j, v, ok := reflect.Select(cases) + if !ok { + n.t.Fatal("unexpected chan close") + } + ch := cases[j].Chan.Interface().(chan EventInfo) + got := v.Interface().(EventInfo) + if ei, ok := unique[ch]; ok { + n.t.Fatalf("duplicated event %v (previous=%v) received on collect", got, ei) + } + unique[ch] = got + cases[j], cases = cases[i-1], cases[:i-1] + } + collected := make([]EventInfo, 0, len(ch)) + for _, ch := range unique { + collected = append(collected, ch) + } + done <- collected + }() + return done +} + +func (n *N) abs(rel Call) *Call { + rel.P = filepath.Join(n.realroot, filepath.FromSlash(rel.P)) + if !filepath.IsAbs(rel.P) { + rel.P = filepath.Join(wd, rel.P) + } + return &rel +} + +func (n *N) ExpectTreeEvents(cases []TCase, all Chans) { + for i, cas := range cases { + dbgprintf("ExpectTreeEvents: i=%d\n", i) + // Ensure there're no dangling event left by previous test-case. + n.expectDry(all, i) + n.c <- n.abs(cas.Event) + switch cas.Receiver { + case nil: + n.expectDry(all, i) + default: + ch := n.collect(cas.Receiver) + select { + case collected := <-ch: + for _, got := range collected { + if err := EqualEventInfo(&cas.Event, got); err != nil { + n.w.Fatalf("%s: %s (i=%d)", caller(), err, i) + } + } + case <-time.After(n.timeout()): + n.w.Fatalf("ExpectTreeEvents has timed out after %v waiting for"+ + " %v on %s (i=%d)", n.timeout(), cas.Event.E, cas.Event.P, i) + } + + } + } + n.expectDry(all, -1) +} + +func (n *N) ExpectNotifyEvents(cases []NCase, all Chans) { + UpdateWait() // Wait some time before starting the test. + for i, cas := range cases { + dbgprintf("ExpectNotifyEvents: i=%d\n", i) + cas.Event.Action() + Sync() + switch cas.Receiver { + case nil: + n.expectDry(all, i) + default: + ch := n.collect(cas.Receiver) + select { + case collected := <-ch: + Compare: + for j, ei := range collected { + dbgprintf("received: path=%q, event=%v, sys=%v (i=%d, j=%d)", ei.Path(), + ei.Event(), ei.Sys(), i, j) + for _, want := range cas.Event.Events { + if err := EqualEventInfo(want, ei); err != nil { + dbgprint(err, j) + continue + } + continue Compare + } + n.w.Fatalf("ExpectNotifyEvents received an event which does not"+ + " match any of the expected ones (i=%d): want one of %v; got %v", i, + cas.Event.Events, ei) + } + case <-time.After(n.timeout()): + n.w.Fatalf("ExpectNotifyEvents did not receive any of the expected events [%v] "+ + "after %v (i=%d)", cas.Event, n.timeout(), i) + } + } + } + n.expectDry(all, -1) +} + +func (n *N) Walk(fn walkFunc) { + switch t := n.tree.(type) { + case *recursiveTree: + if err := t.root.Walk("", fn); err != nil { + n.w.Fatal(err) + } + case *nonrecursiveTree: + if err := t.root.Walk("", fn); err != nil { + n.w.Fatal(err) + } + default: + n.t.Fatal("unknown tree type") + } +} diff --git a/vendor/github.com/rjeczalik/notify/tree.go b/vendor/github.com/rjeczalik/notify/tree.go new file mode 100644 index 00000000..cd6afd60 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/tree.go @@ -0,0 +1,22 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +const buffer = 128 + +type tree interface { + Watch(string, chan<- EventInfo, ...Event) error + Stop(chan<- EventInfo) + Close() error +} + +func newTree() tree { + c := make(chan EventInfo, buffer) + w := newWatcher(c) + if rw, ok := w.(recursiveWatcher); ok { + return newRecursiveTree(rw, c) + } + return newNonrecursiveTree(w, c, make(chan EventInfo, buffer)) +} diff --git a/vendor/github.com/rjeczalik/notify/tree_nonrecursive.go b/vendor/github.com/rjeczalik/notify/tree_nonrecursive.go new file mode 100644 index 00000000..dfa72d1d --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/tree_nonrecursive.go @@ -0,0 +1,292 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import "sync" + +// nonrecursiveTree TODO(rjeczalik) +type nonrecursiveTree struct { + rw sync.RWMutex // protects root + root root + w watcher + c chan EventInfo + rec chan EventInfo +} + +// newNonrecursiveTree TODO(rjeczalik) +func newNonrecursiveTree(w watcher, c, rec chan EventInfo) *nonrecursiveTree { + if rec == nil { + rec = make(chan EventInfo, buffer) + } + t := &nonrecursiveTree{ + root: root{nd: newnode("")}, + w: w, + c: c, + rec: rec, + } + go t.dispatch(c) + go t.internal(rec) + return t +} + +// dispatch TODO(rjeczalik) +func (t *nonrecursiveTree) dispatch(c <-chan EventInfo) { + for ei := range c { + dbgprintf("dispatching %v on %q", ei.Event(), ei.Path()) + go func(ei EventInfo) { + var nd node + var isrec bool + dir, base := split(ei.Path()) + fn := func(it node, isbase bool) error { + isrec = isrec || it.Watch.IsRecursive() + if isbase { + nd = it + } else { + it.Watch.Dispatch(ei, recursive) + } + return nil + } + t.rw.RLock() + // Notify recursive watchpoints found on the path. + if err := t.root.WalkPath(dir, fn); err != nil { + dbgprint("dispatch did not reach leaf:", err) + t.rw.RUnlock() + return + } + // Notify parent watchpoint. + nd.Watch.Dispatch(ei, 0) + isrec = isrec || nd.Watch.IsRecursive() + // If leaf watchpoint exists, notify it. + if nd, ok := nd.Child[base]; ok { + isrec = isrec || nd.Watch.IsRecursive() + nd.Watch.Dispatch(ei, 0) + } + t.rw.RUnlock() + // If the event describes newly leaf directory created within + if !isrec || ei.Event() != Create { + return + } + if ok, err := ei.(isDirer).isDir(); !ok || err != nil { + return + } + t.rec <- ei + }(ei) + } +} + +// internal TODO(rjeczalik) +func (t *nonrecursiveTree) internal(rec <-chan EventInfo) { + for ei := range rec { + var nd node + var eset = internal + t.rw.Lock() + t.root.WalkPath(ei.Path(), func(it node, _ bool) error { + if e := it.Watch[t.rec]; e != 0 && e > eset { + eset = e + } + nd = it + return nil + }) + if eset == internal { + t.rw.Unlock() + continue + } + err := nd.Add(ei.Path()).AddDir(t.recFunc(eset)) + t.rw.Unlock() + if err != nil { + dbgprintf("internal(%p) error: %v", rec, err) + } + } +} + +// watchAdd TODO(rjeczalik) +func (t *nonrecursiveTree) watchAdd(nd node, c chan<- EventInfo, e Event) eventDiff { + if e&recursive != 0 { + diff := nd.Watch.Add(t.rec, e|Create|omit) + nd.Watch.Add(c, e) + return diff + } + return nd.Watch.Add(c, e) +} + +// watchDelMin TODO(rjeczalik) +func (t *nonrecursiveTree) watchDelMin(min Event, nd node, c chan<- EventInfo, e Event) eventDiff { + old, ok := nd.Watch[t.rec] + if ok { + nd.Watch[t.rec] = min + } + diff := nd.Watch.Del(c, e) + if ok { + switch old &^= diff[0] &^ diff[1]; { + case old|internal == internal: + delete(nd.Watch, t.rec) + if set, ok := nd.Watch[nil]; ok && len(nd.Watch) == 1 && set == 0 { + delete(nd.Watch, nil) + } + default: + nd.Watch.Add(t.rec, old|Create) + switch { + case diff == none: + case diff[1]|Create == diff[0]: + diff = none + default: + diff[1] |= Create + } + } + } + return diff +} + +// watchDel TODO(rjeczalik) +func (t *nonrecursiveTree) watchDel(nd node, c chan<- EventInfo, e Event) eventDiff { + return t.watchDelMin(0, nd, c, e) +} + +// Watch TODO(rjeczalik) +func (t *nonrecursiveTree) Watch(path string, c chan<- EventInfo, events ...Event) error { + if c == nil { + panic("notify: Watch using nil channel") + } + // Expanding with empty event set is a nop. + if len(events) == 0 { + return nil + } + path, isrec, err := cleanpath(path) + if err != nil { + return err + } + eset := joinevents(events) + t.rw.Lock() + defer t.rw.Unlock() + nd := t.root.Add(path) + if isrec { + return t.watchrec(nd, c, eset|recursive) + } + return t.watch(nd, c, eset) +} + +func (t *nonrecursiveTree) watch(nd node, c chan<- EventInfo, e Event) (err error) { + diff := nd.Watch.Add(c, e) + switch { + case diff == none: + return nil + case diff[1] == 0: + // TODO(rjeczalik): cleanup this panic after implementation is stable + panic("eset is empty: " + nd.Name) + case diff[0] == 0: + err = t.w.Watch(nd.Name, diff[1]) + default: + err = t.w.Rewatch(nd.Name, diff[0], diff[1]) + } + if err != nil { + nd.Watch.Del(c, diff.Event()) + return err + } + return nil +} + +func (t *nonrecursiveTree) recFunc(e Event) walkFunc { + return func(nd node) error { + switch diff := nd.Watch.Add(t.rec, e|omit|Create); { + case diff == none: + case diff[1] == 0: + // TODO(rjeczalik): cleanup this panic after implementation is stable + panic("eset is empty: " + nd.Name) + case diff[0] == 0: + t.w.Watch(nd.Name, diff[1]) + default: + t.w.Rewatch(nd.Name, diff[0], diff[1]) + } + return nil + } +} + +func (t *nonrecursiveTree) watchrec(nd node, c chan<- EventInfo, e Event) error { + var traverse func(walkFunc) error + // Non-recursive tree listens on Create event for every recursive + // watchpoint in order to automagically set a watch for every + // created directory. + switch diff := nd.Watch.dryAdd(t.rec, e|Create); { + case diff == none: + t.watchAdd(nd, c, e) + nd.Watch.Add(t.rec, e|omit|Create) + return nil + case diff[1] == 0: + // TODO(rjeczalik): cleanup this panic after implementation is stable + panic("eset is empty: " + nd.Name) + case diff[0] == 0: + // TODO(rjeczalik): BFS into directories and skip subtree as soon as first + // recursive watchpoint is encountered. + traverse = nd.AddDir + default: + traverse = nd.Walk + } + // TODO(rjeczalik): account every path that failed to be (re)watched + // and retry. + if err := traverse(t.recFunc(e)); err != nil { + return err + } + t.watchAdd(nd, c, e) + return nil +} + +type walkWatchpointFunc func(Event, node) error + +func (t *nonrecursiveTree) walkWatchpoint(nd node, fn walkWatchpointFunc) error { + type minode struct { + min Event + nd node + } + mnd := minode{nd: nd} + stack := []minode{mnd} +Traverse: + for n := len(stack); n != 0; n = len(stack) { + mnd, stack = stack[n-1], stack[:n-1] + // There must be no recursive watchpoints if the node has no watchpoints + // itself (every node in subtree rooted at recursive watchpoints must + // have at least nil (total) and t.rec watchpoints). + if len(mnd.nd.Watch) != 0 { + switch err := fn(mnd.min, mnd.nd); err { + case nil: + case errSkip: + continue Traverse + default: + return err + } + } + for _, nd := range mnd.nd.Child { + stack = append(stack, minode{mnd.nd.Watch[t.rec], nd}) + } + } + return nil +} + +// Stop TODO(rjeczalik) +func (t *nonrecursiveTree) Stop(c chan<- EventInfo) { + fn := func(min Event, nd node) error { + // TODO(rjeczalik): aggregate watcher errors and retry; in worst case + // forward to the user. + switch diff := t.watchDelMin(min, nd, c, all); { + case diff == none: + return nil + case diff[1] == 0: + t.w.Unwatch(nd.Name) + default: + t.w.Rewatch(nd.Name, diff[0], diff[1]) + } + return nil + } + t.rw.Lock() + err := t.walkWatchpoint(t.root.nd, fn) // TODO(rjeczalik): store max root per c + t.rw.Unlock() + dbgprintf("Stop(%p) error: %v\n", c, err) +} + +// Close TODO(rjeczalik) +func (t *nonrecursiveTree) Close() error { + err := t.w.Close() + close(t.c) + return err +} diff --git a/vendor/github.com/rjeczalik/notify/tree_nonrecursive_test.go b/vendor/github.com/rjeczalik/notify/tree_nonrecursive_test.go new file mode 100644 index 00000000..37625bfc --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/tree_nonrecursive_test.go @@ -0,0 +1,543 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "fmt" + "testing" +) + +func TestNonrecursiveTree(t *testing.T) { + n := NewNonrecursiveTreeTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(5) + + watches := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/fs.go", + C: ch[0], + E: Rename, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/fs.go", + E: Rename, + }, + }, + }, + // i=1 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/...", + C: ch[1], + E: Remove, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd", + E: Create | Remove, + }, + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree", + E: Create | Remove, + }, + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree", + E: Create | Remove, + }, + }, + }, + // i=2 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/...", + C: ch[2], + E: Rename, + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd", + E: Create | Remove, + NE: Create | Remove | Rename, + }, + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree", + E: Create | Remove, + NE: Create | Remove | Rename, + }, + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree", + E: Create | Remove, + NE: Create | Remove | Rename, + }, + }, + }, + // i=3 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree/...", + C: ch[2], + E: Write, + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree", + E: Create | Remove | Rename, + NE: Create | Remove | Rename | Write, + }, + }, + }, + // i=4 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include", + C: ch[3], + E: Create, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include", + E: Create, + }, + }, + }, + // i=5 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu/detail/...", + C: ch[3], + E: Write, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu/detail", + E: Create | Write, + }, + }, + }, + // i=6 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include/...", + C: ch[0], + E: Rename, + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include", + E: Create, + NE: Create | Rename, + }, + { + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu", + E: Create | Rename, + }, + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu/detail", + E: Create | Write, + NE: Create | Write | Rename, + }, + }, + }, + // i=7 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/...", + C: ch[1], + E: Write, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/pblaszczyk", + E: Create | Write, + }, + { + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu", + E: Create | Write, + }, + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include", + E: Create | Rename, + NE: Create | Rename | Write, + }, + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu", + E: Create | Rename, + NE: Create | Rename | Write, + }, + { + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/src", + E: Create | Write, + }, + }, + }, + // i=8 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/include/...", + C: ch[4], + E: Write, + }, + Record: nil, + }, + // i=9 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu", + C: ch[3], + E: Remove, + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu", + E: Create | Write, + NE: Create | Write | Remove, + }, + }, + }, + } + + n.ExpectRecordedCalls(watches[:]) + + events := [...]TCase{ + // i=0 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go", E: Rename}, + Receiver: Chans{ch[0]}, + }, + // i=1 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go", E: Create}, + Receiver: nil, + }, + // i=2 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/cmd.go", E: Remove}, + Receiver: Chans{ch[1]}, + }, + // i=3 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/doc.go", E: Write}, + Receiver: nil, + }, + // i=4 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/mktree/main.go", E: Write}, + Receiver: Chans{ch[2]}, + }, + // i=5 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/mktree/tree.go", E: Create}, + Receiver: nil, + }, + // i=6 + { + Event: Call{P: "src/github.com/pblaszczyk/qttu/include/.lock", E: Create}, + Receiver: Chans{ch[3]}, + }, + // i=7 + { + Event: Call{P: "src/github.com/pblaszczyk/qttu/include/qttu/detail/registry.hh", E: Write}, + Receiver: Chans{ch[3], ch[1], ch[4]}, + }, + // i=8 + { + Event: Call{P: "src/github.com/pblaszczyk/qttu/include/qttu", E: Remove}, + Receiver: nil, + }, + // i=9 + { + Event: Call{P: "src/github.com/pblaszczyk/qttu/include", E: Remove}, + Receiver: Chans{ch[3]}, + }, + } + + n.ExpectTreeEvents(events[:], ch) + + stops := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncStop, + C: ch[4], + }, + Record: nil, + }, + // i=1 + { + Call: Call{ + F: FuncStop, + C: ch[3], + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu", + E: Create | Write | Remove, + NE: Create | Write, + }, + }, + }, + // i=2 + { + Call: Call{ + F: FuncStop, + C: ch[2], + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd", + E: Create | Remove | Rename, + NE: Create | Remove, + }, + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree", + E: Create | Remove | Rename, + NE: Create | Remove, + }, + { + F: FuncRewatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree", + E: Create | Remove | Rename | Write, + NE: Create | Remove, + }, + }, + }, + // i=3 + { + Call: Call{ + F: FuncStop, + C: ch[1], + }, + Record: []Call{ + { + F: FuncUnwatch, + P: "src/github.com/pblaszczyk", + }, + { + F: FuncUnwatch, + P: "src/github.com/pblaszczyk/qttu", + }, + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include", + E: Create | Rename | Write, + NE: Create | Rename, + }, + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu", + E: Create | Rename | Write, + NE: Create | Rename, + }, + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu/detail", + E: Create | Rename | Write, + NE: Create | Rename, + }, + { + F: FuncUnwatch, + P: "src/github.com/pblaszczyk/qttu/src", + }, + { + F: FuncUnwatch, + P: "src/github.com/rjeczalik/fs/cmd", + }, + { + F: FuncUnwatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree", + }, + { + F: FuncUnwatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree", + }, + }, + }, + // i=4 + { + Call: Call{ + F: FuncStop, + C: ch[0], + }, + Record: []Call{ + { + F: FuncUnwatch, + P: "src/github.com/pblaszczyk/qttu/include", + }, + { + F: FuncUnwatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu", + }, + { + F: FuncUnwatch, + P: "src/github.com/pblaszczyk/qttu/include/qttu/detail", + }, + { + F: FuncUnwatch, + P: "src/github.com/rjeczalik/fs/fs.go", + }, + }, + }, + } + + n.ExpectRecordedCalls(stops[:]) + + n.Walk(func(nd node) error { + if len(nd.Watch) != 0 { + return fmt.Errorf("unexpected watchpoint: name=%s, eventset=%v (len=%d)", + nd.Name, nd.Watch.Total(), len(nd.Watch)) + } + return nil + }) +} + +func TestNonrecursiveTreeInternal(t *testing.T) { + n, c := NewNonrecursiveTreeTestC(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(5) + + watches := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/...", + C: ch[0], + E: Remove, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd", + E: Create | Remove, + }, + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree", + E: Create | Remove, + }, + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/mktree", + E: Create | Remove, + }, + }, + }, + // i=1 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/link/include/coost/...", + C: ch[1], + E: Create, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/ppknap/link/include/coost", + E: Create, + }, + { + F: FuncWatch, + P: "src/github.com/ppknap/link/include/coost/link", + E: Create, + }, + { + F: FuncWatch, + P: "src/github.com/ppknap/link/include/coost/link/detail", + E: Create, + }, + { + F: FuncWatch, + P: "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers", + E: Create, + }, + }, + }, + } + + n.ExpectRecordedCalls(watches[:]) + + events := [...]TCase{ + // i=0 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/dir", E: Create, Dir: true}, + Receiver: Chans{c}, + }, + // i=1 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/dir/another", E: Create, Dir: true}, + Receiver: Chans{c}, + }, + // i=2 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/file", E: Create, Dir: false}, + Receiver: nil, + }, + // i=3 + { + Event: Call{P: "src/github.com/ppknap/link/include/coost/dir", E: Create, Dir: true}, + Receiver: Chans{ch[1], c}, + }, + // i=4 + { + Event: Call{P: "src/github.com/ppknap/link/include/coost/dir/another", E: Create, Dir: true}, + Receiver: Chans{ch[1], c}, + }, + // i=5 + { + Event: Call{P: "src/github.com/ppknap/link/include/coost/file", E: Create, Dir: false}, + Receiver: Chans{ch[1]}, + }, + // i=6 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/mktree", E: Remove}, + Receiver: Chans{ch[0]}, + }, + // i=7 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/rmtree", E: Create, Dir: true}, + Receiver: Chans{c}, + }, + } + + n.ExpectTreeEvents(events[:], ch) +} diff --git a/vendor/github.com/rjeczalik/notify/tree_recursive.go b/vendor/github.com/rjeczalik/notify/tree_recursive.go new file mode 100644 index 00000000..7f00dfe3 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/tree_recursive.go @@ -0,0 +1,354 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import "sync" + +// watchAdd TODO(rjeczalik) +func watchAdd(nd node, c chan<- EventInfo, e Event) eventDiff { + diff := nd.Watch.Add(c, e) + if wp := nd.Child[""].Watch; len(wp) != 0 { + e = wp.Total() + diff[0] |= e + diff[1] |= e + if diff[0] == diff[1] { + return none + } + } + return diff +} + +// watchAddInactive TODO(rjeczalik) +func watchAddInactive(nd node, c chan<- EventInfo, e Event) eventDiff { + wp := nd.Child[""].Watch + if wp == nil { + wp = make(watchpoint) + nd.Child[""] = node{Watch: wp} + } + diff := wp.Add(c, e) + e = nd.Watch.Total() + diff[0] |= e + diff[1] |= e + if diff[0] == diff[1] { + return none + } + return diff +} + +// watchCopy TODO(rjeczalik) +func watchCopy(src, dst node) { + for c, e := range src.Watch { + if c == nil { + continue + } + watchAddInactive(dst, c, e) + } + if wpsrc := src.Child[""].Watch; len(wpsrc) != 0 { + wpdst := dst.Child[""].Watch + for c, e := range wpsrc { + if c == nil { + continue + } + wpdst.Add(c, e) + } + } +} + +// watchDel TODO(rjeczalik) +func watchDel(nd node, c chan<- EventInfo, e Event) eventDiff { + diff := nd.Watch.Del(c, e) + if wp := nd.Child[""].Watch; len(wp) != 0 { + diffInactive := wp.Del(c, e) + e = wp.Total() + // TODO(rjeczalik): add e if e != all? + diff[0] |= diffInactive[0] | e + diff[1] |= diffInactive[1] | e + if diff[0] == diff[1] { + return none + } + } + return diff +} + +// watchTotal TODO(rjeczalik) +func watchTotal(nd node) Event { + e := nd.Watch.Total() + if wp := nd.Child[""].Watch; len(wp) != 0 { + e |= wp.Total() + } + return e +} + +// watchIsRecursive TODO(rjeczalik) +func watchIsRecursive(nd node) bool { + ok := nd.Watch.IsRecursive() + // TODO(rjeczalik): add a test for len(wp) != 0 change the condition. + if wp := nd.Child[""].Watch; len(wp) != 0 { + // If a watchpoint holds inactive watchpoints, it means it's a parent + // one, which is recursive by nature even though it may be not recursive + // itself. + ok = true + } + return ok +} + +// recursiveTree TODO(rjeczalik) +type recursiveTree struct { + rw sync.RWMutex // protects root + root root + // TODO(rjeczalik): merge watcher + recursiveWatcher after #5 and #6 + w interface { + watcher + recursiveWatcher + } + c chan EventInfo +} + +// newRecursiveTree TODO(rjeczalik) +func newRecursiveTree(w recursiveWatcher, c chan EventInfo) *recursiveTree { + t := &recursiveTree{ + root: root{nd: newnode("")}, + w: struct { + watcher + recursiveWatcher + }{w.(watcher), w}, + c: c, + } + go t.dispatch() + return t +} + +// dispatch TODO(rjeczalik) +func (t *recursiveTree) dispatch() { + for ei := range t.c { + dbgprintf("dispatching %v on %q", ei.Event(), ei.Path()) + go func(ei EventInfo) { + nd, ok := node{}, false + dir, base := split(ei.Path()) + fn := func(it node, isbase bool) error { + if isbase { + nd = it + } else { + it.Watch.Dispatch(ei, recursive) + } + return nil + } + t.rw.RLock() + defer t.rw.RUnlock() + // Notify recursive watchpoints found on the path. + if err := t.root.WalkPath(dir, fn); err != nil { + dbgprint("dispatch did not reach leaf:", err) + return + } + // Notify parent watchpoint. + nd.Watch.Dispatch(ei, 0) + // If leaf watchpoint exists, notify it. + if nd, ok = nd.Child[base]; ok { + nd.Watch.Dispatch(ei, 0) + } + }(ei) + } +} + +// Watch TODO(rjeczalik) +func (t *recursiveTree) Watch(path string, c chan<- EventInfo, events ...Event) error { + if c == nil { + panic("notify: Watch using nil channel") + } + // Expanding with empty event set is a nop. + if len(events) == 0 { + return nil + } + path, isrec, err := cleanpath(path) + if err != nil { + return err + } + eventset := joinevents(events) + if isrec { + eventset |= recursive + } + t.rw.Lock() + defer t.rw.Unlock() + // case 1: cur is a child + // + // Look for parent watch which already covers the given path. + parent := node{} + self := false + err = t.root.WalkPath(path, func(nd node, isbase bool) error { + if watchTotal(nd) != 0 { + parent = nd + self = isbase + return errSkip + } + return nil + }) + cur := t.root.Add(path) // add after the walk, so it's less to traverse + if err == nil && parent.Watch != nil { + // Parent watch found. Register inactive watchpoint, so we have enough + // information to shrink the eventset on eventual Stop. + // return t.resetwatchpoint(parent, parent, c, eventset|inactive) + var diff eventDiff + if self { + diff = watchAdd(cur, c, eventset) + } else { + diff = watchAddInactive(parent, c, eventset) + } + switch { + case diff == none: + // the parent watchpoint already covers requested subtree with its + // eventset + case diff[0] == 0: + // TODO(rjeczalik): cleanup this panic after implementation is stable + panic("dangling watchpoint: " + parent.Name) + default: + if isrec || watchIsRecursive(parent) { + err = t.w.RecursiveRewatch(parent.Name, parent.Name, diff[0], diff[1]) + } else { + err = t.w.Rewatch(parent.Name, diff[0], diff[1]) + } + if err != nil { + watchDel(parent, c, diff.Event()) + return err + } + watchAdd(cur, c, eventset) + // TODO(rjeczalik): account top-most path for c + return nil + } + if !self { + watchAdd(cur, c, eventset) + } + return nil + } + // case 2: cur is new parent + // + // Look for children nodes, unwatch n-1 of them and rewatch the last one. + var children []node + fn := func(nd node) error { + if len(nd.Watch) == 0 { + return nil + } + children = append(children, nd) + return errSkip + } + switch must(cur.Walk(fn)); len(children) { + case 0: + // no child watches, cur holds a new watch + case 1: + watchAdd(cur, c, eventset) // TODO(rjeczalik): update cache c subtree root? + watchCopy(children[0], cur) + err = t.w.RecursiveRewatch(children[0].Name, cur.Name, watchTotal(children[0]), + watchTotal(cur)) + if err != nil { + // Clean inactive watchpoint. The c chan did not exist before. + cur.Child[""] = node{} + delete(cur.Watch, c) + return err + } + return nil + default: + watchAdd(cur, c, eventset) + // Copy children inactive watchpoints to the new parent. + for _, nd := range children { + watchCopy(nd, cur) + } + // Watch parent subtree. + if err = t.w.RecursiveWatch(cur.Name, watchTotal(cur)); err != nil { + // Clean inactive watchpoint. The c chan did not exist before. + cur.Child[""] = node{} + delete(cur.Watch, c) + return err + } + // Unwatch children subtrees. + var e error + for _, nd := range children { + if watchIsRecursive(nd) { + e = t.w.RecursiveUnwatch(nd.Name) + } else { + e = t.w.Unwatch(nd.Name) + } + if e != nil { + err = nonil(err, e) + // TODO(rjeczalik): child is still watched, warn all its watchpoints + // about possible duplicate events via Error event + } + } + return err + } + // case 3: cur is new, alone node + switch diff := watchAdd(cur, c, eventset); { + case diff == none: + // TODO(rjeczalik): cleanup this panic after implementation is stable + panic("watch requested but no parent watchpoint found: " + cur.Name) + case diff[0] == 0: + if isrec { + err = t.w.RecursiveWatch(cur.Name, diff[1]) + } else { + err = t.w.Watch(cur.Name, diff[1]) + } + if err != nil { + watchDel(cur, c, diff.Event()) + return err + } + default: + // TODO(rjeczalik): cleanup this panic after implementation is stable + panic("watch requested but no parent watchpoint found: " + cur.Name) + } + return nil +} + +// Stop TODO(rjeczalik) +// +// TODO(rjeczalik): Split parent watchpoint - transfer watches to children +// if parent is no longer needed. This carries a risk that underlying +// watcher calls could fail - reconsider if it's worth the effort. +func (t *recursiveTree) Stop(c chan<- EventInfo) { + var err error + fn := func(nd node) (e error) { + diff := watchDel(nd, c, all) + switch { + case diff == none && watchTotal(nd) == 0: + // TODO(rjeczalik): There's no watchpoints deeper in the tree, + // probably we should remove the nodes as well. + return nil + case diff == none: + // Removing c from nd does not require shrinking its eventset. + case diff[1] == 0: + if watchIsRecursive(nd) { + e = t.w.RecursiveUnwatch(nd.Name) + } else { + e = t.w.Unwatch(nd.Name) + } + default: + if watchIsRecursive(nd) { + e = t.w.RecursiveRewatch(nd.Name, nd.Name, diff[0], diff[1]) + } else { + e = t.w.Rewatch(nd.Name, diff[0], diff[1]) + } + } + fn := func(nd node) error { + watchDel(nd, c, all) + return nil + } + err = nonil(err, e, nd.Walk(fn)) + // TODO(rjeczalik): if e != nil store dummy chan in nd.Watch just to + // retry un/rewatching next time and/or let the user handle the failure + // vie Error event? + return errSkip + } + t.rw.Lock() + e := t.root.Walk("", fn) // TODO(rjeczalik): use max root per c + t.rw.Unlock() + if e != nil { + err = nonil(err, e) + } + dbgprintf("Stop(%p) error: %v\n", c, err) +} + +// Close TODO(rjeczalik) +func (t *recursiveTree) Close() error { + err := t.w.Close() + close(t.c) + return err +} diff --git a/vendor/github.com/rjeczalik/notify/tree_recursive_test.go b/vendor/github.com/rjeczalik/notify/tree_recursive_test.go new file mode 100644 index 00000000..329fca06 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/tree_recursive_test.go @@ -0,0 +1,524 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import "testing" + +func TestRecursiveTree(t *testing.T) { + n := NewRecursiveTreeTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(5) + + watches := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/fs.go", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/fs.go", + E: Create, + }, + }, + }, + // i=1 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/...", + C: ch[1], + E: Remove, + }, + Record: []Call{ + { + F: FuncRecursiveWatch, + P: "src/github.com/rjeczalik/fs/cmd", + E: Remove, + }, + }, + }, + // i=2 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs", + C: ch[2], + E: Rename, + }, + Record: []Call{ + { + F: FuncRecursiveWatch, + P: "src/github.com/rjeczalik/fs", + E: Create | Remove | Rename, + }, + { + F: FuncRecursiveUnwatch, + P: "src/github.com/rjeczalik/fs/cmd", + }, + { + F: FuncUnwatch, + P: "src/github.com/rjeczalik/fs/fs.go", + }, + }, + }, + // i=3 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/link/README.md", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/ppknap/link/README.md", + E: Create, + }, + }, + }, + // i=4 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/link/include/...", + C: ch[3], + E: Remove, + }, + Record: []Call{ + { + F: FuncRecursiveWatch, + P: "src/github.com/ppknap/link/include", + E: Remove, + }, + }, + }, + // i=5 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/link/include", + C: ch[0], + E: Write, + }, + Record: []Call{ + { + F: FuncRecursiveRewatch, + P: "src/github.com/ppknap/link/include", + NP: "src/github.com/ppknap/link/include", + E: Remove, + NE: Remove | Write, + }, + }, + }, + // i=6 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/link/test/Jamfile.jam", + C: ch[0], + E: Rename, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/ppknap/link/test/Jamfile.jam", + E: Rename, + }, + }, + }, + // i=7 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/link/test/Jamfile.jam", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/ppknap/link/test/Jamfile.jam", + E: Rename, + NE: Rename | Create, + }, + }, + }, + // i=8 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/ppknap/...", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncRecursiveWatch, + P: "src/github.com/ppknap", + E: Create | Remove | Write | Rename, + }, + { + F: FuncUnwatch, + P: "src/github.com/ppknap/link/README.md", + }, + { + F: FuncRecursiveUnwatch, + P: "src/github.com/ppknap/link/include", + }, + { + F: FuncUnwatch, + P: "src/github.com/ppknap/link/test/Jamfile.jam", + }, + }, + }, + // i=9 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/README.md", + C: ch[0], + E: Rename, + }, + Record: nil, + }, + // i=10 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree", + C: ch[2], + E: Create | Remove, + }, + Record: nil, + }, + // i=11 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/src/main.cc", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/src/main.cc", + E: Create, + }, + }, + }, + // i=12 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/src/main.cc", + C: ch[0], + E: Remove, + }, + Record: []Call{ + { + F: FuncRewatch, + P: "src/github.com/pblaszczyk/qttu/src/main.cc", + E: Create, + NE: Create | Remove, + }, + }, + }, + // i=13 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/src/main.cc", + C: ch[0], + E: Create | Remove, + }, + Record: nil, + }, + // i=14 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu/src", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncRecursiveRewatch, + P: "src/github.com/pblaszczyk/qttu/src/main.cc", + NP: "src/github.com/pblaszczyk/qttu/src", + E: Create | Remove, + NE: Create | Remove, + }, + }, + }, + // i=15 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/pblaszczyk/qttu", + C: ch[4], + E: Write, + }, + Record: []Call{ + { + F: FuncRecursiveRewatch, + P: "src/github.com/pblaszczyk/qttu/src", + NP: "src/github.com/pblaszczyk/qttu", + E: Create | Remove, + NE: Create | Remove | Write, + }, + }, + }, + // i=16 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/fs.go", + C: ch[3], + E: Rename, + }, + Record: nil, + }, + } + + n.ExpectRecordedCalls(watches[:]) + + events := [...]TCase{ + // i=0 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go", E: Rename}, + Receiver: Chans{ch[2], ch[3]}, + }, + // i=1 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go", E: Create}, + Receiver: Chans{ch[0]}, + }, + // i=2 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go/file", E: Create}, + Receiver: Chans{ch[0]}, + }, + // i=3 + { + Event: Call{P: "src/github.com/rjeczalik/fs", E: Rename}, + Receiver: Chans{ch[2]}, + }, + // i=4 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs_test.go", E: Rename}, + Receiver: Chans{ch[2]}, + }, + // i=5 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/mktree/main.go", E: Remove}, + Receiver: Chans{ch[1]}, + }, + // i=6 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/gotree", E: Remove}, + Receiver: Chans{ch[1], ch[2]}, + }, + // i=7 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd", E: Remove}, + Receiver: Chans{ch[1]}, + }, + // i=8 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go/file", E: Write}, + Receiver: nil, + }, + // i=9 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go/file", E: Write}, + Receiver: nil, + }, + // i=10 + { + Event: Call{P: "src/github.com/rjeczalik/fs", E: Remove}, + Receiver: nil, + }, + // i=11 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd", E: Rename}, + Receiver: Chans{ch[2]}, + }, + // i=12 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/mktree/main.go", E: Write}, + Receiver: nil, + }, + // i=13 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/gotree", E: Rename}, + Receiver: nil, + }, + // i=14 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/file", E: Rename}, + Receiver: nil, + }, + // i=15 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go", E: Rename}, + Receiver: Chans{ch[2], ch[3]}, + }, + } + + n.ExpectTreeEvents(events[:], ch) + + stops := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncStop, + C: ch[1], + }, + Record: nil, + }, + { + Call: Call{ + F: FuncStop, + C: ch[4], + }, + Record: []Call{ + { + F: FuncRecursiveRewatch, + P: "src/github.com/pblaszczyk/qttu", + NP: "src/github.com/pblaszczyk/qttu", + E: Create | Remove | Write, + NE: Create | Remove, + }, + }, + }, + } + + n.ExpectRecordedCalls(stops[:]) +} + +func TestRecursiveTreeWatchInactiveMerge(t *testing.T) { + n := NewRecursiveTreeTest(t, "testdata/vfs.txt") + defer n.Close() + + ch := NewChans(1) + + watches := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs", + C: ch[0], + E: Create, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs", + E: Create, + }, + }, + }, + // i=1 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs/cmd/gotree/...", + C: ch[0], + E: Remove, + }, + Record: []Call{ + { + F: FuncRecursiveRewatch, + P: "src/github.com/rjeczalik/fs", + NP: "src/github.com/rjeczalik/fs", + E: Create, + NE: Create | Remove, + }, + }, + }, + } + + n.ExpectRecordedCalls(watches[:]) + + events := [...]TCase{ + // i=0 + { + Event: Call{P: "src/github.com/rjeczalik/fs/.fs.go.swp", E: Create}, + Receiver: Chans{ch[0]}, + }, + // i=1 + { + Event: Call{P: "src/github.com/rjeczalik/fs/.fs.go.swp", E: Remove}, + Receiver: nil, + }, + // i=2 + { + Event: Call{P: "src/github.com/rjeczalik/fs", E: Remove}, + Receiver: nil, + }, + // i=3 + { + Event: Call{P: "src/github.com/rjeczalik/fs/cmd/gotree/main.go", E: Remove}, + Receiver: Chans{ch[0]}, + }, + } + + n.ExpectTreeEvents(events[:], ch) +} + +func TestRecursiveTree_Windows(t *testing.T) { + n := NewRecursiveTreeTest(t, "testdata/vfs.txt") + defer n.Close() + + const ChangeFileName = Event(0x1) + + ch := NewChans(1) + + watches := [...]RCase{ + // i=0 + { + Call: Call{ + F: FuncWatch, + P: "src/github.com/rjeczalik/fs", + C: ch[0], + E: ChangeFileName, + }, + Record: []Call{ + { + F: FuncWatch, + P: "src/github.com/rjeczalik/fs", + E: ChangeFileName, + }, + }, + }, + } + + n.ExpectRecordedCalls(watches[:]) + + events := [...]TCase{ + // i=0 + { + Event: Call{P: "src/github.com/rjeczalik/fs", E: ChangeFileName}, + Receiver: Chans{ch[0]}, + }, + // i=1 + { + Event: Call{P: "src/github.com/rjeczalik/fs/fs.go", E: ChangeFileName}, + Receiver: Chans{ch[0]}, + }, + } + + n.ExpectTreeEvents(events[:], ch) +} diff --git a/vendor/github.com/rjeczalik/notify/util.go b/vendor/github.com/rjeczalik/notify/util.go new file mode 100644 index 00000000..67e01fbb --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/util.go @@ -0,0 +1,150 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "errors" + "os" + "path/filepath" + "strings" +) + +const all = ^Event(0) +const sep = string(os.PathSeparator) + +var errDepth = errors.New("exceeded allowed iteration count (circular symlink?)") + +func min(i, j int) int { + if i > j { + return j + } + return i +} + +func max(i, j int) int { + if i < j { + return j + } + return i +} + +// must panics if err is non-nil. +func must(err error) { + if err != nil { + panic(err) + } +} + +// nonil gives first non-nil error from the given arguments. +func nonil(err ...error) error { + for _, err := range err { + if err != nil { + return err + } + } + return nil +} + +func cleanpath(path string) (realpath string, isrec bool, err error) { + if strings.HasSuffix(path, "...") { + isrec = true + path = path[:len(path)-3] + } + if path, err = filepath.Abs(path); err != nil { + return "", false, err + } + if path, err = canonical(path); err != nil { + return "", false, err + } + return path, isrec, nil +} + +// canonical resolves any symlink in the given path and returns it in a clean form. +// It expects the path to be absolute. It fails to resolve circular symlinks by +// maintaining a simple iteration limit. +func canonical(p string) (string, error) { + p, err := filepath.Abs(p) + if err != nil { + return "", err + } + for i, j, depth := 1, 0, 1; i < len(p); i, depth = i+1, depth+1 { + if depth > 128 { + return "", &os.PathError{Op: "canonical", Path: p, Err: errDepth} + } + if j = strings.IndexRune(p[i:], '/'); j == -1 { + j, i = i, len(p) + } else { + j, i = i, i+j + } + fi, err := os.Lstat(p[:i]) + if err != nil { + return "", err + } + if fi.Mode()&os.ModeSymlink == os.ModeSymlink { + s, err := os.Readlink(p[:i]) + if err != nil { + return "", err + } + if filepath.IsAbs(s) { + p = "/" + s + p[i:] + } else { + p = p[:j] + s + p[i:] + } + i = 1 // no guarantee s is canonical, start all over + } + } + return filepath.Clean(p), nil +} + +func joinevents(events []Event) (e Event) { + if len(events) == 0 { + e = All + } else { + for _, event := range events { + e |= event + } + } + return +} + +func split(s string) (string, string) { + if i := lastIndexSep(s); i != -1 { + return s[:i], s[i+1:] + } + return "", s +} + +func base(s string) string { + if i := lastIndexSep(s); i != -1 { + return s[i+1:] + } + return s +} + +func indexbase(root, name string) int { + if n, m := len(root), len(name); m >= n && name[:n] == root && + (n == m || name[n] == os.PathSeparator) { + return min(n+1, m) + } + return -1 +} + +func indexSep(s string) int { + for i := 0; i < len(s); i++ { + if s[i] == os.PathSeparator { + return i + } + } + return -1 +} + +func lastIndexSep(s string) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == os.PathSeparator { + return i + } + } + return -1 +} diff --git a/vendor/github.com/rjeczalik/notify/util_darwin_test.go b/vendor/github.com/rjeczalik/notify/util_darwin_test.go new file mode 100644 index 00000000..8c95db37 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/util_darwin_test.go @@ -0,0 +1,41 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin + +package notify + +import ( + "os" + "testing" +) + +func TestCanonicalDarwin(t *testing.T) { + cases := [...]caseCanonical{ + {"/etc", "/private/etc"}, + {"/etc/defaults", "/private/etc/defaults"}, + {"/etc/hosts", "/private/etc/hosts"}, + {"/tmp", "/private/tmp"}, + {"/var", "/private/var"}, + } + testCanonical(t, cases[:]) +} + +func TestCanonicalDarwinMultiple(t *testing.T) { + etcsym, err := symlink("/etc", "") + if err != nil { + t.Fatal(err) + } + tmpsym, err := symlink("/tmp", "") + if err != nil { + t.Fatal(nonil(err, os.Remove(etcsym))) + } + defer removeall(etcsym, tmpsym) + cases := [...]caseCanonical{ + {etcsym, "/private/etc"}, + {etcsym + "/hosts", "/private/etc/hosts"}, + {tmpsym, "/private/tmp"}, + } + testCanonical(t, cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/util_test.go b/vendor/github.com/rjeczalik/notify/util_test.go new file mode 100644 index 00000000..dcf6616e --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/util_test.go @@ -0,0 +1,142 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "path/filepath" + "testing" +) + +type caseCanonical struct { + path string + full string +} + +func testCanonical(t *testing.T, cases []caseCanonical) { + for i, cas := range cases { + full, err := canonical(cas.path) + if err != nil { + t.Errorf("want err=nil; got %v (i=%d)", err, i) + continue + } + if full != cas.full { + t.Errorf("want full=%q; got %q (i=%d)", cas.full, full, i) + continue + } + } +} + +func TestCanonicalNoSymlink(t *testing.T) { + td := filepath.Join(wd, "testdata") + cases := [...]caseCanonical{ + {".", wd}, + {"testdata", td}, + {filepath.Join("testdata", ".."), wd}, + } + testCanonical(t, cases[:]) +} + +func TestJoinevents(t *testing.T) { + cases := [...]struct { + evs []Event + ev Event + }{ + 0: {nil, All}, + 1: {[]Event{}, All}, + 2: {[]Event{Create}, Create}, + 3: {[]Event{Rename}, Rename}, + 4: {[]Event{Create, Write, Remove}, Create | Write | Remove}, + } + for i, cas := range cases { + if ev := joinevents(cas.evs); ev != cas.ev { + t.Errorf("want event=%v; got %v (i=%d)", cas.ev, ev, i) + } + } +} + +func TestTreeSplit(t *testing.T) { + cases := [...]struct { + path string + dir string + base string + }{ + {"/github.com/rjeczalik/fakerpc", "/github.com/rjeczalik", "fakerpc"}, + {"/home/rjeczalik/src", "/home/rjeczalik", "src"}, + {"/Users/pknap/porn/gopher.avi", "/Users/pknap/porn", "gopher.avi"}, + {"C:/Documents and Users", "C:", "Documents and Users"}, + {"C:/Documents and Users/pblaszczyk/wiertarka.exe", "C:/Documents and Users/pblaszczyk", "wiertarka.exe"}, + {"/home/(╯°□°)╯︵ ┻━┻", "/home", "(╯°□°)╯︵ ┻━┻"}, + } + for i, cas := range cases { + dir, base := split(filepath.FromSlash(cas.path)) + if want := filepath.FromSlash(cas.dir); dir != want { + t.Errorf("want dir=%s; got %s (i=%d)", want, dir, i) + } + if want := filepath.FromSlash(cas.base); base != want { + t.Errorf("want base=%s; got %s (i=%d)", want, base, i) + } + } +} + +func TestTreeBase(t *testing.T) { + cases := [...]struct { + path string + base string + }{ + {"/github.com/rjeczalik/fakerpc", "fakerpc"}, + {"/home/rjeczalik/src", "src"}, + {"/Users/pknap/porn/gopher.avi", "gopher.avi"}, + {"C:/Documents and Users", "Documents and Users"}, + {"C:/Documents and Users/pblaszczyk/wiertarka.exe", "wiertarka.exe"}, + {"/home/(╯°□°)╯︵ ┻━┻", "(╯°□°)╯︵ ┻━┻"}, + } + for i, cas := range cases { + if base := base(filepath.FromSlash(cas.path)); base != cas.base { + t.Errorf("want base=%s; got %s (i=%d)", cas.base, base, i) + } + } +} + +func TestTreeIndexSep(t *testing.T) { + cases := [...]struct { + path string + n int + }{ + {"github.com/rjeczalik/fakerpc", 10}, + {"home/rjeczalik/src", 4}, + {"Users/pknap/porn/gopher.avi", 5}, + {"C:/Documents and Users", 2}, + {"Documents and Users/pblaszczyk/wiertarka.exe", 19}, + {"(╯°□°)╯︵ ┻━┻/Downloads", 30}, + } + for i, cas := range cases { + if n := indexSep(filepath.FromSlash(cas.path)); n != cas.n { + t.Errorf("want n=%d; got %d (i=%d)", cas.n, n, i) + } + } +} + +func TestTreeLastIndexSep(t *testing.T) { + cases := [...]struct { + path string + n int + }{ + {"github.com/rjeczalik/fakerpc", 20}, + {"home/rjeczalik/src", 14}, + {"Users/pknap/porn/gopher.avi", 16}, + {"C:/Documents and Users", 2}, + {"Documents and Users/pblaszczyk/wiertarka.exe", 30}, + {"/home/(╯°□°)╯︵ ┻━┻", 5}, + } + for i, cas := range cases { + if n := lastIndexSep(filepath.FromSlash(cas.path)); n != cas.n { + t.Errorf("want n=%d; got %d (i=%d)", cas.n, n, i) + } + } +} + +func TestCleanpath(t *testing.T) { + t.Skip("TODO(rjeczalik)") +} diff --git a/vendor/github.com/rjeczalik/notify/util_unix_test.go b/vendor/github.com/rjeczalik/notify/util_unix_test.go new file mode 100644 index 00000000..b944db2a --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/util_unix_test.go @@ -0,0 +1,125 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build !windows + +package notify + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func tmpfile(s string) (string, error) { + f, err := ioutil.TempFile(filepath.Split(s)) + if err != nil { + return "", err + } + if err = nonil(f.Sync(), f.Close()); err != nil { + return "", err + } + return f.Name(), nil +} + +func symlink(src, dst string) (string, error) { + name, err := tmpfile(dst) + if err != nil { + return "", err + } + if err = nonil(os.Remove(name), os.Symlink(src, name)); err != nil { + return "", err + } + return name, nil +} + +func removeall(s ...string) { + for _, s := range s { + os.Remove(s) + } +} + +func TestCanonical(t *testing.T) { + wd, err := os.Getwd() + if err != nil { + t.Fatalf("os.Getwd()=%v", err) + } + wdsym, err := symlink(wd, "") + if err != nil { + t.Fatalf(`symlink(%q, "")=%v`, wd, err) + } + td := filepath.Join(wd, "testdata") + tdsym, err := symlink(td, td) + if err != nil { + t.Errorf("symlink(%q, %q)=%v", td, td, nonil(err, os.Remove(wdsym))) + } + defer removeall(wdsym, tdsym) + vfstxt := filepath.Join(td, "vfs.txt") + cases := [...]caseCanonical{ + {wdsym, wd}, + {tdsym, td}, + {filepath.Join(wdsym, "notify.go"), filepath.Join(wd, "notify.go")}, + {filepath.Join(tdsym, "vfs.txt"), vfstxt}, + {filepath.Join(wdsym, filepath.Base(tdsym), "vfs.txt"), vfstxt}, + } + testCanonical(t, cases[:]) +} + +func TestCanonicalCircular(t *testing.T) { + tmp1, err := tmpfile("circular") + if err != nil { + t.Fatal(err) + } + tmp2, err := tmpfile("circular") + if err != nil { + t.Fatal(nonil(err, os.Remove(tmp1))) + } + defer removeall(tmp1, tmp2) + // Symlink tmp1 -> tmp2. + if err = nonil(os.Remove(tmp1), os.Symlink(tmp2, tmp1)); err != nil { + t.Fatal(err) + } + // Symlnik tmp2 -> tmp1. + if err = nonil(os.Remove(tmp2), os.Symlink(tmp1, tmp2)); err != nil { + t.Fatal(err) + } + if _, err = canonical(tmp1); err == nil { + t.Fatalf("want canonical(%q)!=nil", tmp1) + } + if _, ok := err.(*os.PathError); !ok { + t.Fatalf("want canonical(%q)=os.PathError; got %T", tmp1, err) + } +} + +// issue #83 +func TestCanonical_RelativeSymlink(t *testing.T) { + dir, err := ioutil.TempDir(wd, "") + if err != nil { + t.Fatalf("TempDir()=%v", err) + } + var ( + path = filepath.Join(dir, filepath.FromSlash("a/b/c/d/e/f")) + realpath = filepath.Join(dir, filepath.FromSlash("a/b/x/y/z/d/e/f")) + rel = filepath.FromSlash("x/y/z/../z/../z") + chdir = filepath.Join(dir, filepath.FromSlash("a/b")) + ) + defer os.RemoveAll(dir) + if err = os.MkdirAll(realpath, 0755); err != nil { + t.Fatalf("MkdirAll()=%v", err) + } + if err := os.Chdir(chdir); err != nil { + t.Fatalf("Chdir()=%v", err) + } + if err := nonil(os.Symlink(rel, "c"), os.Chdir(wd)); err != nil { + t.Fatalf("Symlink()=%v", err) + } + got, err := canonical(path) + if err != nil { + t.Fatalf("canonical(%s)=%v", path, err) + } + if got != realpath { + t.Fatalf("want canonical()=%s; got %s", realpath, got) + } +} diff --git a/vendor/github.com/rjeczalik/notify/watcher.go b/vendor/github.com/rjeczalik/notify/watcher.go new file mode 100644 index 00000000..34148eff --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher.go @@ -0,0 +1,85 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import "errors" + +var ( + errAlreadyWatched = errors.New("path is already watched") + errNotWatched = errors.New("path is not being watched") + errInvalidEventSet = errors.New("invalid event set provided") +) + +// Watcher is a intermediate interface for wrapping inotify, ReadDirChangesW, +// FSEvents, kqueue and poller implementations. +// +// The watcher implementation is expected to do its own mapping between paths and +// create watchers if underlying event notification does not support it. For +// the ease of implementation it is guaranteed that paths provided via Watch and +// Unwatch methods are absolute and clean. +type watcher interface { + // Watch requests a watcher creation for the given path and given event set. + Watch(path string, event Event) error + + // Unwatch requests a watcher deletion for the given path and given event set. + Unwatch(path string) error + + // Rewatch provides a functionality for modifying existing watch-points, like + // expanding its event set. + // + // Rewatch modifies existing watch-point under for the given path. It passes + // the existing event set currently registered for the given path, and the + // new, requested event set. + // + // It is guaranteed that Tree will not pass to Rewatch zero value for any + // of its arguments. If old == new and watcher can be upgraded to + // recursiveWatcher interface, a watch for the corresponding path is expected + // to be changed from recursive to the non-recursive one. + Rewatch(path string, old, new Event) error + + // Close unwatches all paths that are registered. When Close returns, it + // is expected it will report no more events. + Close() error +} + +// RecursiveWatcher is an interface for a Watcher for those OS, which do support +// recursive watching over directories. +type recursiveWatcher interface { + RecursiveWatch(path string, event Event) error + + // RecursiveUnwatch removes a recursive watch-point given by the path. For + // native recursive implementation there is no difference in functionality + // between Unwatch and RecursiveUnwatch, however for those platforms, that + // requires emulation for recursive watch-points, the implementation differs. + RecursiveUnwatch(path string) error + + // RecursiveRewatcher provides a functionality for modifying and/or relocating + // existing recursive watch-points. + // + // To relocate a watch-point means to unwatch oldpath and set a watch-point on + // newpath. + // + // To modify a watch-point means either to expand or shrink its event set. + // + // Tree can want to either relocate, modify or relocate and modify a watch-point + // via single RecursiveRewatch call. + // + // If oldpath == newpath, the watch-point is expected to change its event set value + // from oldevent to newevent. + // + // If oldevent == newevent, the watch-point is expected to relocate from oldpath + // to the newpath. + // + // If oldpath != newpath and oldevent != newevent, the watch-point is expected + // to relocate from oldpath to the newpath first and then change its event set + // value from oldevent to the newevent. In other words the end result must be + // a watch-point set on newpath with newevent value of its event set. + // + // It is guaranteed that Tree will not pass to RecurisveRewatcha zero value + // for any of its arguments. If oldpath == newpath and oldevent == newevent, + // a watch for the corresponding path is expected to be changed for + // non-recursive to the recursive one. + RecursiveRewatch(oldpath, newpath string, oldevent, newevent Event) error +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_fen.go b/vendor/github.com/rjeczalik/notify/watcher_fen.go new file mode 100644 index 00000000..dfe77f2f --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_fen.go @@ -0,0 +1,161 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build solaris + +package notify + +import ( + "fmt" + "os" + "syscall" +) + +// newTrigger returns implementation of trigger. +func newTrigger(pthLkp map[string]*watched) trigger { + return &fen{ + pthLkp: pthLkp, + cf: newCfen(), + } +} + +// fen is a structure implementing trigger for FEN. +type fen struct { + // p is a FEN port identifier + p int + // pthLkp is a structure mapping monitored files/dir with data about them, + // shared with parent trg structure + pthLkp map[string]*watched + // cf wraps C operations for FEN + cf cfen +} + +// watched is a data structure representing watched file/directory. +type watched struct { + trgWatched +} + +// Stop implements trigger. +func (f *fen) Stop() error { + return f.cf.portAlert(f.p) +} + +// Close implements trigger. +func (f *fen) Close() (err error) { + return syscall.Close(f.p) +} + +// NewWatched implements trigger. +func (*fen) NewWatched(p string, fi os.FileInfo) (*watched, error) { + return &watched{trgWatched{p: p, fi: fi}}, nil +} + +// Record implements trigger. +func (f *fen) Record(w *watched) { + f.pthLkp[w.p] = w +} + +// Del implements trigger. +func (f *fen) Del(w *watched) { + delete(f.pthLkp, w.p) +} + +func inter2pe(n interface{}) PortEvent { + pe, ok := n.(PortEvent) + if !ok { + panic(fmt.Sprintf("fen: type should be PortEvent, %T instead", n)) + } + return pe +} + +// Watched implements trigger. +func (f *fen) Watched(n interface{}) (*watched, int64, error) { + pe := inter2pe(n) + fo, ok := pe.PortevObject.(*FileObj) + if !ok || fo == nil { + panic(fmt.Sprintf("fen: type should be *FileObj, %T instead", fo)) + } + w, ok := f.pthLkp[fo.Name] + if !ok { + return nil, 0, errNotWatched + } + return w, int64(pe.PortevEvents), nil +} + +// init initializes FEN. +func (f *fen) Init() (err error) { + f.p, err = f.cf.portCreate() + return +} + +func fi2fo(fi os.FileInfo, p string) FileObj { + st, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + panic(fmt.Sprintf("fen: type should be *syscall.Stat_t, %T instead", st)) + } + return FileObj{Name: p, Atim: st.Atim, Mtim: st.Mtim, Ctim: st.Ctim} +} + +// Unwatch implements trigger. +func (f *fen) Unwatch(w *watched) error { + return f.cf.portDissociate(f.p, FileObj{Name: w.p}) +} + +// Watch implements trigger. +func (f *fen) Watch(fi os.FileInfo, w *watched, e int64) error { + return f.cf.portAssociate(f.p, fi2fo(fi, w.p), int(e)) +} + +// Wait implements trigger. +func (f *fen) Wait() (interface{}, error) { + var ( + pe PortEvent + err error + ) + err = f.cf.portGet(f.p, &pe) + return pe, err +} + +// IsStop implements trigger. +func (f *fen) IsStop(n interface{}, err error) bool { + return err == syscall.EBADF || inter2pe(n).PortevSource == srcAlert +} + +func init() { + encode = func(e Event, dir bool) (o int64) { + // Create event is not supported by FEN. Instead FileModified event will + // be registered. If this event will be reported on dir which is to be + // monitored for Create, dir will be rescanned and Create events will + // be generated and returned for new files. In case of files, + // if not requested FileModified event is reported, it will be ignored. + o = int64(e &^ Create) + if (e&Create != 0 && dir) || e&Write != 0 { + o = (o &^ int64(Write)) | int64(FileModified) + } + // Following events are 'exception events' and as such cannot be requested + // explicitly for monitoring or filtered out. If the will be reported + // by FEN and not subscribed with by user, they will be filtered out by + // watcher's logic. + o &= int64(^Rename & ^Remove &^ FileDelete &^ FileRenameTo &^ + FileRenameFrom &^ Unmounted &^ MountedOver) + return + } + nat2not = map[Event]Event{ + FileModified: Write, + FileRenameFrom: Rename, + FileDelete: Remove, + FileAccess: Event(0), + FileAttrib: Event(0), + FileRenameTo: Event(0), + FileTrunc: Event(0), + FileNoFollow: Event(0), + Unmounted: Event(0), + MountedOver: Event(0), + } + not2nat = map[Event]Event{ + Write: FileModified, + Rename: FileRenameFrom, + Remove: FileDelete, + } +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_fen_cgo.go b/vendor/github.com/rjeczalik/notify/watcher_fen_cgo.go new file mode 100644 index 00000000..8ec8ead3 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_fen_cgo.go @@ -0,0 +1,141 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build solaris + +package notify + +// #include +// #include +// #include +// struct file_obj* newFo() { return (struct file_obj*) malloc(sizeof(struct file_obj)); } +// port_event_t* newPe() { return (port_event_t*) malloc(sizeof(port_event_t)); } +// uintptr_t conv(struct file_obj* fo) { return (uintptr_t) fo; } +// struct file_obj* dconv(uintptr_t fo) { return (struct file_obj*) fo; } +import "C" + +import ( + "syscall" + "unsafe" +) + +const ( + fileAccess = Event(C.FILE_ACCESS) + fileModified = Event(C.FILE_MODIFIED) + fileAttrib = Event(C.FILE_ATTRIB) + fileDelete = Event(C.FILE_DELETE) + fileRenameTo = Event(C.FILE_RENAME_TO) + fileRenameFrom = Event(C.FILE_RENAME_FROM) + fileTrunc = Event(C.FILE_TRUNC) + fileNoFollow = Event(C.FILE_NOFOLLOW) + unmounted = Event(C.UNMOUNTED) + mountedOver = Event(C.MOUNTEDOVER) +) + +// PortEvent is a notify's equivalent of port_event_t. +type PortEvent struct { + PortevEvents int // PortevEvents is an equivalent of portev_events. + PortevSource uint8 // PortevSource is an equivalent of portev_source. + PortevPad uint8 // Portevpad is an equivalent of portev_pad. + PortevObject interface{} // PortevObject is an equivalent of portev_object. + PortevUser uintptr // PortevUser is an equivalent of portev_user. +} + +// FileObj is a notify's equivalent of file_obj. +type FileObj struct { + Atim syscall.Timespec // Atim is an equivalent of fo_atime. + Mtim syscall.Timespec // Mtim is an equivalent of fo_mtime. + Ctim syscall.Timespec // Ctim is an equivalent of fo_ctime. + Pad [3]uintptr // Pad is an equivalent of fo_pad. + Name string // Name is an equivalent of fo_name. +} + +type cfen struct { + p2pe map[string]*C.port_event_t + p2fo map[string]*C.struct_file_obj +} + +func newCfen() cfen { + return cfen{ + p2pe: make(map[string]*C.port_event_t), + p2fo: make(map[string]*C.struct_file_obj), + } +} + +func unix2C(sec int64, nsec int64) (C.time_t, C.long) { + return C.time_t(sec), C.long(nsec) +} + +func (c *cfen) portAssociate(p int, fo FileObj, e int) (err error) { + cfo := C.newFo() + cfo.fo_atime.tv_sec, cfo.fo_atime.tv_nsec = unix2C(fo.Atim.Unix()) + cfo.fo_mtime.tv_sec, cfo.fo_mtime.tv_nsec = unix2C(fo.Mtim.Unix()) + cfo.fo_ctime.tv_sec, cfo.fo_ctime.tv_nsec = unix2C(fo.Ctim.Unix()) + cfo.fo_name = C.CString(fo.Name) + c.p2fo[fo.Name] = cfo + _, err = C.port_associate(C.int(p), srcFile, C.conv(cfo), C.int(e), nil) + return +} + +func (c *cfen) portDissociate(port int, fo FileObj) (err error) { + cfo, ok := c.p2fo[fo.Name] + if !ok { + return errNotWatched + } + _, err = C.port_dissociate(C.int(port), srcFile, C.conv(cfo)) + C.free(unsafe.Pointer(cfo.fo_name)) + C.free(unsafe.Pointer(cfo)) + delete(c.p2fo, fo.Name) + return +} + +const srcAlert = C.PORT_SOURCE_ALERT +const srcFile = C.PORT_SOURCE_FILE +const alertSet = C.PORT_ALERT_SET + +func cfo2fo(cfo *C.struct_file_obj) *FileObj { + // Currently remaining attributes are not used. + if cfo == nil { + return nil + } + var fo FileObj + fo.Name = C.GoString(cfo.fo_name) + return &fo +} + +func (c *cfen) portGet(port int, pe *PortEvent) (err error) { + cpe := C.newPe() + if _, err = C.port_get(C.int(port), cpe, nil); err != nil { + C.free(unsafe.Pointer(cpe)) + return + } + pe.PortevEvents, pe.PortevSource, pe.PortevPad = + int(cpe.portev_events), uint8(cpe.portev_source), uint8(cpe.portev_pad) + pe.PortevObject = cfo2fo(C.dconv(cpe.portev_object)) + pe.PortevUser = uintptr(cpe.portev_user) + C.free(unsafe.Pointer(cpe)) + return +} + +func (c *cfen) portCreate() (int, error) { + p, err := C.port_create() + return int(p), err +} + +func (c *cfen) portAlert(p int) (err error) { + _, err = C.port_alert(C.int(p), alertSet, C.int(666), nil) + return +} + +func (c *cfen) free() { + for i := range c.p2fo { + C.free(unsafe.Pointer(c.p2fo[i].fo_name)) + C.free(unsafe.Pointer(c.p2fo[i])) + } + for i := range c.p2pe { + C.free(unsafe.Pointer(c.p2pe[i])) + } + c.p2fo = make(map[string]*C.struct_file_obj) + c.p2pe = make(map[string]*C.port_event_t) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_fen_test.go b/vendor/github.com/rjeczalik/notify/watcher_fen_test.go new file mode 100644 index 00000000..7f811ae2 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_fen_test.go @@ -0,0 +1,92 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build solaris + +package notify + +import ( + "os" + "path/filepath" + "testing" +) + +func fremove(w *W, path string, files []string) WCase { + cas := remove(w, path) + cas.Events[0] = &Call{P: path, E: FileDelete} + for _, f := range files { + cas.Events = append(cas.Events, &Call{P: f, E: FileDelete}) + } + return cas +} + +func fwrite(w *W, path string, p []byte) WCase { + cas := write(w, path, p) + path = cas.Events[0].Path() + cas.Events[0] = &Call{P: path, E: FileModified} + return cas +} + +func frename(w *W, path string, files []string) WCase { + const ext = ".notify" + cas := WCase{ + Action: func() { + file := filepath.Join(w.root, path) + if err := os.Rename(file, file+ext); err != nil { + w.Fatalf("Rename(%q, %q)=%v", path, path+ext, err) + } + }, + Events: []EventInfo{ + &Call{P: path + ext, E: osSpecificCreate}, + &Call{P: path, E: FileRenameFrom}, + }, + } + for _, f := range files { + cas.Events = append(cas.Events, &Call{P: f, E: FileRenameFrom}) + } + return cas +} + +var events = []Event{ + FileModified, + FileAttrib, + FileRenameFrom, + osSpecificCreate, + FileDelete, +} + +func TestWatcherFen(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt", events...) + defer w.Close() + + cases := [...]WCase{ + fremove(w, "src/github.com/ppknap/link/include/coost/link", []string{ + "src/github.com/ppknap/link/include/coost/link/definitions.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/bundle.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/container_invoker.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/container_value_trait.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/dummy_type.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/function_trait.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/immediate_invoker.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers/always_same.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers/make_unique.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers", + "src/github.com/ppknap/link/include/coost/link/detail/vertex.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/wire.hpp", + "src/github.com/ppknap/link/include/coost/link/detail", + "src/github.com/ppknap/link/include/coost/link/link.hpp", + }, + ), + fwrite(w, "src/github.com/rjeczalik/fs/fs.go", []byte("XD")), + fremove(w, "src/github.com/ppknap/link/README.md", nil), + frename(w, "src/github.com/rjeczalik/fs/fs.go", nil), + frename(w, "src/github.com/rjeczalik/fs/cmd/gotree", []string{ + "src/github.com/rjeczalik/fs/cmd/gotree/go.go", + "src/github.com/rjeczalik/fs/cmd/gotree/main.go", + }, + ), + } + + w.ExpectAll(cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents.go new file mode 100644 index 00000000..7d9b97b6 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents.go @@ -0,0 +1,311 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,!kqueue + +package notify + +import ( + "errors" + "strings" + "sync/atomic" +) + +const ( + failure = uint32(FSEventsMustScanSubDirs | FSEventsUserDropped | FSEventsKernelDropped) + filter = uint32(FSEventsCreated | FSEventsRemoved | FSEventsRenamed | + FSEventsModified | FSEventsInodeMetaMod) +) + +// FSEvent represents single file event. It is created out of values passed by +// FSEvents to FSEventStreamCallback function. +type FSEvent struct { + Path string // real path of the file or directory + ID uint64 // ID of the event (FSEventStreamEventId) + Flags uint32 // joint FSEvents* flags (FSEventStreamEventFlags) +} + +// splitflags separates event flags from single set into slice of flags. +func splitflags(set uint32) (e []uint32) { + for i := uint32(1); set != 0; i, set = i<<1, set>>1 { + if (set & 1) != 0 { + e = append(e, i) + } + } + return +} + +// watch represents a filesystem watchpoint. It is a higher level abstraction +// over FSEvents' stream, which implements filtering of file events based +// on path and event set. It emulates non-recursive watch-point by filtering out +// events which paths are more than 1 level deeper than the watched path. +type watch struct { + // prev stores last event set per path in order to filter out old flags + // for new events, which appratenly FSEvents likes to retain. It's a disgusting + // hack, it should be researched how to get rid of it. + prev map[string]uint32 + c chan<- EventInfo + stream *stream + path string + events uint32 + isrec int32 + flushed bool +} + +// Example format: +// +// ~ $ (trigger command) # (event set) -> (effective event set) +// +// Heuristics: +// +// 1. Create event is removed when it was present in previous event set. +// Example: +// +// ~ $ echo > file # Create|Write -> Create|Write +// ~ $ echo > file # Create|Write|InodeMetaMod -> Write|InodeMetaMod +// +// 2. Remove event is removed if it was present in previouse event set. +// Example: +// +// ~ $ touch file # Create -> Create +// ~ $ rm file # Create|Remove -> Remove +// ~ $ touch file # Create|Remove -> Create +// +// 3. Write event is removed if not followed by InodeMetaMod on existing +// file. Example: +// +// ~ $ echo > file # Create|Write -> Create|Write +// ~ $ chmod +x file # Create|Write|ChangeOwner -> ChangeOwner +// +// 4. Write&InodeMetaMod is removed when effective event set contain Remove event. +// Example: +// +// ~ $ echo > file # Write|InodeMetaMod -> Write|InodeMetaMod +// ~ $ rm file # Remove|Write|InodeMetaMod -> Remove +// +func (w *watch) strip(base string, set uint32) uint32 { + const ( + write = FSEventsModified | FSEventsInodeMetaMod + both = FSEventsCreated | FSEventsRemoved + ) + switch w.prev[base] { + case FSEventsCreated: + set &^= FSEventsCreated + if set&FSEventsRemoved != 0 { + w.prev[base] = FSEventsRemoved + set &^= write + } + case FSEventsRemoved: + set &^= FSEventsRemoved + if set&FSEventsCreated != 0 { + w.prev[base] = FSEventsCreated + } + default: + switch set & both { + case FSEventsCreated: + w.prev[base] = FSEventsCreated + case FSEventsRemoved: + w.prev[base] = FSEventsRemoved + set &^= write + } + } + dbgprintf("split()=%v\n", Event(set)) + return set +} + +// Dispatch is a stream function which forwards given file events for the watched +// path to underlying FileInfo channel. +func (w *watch) Dispatch(ev []FSEvent) { + events := atomic.LoadUint32(&w.events) + isrec := (atomic.LoadInt32(&w.isrec) == 1) + for i := range ev { + if ev[i].Flags&FSEventsHistoryDone != 0 { + w.flushed = true + continue + } + if !w.flushed { + continue + } + dbgprintf("%v (0x%x) (%s, i=%d, ID=%d, len=%d)\n", Event(ev[i].Flags), + ev[i].Flags, ev[i].Path, i, ev[i].ID, len(ev)) + if ev[i].Flags&failure != 0 { + // TODO(rjeczalik): missing error handling + continue + } + if !strings.HasPrefix(ev[i].Path, w.path) { + continue + } + n := len(w.path) + base := "" + if len(ev[i].Path) > n { + if ev[i].Path[n] != '/' { + continue + } + base = ev[i].Path[n+1:] + if !isrec && strings.IndexByte(base, '/') != -1 { + continue + } + } + // TODO(rjeczalik): get diff only from filtered events? + e := w.strip(string(base), ev[i].Flags) & events + if e == 0 { + continue + } + for _, e := range splitflags(e) { + dbgprintf("%d: single event: %v", ev[i].ID, Event(e)) + w.c <- &event{ + fse: ev[i], + event: Event(e), + } + } + } +} + +// Stop closes underlying FSEvents stream and stops dispatching events. +func (w *watch) Stop() { + w.stream.Stop() + // TODO(rjeczalik): make (*stream).Stop flush synchronously undelivered events, + // so the following hack can be removed. It should flush all the streams + // concurrently as we care not to block too much here. + atomic.StoreUint32(&w.events, 0) + atomic.StoreInt32(&w.isrec, 0) +} + +// fsevents implements Watcher and RecursiveWatcher interfaces backed by FSEvents +// framework. +type fsevents struct { + watches map[string]*watch + c chan<- EventInfo +} + +func newWatcher(c chan<- EventInfo) watcher { + return &fsevents{ + watches: make(map[string]*watch), + c: c, + } +} + +func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) { + if _, ok := fse.watches[path]; ok { + return errAlreadyWatched + } + w := &watch{ + prev: make(map[string]uint32), + c: fse.c, + path: path, + events: uint32(event), + isrec: isrec, + } + w.stream = newStream(path, w.Dispatch) + if err = w.stream.Start(); err != nil { + return err + } + fse.watches[path] = w + return nil +} + +func (fse *fsevents) unwatch(path string) (err error) { + w, ok := fse.watches[path] + if !ok { + return errNotWatched + } + w.stream.Stop() + delete(fse.watches, path) + return nil +} + +// Watch implements Watcher interface. It fails with non-nil error when setting +// the watch-point by FSEvents fails or with errAlreadyWatched error when +// the given path is already watched. +func (fse *fsevents) Watch(path string, event Event) error { + return fse.watch(path, event, 0) +} + +// Unwatch implements Watcher interface. It fails with errNotWatched when +// the given path is not being watched. +func (fse *fsevents) Unwatch(path string) error { + return fse.unwatch(path) +} + +// Rewatch implements Watcher interface. It fails with errNotWatched when +// the given path is not being watched or with errInvalidEventSet when oldevent +// does not match event set the watch-point currently holds. +func (fse *fsevents) Rewatch(path string, oldevent, newevent Event) error { + w, ok := fse.watches[path] + if !ok { + return errNotWatched + } + if !atomic.CompareAndSwapUint32(&w.events, uint32(oldevent), uint32(newevent)) { + return errInvalidEventSet + } + atomic.StoreInt32(&w.isrec, 0) + return nil +} + +// RecursiveWatch implements RecursiveWatcher interface. It fails with non-nil +// error when setting the watch-point by FSEvents fails or with errAlreadyWatched +// error when the given path is already watched. +func (fse *fsevents) RecursiveWatch(path string, event Event) error { + return fse.watch(path, event, 1) +} + +// RecursiveUnwatch implements RecursiveWatcher interface. It fails with +// errNotWatched when the given path is not being watched. +// +// TODO(rjeczalik): fail if w.isrec == 0? +func (fse *fsevents) RecursiveUnwatch(path string) error { + return fse.unwatch(path) +} + +// RecrusiveRewatch implements RecursiveWatcher interface. It fails: +// +// * with errNotWatched when the given path is not being watched +// * with errInvalidEventSet when oldevent does not match the current event set +// * with errAlreadyWatched when watch-point given by the oldpath was meant to +// be relocated to newpath, but the newpath is already watched +// * a non-nil error when setting the watch-point with FSEvents fails +// +// TODO(rjeczalik): Improve handling of watch-point relocation? See two TODOs +// that follows. +func (fse *fsevents) RecursiveRewatch(oldpath, newpath string, oldevent, newevent Event) error { + switch [2]bool{oldpath == newpath, oldevent == newevent} { + case [2]bool{true, true}: + w, ok := fse.watches[oldpath] + if !ok { + return errNotWatched + } + atomic.StoreInt32(&w.isrec, 1) + return nil + case [2]bool{true, false}: + w, ok := fse.watches[oldpath] + if !ok { + return errNotWatched + } + if !atomic.CompareAndSwapUint32(&w.events, uint32(oldevent), uint32(newevent)) { + return errors.New("invalid event state diff") + } + atomic.StoreInt32(&w.isrec, 1) + return nil + default: + // TODO(rjeczalik): rewatch newpath only if exists? + // TODO(rjeczalik): migrate w.prev to new watch? + if _, ok := fse.watches[newpath]; ok { + return errAlreadyWatched + } + if err := fse.Unwatch(oldpath); err != nil { + return err + } + // TODO(rjeczalik): revert unwatch if watch fails? + return fse.watch(newpath, newevent, 1) + } +} + +// Close unwatches all watch-points. +func (fse *fsevents) Close() error { + for _, w := range fse.watches { + w.Stop() + } + fse.watches = nil + return nil +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go new file mode 100644 index 00000000..17f7a9ee --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go @@ -0,0 +1,197 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,!kqueue + +package notify + +/* +#include + +typedef void (*CFRunLoopPerformCallBack)(void*); + +void gosource(void *); +void gostream(uintptr_t, uintptr_t, size_t, uintptr_t, uintptr_t, uintptr_t); + +static FSEventStreamRef EventStreamCreate(FSEventStreamContext * context, uintptr_t info, CFArrayRef paths, FSEventStreamEventId since, CFTimeInterval latency, FSEventStreamCreateFlags flags) { + context->info = (void*) info; + return FSEventStreamCreate(NULL, (FSEventStreamCallback) gostream, context, paths, since, latency, flags); +} + +#cgo LDFLAGS: -framework CoreServices +*/ +import "C" + +import ( + "errors" + "os" + "runtime" + "sync" + "sync/atomic" + "unsafe" +) + +var nilstream C.FSEventStreamRef + +// Default arguments for FSEventStreamCreate function. +var ( + latency C.CFTimeInterval + flags = C.FSEventStreamCreateFlags(C.kFSEventStreamCreateFlagFileEvents | C.kFSEventStreamCreateFlagNoDefer) + since = uint64(C.FSEventsGetCurrentEventId()) +) + +var runloop C.CFRunLoopRef // global runloop which all streams are registered with +var wg sync.WaitGroup // used to wait until the runloop starts + +// source is used for synchronization purposes - it signals when runloop has +// started and is ready via the wg. It also serves purpose of a dummy source, +// thanks to it the runloop does not return as it also has at least one source +// registered. +var source = C.CFRunLoopSourceCreate(nil, 0, &C.CFRunLoopSourceContext{ + perform: (C.CFRunLoopPerformCallBack)(C.gosource), +}) + +// Errors returned when FSEvents functions fail. +var ( + errCreate = os.NewSyscallError("FSEventStreamCreate", errors.New("NULL")) + errStart = os.NewSyscallError("FSEventStreamStart", errors.New("false")) +) + +// initializes the global runloop and ensures any created stream awaits its +// readiness. +func init() { + wg.Add(1) + go func() { + // There is exactly one run loop per thread. Lock this goroutine to its + // thread to ensure that it's not rescheduled on a different thread while + // setting up the run loop. + runtime.LockOSThread() + runloop = C.CFRunLoopGetCurrent() + C.CFRunLoopAddSource(runloop, source, C.kCFRunLoopDefaultMode) + C.CFRunLoopRun() + panic("runloop has just unexpectedly stopped") + }() + C.CFRunLoopSourceSignal(source) +} + +//export gosource +func gosource(unsafe.Pointer) { + wg.Done() +} + +//export gostream +func gostream(_, info uintptr, n C.size_t, paths, flags, ids uintptr) { + const ( + offchar = unsafe.Sizeof((*C.char)(nil)) + offflag = unsafe.Sizeof(C.FSEventStreamEventFlags(0)) + offid = unsafe.Sizeof(C.FSEventStreamEventId(0)) + ) + if n == 0 { + return + } + fn := streamFuncs.get(info) + if fn == nil { + return + } + ev := make([]FSEvent, 0, int(n)) + for i := uintptr(0); i < uintptr(n); i++ { + switch flags := *(*uint32)(unsafe.Pointer((flags + i*offflag))); { + case flags&uint32(FSEventsEventIdsWrapped) != 0: + atomic.StoreUint64(&since, uint64(C.FSEventsGetCurrentEventId())) + default: + ev = append(ev, FSEvent{ + Path: C.GoString(*(**C.char)(unsafe.Pointer(paths + i*offchar))), + Flags: flags, + ID: *(*uint64)(unsafe.Pointer(ids + i*offid)), + }) + } + + } + fn(ev) +} + +// StreamFunc is a callback called when stream receives file events. +type streamFunc func([]FSEvent) + +var streamFuncs = streamFuncRegistry{m: map[uintptr]streamFunc{}} + +type streamFuncRegistry struct { + mu sync.Mutex + m map[uintptr]streamFunc + i uintptr +} + +func (r *streamFuncRegistry) get(id uintptr) streamFunc { + r.mu.Lock() + defer r.mu.Unlock() + return r.m[id] +} + +func (r *streamFuncRegistry) add(fn streamFunc) uintptr { + r.mu.Lock() + defer r.mu.Unlock() + r.i++ + r.m[r.i] = fn + return r.i +} + +func (r *streamFuncRegistry) delete(id uintptr) { + r.mu.Lock() + defer r.mu.Unlock() + delete(r.m, id) +} + +// Stream represents single watch-point which listens for events scheduled by +// the global runloop. +type stream struct { + path string + ref C.FSEventStreamRef + info uintptr +} + +// NewStream creates a stream for given path, listening for file events and +// calling fn upon receiving any. +func newStream(path string, fn streamFunc) *stream { + return &stream{ + path: path, + info: streamFuncs.add(fn), + } +} + +// Start creates a FSEventStream for the given path and schedules it with +// global runloop. It's a nop if the stream was already started. +func (s *stream) Start() error { + if s.ref != nilstream { + return nil + } + wg.Wait() + p := C.CFStringCreateWithCStringNoCopy(nil, C.CString(s.path), C.kCFStringEncodingUTF8, nil) + path := C.CFArrayCreate(nil, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil) + ctx := C.FSEventStreamContext{} + ref := C.EventStreamCreate(&ctx, C.uintptr_t(s.info), path, C.FSEventStreamEventId(atomic.LoadUint64(&since)), latency, flags) + if ref == nilstream { + return errCreate + } + C.FSEventStreamScheduleWithRunLoop(ref, runloop, C.kCFRunLoopDefaultMode) + if C.FSEventStreamStart(ref) == C.Boolean(0) { + C.FSEventStreamInvalidate(ref) + return errStart + } + C.CFRunLoopWakeUp(runloop) + s.ref = ref + return nil +} + +// Stop stops underlying FSEventStream and unregisters it from global runloop. +func (s *stream) Stop() { + if s.ref == nilstream { + return + } + wg.Wait() + C.FSEventStreamStop(s.ref) + C.FSEventStreamInvalidate(s.ref) + C.CFRunLoopWakeUp(runloop) + s.ref = nilstream + streamFuncs.delete(s.info) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_test.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_test.go new file mode 100644 index 00000000..1d608778 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_test.go @@ -0,0 +1,111 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,!kqueue + +package notify + +import ( + "reflect" + "testing" +) + +func TestSplitflags(t *testing.T) { + cases := [...]struct { + set uint32 + flags []uint32 + }{ + {0, nil}, + {0xD, []uint32{0x1, 0x4, 0x8}}, + {0x0010 | 0x0040 | 0x0080 | 0x01000, []uint32{0x0010, 0x0040, 0x0080, 0x01000}}, + {0x40000 | 0x00100 | 0x00200, []uint32{0x00100, 0x00200, 0x40000}}, + } + for i, cas := range cases { + if flags := splitflags(cas.set); !reflect.DeepEqual(flags, cas.flags) { + t.Errorf("want flags=%v; got %v (i=%d)", cas.flags, flags, i) + } + } +} + +func TestWatchStrip(t *testing.T) { + const ( + create = uint32(FSEventsCreated) + remove = uint32(FSEventsRemoved) + rename = uint32(FSEventsRenamed) + write = uint32(FSEventsModified) + inode = uint32(FSEventsInodeMetaMod) + owner = uint32(FSEventsChangeOwner) + ) + cases := [...][]struct { + path string + flag uint32 + diff uint32 + }{ + // 1. + { + {"file", create | write, create | write}, + {"file", create | write | inode, write | inode}, + }, + // 2. + { + {"file", create, create}, + {"file", create | remove, remove}, + {"file", create | remove, create}, + }, + // 3. + { + {"file", create | write, create | write}, + {"file", create | write | owner, write | owner}, + }, + // 4. + { + {"file", create | write, create | write}, + {"file", write | inode, write | inode}, + {"file", remove | write | inode, remove}, + }, + { + {"file", remove | write | inode, remove}, + }, + } +Test: + for i, cas := range cases { + if len(cas) == 0 { + t.Log("skipped") + continue + } + w := &watch{prev: make(map[string]uint32)} + for j, cas := range cas { + if diff := w.strip(cas.path, cas.flag); diff != cas.diff { + t.Errorf("want diff=%v; got %v (i=%d, j=%d)", Event(cas.diff), + Event(diff), i, j) + continue Test + } + } + } +} + +// Test for cases 3) and 5) with shadowed write&create events. +// +// See comment for (flagdiff).diff method. +func TestWatcherShadowedWriteCreate(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt") + defer w.Close() + + cases := [...]WCase{ + // i=0 + create(w, "src/github.com/rjeczalik/fs/.fs.go.swp"), + // i=1 + write(w, "src/github.com/rjeczalik/fs/.fs.go.swp", []byte("XD")), + // i=2 + write(w, "src/github.com/rjeczalik/fs/.fs.go.swp", []byte("XD")), + // i=3 + remove(w, "src/github.com/rjeczalik/fs/.fs.go.swp"), + // i=4 + create(w, "src/github.com/rjeczalik/fs/.fs.go.swp"), + // i=5 + write(w, "src/github.com/rjeczalik/fs/.fs.go.swp", []byte("XD")), + } + + w.ExpectAny(cases[:5]) // BUG(rjeczalik): #62 +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_inotify.go b/vendor/github.com/rjeczalik/notify/watcher_inotify.go new file mode 100644 index 00000000..d082baca --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_inotify.go @@ -0,0 +1,405 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build linux + +package notify + +import ( + "bytes" + "errors" + "path/filepath" + "runtime" + "sync" + "sync/atomic" + "unsafe" + + "golang.org/x/sys/unix" +) + +// eventBufferSize defines the size of the buffer given to read(2) function. One +// should not depend on this value, since it was arbitrary chosen and may be +// changed in the future. +const eventBufferSize = 64 * (unix.SizeofInotifyEvent + unix.PathMax + 1) + +// consumersCount defines the number of consumers in producer-consumer based +// implementation. Each consumer is run in a separate goroutine and has read +// access to watched files map. +const consumersCount = 2 + +const invalidDescriptor = -1 + +// watched is a pair of file path and inotify mask used as a value in +// watched files map. +type watched struct { + path string + mask uint32 +} + +// inotify implements Watcher interface. +type inotify struct { + sync.RWMutex // protects inotify.m map + m map[int32]*watched // watch descriptor to watched object + fd int32 // inotify file descriptor + pipefd []int // pipe's read and write descriptors + epfd int // epoll descriptor + epes []unix.EpollEvent // epoll events + buffer [eventBufferSize]byte // inotify event buffer + wg sync.WaitGroup // wait group used to close main loop + c chan<- EventInfo // event dispatcher channel +} + +// NewWatcher creates new non-recursive inotify backed by inotify. +func newWatcher(c chan<- EventInfo) watcher { + i := &inotify{ + m: make(map[int32]*watched), + fd: invalidDescriptor, + pipefd: []int{invalidDescriptor, invalidDescriptor}, + epfd: invalidDescriptor, + epes: make([]unix.EpollEvent, 0), + c: c, + } + runtime.SetFinalizer(i, func(i *inotify) { + i.epollclose() + if i.fd != invalidDescriptor { + unix.Close(int(i.fd)) + } + }) + return i +} + +// Watch implements notify.watcher interface. +func (i *inotify) Watch(path string, e Event) error { + return i.watch(path, e) +} + +// Rewatch implements notify.watcher interface. +func (i *inotify) Rewatch(path string, _, newevent Event) error { + return i.watch(path, newevent) +} + +// watch adds a new watcher to the set of watched objects or modifies the existing +// one. If called for the first time, this function initializes inotify filesystem +// monitor and starts producer-consumers goroutines. +func (i *inotify) watch(path string, e Event) (err error) { + if e&^(All|Event(unix.IN_ALL_EVENTS)) != 0 { + return errors.New("notify: unknown event") + } + if err = i.lazyinit(); err != nil { + return + } + iwd, err := unix.InotifyAddWatch(int(i.fd), path, encode(e)) + if err != nil { + return + } + i.RLock() + wd := i.m[int32(iwd)] + i.RUnlock() + if wd == nil { + i.Lock() + if i.m[int32(iwd)] == nil { + i.m[int32(iwd)] = &watched{path: path, mask: uint32(e)} + } + i.Unlock() + } else { + i.Lock() + wd.mask = uint32(e) + i.Unlock() + } + return nil +} + +// lazyinit sets up all required file descriptors and starts 1+consumersCount +// goroutines. The producer goroutine blocks until file-system notifications +// occur. Then, all events are read from system buffer and sent to consumer +// goroutines which construct valid notify events. This method uses +// Double-Checked Locking optimization. +func (i *inotify) lazyinit() error { + if atomic.LoadInt32(&i.fd) == invalidDescriptor { + i.Lock() + defer i.Unlock() + if atomic.LoadInt32(&i.fd) == invalidDescriptor { + fd, err := unix.InotifyInit1(unix.IN_CLOEXEC) + if err != nil { + return err + } + i.fd = int32(fd) + if err = i.epollinit(); err != nil { + _, _ = i.epollclose(), unix.Close(int(fd)) // Ignore errors. + i.fd = invalidDescriptor + return err + } + esch := make(chan []*event) + go i.loop(esch) + i.wg.Add(consumersCount) + for n := 0; n < consumersCount; n++ { + go i.send(esch) + } + } + } + return nil +} + +// epollinit opens an epoll file descriptor and creates a pipe which will be +// used to wake up the epoll_wait(2) function. Then, file descriptor associated +// with inotify event queue and the read end of the pipe are added to epoll set. +// Note that `fd` member must be set before this function is called. +func (i *inotify) epollinit() (err error) { + if i.epfd, err = unix.EpollCreate1(0); err != nil { + return + } + if err = unix.Pipe(i.pipefd); err != nil { + return + } + i.epes = []unix.EpollEvent{ + {Events: unix.EPOLLIN, Fd: i.fd}, + {Events: unix.EPOLLIN, Fd: int32(i.pipefd[0])}, + } + if err = unix.EpollCtl(i.epfd, unix.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil { + return + } + return unix.EpollCtl(i.epfd, unix.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1]) +} + +// epollclose closes the file descriptor created by the call to epoll_create(2) +// and two file descriptors opened by pipe(2) function. +func (i *inotify) epollclose() (err error) { + if i.epfd != invalidDescriptor { + if err = unix.Close(i.epfd); err == nil { + i.epfd = invalidDescriptor + } + } + for n, fd := range i.pipefd { + if fd != invalidDescriptor { + switch e := unix.Close(fd); { + case e != nil && err == nil: + err = e + case e == nil: + i.pipefd[n] = invalidDescriptor + } + } + } + return +} + +// loop blocks until either inotify or pipe file descriptor is ready for I/O. +// All read operations triggered by filesystem notifications are forwarded to +// one of the event's consumers. If pipe fd became ready, loop function closes +// all file descriptors opened by lazyinit method and returns afterwards. +func (i *inotify) loop(esch chan<- []*event) { + epes := make([]unix.EpollEvent, 1) + fd := atomic.LoadInt32(&i.fd) + for { + switch _, err := unix.EpollWait(i.epfd, epes, -1); err { + case nil: + switch epes[0].Fd { + case fd: + esch <- i.read() + epes[0].Fd = 0 + case int32(i.pipefd[0]): + i.Lock() + defer i.Unlock() + if err = unix.Close(int(fd)); err != nil && err != unix.EINTR { + panic("notify: close(2) error " + err.Error()) + } + atomic.StoreInt32(&i.fd, invalidDescriptor) + if err = i.epollclose(); err != nil && err != unix.EINTR { + panic("notify: epollclose error " + err.Error()) + } + close(esch) + return + } + case unix.EINTR: + continue + default: // We should never reach this line. + panic("notify: epoll_wait(2) error " + err.Error()) + } + } +} + +// read reads events from an inotify file descriptor. It does not handle errors +// returned from read(2) function since they are not critical to watcher logic. +func (i *inotify) read() (es []*event) { + n, err := unix.Read(int(i.fd), i.buffer[:]) + if err != nil || n < unix.SizeofInotifyEvent { + return + } + var sys *unix.InotifyEvent + nmin := n - unix.SizeofInotifyEvent + for pos, path := 0, ""; pos <= nmin; { + sys = (*unix.InotifyEvent)(unsafe.Pointer(&i.buffer[pos])) + pos += unix.SizeofInotifyEvent + if path = ""; sys.Len > 0 { + endpos := pos + int(sys.Len) + path = string(bytes.TrimRight(i.buffer[pos:endpos], "\x00")) + pos = endpos + } + es = append(es, &event{ + sys: unix.InotifyEvent{ + Wd: sys.Wd, + Mask: sys.Mask, + Cookie: sys.Cookie, + }, + path: path, + }) + } + return +} + +// send is a consumer function which sends events to event dispatcher channel. +// It is run in a separate goroutine in order to not block loop method when +// possibly expensive write operations are performed on inotify map. +func (i *inotify) send(esch <-chan []*event) { + for es := range esch { + for _, e := range i.transform(es) { + if e != nil { + i.c <- e + } + } + } + i.wg.Done() +} + +// transform prepares events read from inotify file descriptor for sending to +// user. It removes invalid events and these which are no longer present in +// inotify map. This method may also split one raw event into two different ones +// when system-dependent result is required. +func (i *inotify) transform(es []*event) []*event { + var multi []*event + i.RLock() + for idx, e := range es { + if e.sys.Mask&(unix.IN_IGNORED|unix.IN_Q_OVERFLOW) != 0 { + es[idx] = nil + continue + } + wd, ok := i.m[e.sys.Wd] + if !ok || e.sys.Mask&encode(Event(wd.mask)) == 0 { + es[idx] = nil + continue + } + if e.path == "" { + e.path = wd.path + } else { + e.path = filepath.Join(wd.path, e.path) + } + multi = append(multi, decode(Event(wd.mask), e)) + if e.event == 0 { + es[idx] = nil + } + } + i.RUnlock() + es = append(es, multi...) + return es +} + +// encode converts notify system-independent events to valid inotify mask +// which can be passed to inotify_add_watch(2) function. +func encode(e Event) uint32 { + if e&Create != 0 { + e = (e ^ Create) | InCreate | InMovedTo + } + if e&Remove != 0 { + e = (e ^ Remove) | InDelete | InDeleteSelf + } + if e&Write != 0 { + e = (e ^ Write) | InModify + } + if e&Rename != 0 { + e = (e ^ Rename) | InMovedFrom | InMoveSelf + } + return uint32(e) +} + +// decode uses internally stored mask to distinguish whether system-independent +// or system-dependent event is requested. The first one is created by modifying +// `e` argument. decode method sets e.event value to 0 when an event should be +// skipped. System-dependent event is set as the function's return value which +// can be nil when the event should not be passed on. +func decode(mask Event, e *event) (syse *event) { + if sysmask := uint32(mask) & e.sys.Mask; sysmask != 0 { + syse = &event{sys: unix.InotifyEvent{ + Wd: e.sys.Wd, + Mask: e.sys.Mask, + Cookie: e.sys.Cookie, + }, event: Event(sysmask), path: e.path} + } + imask := encode(mask) + switch { + case mask&Create != 0 && imask&uint32(InCreate|InMovedTo)&e.sys.Mask != 0: + e.event = Create + case mask&Remove != 0 && imask&uint32(InDelete|InDeleteSelf)&e.sys.Mask != 0: + e.event = Remove + case mask&Write != 0 && imask&uint32(InModify)&e.sys.Mask != 0: + e.event = Write + case mask&Rename != 0 && imask&uint32(InMovedFrom|InMoveSelf)&e.sys.Mask != 0: + e.event = Rename + default: + e.event = 0 + } + return +} + +// Unwatch implements notify.watcher interface. It looks for watch descriptor +// related to registered path and if found, calls inotify_rm_watch(2) function. +// This method is allowed to return EINVAL error when concurrently requested to +// delete identical path. +func (i *inotify) Unwatch(path string) (err error) { + iwd := int32(invalidDescriptor) + i.RLock() + for iwdkey, wd := range i.m { + if wd.path == path { + iwd = iwdkey + break + } + } + i.RUnlock() + if iwd == invalidDescriptor { + return errors.New("notify: path " + path + " is already watched") + } + fd := atomic.LoadInt32(&i.fd) + if err = removeInotifyWatch(fd, iwd); err != nil { + return + } + i.Lock() + delete(i.m, iwd) + i.Unlock() + return nil +} + +// Close implements notify.watcher interface. It removes all existing watch +// descriptors and wakes up producer goroutine by sending data to the write end +// of the pipe. The function waits for a signal from producer which means that +// all operations on current monitoring instance are done. +func (i *inotify) Close() (err error) { + i.Lock() + if fd := atomic.LoadInt32(&i.fd); fd == invalidDescriptor { + i.Unlock() + return nil + } + for iwd := range i.m { + if e := removeInotifyWatch(i.fd, iwd); e != nil && err == nil { + err = e + } + delete(i.m, iwd) + } + switch _, errwrite := unix.Write(i.pipefd[1], []byte{0x00}); { + case errwrite != nil && err == nil: + err = errwrite + fallthrough + case errwrite != nil: + i.Unlock() + default: + i.Unlock() + i.wg.Wait() + } + return +} + +// if path was removed, notify already removed the watch and returns EINVAL error +func removeInotifyWatch(fd int32, iwd int32) (err error) { + if _, err = unix.InotifyRmWatch(int(fd), uint32(iwd)); err != nil && err != unix.EINVAL { + return + } + return nil +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_inotify_test.go b/vendor/github.com/rjeczalik/notify/watcher_inotify_test.go new file mode 100644 index 00000000..5feadafc --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_inotify_test.go @@ -0,0 +1,132 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build linux + +package notify + +import ( + "os" + "path/filepath" + "testing" +) + +func icreate(w *W, path string) WCase { + cas := create(w, path) + cas.Events = append(cas.Events, + &Call{P: path, E: InCreate}, + ) + return cas +} + +func iremove(w *W, path string) WCase { + cas := remove(w, path) + cas.Events = append(cas.Events, + &Call{P: path, E: InDelete}, + ) + return cas +} + +func iopen(w *W, path string) WCase { + return WCase{ + Action: func() { + f, err := os.OpenFile(filepath.Join(w.root, path), os.O_RDWR, 0644) + if err != nil { + w.Fatalf("OpenFile(%q)=%v", path, err) + } + if err := f.Close(); err != nil { + w.Fatalf("Close(%q)=%v", path, err) + } + }, + Events: []EventInfo{ + &Call{P: path, E: InAccess}, + &Call{P: path, E: InOpen}, + &Call{P: path, E: InCloseNowrite}, + }, + } +} + +func iread(w *W, path string, p []byte) WCase { + return WCase{ + Action: func() { + f, err := os.OpenFile(filepath.Join(w.root, path), os.O_RDWR, 0644) + if err != nil { + w.Fatalf("OpenFile(%q)=%v", path, err) + } + if _, err := f.Read(p); err != nil { + w.Fatalf("Read(%q)=%v", path, err) + } + if err := f.Close(); err != nil { + w.Fatalf("Close(%q)=%v", path, err) + } + }, + Events: []EventInfo{ + &Call{P: path, E: InAccess}, + &Call{P: path, E: InOpen}, + &Call{P: path, E: InModify}, + &Call{P: path, E: InCloseNowrite}, + }, + } +} + +func iwrite(w *W, path string, p []byte) WCase { + cas := write(w, path, p) + path = cas.Events[0].Path() + cas.Events = append(cas.Events, + &Call{P: path, E: InAccess}, + &Call{P: path, E: InOpen}, + &Call{P: path, E: InModify}, + &Call{P: path, E: InCloseWrite}, + ) + return cas +} + +func irename(w *W, path string) WCase { + const ext = ".notify" + return WCase{ + Action: func() { + file := filepath.Join(w.root, path) + if err := os.Rename(file, file+ext); err != nil { + w.Fatalf("Rename(%q, %q)=%v", path, path+ext, err) + } + }, + Events: []EventInfo{ + &Call{P: path, E: InMovedFrom}, + &Call{P: path + ext, E: InMovedTo}, + &Call{P: path, E: InOpen}, + &Call{P: path, E: InAccess}, + &Call{P: path, E: InCreate}, + }, + } +} + +var events = []Event{ + InAccess, + InModify, + InAttrib, + InCloseWrite, + InCloseNowrite, + InOpen, + InMovedFrom, + InMovedTo, + InCreate, + InDelete, + InDeleteSelf, + InMoveSelf, +} + +func TestWatcherInotify(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt", events...) + defer w.Close() + + cases := [...]WCase{ + iopen(w, "src/github.com/rjeczalik/fs/fs.go"), + iwrite(w, "src/github.com/rjeczalik/fs/fs.go", []byte("XD")), + iread(w, "src/github.com/rjeczalik/fs/fs.go", []byte("XD")), + iremove(w, "src/github.com/ppknap/link/README.md"), + irename(w, "src/github.com/rjeczalik/fs/LICENSE"), + } + + w.ExpectAny(cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_kqueue.go b/vendor/github.com/rjeczalik/notify/watcher_kqueue.go new file mode 100644 index 00000000..22e3c2c4 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_kqueue.go @@ -0,0 +1,189 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,kqueue dragonfly freebsd netbsd openbsd + +package notify + +import ( + "fmt" + "os" + "syscall" +) + +// newTrigger returns implementation of trigger. +func newTrigger(pthLkp map[string]*watched) trigger { + return &kq{ + pthLkp: pthLkp, + idLkp: make(map[int]*watched), + } +} + +// kq is a structure implementing trigger for kqueue. +type kq struct { + // fd is a kqueue file descriptor + fd int + // pipefds are file descriptors used to stop `Kevent` call. + pipefds [2]int + // idLkp is a data structure mapping file descriptors with data about watching + // represented by them files/directories. + idLkp map[int]*watched + // pthLkp is a structure mapping monitored files/dir with data about them, + // shared with parent trg structure + pthLkp map[string]*watched +} + +// watched is a data structure representing watched file/directory. +type watched struct { + trgWatched + // fd is a file descriptor for watched file/directory. + fd int +} + +// Stop implements trigger. +func (k *kq) Stop() (err error) { + // trigger event used to interrupt Kevent call. + _, err = syscall.Write(k.pipefds[1], []byte{0x00}) + return +} + +// Close implements trigger. +func (k *kq) Close() error { + return syscall.Close(k.fd) +} + +// NewWatched implements trigger. +func (*kq) NewWatched(p string, fi os.FileInfo) (*watched, error) { + fd, err := syscall.Open(p, syscall.O_NONBLOCK|syscall.O_RDONLY, 0) + if err != nil { + return nil, err + } + return &watched{ + trgWatched: trgWatched{p: p, fi: fi}, + fd: fd, + }, nil +} + +// Record implements trigger. +func (k *kq) Record(w *watched) { + k.idLkp[w.fd], k.pthLkp[w.p] = w, w +} + +// Del implements trigger. +func (k *kq) Del(w *watched) { + syscall.Close(w.fd) + delete(k.idLkp, w.fd) + delete(k.pthLkp, w.p) +} + +func inter2kq(n interface{}) syscall.Kevent_t { + kq, ok := n.(syscall.Kevent_t) + if !ok { + panic(fmt.Sprintf("kqueue: type should be Kevent_t, %T instead", n)) + } + return kq +} + +// Init implements trigger. +func (k *kq) Init() (err error) { + if k.fd, err = syscall.Kqueue(); err != nil { + return + } + // Creates pipe used to stop `Kevent` call by registering it, + // watching read end and writing to other end of it. + if err = syscall.Pipe(k.pipefds[:]); err != nil { + return nonil(err, k.Close()) + } + var kevn [1]syscall.Kevent_t + syscall.SetKevent(&kevn[0], k.pipefds[0], syscall.EVFILT_READ, syscall.EV_ADD) + if _, err = syscall.Kevent(k.fd, kevn[:], nil, nil); err != nil { + return nonil(err, k.Close()) + } + return +} + +// Unwatch implements trigger. +func (k *kq) Unwatch(w *watched) (err error) { + var kevn [1]syscall.Kevent_t + syscall.SetKevent(&kevn[0], w.fd, syscall.EVFILT_VNODE, syscall.EV_DELETE) + + _, err = syscall.Kevent(k.fd, kevn[:], nil, nil) + return +} + +// Watch implements trigger. +func (k *kq) Watch(fi os.FileInfo, w *watched, e int64) (err error) { + var kevn [1]syscall.Kevent_t + syscall.SetKevent(&kevn[0], w.fd, syscall.EVFILT_VNODE, + syscall.EV_ADD|syscall.EV_CLEAR) + kevn[0].Fflags = uint32(e) + + _, err = syscall.Kevent(k.fd, kevn[:], nil, nil) + return +} + +// Wait implements trigger. +func (k *kq) Wait() (interface{}, error) { + var ( + kevn [1]syscall.Kevent_t + err error + ) + kevn[0] = syscall.Kevent_t{} + _, err = syscall.Kevent(k.fd, nil, kevn[:], nil) + + return kevn[0], err +} + +// Watched implements trigger. +func (k *kq) Watched(n interface{}) (*watched, int64, error) { + kevn, ok := n.(syscall.Kevent_t) + if !ok { + panic(fmt.Sprintf("kq: type should be syscall.Kevent_t, %T instead", kevn)) + } + if _, ok = k.idLkp[int(kevn.Ident)]; !ok { + return nil, 0, errNotWatched + } + return k.idLkp[int(kevn.Ident)], int64(kevn.Fflags), nil +} + +// IsStop implements trigger. +func (k *kq) IsStop(n interface{}, err error) bool { + return int(inter2kq(n).Ident) == k.pipefds[0] +} + +func init() { + encode = func(e Event, dir bool) (o int64) { + // Create event is not supported by kqueue. Instead NoteWrite event will + // be registered for a directory. If this event will be reported on dir + // which is to be monitored for Create, dir will be rescanned + // and Create events will be generated and returned for new files. + // In case of files, if not requested NoteRename event is reported, + // it will be ignored. + o = int64(e &^ Create) + if (e&Create != 0 && dir) || e&Write != 0 { + o = (o &^ int64(Write)) | int64(NoteWrite) + } + if e&Rename != 0 { + o = (o &^ int64(Rename)) | int64(NoteRename) + } + if e&Remove != 0 { + o = (o &^ int64(Remove)) | int64(NoteDelete) + } + return + } + nat2not = map[Event]Event{ + NoteWrite: Write, + NoteRename: Rename, + NoteDelete: Remove, + NoteExtend: Event(0), + NoteAttrib: Event(0), + NoteRevoke: Event(0), + NoteLink: Event(0), + } + not2nat = map[Event]Event{ + Write: NoteWrite, + Rename: NoteRename, + Remove: NoteDelete, + } +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_kqueue_test.go b/vendor/github.com/rjeczalik/notify/watcher_kqueue_test.go new file mode 100644 index 00000000..8c07dc10 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_kqueue_test.go @@ -0,0 +1,111 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,kqueue dragonfly freebsd netbsd openbsd + +package notify + +import ( + "os" + "path/filepath" + "testing" +) + +func kqremove(w *W, path string, files []string) WCase { + cas := remove(w, path) + cas.Events[0] = &Call{P: path, E: NoteDelete} + for _, f := range files { + cas.Events = append(cas.Events, &Call{P: f, E: NoteDelete}) + } + return cas +} + +func kqwrite(w *W, path string, p []byte) WCase { + cas := write(w, path, p) + path = cas.Events[0].Path() + cas.Events[0] = &Call{P: path, E: NoteExtend | NoteWrite} + return cas +} + +func kqrename(w *W, path string, files []string) WCase { + const ext = ".notify" + cas := WCase{ + Action: func() { + file := filepath.Join(w.root, path) + if err := os.Rename(file, file+ext); err != nil { + w.Fatalf("Rename(%q, %q)=%v", path, path+ext, err) + } + }, + Events: []EventInfo{ + &Call{P: path + ext, E: osSpecificCreate}, + &Call{P: path, E: NoteRename}, + }, + } + for _, f := range files { + cas.Events = append(cas.Events, &Call{P: f, E: NoteRename}) + } + return cas +} + +func kqlink(w *W, path string) WCase { + const ext = ".notify" + return WCase{ + Action: func() { + file := filepath.Join(w.root, path) + if err := os.Link(file, file+ext); err != nil { + w.Fatalf("Link(%q, %q)=%v", path, path+ext, err) + } + }, + Events: []EventInfo{ + &Call{P: path, E: NoteLink}, + &Call{P: path + ext, E: osSpecificCreate}, + }, + } +} + +var events = []Event{ + NoteWrite, + NoteAttrib, + NoteRename, + osSpecificCreate, + NoteDelete, + NoteExtend, + NoteLink, +} + +func TestWatcherKqueue(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt", events...) + defer w.Close() + + cases := [...]WCase{ + kqremove(w, "src/github.com/ppknap/link/include/coost/link", []string{ + "src/github.com/ppknap/link/include/coost/link/definitions.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/bundle.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/container_invoker.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/container_value_trait.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/dummy_type.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/function_trait.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/immediate_invoker.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers/always_same.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers/make_unique.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/stdhelpers", + "src/github.com/ppknap/link/include/coost/link/detail/vertex.hpp", + "src/github.com/ppknap/link/include/coost/link/detail/wire.hpp", + "src/github.com/ppknap/link/include/coost/link/detail", + "src/github.com/ppknap/link/include/coost/link/link.hpp", + }, + ), + kqwrite(w, "src/github.com/rjeczalik/fs/fs.go", []byte("XD")), + kqremove(w, "src/github.com/ppknap/link/README.md", nil), + kqlink(w, "src/github.com/rjeczalik/fs/LICENSE"), + kqrename(w, "src/github.com/rjeczalik/fs/fs.go", nil), + kqrename(w, "src/github.com/rjeczalik/fs/cmd/gotree", []string{ + "src/github.com/rjeczalik/fs/cmd/gotree/go.go", + "src/github.com/rjeczalik/fs/cmd/gotree/main.go", + }, + ), + } + + w.ExpectAll(cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_notimplemented.go b/vendor/github.com/rjeczalik/notify/watcher_notimplemented.go new file mode 100644 index 00000000..bb0672fd --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_notimplemented.go @@ -0,0 +1,15 @@ +// Copyright (c) 2014-2018 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build !darwin,!linux,!freebsd,!dragonfly,!netbsd,!openbsd,!windows +// +build !kqueue,!solaris + +package notify + +import "errors" + +// newWatcher stub. +func newWatcher(chan<- EventInfo) watcher { + return watcherStub{errors.New("notify: not implemented")} +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go new file mode 100644 index 00000000..b69811a6 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go @@ -0,0 +1,605 @@ +// Copyright (c) 2014-2018 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify + +import ( + "errors" + "runtime" + "sync" + "sync/atomic" + "syscall" + "unsafe" +) + +// readBufferSize defines the size of an array in which read statuses are stored. +// The buffer have to be DWORD-aligned and, if notify is used in monitoring a +// directory over the network, its size must not be greater than 64KB. Each of +// watched directories uses its own buffer for storing events. +const readBufferSize = 4096 + +// Since all operations which go through the Windows completion routine are done +// asynchronously, filter may set one of the constants below. They were defined +// in order to distinguish whether current folder should be re-registered in +// ReadDirectoryChangesW function or some control operations need to be executed. +const ( + stateRewatch uint32 = 1 << (28 + iota) + stateUnwatch + stateCPClose +) + +// Filter used in current implementation was split into four segments: +// - bits 0-11 store ReadDirectoryChangesW filters, +// - bits 12-19 store File notify actions, +// - bits 20-27 store notify specific events and flags, +// - bits 28-31 store states which are used in loop's FSM. +// Constants below are used as masks to retrieve only specific filter parts. +const ( + onlyNotifyChanges uint32 = 0x00000FFF + onlyNGlobalEvents uint32 = 0x0FF00000 + onlyMachineStates uint32 = 0xF0000000 +) + +// grip represents a single watched directory. It stores the data required by +// ReadDirectoryChangesW function. Only the filter, recursive, and handle members +// may by modified by watcher implementation. Rest of the them have to remain +// constant since they are used by Windows completion routine. This indicates that +// grip can be removed only when all operations on the file handle are finished. +type grip struct { + handle syscall.Handle + filter uint32 + recursive bool + pathw []uint16 + buffer [readBufferSize]byte + parent *watched + ovlapped *overlappedEx +} + +// overlappedEx stores information used in asynchronous input and output. +// Additionally, overlappedEx contains a pointer to 'grip' item which is used in +// order to gather the structure in which the overlappedEx object was created. +type overlappedEx struct { + syscall.Overlapped + parent *grip +} + +// newGrip creates a new file handle that can be used in overlapped operations. +// Then, the handle is associated with I/O completion port 'cph' and its value +// is stored in newly created 'grip' object. +func newGrip(cph syscall.Handle, parent *watched, filter uint32) (*grip, error) { + g := &grip{ + handle: syscall.InvalidHandle, + filter: filter, + recursive: parent.recursive, + pathw: parent.pathw, + parent: parent, + ovlapped: &overlappedEx{}, + } + if err := g.register(cph); err != nil { + return nil, err + } + g.ovlapped.parent = g + return g, nil +} + +// NOTE : Thread safe +func (g *grip) register(cph syscall.Handle) (err error) { + if g.handle, err = syscall.CreateFile( + &g.pathw[0], + syscall.FILE_LIST_DIRECTORY, + syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, + nil, + syscall.OPEN_EXISTING, + syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, + 0, + ); err != nil { + return + } + if _, err = syscall.CreateIoCompletionPort(g.handle, cph, 0, 0); err != nil { + syscall.CloseHandle(g.handle) + return + } + return g.readDirChanges() +} + +// readDirChanges tells the system to store file change information in grip's +// buffer. Directory changes that occur between calls to this function are added +// to the buffer and then, returned with the next call. +func (g *grip) readDirChanges() error { + handle := syscall.Handle(atomic.LoadUintptr((*uintptr)(&g.handle))) + if handle == syscall.InvalidHandle { + return nil // Handle was closed. + } + + return syscall.ReadDirectoryChanges( + handle, + &g.buffer[0], + uint32(unsafe.Sizeof(g.buffer)), + g.recursive, + encode(g.filter), + nil, + (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped)), + 0, + ) +} + +// encode transforms a generic filter, which contains platform independent and +// implementation specific bit fields, to value that can be used as NotifyFilter +// parameter in ReadDirectoryChangesW function. +func encode(filter uint32) uint32 { + e := Event(filter & (onlyNGlobalEvents | onlyNotifyChanges)) + if e&dirmarker != 0 { + return uint32(FileNotifyChangeDirName) + } + if e&Create != 0 { + e = (e ^ Create) | FileNotifyChangeFileName + } + if e&Remove != 0 { + e = (e ^ Remove) | FileNotifyChangeFileName + } + if e&Write != 0 { + e = (e ^ Write) | FileNotifyChangeAttributes | FileNotifyChangeSize | + FileNotifyChangeCreation | FileNotifyChangeSecurity + } + if e&Rename != 0 { + e = (e ^ Rename) | FileNotifyChangeFileName + } + return uint32(e) +} + +// watched is made in order to check whether an action comes from a directory or +// file. This approach requires two file handlers per single monitored folder. The +// second grip handles actions which include creating or deleting a directory. If +// these processes are not monitored, only the first grip is created. +type watched struct { + filter uint32 + recursive bool + count uint8 + pathw []uint16 + digrip [2]*grip +} + +// newWatched creates a new watched instance. It splits the filter variable into +// two parts. The first part is responsible for watching all events which can be +// created for a file in watched directory structure and the second one watches +// only directory Create/Remove actions. If all operations succeed, the Create +// message is sent to I/O completion port queue for further processing. +func newWatched(cph syscall.Handle, filter uint32, recursive bool, + path string) (wd *watched, err error) { + wd = &watched{ + filter: filter, + recursive: recursive, + } + if wd.pathw, err = syscall.UTF16FromString(path); err != nil { + return + } + if err = wd.recreate(cph); err != nil { + return + } + return wd, nil +} + +// TODO : doc +func (wd *watched) recreate(cph syscall.Handle) (err error) { + filefilter := wd.filter &^ uint32(FileNotifyChangeDirName) + if err = wd.updateGrip(0, cph, filefilter == 0, filefilter); err != nil { + return + } + dirfilter := wd.filter & uint32(FileNotifyChangeDirName|Create|Remove) + if err = wd.updateGrip(1, cph, dirfilter == 0, wd.filter|uint32(dirmarker)); err != nil { + return + } + wd.filter &^= onlyMachineStates + return +} + +// TODO : doc +func (wd *watched) updateGrip(idx int, cph syscall.Handle, reset bool, + newflag uint32) (err error) { + if reset { + wd.digrip[idx] = nil + } else { + if wd.digrip[idx] == nil { + if wd.digrip[idx], err = newGrip(cph, wd, newflag); err != nil { + wd.closeHandle() + return + } + } else { + wd.digrip[idx].filter = newflag + wd.digrip[idx].recursive = wd.recursive + if err = wd.digrip[idx].register(cph); err != nil { + wd.closeHandle() + return + } + } + wd.count++ + } + return +} + +// closeHandle closes handles that are stored in digrip array. Function always +// tries to close all of the handlers before it exits, even when there are errors +// returned from the operating system kernel. +func (wd *watched) closeHandle() (err error) { + for _, g := range wd.digrip { + if g == nil { + continue + } + + for { + handle := syscall.Handle(atomic.LoadUintptr((*uintptr)(&g.handle))) + if handle == syscall.InvalidHandle { + break // Already closed. + } + + e := syscall.CloseHandle(handle) + if e != nil && err == nil { + err = e + } + + // Set invalid handle even when CloseHandle fails. This will leak + // the handle but, since we can't close it anyway, there won't be + // any difference. + if atomic.CompareAndSwapUintptr((*uintptr)(&g.handle), + (uintptr)(handle), (uintptr)(syscall.InvalidHandle)) { + break + } + } + } + return +} + +// watcher implements Watcher interface. It stores a set of watched directories. +// All operations which remove watched objects from map `m` must be performed in +// loop goroutine since these structures are used internally by operating system. +type readdcw struct { + sync.Mutex + m map[string]*watched + cph syscall.Handle + start bool + wg sync.WaitGroup + c chan<- EventInfo +} + +// NewWatcher creates new non-recursive watcher backed by ReadDirectoryChangesW. +func newWatcher(c chan<- EventInfo) watcher { + r := &readdcw{ + m: make(map[string]*watched), + cph: syscall.InvalidHandle, + c: c, + } + runtime.SetFinalizer(r, func(r *readdcw) { + if r.cph != syscall.InvalidHandle { + syscall.CloseHandle(r.cph) + } + }) + return r +} + +// Watch implements notify.Watcher interface. +func (r *readdcw) Watch(path string, event Event) error { + return r.watch(path, event, false) +} + +// RecursiveWatch implements notify.RecursiveWatcher interface. +func (r *readdcw) RecursiveWatch(path string, event Event) error { + return r.watch(path, event, true) +} + +// watch inserts a directory to the group of watched folders. If watched folder +// already exists, function tries to rewatch it with new filters(NOT VALID). Moreover, +// watch starts the main event loop goroutine when called for the first time. +func (r *readdcw) watch(path string, event Event, recursive bool) error { + if event&^(All|fileNotifyChangeAll) != 0 { + return errors.New("notify: unknown event") + } + + r.Lock() + defer r.Unlock() + + if wd, ok := r.m[path]; ok { + dbgprint("watch: already exists") + wd.filter &^= stateUnwatch + return nil + } + + if err := r.lazyinit(); err != nil { + return err + } + + wd, err := newWatched(r.cph, uint32(event), recursive, path) + if err != nil { + return err + } + + r.m[path] = wd + dbgprint("watch: new watch added") + + return nil +} + +// lazyinit creates an I/O completion port and starts the main event loop. +func (r *readdcw) lazyinit() (err error) { + invalid := uintptr(syscall.InvalidHandle) + + if atomic.LoadUintptr((*uintptr)(&r.cph)) == invalid { + cph := syscall.InvalidHandle + if cph, err = syscall.CreateIoCompletionPort(cph, 0, 0, 0); err != nil { + return + } + + r.cph, r.start = cph, true + go r.loop() + } + + return +} + +// TODO(pknap) : doc +func (r *readdcw) loop() { + var n, key uint32 + var overlapped *syscall.Overlapped + for { + err := syscall.GetQueuedCompletionStatus(r.cph, &n, &key, &overlapped, syscall.INFINITE) + if key == stateCPClose { + r.Lock() + handle := r.cph + r.cph = syscall.InvalidHandle + r.Unlock() + syscall.CloseHandle(handle) + r.wg.Done() + return + } + if overlapped == nil { + // TODO: check key == rewatch delete or 0(panic) + continue + } + overEx := (*overlappedEx)(unsafe.Pointer(overlapped)) + if n != 0 { + r.loopevent(n, overEx) + if err = overEx.parent.readDirChanges(); err != nil { + // TODO: error handling + } + } + r.loopstate(overEx) + } +} + +// TODO(pknap) : doc +func (r *readdcw) loopstate(overEx *overlappedEx) { + r.Lock() + defer r.Unlock() + filter := overEx.parent.parent.filter + if filter&onlyMachineStates == 0 { + return + } + if overEx.parent.parent.count--; overEx.parent.parent.count == 0 { + switch filter & onlyMachineStates { + case stateRewatch: + dbgprint("loopstate rewatch") + overEx.parent.parent.recreate(r.cph) + case stateUnwatch: + dbgprint("loopstate unwatch") + overEx.parent.parent.closeHandle() + delete(r.m, syscall.UTF16ToString(overEx.parent.pathw)) + case stateCPClose: + default: + panic(`notify: windows loopstate logic error`) + } + } +} + +// TODO(pknap) : doc +func (r *readdcw) loopevent(n uint32, overEx *overlappedEx) { + events := []*event{} + var currOffset uint32 + for { + raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&overEx.parent.buffer[currOffset])) + name := syscall.UTF16ToString((*[syscall.MAX_LONG_PATH]uint16)(unsafe.Pointer(&raw.FileName))[:raw.FileNameLength>>1]) + events = append(events, &event{ + pathw: overEx.parent.pathw, + filter: overEx.parent.filter, + action: raw.Action, + name: name, + }) + if raw.NextEntryOffset == 0 { + break + } + if currOffset += raw.NextEntryOffset; currOffset >= n { + break + } + } + r.send(events) +} + +// TODO(pknap) : doc +func (r *readdcw) send(es []*event) { + for _, e := range es { + var syse Event + if e.e, syse = decode(e.filter, e.action); e.e == 0 && syse == 0 { + continue + } + switch { + case e.action == syscall.FILE_ACTION_MODIFIED: + e.ftype = fTypeUnknown + case e.filter&uint32(dirmarker) != 0: + e.ftype = fTypeDirectory + default: + e.ftype = fTypeFile + } + switch { + case e.e == 0: + e.e = syse + case syse != 0: + r.c <- &event{ + pathw: e.pathw, + name: e.name, + ftype: e.ftype, + action: e.action, + filter: e.filter, + e: syse, + } + } + r.c <- e + } +} + +// Rewatch implements notify.Rewatcher interface. +func (r *readdcw) Rewatch(path string, oldevent, newevent Event) error { + return r.rewatch(path, uint32(oldevent), uint32(newevent), false) +} + +// RecursiveRewatch implements notify.RecursiveRewatcher interface. +func (r *readdcw) RecursiveRewatch(oldpath, newpath string, oldevent, + newevent Event) error { + if oldpath != newpath { + if err := r.unwatch(oldpath); err != nil { + return err + } + return r.watch(newpath, newevent, true) + } + return r.rewatch(newpath, uint32(oldevent), uint32(newevent), true) +} + +// TODO : (pknap) doc. +func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool) (err error) { + if Event(newevent)&^(All|fileNotifyChangeAll) != 0 { + return errors.New("notify: unknown event") + } + var wd *watched + r.Lock() + defer r.Unlock() + if wd, err = r.nonStateWatchedLocked(path); err != nil { + return + } + if wd.filter&(onlyNotifyChanges|onlyNGlobalEvents) != oldevent { + panic(`notify: windows re-watcher logic error`) + } + wd.filter = stateRewatch | newevent + wd.recursive, recursive = recursive, wd.recursive + if err = wd.closeHandle(); err != nil { + wd.filter = oldevent + wd.recursive = recursive + return + } + return +} + +// TODO : pknap +func (r *readdcw) nonStateWatchedLocked(path string) (wd *watched, err error) { + wd, ok := r.m[path] + if !ok || wd == nil { + err = errors.New(`notify: ` + path + ` path is unwatched`) + return + } + if wd.filter&onlyMachineStates != 0 { + err = errors.New(`notify: another re/unwatching operation in progress`) + return + } + return +} + +// Unwatch implements notify.Watcher interface. +func (r *readdcw) Unwatch(path string) error { + return r.unwatch(path) +} + +// RecursiveUnwatch implements notify.RecursiveWatcher interface. +func (r *readdcw) RecursiveUnwatch(path string) error { + return r.unwatch(path) +} + +// TODO : pknap +func (r *readdcw) unwatch(path string) (err error) { + var wd *watched + + r.Lock() + defer r.Unlock() + if wd, err = r.nonStateWatchedLocked(path); err != nil { + return + } + + wd.filter |= stateUnwatch + dbgprint("unwatch: set unwatch state") + + if _, attrErr := syscall.GetFileAttributes(&wd.pathw[0]); attrErr != nil { + for _, g := range wd.digrip { + if g == nil { + continue + } + + dbgprint("unwatch: posting") + if err = syscall.PostQueuedCompletionStatus(r.cph, 0, 0, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped))); err != nil { + wd.filter &^= stateUnwatch + return + } + } + } + + return +} + +// Close resets the whole watcher object, closes all existing file descriptors, +// and sends stateCPClose state as completion key to the main watcher's loop. +func (r *readdcw) Close() (err error) { + r.Lock() + if !r.start { + r.Unlock() + return nil + } + for _, wd := range r.m { + wd.filter &^= onlyMachineStates + wd.filter |= stateCPClose + if e := wd.closeHandle(); e != nil && err == nil { + err = e + } + } + r.start = false + r.Unlock() + r.wg.Add(1) + if e := syscall.PostQueuedCompletionStatus(r.cph, 0, stateCPClose, nil); e != nil && err == nil { + return e + } + r.wg.Wait() + return +} + +// decode creates a notify event from both non-raw filter and action which was +// returned from completion routine. Function may return Event(0) in case when +// filter was replaced by a new value which does not contain fields that are +// valid with passed action. +func decode(filter, action uint32) (Event, Event) { + switch action { + case syscall.FILE_ACTION_ADDED: + return gensys(filter, Create, FileActionAdded) + case syscall.FILE_ACTION_REMOVED: + return gensys(filter, Remove, FileActionRemoved) + case syscall.FILE_ACTION_MODIFIED: + return gensys(filter, Write, FileActionModified) + case syscall.FILE_ACTION_RENAMED_OLD_NAME: + return gensys(filter, Rename, FileActionRenamedOldName) + case syscall.FILE_ACTION_RENAMED_NEW_NAME: + return gensys(filter, Rename, FileActionRenamedNewName) + } + panic(`notify: cannot decode internal mask`) +} + +// gensys decides whether the Windows action, system-independent event or both +// of them should be returned. Since the grip's filter may be atomically changed +// during watcher lifetime, it is possible that neither Windows nor notify masks +// are watched by the user when this function is called. +func gensys(filter uint32, ge, se Event) (gene, syse Event) { + isdir := filter&uint32(dirmarker) != 0 + if isdir && filter&uint32(FileNotifyChangeDirName) != 0 || + !isdir && filter&uint32(FileNotifyChangeFileName) != 0 || + filter&uint32(fileNotifyChangeModified) != 0 { + syse = se + } + if filter&uint32(ge) != 0 { + gene = ge + } + return +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_readdcw_test.go b/vendor/github.com/rjeczalik/notify/watcher_readdcw_test.go new file mode 100644 index 00000000..ea15b4a4 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_readdcw_test.go @@ -0,0 +1,67 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify + +import "testing" + +// TODO(ppknap) : remove notify.Create event. +func rcreate(w *W, path string) WCase { + cas := create(w, path) + cas.Events = append(cas.Events, + &Call{P: path, E: FileActionAdded}, + ) + return cas +} + +// TODO(ppknap) : remove notify.Remove event. +func rremove(w *W, path string) WCase { + cas := remove(w, path) + cas.Events = append(cas.Events, + &Call{P: path, E: FileActionRemoved}, + ) + return cas +} + +// TODO(ppknap) : remove notify.Rename event. +func rrename(w *W, oldpath, newpath string) WCase { + cas := rename(w, oldpath, newpath) + cas.Events = append(cas.Events, + &Call{P: oldpath, E: FileActionRenamedOldName}, + &Call{P: newpath, E: FileActionRenamedNewName}, + ) + return cas +} + +// TODO(ppknap) : remove notify.Write event. +func rwrite(w *W, path string, p []byte) WCase { + cas := write(w, path, p) + cas.Events = append(cas.Events, + &Call{P: path, E: FileActionModified}, + ) + return cas +} + +var events = []Event{ + FileNotifyChangeFileName, + FileNotifyChangeDirName, + FileNotifyChangeSize, +} + +func TestWatcherReadDirectoryChangesW(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt", events...) + defer w.Close() + + cases := [...]WCase{ + rcreate(w, "src/github.com/rjeczalik/fs/fs_windows.go"), + rcreate(w, "src/github.com/rjeczalik/fs/subdir/"), + rremove(w, "src/github.com/rjeczalik/fs/fs.go"), + rrename(w, "src/github.com/rjeczalik/fs/LICENSE", "src/github.com/rjeczalik/fs/COPYLEFT"), + rwrite(w, "src/github.com/rjeczalik/fs/cmd/gotree/go.go", []byte("XD")), + } + + w.ExpectAny(cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_recursive_test.go b/vendor/github.com/rjeczalik/notify/watcher_recursive_test.go new file mode 100644 index 00000000..3b1f148f --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_recursive_test.go @@ -0,0 +1,102 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,!kqueue windows + +package notify + +import ( + "fmt" + "testing" +) + +// noevent stripts test-case from expected event list, used when action is not +// expected to trigger any events. +func noevent(cas WCase) WCase { + return WCase{Action: cas.Action} +} + +func TestWatcherRecursiveRewatch(t *testing.T) { + w := newWatcherTest(t, "testdata/vfs.txt") + defer w.Close() + + cases := []WCase{ + create(w, "src/github.com/rjeczalik/file"), + create(w, "src/github.com/rjeczalik/dir/"), + noevent(create(w, "src/github.com/rjeczalik/fs/dir/")), + noevent(create(w, "src/github.com/dir/")), + noevent(write(w, "src/github.com/rjeczalik/file", []byte("XD"))), + noevent(rename(w, "src/github.com/rjeczalik/fs/LICENSE", "src/LICENSE")), + } + + w.Watch("src/github.com/rjeczalik", Create) + w.ExpectAny(cases) + + cases = []WCase{ + create(w, "src/github.com/rjeczalik/fs/file"), + create(w, "src/github.com/rjeczalik/fs/cmd/gotree/file"), + create(w, "src/github.com/rjeczalik/fs/cmd/dir/"), + create(w, "src/github.com/rjeczalik/fs/cmd/gotree/dir/"), + noevent(write(w, "src/github.com/rjeczalik/fs/file", []byte("XD"))), + noevent(create(w, "src/github.com/anotherdir/")), + } + + w.RecursiveRewatch("src/github.com/rjeczalik", "src/github.com/rjeczalik", Create, Create) + w.ExpectAny(cases) + + cases = []WCase{ + create(w, "src/github.com/rjeczalik/1"), + create(w, "src/github.com/rjeczalik/2/"), + noevent(create(w, "src/github.com/rjeczalik/fs/cmd/1")), + noevent(create(w, "src/github.com/rjeczalik/fs/1/")), + noevent(write(w, "src/github.com/rjeczalik/fs/file", []byte("XD"))), + } + + w.Rewatch("src/github.com/rjeczalik", Create, Create) + w.ExpectAny(cases) +} + +// TODO(rjeczalik): move to watcher_test.go after #5 +func TestIsDirCreateEvent(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt") + defer w.Close() + + cases := [...]WCase{ + // i=0 + create(w, "src/github.com/jszwec/"), + // i=1 + create(w, "src/github.com/jszwec/gojunitxml/"), + // i=2 + create(w, "src/github.com/jszwec/gojunitxml/README.md"), + // i=3 + create(w, "src/github.com/jszwec/gojunitxml/LICENSE"), + // i=4 + create(w, "src/github.com/jszwec/gojunitxml/cmd/"), + } + + dirs := [...]bool{ + true, // i=0 + true, // i=1 + false, // i=2 + false, // i=3 + true, // i=4 + } + + fn := func(i int, _ WCase, ei EventInfo) error { + d, ok := ei.(isDirer) + if !ok { + return fmt.Errorf("received EventInfo does not implement isDirer") + } + switch ok, err := d.isDir(); { + case err != nil: + return err + case ok != dirs[i]: + return fmt.Errorf("want ok=%v; got %v", dirs[i], ok) + default: + return nil + } + } + + w.ExpectAnyFunc(cases[:], fn) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_stub.go b/vendor/github.com/rjeczalik/notify/watcher_stub.go new file mode 100644 index 00000000..9b284ddc --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_stub.go @@ -0,0 +1,13 @@ +// Copyright (c) 2014-2018 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +type watcherStub struct{ error } + +// Following methods implement notify.watcher interface. +func (s watcherStub) Watch(string, Event) error { return s } +func (s watcherStub) Rewatch(string, Event, Event) error { return s } +func (s watcherStub) Unwatch(string) (err error) { return s } +func (s watcherStub) Close() error { return s } diff --git a/vendor/github.com/rjeczalik/notify/watcher_test.go b/vendor/github.com/rjeczalik/notify/watcher_test.go new file mode 100644 index 00000000..fd33d238 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_test.go @@ -0,0 +1,86 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin linux freebsd dragonfly netbsd openbsd windows solaris + +package notify + +import ( + "os" + "testing" + "time" +) + +// NOTE Set NOTIFY_DEBUG env var or debug build tag for extra debugging info. + +func TestWatcher(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt") + defer w.Close() + + cases := [...]WCase{ + create(w, "src/github.com/ppknap/link/include/coost/.link.hpp.swp"), + create(w, "src/github.com/rjeczalik/fs/fs_test.go"), + create(w, "src/github.com/rjeczalik/fs/binfs/"), + create(w, "src/github.com/rjeczalik/fs/binfs.go"), + create(w, "src/github.com/rjeczalik/fs/binfs_test.go"), + remove(w, "src/github.com/rjeczalik/fs/binfs/"), + create(w, "src/github.com/rjeczalik/fs/binfs/"), + create(w, "src/github.com/rjeczalik/fs/virfs"), + remove(w, "src/github.com/rjeczalik/fs/virfs"), + create(w, "file"), + create(w, "dir/"), + } + + w.ExpectAny(cases[:]) +} + +// Simulates the scenario, where outside of the programs control the base dir +// is removed. This is detected and the watch removed. Then the directory is +// restored and a new watch set up. +func TestStopPathNotExists(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt") + defer w.Close() + + if err := os.RemoveAll(w.root); err != nil { + panic(err) + } + Sync() + + // Don't check the returned error, as the public function (notify.Stop) + // does not return a potential error. As long as everything later on + // works as inteded, that's fine + time.Sleep(time.Duration(100) * time.Millisecond) + w.Watcher.Unwatch(w.root) + time.Sleep(time.Duration(100) * time.Millisecond) + + if err := os.Mkdir(w.root, 0777); err != nil { + panic(err) + } + Sync() + w.Watch("", All) + + drainall(w.C) + cases := [...]WCase{ + create(w, "file"), + create(w, "dir/"), + } + w.ExpectAny(cases[:]) +} + +func TestWatcherUnwatch(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt") + defer w.Close() + + remove(w, "src/github.com/ppknap/link/test/test_circular_calls.cpp").Action() + w.Unwatch("") + + w.Watch("", All) + + drainall(w.C) + cases := [...]WCase{ + create(w, "file"), + create(w, "dir/"), + } + w.ExpectAny(cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_trigger.go b/vendor/github.com/rjeczalik/notify/watcher_trigger.go new file mode 100644 index 00000000..1ebe0482 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_trigger.go @@ -0,0 +1,450 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,kqueue dragonfly freebsd netbsd openbsd solaris + +// watcher_trigger is used for FEN and kqueue which behave similarly: +// only files and dirs can be watched directly, but not files inside dirs. +// As a result Create events have to be generated by implementation when +// after Write event is returned for watched dir, it is rescanned and Create +// event is returned for new files and these are automatically added +// to watchlist. In case of removal of watched directory, native system returns +// events for all files, but for Rename, they also need to be generated. +// As a result native system works as something like trigger for rescan, +// but contains additional data about dir in which changes occurred. For files +// detailed data is returned. +// Usage of watcher_trigger requires: +// - trigger implementation, +// - encode func, +// - not2nat, nat2not maps. +// Required manual operations on filesystem can lead to loss of precision. + +package notify + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "sync" + "syscall" +) + +// trigger is to be implemented by platform implementation like FEN or kqueue. +type trigger interface { + // Close closes watcher's main native file descriptor. + Close() error + // Stop waiting for new events. + Stop() error + // Create new instance of watched. + NewWatched(string, os.FileInfo) (*watched, error) + // Record internally new *watched instance. + Record(*watched) + // Del removes internal copy of *watched instance. + Del(*watched) + // Watched returns *watched instance and native events for native type. + Watched(interface{}) (*watched, int64, error) + // Init initializes native watcher call. + Init() error + // Watch starts watching provided file/dir. + Watch(os.FileInfo, *watched, int64) error + // Unwatch stops watching provided file/dir. + Unwatch(*watched) error + // Wait for new events. + Wait() (interface{}, error) + // IsStop checks if Wait finished because of request watcher's stop. + IsStop(n interface{}, err error) bool +} + +// trgWatched is a the base data structure representing watched file/directory. +// The platform specific full data structure (watched) must embed this type. +type trgWatched struct { + // p is a path to watched file/directory. + p string + // fi provides information about watched file/dir. + fi os.FileInfo + // eDir represents events watched directly. + eDir Event + // eNonDir represents events watched indirectly. + eNonDir Event +} + +// encode Event to native representation. Implementation is to be provided by +// platform specific implementation. +var encode func(Event, bool) int64 + +var ( + // nat2not matches native events to notify's ones. To be initialized by + // platform dependent implementation. + nat2not map[Event]Event + // not2nat matches notify's events to native ones. To be initialized by + // platform dependent implementation. + not2nat map[Event]Event +) + +// trg is a main structure implementing watcher. +type trg struct { + sync.Mutex + // s is a channel used to stop monitoring. + s chan struct{} + // c is a channel used to pass events further. + c chan<- EventInfo + // pthLkp is a data structure mapping file names with data about watching + // represented by them files/directories. + pthLkp map[string]*watched + // t is a platform dependent implementation of trigger. + t trigger +} + +// newWatcher returns new watcher's implementation. +func newWatcher(c chan<- EventInfo) watcher { + t := &trg{ + s: make(chan struct{}, 1), + pthLkp: make(map[string]*watched, 0), + c: c, + } + t.t = newTrigger(t.pthLkp) + if err := t.t.Init(); err != nil { + t.Close() + return watcherStub{fmt.Errorf("failed setting up watcher: %v", err)} + } + go t.monitor() + return t +} + +// Close implements watcher. +func (t *trg) Close() (err error) { + t.Lock() + if err = t.t.Stop(); err != nil { + t.Unlock() + return + } + <-t.s + var e error + for _, w := range t.pthLkp { + if e = t.unwatch(w.p, w.fi); e != nil { + dbgprintf("trg: unwatch %q failed: %q\n", w.p, e) + err = nonil(err, e) + } + } + if e = t.t.Close(); e != nil { + dbgprintf("trg: closing native watch failed: %q\n", e) + err = nonil(err, e) + } + if remaining := len(t.pthLkp); remaining != 0 { + err = nonil(err, fmt.Errorf("Not all watches were removed: len(t.pthLkp) == %v", len(t.pthLkp))) + } + t.Unlock() + return +} + +// send reported events one by one through chan. +func (t *trg) send(evn []event) { + for i := range evn { + t.c <- &evn[i] + } +} + +// singlewatch starts to watch given p file/directory. +func (t *trg) singlewatch(p string, e Event, direct mode, fi os.FileInfo) (err error) { + w, ok := t.pthLkp[p] + if !ok { + if w, err = t.t.NewWatched(p, fi); err != nil { + return + } + } + switch direct { + case dir: + w.eDir |= e + case ndir: + w.eNonDir |= e + case both: + w.eDir |= e + w.eNonDir |= e + } + if err = t.t.Watch(fi, w, encode(w.eDir|w.eNonDir, fi.IsDir())); err != nil { + return + } + if !ok { + t.t.Record(w) + return nil + } + return errAlreadyWatched +} + +// decode converts event received from native to notify.Event +// representation taking into account requested events (w). +func decode(o int64, w Event) (e Event) { + for f, n := range nat2not { + if o&int64(f) != 0 { + if w&f != 0 { + e |= f + } + if w&n != 0 { + e |= n + } + } + } + + return +} + +func (t *trg) watch(p string, e Event, fi os.FileInfo) error { + if err := t.singlewatch(p, e, dir, fi); err != nil { + if err != errAlreadyWatched { + return err + } + } + if fi.IsDir() { + err := t.walk(p, func(fi os.FileInfo) (err error) { + if err = t.singlewatch(filepath.Join(p, fi.Name()), e, ndir, + fi); err != nil { + if err != errAlreadyWatched { + return + } + } + return nil + }) + if err != nil { + return err + } + } + return nil +} + +// walk runs f func on each file/dir from p directory. +func (t *trg) walk(p string, fn func(os.FileInfo) error) error { + fp, err := os.Open(p) + if err != nil { + return err + } + ls, err := fp.Readdir(0) + fp.Close() + if err != nil { + return err + } + for i := range ls { + if err := fn(ls[i]); err != nil { + return err + } + } + return nil +} + +func (t *trg) unwatch(p string, fi os.FileInfo) error { + if fi.IsDir() { + err := t.walk(p, func(fi os.FileInfo) error { + err := t.singleunwatch(filepath.Join(p, fi.Name()), ndir) + if err != errNotWatched { + return err + } + return nil + }) + if err != nil { + return err + } + } + return t.singleunwatch(p, dir) +} + +// Watch implements Watcher interface. +func (t *trg) Watch(p string, e Event) error { + fi, err := os.Stat(p) + if err != nil { + return err + } + t.Lock() + err = t.watch(p, e, fi) + t.Unlock() + return err +} + +// Unwatch implements Watcher interface. +func (t *trg) Unwatch(p string) error { + fi, err := os.Stat(p) + if err != nil { + return err + } + t.Lock() + err = t.unwatch(p, fi) + t.Unlock() + return err +} + +// Rewatch implements Watcher interface. +// +// TODO(rjeczalik): This is a naive hack. Rewrite might help. +func (t *trg) Rewatch(p string, _, e Event) error { + fi, err := os.Stat(p) + if err != nil { + return err + } + t.Lock() + if err = t.unwatch(p, fi); err == nil { + // TODO(rjeczalik): If watch fails then we leave trigger in inconsistent + // state. Handle? Panic? Native version of rewatch? + err = t.watch(p, e, fi) + } + t.Unlock() + return nil +} + +func (*trg) file(w *watched, n interface{}, e Event) (evn []event) { + evn = append(evn, event{w.p, e, w.fi.IsDir(), n}) + return +} + +func (t *trg) dir(w *watched, n interface{}, e, ge Event) (evn []event) { + // If it's dir and delete we have to send it and continue, because + // other processing relies on opening (in this case not existing) dir. + // Events for contents of this dir are reported by native impl. + // However events for rename must be generated for all monitored files + // inside of moved directory, because native impl does not report it independently + // for each file descriptor being moved in result of move action on + // parent directory. + if (ge & (not2nat[Rename] | not2nat[Remove])) != 0 { + // Write is reported also for Remove on directory. Because of that + // we have to filter it out explicitly. + evn = append(evn, event{w.p, e & ^Write & ^not2nat[Write], true, n}) + if ge¬2nat[Rename] != 0 { + for p := range t.pthLkp { + if strings.HasPrefix(p, w.p+string(os.PathSeparator)) { + if err := t.singleunwatch(p, both); err != nil && err != errNotWatched && + !os.IsNotExist(err) { + dbgprintf("trg: failed stop watching moved file (%q): %q\n", + p, err) + } + if (w.eDir|w.eNonDir)&(not2nat[Rename]|Rename) != 0 { + evn = append(evn, event{ + p, (w.eDir | w.eNonDir) & e &^ Write &^ not2nat[Write], + w.fi.IsDir(), nil, + }) + } + } + } + } + t.t.Del(w) + return + } + if (ge & not2nat[Write]) != 0 { + switch err := t.walk(w.p, func(fi os.FileInfo) error { + p := filepath.Join(w.p, fi.Name()) + switch err := t.singlewatch(p, w.eDir, ndir, fi); { + case os.IsNotExist(err) && ((w.eDir & Remove) != 0): + evn = append(evn, event{p, Remove, fi.IsDir(), n}) + case err == errAlreadyWatched: + case err != nil: + dbgprintf("trg: watching %q failed: %q", p, err) + case (w.eDir & Create) != 0: + evn = append(evn, event{p, Create, fi.IsDir(), n}) + default: + } + return nil + }); { + case os.IsNotExist(err): + return + case err != nil: + dbgprintf("trg: dir processing failed: %q", err) + default: + } + } + return +} + +type mode uint + +const ( + dir mode = iota + ndir + both +) + +// unwatch stops watching p file/directory. +func (t *trg) singleunwatch(p string, direct mode) error { + w, ok := t.pthLkp[p] + if !ok { + return errNotWatched + } + switch direct { + case dir: + w.eDir = 0 + case ndir: + w.eNonDir = 0 + case both: + w.eDir, w.eNonDir = 0, 0 + } + if err := t.t.Unwatch(w); err != nil { + return err + } + if w.eNonDir|w.eDir != 0 { + mod := dir + if w.eNonDir != 0 { + mod = ndir + } + if err := t.singlewatch(p, w.eNonDir|w.eDir, mod, + w.fi); err != nil && err != errAlreadyWatched { + return err + } + } else { + t.t.Del(w) + } + return nil +} + +func (t *trg) monitor() { + var ( + n interface{} + err error + ) + for { + switch n, err = t.t.Wait(); { + case err == syscall.EINTR: + case t.t.IsStop(n, err): + t.s <- struct{}{} + return + case err != nil: + dbgprintf("trg: failed to read events: %q\n", err) + default: + t.send(t.process(n)) + } + } +} + +// process event returned by native call. +func (t *trg) process(n interface{}) (evn []event) { + t.Lock() + w, ge, err := t.t.Watched(n) + if err != nil { + t.Unlock() + dbgprintf("trg: %v event lookup failed: %q", Event(ge), err) + return + } + + e := decode(ge, w.eDir|w.eNonDir) + if ge&int64(not2nat[Remove]|not2nat[Rename]) == 0 { + switch fi, err := os.Stat(w.p); { + case err != nil: + default: + if err = t.t.Watch(fi, w, encode(w.eDir|w.eNonDir, fi.IsDir())); err != nil { + dbgprintf("trg: %q is no longer watched: %q", w.p, err) + t.t.Del(w) + } + } + } + if e == Event(0) && (!w.fi.IsDir() || (ge&int64(not2nat[Write])) == 0) { + t.Unlock() + return + } + + if w.fi.IsDir() { + evn = append(evn, t.dir(w, n, e, Event(ge))...) + } else { + evn = append(evn, t.file(w, n, e)...) + } + if Event(ge)&(not2nat[Remove]|not2nat[Rename]) != 0 { + t.t.Del(w) + } + t.Unlock() + return +} diff --git a/vendor/github.com/rjeczalik/notify/watcher_trigger_test.go b/vendor/github.com/rjeczalik/notify/watcher_trigger_test.go new file mode 100644 index 00000000..e59cbbcd --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watcher_trigger_test.go @@ -0,0 +1,21 @@ +// Copyright (c) 2014-2017 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build darwin,kqueue dragonfly freebsd netbsd openbsd solaris + +package notify + +import "testing" + +func TestWatcherCreateOnly(t *testing.T) { + w := NewWatcherTest(t, "testdata/vfs.txt", Create) + defer w.Close() + + cases := [...]WCase{ + create(w, "dir/"), + create(w, "dir2/"), + } + + w.ExpectAny(cases[:]) +} diff --git a/vendor/github.com/rjeczalik/notify/watchpoint.go b/vendor/github.com/rjeczalik/notify/watchpoint.go new file mode 100644 index 00000000..5afc914f --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watchpoint.go @@ -0,0 +1,103 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +// EventDiff describes a change to an event set - EventDiff[0] is an old state, +// while EventDiff[1] is a new state. If event set has not changed (old == new), +// functions typically return the None value. +type eventDiff [2]Event + +func (diff eventDiff) Event() Event { + return diff[1] &^ diff[0] +} + +// Watchpoint +// +// The nil key holds total event set - logical sum for all registered events. +// It speeds up computing EventDiff for Add method. +// +// The rec key holds an event set for a watchpoints created by RecursiveWatch +// for a Watcher implementation which is not natively recursive. +type watchpoint map[chan<- EventInfo]Event + +// None is an empty event diff, think null object. +var none eventDiff + +// rec is just a placeholder +var rec = func() (ch chan<- EventInfo) { + ch = make(chan<- EventInfo) + close(ch) + return +}() + +func (wp watchpoint) dryAdd(ch chan<- EventInfo, e Event) eventDiff { + if e &^= internal; wp[ch]&e == e { + return none + } + total := wp[ch] &^ internal + return eventDiff{total, total | e} +} + +// Add assumes neither c nor e are nil or zero values. +func (wp watchpoint) Add(c chan<- EventInfo, e Event) (diff eventDiff) { + wp[c] |= e + diff[0] = wp[nil] + diff[1] = diff[0] | e + wp[nil] = diff[1] &^ omit + // Strip diff from internal events. + diff[0] &^= internal + diff[1] &^= internal + if diff[0] == diff[1] { + return none + } + return +} + +func (wp watchpoint) Del(c chan<- EventInfo, e Event) (diff eventDiff) { + wp[c] &^= e + if wp[c] == 0 { + delete(wp, c) + } + diff[0] = wp[nil] + delete(wp, nil) + if len(wp) != 0 { + // Recalculate total event set. + for _, e := range wp { + diff[1] |= e + } + wp[nil] = diff[1] &^ omit + } + // Strip diff from internal events. + diff[0] &^= internal + diff[1] &^= internal + if diff[0] == diff[1] { + return none + } + return +} + +func (wp watchpoint) Dispatch(ei EventInfo, extra Event) { + e := eventmask(ei, extra) + if !matches(wp[nil], e) { + return + } + for ch, eset := range wp { + if ch != nil && matches(eset, e) { + select { + case ch <- ei: + default: // Drop event if receiver is too slow + dbgprintf("dropped %s on %q: receiver too slow", ei.Event(), ei.Path()) + } + } + } +} + +func (wp watchpoint) Total() Event { + return wp[nil] &^ internal +} + +func (wp watchpoint) IsRecursive() bool { + return wp[nil]&recursive != 0 +} diff --git a/vendor/github.com/rjeczalik/notify/watchpoint_other.go b/vendor/github.com/rjeczalik/notify/watchpoint_other.go new file mode 100644 index 00000000..9bb381db --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watchpoint_other.go @@ -0,0 +1,23 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build !windows + +package notify + +// eventmask uses ei to create a new event which contains internal flags used by +// notify package logic. +func eventmask(ei EventInfo, extra Event) Event { + return ei.Event() | extra +} + +// matches reports a match only when: +// +// - for user events, when event is present in the given set +// - for internal events, when additionally both event and set have omit bit set +// +// Internal events must not be sent to user channels and vice versa. +func matches(set, event Event) bool { + return (set&omit)^(event&omit) == 0 && set&event == event +} diff --git a/vendor/github.com/rjeczalik/notify/watchpoint_readdcw.go b/vendor/github.com/rjeczalik/notify/watchpoint_readdcw.go new file mode 100644 index 00000000..9fd1e1df --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watchpoint_readdcw.go @@ -0,0 +1,38 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// +build windows + +package notify + +// eventmask uses ei to create a new event which contains internal flags used by +// notify package logic. If one of FileAction* masks is detected, this function +// adds corresponding FileNotifyChange* values. This allows non registered +// FileAction* events to be passed on. +func eventmask(ei EventInfo, extra Event) (e Event) { + if e = ei.Event() | extra; e&fileActionAll != 0 { + if ev, ok := ei.(*event); ok { + switch ev.ftype { + case fTypeFile: + e |= FileNotifyChangeFileName + case fTypeDirectory: + e |= FileNotifyChangeDirName + case fTypeUnknown: + e |= fileNotifyChangeModified + } + return e &^ fileActionAll + } + } + return +} + +// matches reports a match only when: +// +// - for user events, when event is present in the given set +// - for internal events, when additionally both event and set have omit bit set +// +// Internal events must not be sent to user channels and vice versa. +func matches(set, event Event) bool { + return (set&omit)^(event&omit) == 0 && (set&event == event || set&fileNotifyChangeModified&event != 0) +} diff --git a/vendor/github.com/rjeczalik/notify/watchpoint_test.go b/vendor/github.com/rjeczalik/notify/watchpoint_test.go new file mode 100644 index 00000000..e35483d1 --- /dev/null +++ b/vendor/github.com/rjeczalik/notify/watchpoint_test.go @@ -0,0 +1,162 @@ +// Copyright (c) 2014-2015 The Notify Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +package notify + +import ( + "fmt" + "reflect" + "testing" +) + +func call(wp watchpoint, fn interface{}, args []interface{}) eventDiff { + vals := []reflect.Value{reflect.ValueOf(wp)} + for _, arg := range args { + vals = append(vals, reflect.ValueOf(arg)) + } + res := reflect.ValueOf(fn).Call(vals) + if n := len(res); n != 1 { + panic(fmt.Sprintf("unexpected len(res)=%d", n)) + } + diff, ok := res[0].Interface().(eventDiff) + if !ok { + panic(fmt.Sprintf("want typeof(diff)=EventDiff; got %T", res[0].Interface())) + } + return diff +} + +func TestWatchpoint(t *testing.T) { + ch := NewChans(5) + all := All | recursive + cases := [...]struct { + fn interface{} + args []interface{} + diff eventDiff + total Event + }{ + // i=0 + { + watchpoint.Add, + []interface{}{ch[0], Remove}, + eventDiff{0, Remove}, + Remove, + }, + // i=1 + { + watchpoint.Add, + []interface{}{ch[1], Create | Remove | recursive}, + eventDiff{Remove, Remove | Create}, + Create | Remove | recursive, + }, + // i=2 + { + watchpoint.Add, + []interface{}{ch[2], Create | Rename}, + eventDiff{Create | Remove, Create | Remove | Rename}, + Create | Remove | Rename | recursive, + }, + // i=3 + { + watchpoint.Add, + []interface{}{ch[0], Write | recursive}, + eventDiff{Create | Remove | Rename, Create | Remove | Rename | Write}, + Create | Remove | Rename | Write | recursive, + }, + // i=4 + { + watchpoint.Add, + []interface{}{ch[2], Remove | recursive}, + none, + Create | Remove | Rename | Write | recursive, + }, + // i=5 + { + watchpoint.Del, + []interface{}{ch[0], all}, + eventDiff{Create | Remove | Rename | Write, Create | Remove | Rename}, + Create | Remove | Rename | recursive, + }, + // i=6 + { + watchpoint.Del, + []interface{}{ch[2], all}, + eventDiff{Create | Remove | Rename, Create | Remove}, + Create | Remove | recursive, + }, + // i=7 + { + watchpoint.Add, + []interface{}{ch[3], Create | Remove}, + none, + Create | Remove | recursive, + }, + // i=8 + { + watchpoint.Del, + []interface{}{ch[1], all}, + none, + Create | Remove, + }, + // i=9 + { + watchpoint.Add, + []interface{}{ch[3], recursive | Write}, + eventDiff{Create | Remove, Create | Remove | Write}, + Create | Remove | Write | recursive, + }, + // i=10 + { + watchpoint.Del, + []interface{}{ch[3], Create}, + eventDiff{Create | Remove | Write, Remove | Write}, + Remove | Write | recursive, + }, + // i=11 + { + watchpoint.Add, + []interface{}{ch[3], Create | Rename}, + eventDiff{Remove | Write, Create | Remove | Rename | Write}, + Create | Remove | Rename | Write | recursive, + }, + // i=12 + { + watchpoint.Add, + []interface{}{ch[2], Remove | Write}, + none, + Create | Remove | Rename | Write | recursive, + }, + // i=13 + { + watchpoint.Del, + []interface{}{ch[3], Create | Remove | Write}, + eventDiff{Create | Remove | Rename | Write, Remove | Rename | Write}, + Remove | Rename | Write | recursive, + }, + // i=14 + { + watchpoint.Del, + []interface{}{ch[2], Remove}, + eventDiff{Remove | Rename | Write, Rename | Write}, + Rename | Write | recursive, + }, + // i=15 + { + watchpoint.Del, + []interface{}{ch[3], Rename | recursive}, + eventDiff{Rename | Write, Write}, + Write, + }, + } + wp := watchpoint{} + for i, cas := range cases { + if diff := call(wp, cas.fn, cas.args); diff != cas.diff { + t.Errorf("want diff=%v; got %v (i=%d)", cas.diff, diff, i) + continue + } + if total := wp[nil]; total != cas.total { + t.Errorf("want total=%v; got %v (i=%d)", cas.total, total, i) + continue + } + } +} diff --git a/vendor/golang.org/x/tools/.gitattributes b/vendor/golang.org/x/tools/.gitattributes new file mode 100644 index 00000000..d2f212e5 --- /dev/null +++ b/vendor/golang.org/x/tools/.gitattributes @@ -0,0 +1,10 @@ +# Treat all files in this repo as binary, with no git magic updating +# line endings. Windows users contributing to Go will need to use a +# modern version of git and editors capable of LF line endings. +# +# We'll prevent accidental CRLF line endings from entering the repo +# via the git-review gofmt checks. +# +# See golang.org/issue/9281 + +* -text diff --git a/vendor/golang.org/x/tools/.gitignore b/vendor/golang.org/x/tools/.gitignore new file mode 100644 index 00000000..5a9d62ef --- /dev/null +++ b/vendor/golang.org/x/tools/.gitignore @@ -0,0 +1,2 @@ +# Add no patterns to .gitignore except for files generated by the build. +last-change diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS new file mode 100644 index 00000000..15167cd7 --- /dev/null +++ b/vendor/golang.org/x/tools/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/tools/CONTRIBUTING.md b/vendor/golang.org/x/tools/CONTRIBUTING.md new file mode 100644 index 00000000..d0485e88 --- /dev/null +++ b/vendor/golang.org/x/tools/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contributing to Go + +Go is an open source project. + +It is the work of hundreds of contributors. We appreciate your help! + +## Filing issues + +When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. +The gophers there will answer or ask you to file an issue if you've tripped over a bug. + +## Contributing code + +Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) +before sending patches. + +Unless otherwise noted, the Go source files are distributed under +the BSD-style license found in the LICENSE file. diff --git a/vendor/golang.org/x/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS new file mode 100644 index 00000000..1c4577e9 --- /dev/null +++ b/vendor/golang.org/x/tools/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/vendor/golang.org/x/tools/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/vendor/golang.org/x/tools/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/tools/README.md b/vendor/golang.org/x/tools/README.md new file mode 100644 index 00000000..20be9e1a --- /dev/null +++ b/vendor/golang.org/x/tools/README.md @@ -0,0 +1,27 @@ +# Go Tools + +This subrepository holds the source for various packages and tools that support +the Go programming language. + +Some of the tools, `godoc` and `vet` for example, are included in binary Go +distributions. + +Others, including the Go `guru` and the test coverage tool, can be fetched with +`go get`. + +Packages include a type-checker for Go and an implementation of the +Static Single Assignment form (SSA) representation for Go programs. + +## Download/Install + +The easiest way to install is to run `go get -u golang.org/x/tools/...`. You can +also manually git clone the repository to `$GOPATH/src/golang.org/x/tools`. + +## Report Issues / Send Patches + +This repository uses Gerrit for code changes. To learn how to submit changes to +this repository, see https://golang.org/doc/contribute.html. + +The main issue tracker for the tools repository is located at +https://github.com/golang/go/issues. Prefix your issue with "x/tools/(your +subdir):" in the subject line, so it is easy to find. diff --git a/vendor/golang.org/x/tools/benchmark/parse/parse.go b/vendor/golang.org/x/tools/benchmark/parse/parse.go new file mode 100644 index 00000000..b37e6f0f --- /dev/null +++ b/vendor/golang.org/x/tools/benchmark/parse/parse.go @@ -0,0 +1,131 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package parse provides support for parsing benchmark results as +// generated by 'go test -bench'. +package parse // import "golang.org/x/tools/benchmark/parse" + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" +) + +// Flags used by Benchmark.Measured to indicate +// which measurements a Benchmark contains. +const ( + NsPerOp = 1 << iota + MBPerS + AllocedBytesPerOp + AllocsPerOp +) + +// Benchmark is one run of a single benchmark. +type Benchmark struct { + Name string // benchmark name + N int // number of iterations + NsPerOp float64 // nanoseconds per iteration + AllocedBytesPerOp uint64 // bytes allocated per iteration + AllocsPerOp uint64 // allocs per iteration + MBPerS float64 // MB processed per second + Measured int // which measurements were recorded + Ord int // ordinal position within a benchmark run +} + +// ParseLine extracts a Benchmark from a single line of testing.B +// output. +func ParseLine(line string) (*Benchmark, error) { + fields := strings.Fields(line) + + // Two required, positional fields: Name and iterations. + if len(fields) < 2 { + return nil, fmt.Errorf("two fields required, have %d", len(fields)) + } + if !strings.HasPrefix(fields[0], "Benchmark") { + return nil, fmt.Errorf(`first field does not start with "Benchmark"`) + } + n, err := strconv.Atoi(fields[1]) + if err != nil { + return nil, err + } + b := &Benchmark{Name: fields[0], N: n} + + // Parse any remaining pairs of fields; we've parsed one pair already. + for i := 1; i < len(fields)/2; i++ { + b.parseMeasurement(fields[i*2], fields[i*2+1]) + } + return b, nil +} + +func (b *Benchmark) parseMeasurement(quant string, unit string) { + switch unit { + case "ns/op": + if f, err := strconv.ParseFloat(quant, 64); err == nil { + b.NsPerOp = f + b.Measured |= NsPerOp + } + case "MB/s": + if f, err := strconv.ParseFloat(quant, 64); err == nil { + b.MBPerS = f + b.Measured |= MBPerS + } + case "B/op": + if i, err := strconv.ParseUint(quant, 10, 64); err == nil { + b.AllocedBytesPerOp = i + b.Measured |= AllocedBytesPerOp + } + case "allocs/op": + if i, err := strconv.ParseUint(quant, 10, 64); err == nil { + b.AllocsPerOp = i + b.Measured |= AllocsPerOp + } + } +} + +func (b *Benchmark) String() string { + buf := new(bytes.Buffer) + fmt.Fprintf(buf, "%s %d", b.Name, b.N) + if (b.Measured & NsPerOp) != 0 { + fmt.Fprintf(buf, " %.2f ns/op", b.NsPerOp) + } + if (b.Measured & MBPerS) != 0 { + fmt.Fprintf(buf, " %.2f MB/s", b.MBPerS) + } + if (b.Measured & AllocedBytesPerOp) != 0 { + fmt.Fprintf(buf, " %d B/op", b.AllocedBytesPerOp) + } + if (b.Measured & AllocsPerOp) != 0 { + fmt.Fprintf(buf, " %d allocs/op", b.AllocsPerOp) + } + return buf.String() +} + +// Set is a collection of benchmarks from one +// testing.B run, keyed by name to facilitate comparison. +type Set map[string][]*Benchmark + +// ParseSet extracts a Set from testing.B output. +// ParseSet preserves the order of benchmarks that have identical +// names. +func ParseSet(r io.Reader) (Set, error) { + bb := make(Set) + scan := bufio.NewScanner(r) + ord := 0 + for scan.Scan() { + if b, err := ParseLine(scan.Text()); err == nil { + b.Ord = ord + ord++ + bb[b.Name] = append(bb[b.Name], b) + } + } + + if err := scan.Err(); err != nil { + return nil, err + } + + return bb, nil +} diff --git a/vendor/golang.org/x/tools/benchmark/parse/parse_test.go b/vendor/golang.org/x/tools/benchmark/parse/parse_test.go new file mode 100644 index 00000000..06db8489 --- /dev/null +++ b/vendor/golang.org/x/tools/benchmark/parse/parse_test.go @@ -0,0 +1,154 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package parse + +import ( + "reflect" + "strings" + "testing" +) + +func TestParseLine(t *testing.T) { + cases := []struct { + line string + want *Benchmark + err bool // expect an error + }{ + { + line: "BenchmarkEncrypt 100000000 19.6 ns/op", + want: &Benchmark{ + Name: "BenchmarkEncrypt", + N: 100000000, NsPerOp: 19.6, + Measured: NsPerOp, + }, + }, + { + line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77 MB/s", + want: &Benchmark{ + Name: "BenchmarkEncrypt", + N: 100000000, NsPerOp: 19.6, MBPerS: 817.77, + Measured: NsPerOp | MBPerS, + }, + }, + { + line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77", + want: &Benchmark{ + Name: "BenchmarkEncrypt", + N: 100000000, NsPerOp: 19.6, + Measured: NsPerOp, + }, + }, + { + line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77 MB/s 5 allocs/op", + want: &Benchmark{ + Name: "BenchmarkEncrypt", + N: 100000000, NsPerOp: 19.6, MBPerS: 817.77, AllocsPerOp: 5, + Measured: NsPerOp | MBPerS | AllocsPerOp, + }, + }, + { + line: "BenchmarkEncrypt 100000000 19.6 ns/op 817.77 MB/s 3 B/op 5 allocs/op", + want: &Benchmark{ + Name: "BenchmarkEncrypt", + N: 100000000, NsPerOp: 19.6, MBPerS: 817.77, AllocedBytesPerOp: 3, AllocsPerOp: 5, + Measured: NsPerOp | MBPerS | AllocedBytesPerOp | AllocsPerOp, + }, + }, + // error handling cases + { + line: "BenchPress 100 19.6 ns/op", // non-benchmark + err: true, + }, + { + line: "BenchmarkEncrypt lots 19.6 ns/op", // non-int iterations + err: true, + }, + { + line: "BenchmarkBridge 100000000 19.6 smoots", // unknown unit + want: &Benchmark{ + Name: "BenchmarkBridge", + N: 100000000, + }, + }, + { + line: "PASS", + err: true, + }, + } + + for _, tt := range cases { + have, err := ParseLine(tt.line) + if tt.err && err == nil { + t.Errorf("parsing line %q should have failed", tt.line) + continue + } + if !reflect.DeepEqual(have, tt.want) { + t.Errorf("parsed line %q incorrectly, want %v have %v", tt.line, tt.want, have) + } + } +} + +func TestParseSet(t *testing.T) { + // Test two things: + // 1. The noise that can accompany testing.B output gets ignored. + // 2. Benchmarks with the same name have their order preserved. + in := ` + ? crypto [no test files] + PASS + pem_decrypt_test.go:17: test 4. %!s(x509.PEMCipher=5) + ... [output truncated] + + BenchmarkEncrypt 100000000 19.6 ns/op + BenchmarkEncrypt 5000000 517 ns/op + === RUN TestChunk + --- PASS: TestChunk (0.00 seconds) + --- SKIP: TestLinuxSendfile (0.00 seconds) + fs_test.go:716: skipping; linux-only test + BenchmarkReadRequestApachebench 1000000 2960 ns/op 27.70 MB/s 839 B/op 9 allocs/op + BenchmarkClientServerParallel64 50000 59192 ns/op 7028 B/op 60 allocs/op + ok net/http 95.783s + ` + + want := Set{ + "BenchmarkReadRequestApachebench": []*Benchmark{ + { + Name: "BenchmarkReadRequestApachebench", + N: 1000000, NsPerOp: 2960, MBPerS: 27.70, AllocedBytesPerOp: 839, AllocsPerOp: 9, + Measured: NsPerOp | MBPerS | AllocedBytesPerOp | AllocsPerOp, + Ord: 2, + }, + }, + "BenchmarkClientServerParallel64": []*Benchmark{ + { + Name: "BenchmarkClientServerParallel64", + N: 50000, NsPerOp: 59192, AllocedBytesPerOp: 7028, AllocsPerOp: 60, + Measured: NsPerOp | AllocedBytesPerOp | AllocsPerOp, + Ord: 3, + }, + }, + "BenchmarkEncrypt": []*Benchmark{ + { + Name: "BenchmarkEncrypt", + N: 100000000, NsPerOp: 19.6, + Measured: NsPerOp, + Ord: 0, + }, + { + Name: "BenchmarkEncrypt", + N: 5000000, NsPerOp: 517, + Measured: NsPerOp, + Ord: 1, + }, + }, + } + + have, err := ParseSet(strings.NewReader(in)) + if err != nil { + t.Fatalf("unexpected err during ParseSet: %v", err) + } + if !reflect.DeepEqual(want, have) { + t.Errorf("parsed bench set incorrectly, want %v have %v", want, have) + } +} diff --git a/vendor/golang.org/x/tools/blog/atom/atom.go b/vendor/golang.org/x/tools/blog/atom/atom.go new file mode 100644 index 00000000..542c50e6 --- /dev/null +++ b/vendor/golang.org/x/tools/blog/atom/atom.go @@ -0,0 +1,61 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Adapted from encoding/xml/read_test.go. + +// Package atom defines XML data structures for an Atom feed. +package atom // import "golang.org/x/tools/blog/atom" + +import ( + "encoding/xml" + "time" +) + +type Feed struct { + XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"` + Title string `xml:"title"` + ID string `xml:"id"` + Link []Link `xml:"link"` + Updated TimeStr `xml:"updated"` + Author *Person `xml:"author"` + Entry []*Entry `xml:"entry"` +} + +type Entry struct { + Title string `xml:"title"` + ID string `xml:"id"` + Link []Link `xml:"link"` + Published TimeStr `xml:"published"` + Updated TimeStr `xml:"updated"` + Author *Person `xml:"author"` + Summary *Text `xml:"summary"` + Content *Text `xml:"content"` +} + +type Link struct { + Rel string `xml:"rel,attr,omitempty"` + Href string `xml:"href,attr"` + Type string `xml:"type,attr,omitempty"` + HrefLang string `xml:"hreflang,attr,omitempty"` + Title string `xml:"title,attr,omitempty"` + Length uint `xml:"length,attr,omitempty"` +} + +type Person struct { + Name string `xml:"name"` + URI string `xml:"uri,omitempty"` + Email string `xml:"email,omitempty"` + InnerXML string `xml:",innerxml"` +} + +type Text struct { + Type string `xml:"type,attr"` + Body string `xml:",chardata"` +} + +type TimeStr string + +func Time(t time.Time) TimeStr { + return TimeStr(t.Format("2006-01-02T15:04:05-07:00")) +} diff --git a/vendor/golang.org/x/tools/blog/blog.go b/vendor/golang.org/x/tools/blog/blog.go new file mode 100644 index 00000000..73c184d4 --- /dev/null +++ b/vendor/golang.org/x/tools/blog/blog.go @@ -0,0 +1,456 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package blog implements a web server for articles written in present format. +package blog // import "golang.org/x/tools/blog" + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "html/template" + "log" + "net/http" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + "time" + + "golang.org/x/tools/blog/atom" + "golang.org/x/tools/present" +) + +var ( + validJSONPFunc = regexp.MustCompile(`(?i)^[a-z_][a-z0-9_.]*$`) + // used to serve relative paths when ServeLocalLinks is enabled. + golangOrgAbsLinkReplacer = strings.NewReplacer( + `href="https://golang.org/pkg`, `href="/pkg`, + `href="https://golang.org/cmd`, `href="/cmd`, + ) +) + +// Config specifies Server configuration values. +type Config struct { + ContentPath string // Relative or absolute location of article files and related content. + TemplatePath string // Relative or absolute location of template files. + + BaseURL string // Absolute base URL (for permalinks; no trailing slash). + BasePath string // Base URL path relative to server root (no trailing slash). + GodocURL string // The base URL of godoc (for menu bar; no trailing slash). + Hostname string // Server host name, used for rendering ATOM feeds. + + HomeArticles int // Articles to display on the home page. + FeedArticles int // Articles to include in Atom and JSON feeds. + FeedTitle string // The title of the Atom XML feed + + PlayEnabled bool + ServeLocalLinks bool // rewrite golang.org/{pkg,cmd} links to host-less, relative paths. +} + +// Doc represents an article adorned with presentation data. +type Doc struct { + *present.Doc + Permalink string // Canonical URL for this document. + Path string // Path relative to server root (including base). + HTML template.HTML // rendered article + + Related []*Doc + Newer, Older *Doc +} + +// Server implements an http.Handler that serves blog articles. +type Server struct { + cfg Config + docs []*Doc + tags []string + docPaths map[string]*Doc // key is path without BasePath. + docTags map[string][]*Doc + template struct { + home, index, article, doc *template.Template + } + atomFeed []byte // pre-rendered Atom feed + jsonFeed []byte // pre-rendered JSON feed + content http.Handler +} + +// NewServer constructs a new Server using the specified config. +func NewServer(cfg Config) (*Server, error) { + present.PlayEnabled = cfg.PlayEnabled + + if notExist(cfg.TemplatePath) { + return nil, fmt.Errorf("template directory not found: %s", cfg.TemplatePath) + } + root := filepath.Join(cfg.TemplatePath, "root.tmpl") + parse := func(name string) (*template.Template, error) { + path := filepath.Join(cfg.TemplatePath, name) + if notExist(path) { + return nil, fmt.Errorf("template %s was not found in %s", name, cfg.TemplatePath) + } + t := template.New("").Funcs(funcMap) + return t.ParseFiles(root, path) + } + + s := &Server{cfg: cfg} + + // Parse templates. + var err error + s.template.home, err = parse("home.tmpl") + if err != nil { + return nil, err + } + s.template.index, err = parse("index.tmpl") + if err != nil { + return nil, err + } + s.template.article, err = parse("article.tmpl") + if err != nil { + return nil, err + } + p := present.Template().Funcs(funcMap) + s.template.doc, err = p.ParseFiles(filepath.Join(cfg.TemplatePath, "doc.tmpl")) + if err != nil { + return nil, err + } + + // Load content. + err = s.loadDocs(filepath.Clean(cfg.ContentPath)) + if err != nil { + return nil, err + } + + err = s.renderAtomFeed() + if err != nil { + return nil, err + } + + err = s.renderJSONFeed() + if err != nil { + return nil, err + } + + // Set up content file server. + s.content = http.StripPrefix(s.cfg.BasePath, http.FileServer(http.Dir(cfg.ContentPath))) + + return s, nil +} + +var funcMap = template.FuncMap{ + "sectioned": sectioned, + "authors": authors, +} + +// sectioned returns true if the provided Doc contains more than one section. +// This is used to control whether to display the table of contents and headings. +func sectioned(d *present.Doc) bool { + return len(d.Sections) > 1 +} + +// authors returns a comma-separated list of author names. +func authors(authors []present.Author) string { + var b bytes.Buffer + last := len(authors) - 1 + for i, a := range authors { + if i > 0 { + if i == last { + b.WriteString(" and ") + } else { + b.WriteString(", ") + } + } + b.WriteString(authorName(a)) + } + return b.String() +} + +// authorName returns the first line of the Author text: the author's name. +func authorName(a present.Author) string { + el := a.TextElem() + if len(el) == 0 { + return "" + } + text, ok := el[0].(present.Text) + if !ok || len(text.Lines) == 0 { + return "" + } + return text.Lines[0] +} + +// loadDocs reads all content from the provided file system root, renders all +// the articles it finds, adds them to the Server's docs field, computes the +// denormalized docPaths, docTags, and tags fields, and populates the various +// helper fields (Next, Previous, Related) for each Doc. +func (s *Server) loadDocs(root string) error { + // Read content into docs field. + const ext = ".article" + fn := func(p string, info os.FileInfo, err error) error { + if filepath.Ext(p) != ext { + return nil + } + f, err := os.Open(p) + if err != nil { + return err + } + defer f.Close() + d, err := present.Parse(f, p, 0) + if err != nil { + return err + } + var html bytes.Buffer + err = d.Render(&html, s.template.doc) + if err != nil { + return err + } + p = p[len(root) : len(p)-len(ext)] // trim root and extension + p = filepath.ToSlash(p) + s.docs = append(s.docs, &Doc{ + Doc: d, + Path: s.cfg.BasePath + p, + Permalink: s.cfg.BaseURL + p, + HTML: template.HTML(html.String()), + }) + return nil + } + err := filepath.Walk(root, fn) + if err != nil { + return err + } + sort.Sort(docsByTime(s.docs)) + + // Pull out doc paths and tags and put in reverse-associating maps. + s.docPaths = make(map[string]*Doc) + s.docTags = make(map[string][]*Doc) + for _, d := range s.docs { + s.docPaths[strings.TrimPrefix(d.Path, s.cfg.BasePath)] = d + for _, t := range d.Tags { + s.docTags[t] = append(s.docTags[t], d) + } + } + + // Pull out unique sorted list of tags. + for t := range s.docTags { + s.tags = append(s.tags, t) + } + sort.Strings(s.tags) + + // Set up presentation-related fields, Newer, Older, and Related. + for _, doc := range s.docs { + // Newer, Older: docs adjacent to doc + for i := range s.docs { + if s.docs[i] != doc { + continue + } + if i > 0 { + doc.Newer = s.docs[i-1] + } + if i+1 < len(s.docs) { + doc.Older = s.docs[i+1] + } + break + } + + // Related: all docs that share tags with doc. + related := make(map[*Doc]bool) + for _, t := range doc.Tags { + for _, d := range s.docTags[t] { + if d != doc { + related[d] = true + } + } + } + for d := range related { + doc.Related = append(doc.Related, d) + } + sort.Sort(docsByTime(doc.Related)) + } + + return nil +} + +// renderAtomFeed generates an XML Atom feed and stores it in the Server's +// atomFeed field. +func (s *Server) renderAtomFeed() error { + var updated time.Time + if len(s.docs) > 0 { + updated = s.docs[0].Time + } + feed := atom.Feed{ + Title: s.cfg.FeedTitle, + ID: "tag:" + s.cfg.Hostname + ",2013:" + s.cfg.Hostname, + Updated: atom.Time(updated), + Link: []atom.Link{{ + Rel: "self", + Href: s.cfg.BaseURL + "/feed.atom", + }}, + } + for i, doc := range s.docs { + if i >= s.cfg.FeedArticles { + break + } + e := &atom.Entry{ + Title: doc.Title, + ID: feed.ID + doc.Path, + Link: []atom.Link{{ + Rel: "alternate", + Href: doc.Permalink, + }}, + Published: atom.Time(doc.Time), + Updated: atom.Time(doc.Time), + Summary: &atom.Text{ + Type: "html", + Body: summary(doc), + }, + Content: &atom.Text{ + Type: "html", + Body: string(doc.HTML), + }, + Author: &atom.Person{ + Name: authors(doc.Authors), + }, + } + feed.Entry = append(feed.Entry, e) + } + data, err := xml.Marshal(&feed) + if err != nil { + return err + } + s.atomFeed = data + return nil +} + +type jsonItem struct { + Title string + Link string + Time time.Time + Summary string + Content string + Author string +} + +// renderJSONFeed generates a JSON feed and stores it in the Server's jsonFeed +// field. +func (s *Server) renderJSONFeed() error { + var feed []jsonItem + for i, doc := range s.docs { + if i >= s.cfg.FeedArticles { + break + } + item := jsonItem{ + Title: doc.Title, + Link: doc.Permalink, + Time: doc.Time, + Summary: summary(doc), + Content: string(doc.HTML), + Author: authors(doc.Authors), + } + feed = append(feed, item) + } + data, err := json.Marshal(feed) + if err != nil { + return err + } + s.jsonFeed = data + return nil +} + +// summary returns the first paragraph of text from the provided Doc. +func summary(d *Doc) string { + if len(d.Sections) == 0 { + return "" + } + for _, elem := range d.Sections[0].Elem { + text, ok := elem.(present.Text) + if !ok || text.Pre { + // skip everything but non-text elements + continue + } + var buf bytes.Buffer + for _, s := range text.Lines { + buf.WriteString(string(present.Style(s))) + buf.WriteByte('\n') + } + return buf.String() + } + return "" +} + +// rootData encapsulates data destined for the root template. +type rootData struct { + Doc *Doc + BasePath string + GodocURL string + Data interface{} +} + +// ServeHTTP serves the front, index, and article pages +// as well as the ATOM and JSON feeds. +func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var ( + d = rootData{BasePath: s.cfg.BasePath, GodocURL: s.cfg.GodocURL} + t *template.Template + ) + switch p := strings.TrimPrefix(r.URL.Path, s.cfg.BasePath); p { + case "/": + d.Data = s.docs + if len(s.docs) > s.cfg.HomeArticles { + d.Data = s.docs[:s.cfg.HomeArticles] + } + t = s.template.home + case "/index": + d.Data = s.docs + t = s.template.index + case "/feed.atom", "/feeds/posts/default": + w.Header().Set("Content-type", "application/atom+xml; charset=utf-8") + w.Write(s.atomFeed) + return + case "/.json": + if p := r.FormValue("jsonp"); validJSONPFunc.MatchString(p) { + w.Header().Set("Content-type", "application/javascript; charset=utf-8") + fmt.Fprintf(w, "%v(%s)", p, s.jsonFeed) + return + } + w.Header().Set("Content-type", "application/json; charset=utf-8") + w.Write(s.jsonFeed) + return + default: + doc, ok := s.docPaths[p] + if !ok { + // Not a doc; try to just serve static content. + s.content.ServeHTTP(w, r) + return + } + d.Doc = doc + t = s.template.article + } + var err error + if s.cfg.ServeLocalLinks { + var buf bytes.Buffer + err = t.ExecuteTemplate(&buf, "root", d) + if err != nil { + log.Println(err) + return + } + _, err = golangOrgAbsLinkReplacer.WriteString(w, buf.String()) + } else { + err = t.ExecuteTemplate(w, "root", d) + } + if err != nil { + log.Println(err) + } +} + +// docsByTime implements sort.Interface, sorting Docs by their Time field. +type docsByTime []*Doc + +func (s docsByTime) Len() int { return len(s) } +func (s docsByTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s docsByTime) Less(i, j int) bool { return s[i].Time.After(s[j].Time) } + +// notExist reports whether the path exists or not. +func notExist(path string) bool { + _, err := os.Stat(path) + return os.IsNotExist(err) +} diff --git a/vendor/golang.org/x/tools/blog/blog_test.go b/vendor/golang.org/x/tools/blog/blog_test.go new file mode 100644 index 00000000..c84be2a7 --- /dev/null +++ b/vendor/golang.org/x/tools/blog/blog_test.go @@ -0,0 +1,44 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package blog + +import ( + "bytes" + "testing" +) + +func TestLinkRewrite(t *testing.T) { + tests := []struct { + input string + output string + }{ + { + `For instance, the bytes package from the standard library exports the Buffer type.`, + `For instance, the bytes package from the standard library exports the Buffer type.`}, + { + `(The gofmt command has a -r flag that provides a syntax-aware search and replace, making large-scale refactoring easier.)`, + `(The gofmt command has a -r flag that provides a syntax-aware search and replace, making large-scale refactoring easier.)`, + }, + { + `BSD license.
Terms of Service `, + `BSD license.
Terms of Service `, + }, + { + `For instance, the websocket package from the go.net sub-repository has an import path of "golang.org/x/net/websocket".`, + `For instance, the websocket package from the go.net sub-repository has an import path of "golang.org/x/net/websocket".`, + }, + } + for _, test := range tests { + var buf bytes.Buffer + _, err := golangOrgAbsLinkReplacer.WriteString(&buf, test.input) + if err != nil { + t.Errorf("unexpected error during replacing links. Got: %#v, Want: nil.\n", err) + continue + } + if got, want := buf.String(), test.output; got != want { + t.Errorf("WriteString(%q) = %q. Expected: %q", test.input, got, want) + } + } +} diff --git a/vendor/golang.org/x/tools/cmd/benchcmp/benchcmp.go b/vendor/golang.org/x/tools/cmd/benchcmp/benchcmp.go new file mode 100644 index 00000000..32f3a1c8 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/benchcmp/benchcmp.go @@ -0,0 +1,184 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "flag" + "fmt" + "os" + "sort" + "strconv" + "text/tabwriter" + + "golang.org/x/tools/benchmark/parse" +) + +var ( + changedOnly = flag.Bool("changed", false, "show only benchmarks that have changed") + magSort = flag.Bool("mag", false, "sort benchmarks by magnitude of change") + best = flag.Bool("best", false, "compare best times from old and new") +) + +const usageFooter = ` +Each input file should be from: + go test -run=NONE -bench=. > [old,new].txt + +Benchcmp compares old and new for each benchmark. + +If -test.benchmem=true is added to the "go test" command +benchcmp will also compare memory allocations. +` + +func main() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "usage: %s old.txt new.txt\n\n", os.Args[0]) + flag.PrintDefaults() + fmt.Fprint(os.Stderr, usageFooter) + os.Exit(2) + } + flag.Parse() + if flag.NArg() != 2 { + flag.Usage() + } + + before := parseFile(flag.Arg(0)) + after := parseFile(flag.Arg(1)) + + cmps, warnings := Correlate(before, after) + + for _, warn := range warnings { + fmt.Fprintln(os.Stderr, warn) + } + + if len(cmps) == 0 { + fatal("benchcmp: no repeated benchmarks") + } + + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 0, 5, ' ', 0) + defer w.Flush() + + var header bool // Has the header has been displayed yet for a given block? + + if *magSort { + sort.Sort(ByDeltaNsPerOp(cmps)) + } else { + sort.Sort(ByParseOrder(cmps)) + } + for _, cmp := range cmps { + if !cmp.Measured(parse.NsPerOp) { + continue + } + if delta := cmp.DeltaNsPerOp(); !*changedOnly || delta.Changed() { + if !header { + fmt.Fprint(w, "benchmark\told ns/op\tnew ns/op\tdelta\n") + header = true + } + fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", cmp.Name(), formatNs(cmp.Before.NsPerOp), formatNs(cmp.After.NsPerOp), delta.Percent()) + } + } + + header = false + if *magSort { + sort.Sort(ByDeltaMBPerS(cmps)) + } + for _, cmp := range cmps { + if !cmp.Measured(parse.MBPerS) { + continue + } + if delta := cmp.DeltaMBPerS(); !*changedOnly || delta.Changed() { + if !header { + fmt.Fprint(w, "\nbenchmark\told MB/s\tnew MB/s\tspeedup\n") + header = true + } + fmt.Fprintf(w, "%s\t%.2f\t%.2f\t%s\n", cmp.Name(), cmp.Before.MBPerS, cmp.After.MBPerS, delta.Multiple()) + } + } + + header = false + if *magSort { + sort.Sort(ByDeltaAllocsPerOp(cmps)) + } + for _, cmp := range cmps { + if !cmp.Measured(parse.AllocsPerOp) { + continue + } + if delta := cmp.DeltaAllocsPerOp(); !*changedOnly || delta.Changed() { + if !header { + fmt.Fprint(w, "\nbenchmark\told allocs\tnew allocs\tdelta\n") + header = true + } + fmt.Fprintf(w, "%s\t%d\t%d\t%s\n", cmp.Name(), cmp.Before.AllocsPerOp, cmp.After.AllocsPerOp, delta.Percent()) + } + } + + header = false + if *magSort { + sort.Sort(ByDeltaAllocedBytesPerOp(cmps)) + } + for _, cmp := range cmps { + if !cmp.Measured(parse.AllocedBytesPerOp) { + continue + } + if delta := cmp.DeltaAllocedBytesPerOp(); !*changedOnly || delta.Changed() { + if !header { + fmt.Fprint(w, "\nbenchmark\told bytes\tnew bytes\tdelta\n") + header = true + } + fmt.Fprintf(w, "%s\t%d\t%d\t%s\n", cmp.Name(), cmp.Before.AllocedBytesPerOp, cmp.After.AllocedBytesPerOp, cmp.DeltaAllocedBytesPerOp().Percent()) + } + } +} + +func fatal(msg interface{}) { + fmt.Fprintln(os.Stderr, msg) + os.Exit(1) +} + +func parseFile(path string) parse.Set { + f, err := os.Open(path) + if err != nil { + fatal(err) + } + defer f.Close() + bb, err := parse.ParseSet(f) + if err != nil { + fatal(err) + } + if *best { + selectBest(bb) + } + return bb +} + +func selectBest(bs parse.Set) { + for name, bb := range bs { + if len(bb) < 2 { + continue + } + ord := bb[0].Ord + best := bb[0] + for _, b := range bb { + if b.NsPerOp < best.NsPerOp { + b.Ord = ord + best = b + } + } + bs[name] = []*parse.Benchmark{best} + } +} + +// formatNs formats ns measurements to expose a useful amount of +// precision. It mirrors the ns precision logic of testing.B. +func formatNs(ns float64) string { + prec := 0 + switch { + case ns < 10: + prec = 2 + case ns < 100: + prec = 1 + } + return strconv.FormatFloat(ns, 'f', prec, 64) +} diff --git a/vendor/golang.org/x/tools/cmd/benchcmp/benchcmp_test.go b/vendor/golang.org/x/tools/cmd/benchcmp/benchcmp_test.go new file mode 100644 index 00000000..22260795 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/benchcmp/benchcmp_test.go @@ -0,0 +1,59 @@ +package main + +import ( + "reflect" + "testing" + + "golang.org/x/tools/benchmark/parse" +) + +func TestSelectBest(t *testing.T) { + have := parse.Set{ + "Benchmark1": []*parse.Benchmark{ + { + Name: "Benchmark1", + N: 10, NsPerOp: 100, Measured: parse.NsPerOp, + Ord: 0, + }, + { + Name: "Benchmark1", + N: 10, NsPerOp: 50, Measured: parse.NsPerOp, + Ord: 3, + }, + }, + "Benchmark2": []*parse.Benchmark{ + { + Name: "Benchmark2", + N: 10, NsPerOp: 60, Measured: parse.NsPerOp, + Ord: 1, + }, + { + Name: "Benchmark2", + N: 10, NsPerOp: 500, Measured: parse.NsPerOp, + Ord: 2, + }, + }, + } + + want := parse.Set{ + "Benchmark1": []*parse.Benchmark{ + { + Name: "Benchmark1", + N: 10, NsPerOp: 50, Measured: parse.NsPerOp, + Ord: 0, + }, + }, + "Benchmark2": []*parse.Benchmark{ + { + Name: "Benchmark2", + N: 10, NsPerOp: 60, Measured: parse.NsPerOp, + Ord: 1, + }, + }, + } + + selectBest(have) + if !reflect.DeepEqual(want, have) { + t.Errorf("filtered bench set incorrectly, want %v have %v", want, have) + } +} diff --git a/vendor/golang.org/x/tools/cmd/benchcmp/compare.go b/vendor/golang.org/x/tools/cmd/benchcmp/compare.go new file mode 100644 index 00000000..c3f5e89c --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/benchcmp/compare.go @@ -0,0 +1,156 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "math" + + "golang.org/x/tools/benchmark/parse" +) + +// BenchCmp is a pair of benchmarks. +type BenchCmp struct { + Before *parse.Benchmark + After *parse.Benchmark +} + +// Correlate correlates benchmarks from two BenchSets. +func Correlate(before, after parse.Set) (cmps []BenchCmp, warnings []string) { + cmps = make([]BenchCmp, 0, len(after)) + for name, beforebb := range before { + afterbb := after[name] + if len(beforebb) != len(afterbb) { + warnings = append(warnings, fmt.Sprintf("ignoring %s: before has %d instances, after has %d", name, len(beforebb), len(afterbb))) + continue + } + for i, beforeb := range beforebb { + afterb := afterbb[i] + cmps = append(cmps, BenchCmp{beforeb, afterb}) + } + } + return +} + +func (c BenchCmp) Name() string { return c.Before.Name } +func (c BenchCmp) String() string { return fmt.Sprintf("<%s, %s>", c.Before, c.After) } +func (c BenchCmp) Measured(flag int) bool { return (c.Before.Measured & c.After.Measured & flag) != 0 } +func (c BenchCmp) DeltaNsPerOp() Delta { return Delta{c.Before.NsPerOp, c.After.NsPerOp} } +func (c BenchCmp) DeltaMBPerS() Delta { return Delta{c.Before.MBPerS, c.After.MBPerS} } +func (c BenchCmp) DeltaAllocedBytesPerOp() Delta { + return Delta{float64(c.Before.AllocedBytesPerOp), float64(c.After.AllocedBytesPerOp)} +} +func (c BenchCmp) DeltaAllocsPerOp() Delta { + return Delta{float64(c.Before.AllocsPerOp), float64(c.After.AllocsPerOp)} +} + +// Delta is the before and after value for a benchmark measurement. +// Both must be non-negative. +type Delta struct { + Before float64 + After float64 +} + +// mag calculates the magnitude of a change, regardless of the direction of +// the change. mag is intended for sorting and has no independent meaning. +func (d Delta) mag() float64 { + switch { + case d.Before != 0 && d.After != 0 && d.Before >= d.After: + return d.After / d.Before + case d.Before != 0 && d.After != 0 && d.Before < d.After: + return d.Before / d.After + case d.Before == 0 && d.After == 0: + return 1 + default: + // 0 -> 1 or 1 -> 0 + // These are significant changes and worth surfacing. + return math.Inf(1) + } +} + +// Changed reports whether the benchmark quantities are different. +func (d Delta) Changed() bool { return d.Before != d.After } + +// Float64 returns After / Before. If Before is 0, Float64 returns +// 1 if After is also 0, and +Inf otherwise. +func (d Delta) Float64() float64 { + switch { + case d.Before != 0: + return d.After / d.Before + case d.After == 0: + return 1 + default: + return math.Inf(1) + } +} + +// Percent formats a Delta as a percent change, ranging from -100% up. +func (d Delta) Percent() string { + return fmt.Sprintf("%+.2f%%", 100*d.Float64()-100) +} + +// Multiple formats a Delta as a multiplier, ranging from 0.00x up. +func (d Delta) Multiple() string { + return fmt.Sprintf("%.2fx", d.Float64()) +} + +func (d Delta) String() string { + return fmt.Sprintf("Δ(%f, %f)", d.Before, d.After) +} + +// ByParseOrder sorts BenchCmps to match the order in +// which the Before benchmarks were presented to Parse. +type ByParseOrder []BenchCmp + +func (x ByParseOrder) Len() int { return len(x) } +func (x ByParseOrder) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x ByParseOrder) Less(i, j int) bool { return x[i].Before.Ord < x[j].Before.Ord } + +// lessByDelta provides lexicographic ordering: +// * largest delta by magnitude +// * alphabetic by name +func lessByDelta(i, j BenchCmp, calcDelta func(BenchCmp) Delta) bool { + iDelta, jDelta := calcDelta(i).mag(), calcDelta(j).mag() + if iDelta != jDelta { + return iDelta < jDelta + } + return i.Name() < j.Name() +} + +// ByDeltaNsPerOp sorts BenchCmps lexicographically by change +// in ns/op, descending, then by benchmark name. +type ByDeltaNsPerOp []BenchCmp + +func (x ByDeltaNsPerOp) Len() int { return len(x) } +func (x ByDeltaNsPerOp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x ByDeltaNsPerOp) Less(i, j int) bool { return lessByDelta(x[i], x[j], BenchCmp.DeltaNsPerOp) } + +// ByDeltaMBPerS sorts BenchCmps lexicographically by change +// in MB/s, descending, then by benchmark name. +type ByDeltaMBPerS []BenchCmp + +func (x ByDeltaMBPerS) Len() int { return len(x) } +func (x ByDeltaMBPerS) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x ByDeltaMBPerS) Less(i, j int) bool { return lessByDelta(x[i], x[j], BenchCmp.DeltaMBPerS) } + +// ByDeltaAllocedBytesPerOp sorts BenchCmps lexicographically by change +// in B/op, descending, then by benchmark name. +type ByDeltaAllocedBytesPerOp []BenchCmp + +func (x ByDeltaAllocedBytesPerOp) Len() int { return len(x) } +func (x ByDeltaAllocedBytesPerOp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x ByDeltaAllocedBytesPerOp) Less(i, j int) bool { + return lessByDelta(x[i], x[j], BenchCmp.DeltaAllocedBytesPerOp) +} + +// ByDeltaAllocsPerOp sorts BenchCmps lexicographically by change +// in allocs/op, descending, then by benchmark name. +type ByDeltaAllocsPerOp []BenchCmp + +func (x ByDeltaAllocsPerOp) Len() int { return len(x) } +func (x ByDeltaAllocsPerOp) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x ByDeltaAllocsPerOp) Less(i, j int) bool { + return lessByDelta(x[i], x[j], BenchCmp.DeltaAllocsPerOp) +} diff --git a/vendor/golang.org/x/tools/cmd/benchcmp/compare_test.go b/vendor/golang.org/x/tools/cmd/benchcmp/compare_test.go new file mode 100644 index 00000000..3403796d --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/benchcmp/compare_test.go @@ -0,0 +1,133 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "math" + "reflect" + "sort" + "testing" + + "golang.org/x/tools/benchmark/parse" +) + +func TestDelta(t *testing.T) { + cases := []struct { + before float64 + after float64 + mag float64 + f float64 + changed bool + pct string + mult string + }{ + {before: 1, after: 1, mag: 1, f: 1, changed: false, pct: "+0.00%", mult: "1.00x"}, + {before: 1, after: 2, mag: 0.5, f: 2, changed: true, pct: "+100.00%", mult: "2.00x"}, + {before: 2, after: 1, mag: 0.5, f: 0.5, changed: true, pct: "-50.00%", mult: "0.50x"}, + {before: 0, after: 0, mag: 1, f: 1, changed: false, pct: "+0.00%", mult: "1.00x"}, + {before: 1, after: 0, mag: math.Inf(1), f: 0, changed: true, pct: "-100.00%", mult: "0.00x"}, + {before: 0, after: 1, mag: math.Inf(1), f: math.Inf(1), changed: true, pct: "+Inf%", mult: "+Infx"}, + } + for _, tt := range cases { + d := Delta{tt.before, tt.after} + if want, have := tt.mag, d.mag(); want != have { + t.Errorf("%s.mag(): want %f have %f", d, want, have) + } + if want, have := tt.f, d.Float64(); want != have { + t.Errorf("%s.Float64(): want %f have %f", d, want, have) + } + if want, have := tt.changed, d.Changed(); want != have { + t.Errorf("%s.Changed(): want %t have %t", d, want, have) + } + if want, have := tt.pct, d.Percent(); want != have { + t.Errorf("%s.Percent(): want %q have %q", d, want, have) + } + if want, have := tt.mult, d.Multiple(); want != have { + t.Errorf("%s.Multiple(): want %q have %q", d, want, have) + } + } +} + +func TestCorrelate(t *testing.T) { + // Benches that are going to be successfully correlated get N thus: + // 0x + // Read this: " of , from ". + before := parse.Set{ + "BenchmarkOneEach": []*parse.Benchmark{{Name: "BenchmarkOneEach", N: 0x11b}}, + "BenchmarkOneToNone": []*parse.Benchmark{{Name: "BenchmarkOneToNone"}}, + "BenchmarkOneToTwo": []*parse.Benchmark{{Name: "BenchmarkOneToTwo"}}, + "BenchmarkTwoToOne": []*parse.Benchmark{ + {Name: "BenchmarkTwoToOne"}, + {Name: "BenchmarkTwoToOne"}, + }, + "BenchmarkTwoEach": []*parse.Benchmark{ + {Name: "BenchmarkTwoEach", N: 0x12b}, + {Name: "BenchmarkTwoEach", N: 0x22b}, + }, + } + + after := parse.Set{ + "BenchmarkOneEach": []*parse.Benchmark{{Name: "BenchmarkOneEach", N: 0x11a}}, + "BenchmarkNoneToOne": []*parse.Benchmark{{Name: "BenchmarkNoneToOne"}}, + "BenchmarkTwoToOne": []*parse.Benchmark{{Name: "BenchmarkTwoToOne"}}, + "BenchmarkOneToTwo": []*parse.Benchmark{ + {Name: "BenchmarkOneToTwo"}, + {Name: "BenchmarkOneToTwo"}, + }, + "BenchmarkTwoEach": []*parse.Benchmark{ + {Name: "BenchmarkTwoEach", N: 0x12a}, + {Name: "BenchmarkTwoEach", N: 0x22a}, + }, + } + + pairs, errs := Correlate(before, after) + + // Fail to match: BenchmarkOneToNone, BenchmarkOneToTwo, BenchmarkTwoToOne. + // Correlate does not notice BenchmarkNoneToOne. + if len(errs) != 3 { + t.Errorf("Correlated expected 4 errors, got %d: %v", len(errs), errs) + } + + // Want three correlated pairs: one BenchmarkOneEach, two BenchmarkTwoEach. + if len(pairs) != 3 { + t.Fatalf("Correlated expected 3 pairs, got %v", pairs) + } + + for _, pair := range pairs { + if pair.Before.N&0xF != 0xb { + t.Errorf("unexpected Before in pair %s", pair) + } + if pair.After.N&0xF != 0xa { + t.Errorf("unexpected After in pair %s", pair) + } + if pair.Before.N>>4 != pair.After.N>>4 { + t.Errorf("mismatched pair %s", pair) + } + } +} + +func TestBenchCmpSorting(t *testing.T) { + c := []BenchCmp{ + {&parse.Benchmark{Name: "BenchmarkMuchFaster", NsPerOp: 10, Ord: 3}, &parse.Benchmark{Name: "BenchmarkMuchFaster", NsPerOp: 1}}, + {&parse.Benchmark{Name: "BenchmarkSameB", NsPerOp: 5, Ord: 1}, &parse.Benchmark{Name: "BenchmarkSameB", NsPerOp: 5}}, + {&parse.Benchmark{Name: "BenchmarkSameA", NsPerOp: 5, Ord: 2}, &parse.Benchmark{Name: "BenchmarkSameA", NsPerOp: 5}}, + {&parse.Benchmark{Name: "BenchmarkSlower", NsPerOp: 10, Ord: 0}, &parse.Benchmark{Name: "BenchmarkSlower", NsPerOp: 11}}, + } + + // Test just one magnitude-based sort order; they are symmetric. + sort.Sort(ByDeltaNsPerOp(c)) + want := []string{"BenchmarkMuchFaster", "BenchmarkSlower", "BenchmarkSameA", "BenchmarkSameB"} + have := []string{c[0].Name(), c[1].Name(), c[2].Name(), c[3].Name()} + if !reflect.DeepEqual(want, have) { + t.Errorf("ByDeltaNsOp incorrect sorting: want %v have %v", want, have) + } + + sort.Sort(ByParseOrder(c)) + want = []string{"BenchmarkSlower", "BenchmarkSameB", "BenchmarkSameA", "BenchmarkMuchFaster"} + have = []string{c[0].Name(), c[1].Name(), c[2].Name(), c[3].Name()} + if !reflect.DeepEqual(want, have) { + t.Errorf("ByParseOrder incorrect sorting: want %v have %v", want, have) + } +} diff --git a/vendor/golang.org/x/tools/cmd/benchcmp/doc.go b/vendor/golang.org/x/tools/cmd/benchcmp/doc.go new file mode 100644 index 00000000..f5c7a361 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/benchcmp/doc.go @@ -0,0 +1,37 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + +The benchcmp command displays performance changes between benchmarks. + +Benchcmp parses the output of two 'go test' benchmark runs, +correlates the results per benchmark, and displays the deltas. + +To measure the performance impact of a change, use 'go test' +to run benchmarks before and after the change: + + go test -run=NONE -bench=. ./... > old.txt + # make changes + go test -run=NONE -bench=. ./... > new.txt + +Then feed the benchmark results to benchcmp: + + benchcmp old.txt new.txt + +Benchcmp will summarize and display the performance changes, +in a format like this: + + $ benchcmp old.txt new.txt + benchmark old ns/op new ns/op delta + BenchmarkConcat 523 68.6 -86.88% + + benchmark old allocs new allocs delta + BenchmarkConcat 3 1 -66.67% + + benchmark old bytes new bytes delta + BenchmarkConcat 80 48 -40.00% + +*/ +package main // import "golang.org/x/tools/cmd/benchcmp" diff --git a/vendor/golang.org/x/tools/cmd/bundle/.gitignore b/vendor/golang.org/x/tools/cmd/bundle/.gitignore new file mode 100644 index 00000000..caaeb09d --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/.gitignore @@ -0,0 +1 @@ +testdata/out.got diff --git a/vendor/golang.org/x/tools/cmd/bundle/main.go b/vendor/golang.org/x/tools/cmd/bundle/main.go new file mode 100644 index 00000000..601da7f8 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/main.go @@ -0,0 +1,468 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Bundle creates a single-source-file version of a source package +// suitable for inclusion in a particular target package. +// +// Usage: +// +// bundle [-o file] [-dst path] [-pkg name] [-prefix p] [-import old=new] +// +// The src argument specifies the import path of the package to bundle. +// The bundling of a directory of source files into a single source file +// necessarily imposes a number of constraints. +// The package being bundled must not use cgo; must not use conditional +// file compilation, whether with build tags or system-specific file names +// like code_amd64.go; must not depend on any special comments, which +// may not be preserved; must not use any assembly sources; +// must not use renaming imports; and must not use reflection-based APIs +// that depend on the specific names of types or struct fields. +// +// By default, bundle writes the bundled code to standard output. +// If the -o argument is given, bundle writes to the named file +// and also includes a ``//go:generate'' comment giving the exact +// command line used, for regenerating the file with ``go generate.'' +// +// Bundle customizes its output for inclusion in a particular package, the destination package. +// By default bundle assumes the destination is the package in the current directory, +// but the destination package can be specified explicitly using the -dst option, +// which takes an import path as its argument. +// If the source package imports the destination package, bundle will remove +// those imports and rewrite any references to use direct references to the +// corresponding symbols. +// Bundle also must write a package declaration in the output and must +// choose a name to use in that declaration. +// If the -package option is given, bundle uses that name. +// Otherwise, if the -dst option is given, bundle uses the last +// element of the destination import path. +// Otherwise, by default bundle uses the package name found in the +// package sources in the current directory. +// +// To avoid collisions, bundle inserts a prefix at the beginning of +// every package-level const, func, type, and var identifier in src's code, +// updating references accordingly. The default prefix is the package name +// of the source package followed by an underscore. The -prefix option +// specifies an alternate prefix. +// +// Occasionally it is necessary to rewrite imports during the bundling +// process. The -import option, which may be repeated, specifies that +// an import of "old" should be rewritten to import "new" instead. +// +// Example +// +// Bundle archive/zip for inclusion in cmd/dist: +// +// cd $GOROOT/src/cmd/dist +// bundle -o zip.go archive/zip +// +// Bundle golang.org/x/net/http2 for inclusion in net/http, +// prefixing all identifiers by "http2" instead of "http2_", +// and rewriting the import "golang.org/x/net/http2/hpack" +// to "internal/golang.org/x/net/http2/hpack": +// +// cd $GOROOT/src/net/http +// bundle -o h2_bundle.go \ +// -prefix http2 \ +// -import golang.org/x/net/http2/hpack=internal/golang.org/x/net/http2/hpack \ +// golang.org/x/net/http2 +// +// Two ways to update the http2 bundle: +// +// go generate net/http +// +// cd $GOROOT/src/net/http +// go generate +// +// Update both bundles, restricting ``go generate'' to running bundle commands: +// +// go generate -run bundle cmd/dist net/http +// +package main + +import ( + "bytes" + "flag" + "fmt" + "go/ast" + "go/build" + "go/format" + "go/parser" + "go/printer" + "go/token" + "go/types" + "io/ioutil" + "log" + "os" + "path" + "strconv" + "strings" + + "golang.org/x/tools/go/loader" +) + +var ( + outputFile = flag.String("o", "", "write output to `file` (default standard output)") + dstPath = flag.String("dst", "", "set destination import `path` (default taken from current directory)") + pkgName = flag.String("pkg", "", "set destination package `name` (default taken from current directory)") + prefix = flag.String("prefix", "", "set bundled identifier prefix to `p` (default source package name + \"_\")") + underscore = flag.Bool("underscore", false, "rewrite golang.org to golang_org in imports; temporary workaround for golang.org/issue/16333") + + importMap = map[string]string{} +) + +func init() { + flag.Var(flagFunc(addImportMap), "import", "rewrite import using `map`, of form old=new (can be repeated)") +} + +func addImportMap(s string) { + if strings.Count(s, "=") != 1 { + log.Fatal("-import argument must be of the form old=new") + } + i := strings.Index(s, "=") + old, new := s[:i], s[i+1:] + if old == "" || new == "" { + log.Fatal("-import argument must be of the form old=new; old and new must be non-empty") + } + importMap[old] = new +} + +func usage() { + fmt.Fprintf(os.Stderr, "Usage: bundle [options] \n") + flag.PrintDefaults() +} + +func main() { + log.SetPrefix("bundle: ") + log.SetFlags(0) + + flag.Usage = usage + flag.Parse() + args := flag.Args() + if len(args) != 1 { + usage() + os.Exit(2) + } + + if *dstPath != "" { + if *pkgName == "" { + *pkgName = path.Base(*dstPath) + } + } else { + wd, _ := os.Getwd() + pkg, err := build.ImportDir(wd, 0) + if err != nil { + log.Fatalf("cannot find package in current directory: %v", err) + } + *dstPath = pkg.ImportPath + if *pkgName == "" { + *pkgName = pkg.Name + } + } + + code, err := bundle(args[0], *dstPath, *pkgName, *prefix) + if err != nil { + log.Fatal(err) + } + if *outputFile != "" { + err := ioutil.WriteFile(*outputFile, code, 0666) + if err != nil { + log.Fatal(err) + } + } else { + _, err := os.Stdout.Write(code) + if err != nil { + log.Fatal(err) + } + } +} + +// isStandardImportPath is copied from cmd/go in the standard library. +func isStandardImportPath(path string) bool { + i := strings.Index(path, "/") + if i < 0 { + i = len(path) + } + elem := path[:i] + return !strings.Contains(elem, ".") +} + +var ctxt = &build.Default + +func bundle(src, dst, dstpkg, prefix string) ([]byte, error) { + // Load the initial package. + conf := loader.Config{ParserMode: parser.ParseComments, Build: ctxt} + conf.TypeCheckFuncBodies = func(p string) bool { return p == src } + conf.Import(src) + + lprog, err := conf.Load() + if err != nil { + return nil, err + } + + // Because there was a single Import call and Load succeeded, + // InitialPackages is guaranteed to hold the sole requested package. + info := lprog.InitialPackages()[0] + if prefix == "" { + pkgName := info.Files[0].Name.Name + prefix = pkgName + "_" + } + + objsToUpdate := make(map[types.Object]bool) + var rename func(from types.Object) + rename = func(from types.Object) { + if !objsToUpdate[from] { + objsToUpdate[from] = true + + // Renaming a type that is used as an embedded field + // requires renaming the field too. e.g. + // type T int // if we rename this to U.. + // var s struct {T} + // print(s.T) // ...this must change too + if _, ok := from.(*types.TypeName); ok { + for id, obj := range info.Uses { + if obj == from { + if field := info.Defs[id]; field != nil { + rename(field) + } + } + } + } + } + } + + // Rename each package-level object. + scope := info.Pkg.Scope() + for _, name := range scope.Names() { + rename(scope.Lookup(name)) + } + + var out bytes.Buffer + + fmt.Fprintf(&out, "// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.\n") + if *outputFile != "" { + fmt.Fprintf(&out, "//go:generate bundle %s\n", strings.Join(os.Args[1:], " ")) + } else { + fmt.Fprintf(&out, "// $ bundle %s\n", strings.Join(os.Args[1:], " ")) + } + fmt.Fprintf(&out, "\n") + + // Concatenate package comments from all files... + for _, f := range info.Files { + if doc := f.Doc.Text(); strings.TrimSpace(doc) != "" { + for _, line := range strings.Split(doc, "\n") { + fmt.Fprintf(&out, "// %s\n", line) + } + } + } + // ...but don't let them become the actual package comment. + fmt.Fprintln(&out) + + fmt.Fprintf(&out, "package %s\n\n", dstpkg) + + // BUG(adonovan,shurcooL): bundle may generate incorrect code + // due to shadowing between identifiers and imported package names. + // + // The generated code will either fail to compile or + // (unlikely) compile successfully but have different behavior + // than the original package. The risk of this happening is higher + // when the original package has renamed imports (they're typically + // renamed in order to resolve a shadow inside that particular .go file). + + // TODO(adonovan,shurcooL): + // - detect shadowing issues, and either return error or resolve them + // - preserve comments from the original import declarations. + + // pkgStd and pkgExt are sets of printed import specs. This is done + // to deduplicate instances of the same import name and path. + var pkgStd = make(map[string]bool) + var pkgExt = make(map[string]bool) + for _, f := range info.Files { + for _, imp := range f.Imports { + path, err := strconv.Unquote(imp.Path.Value) + if err != nil { + log.Fatalf("invalid import path string: %v", err) // Shouldn't happen here since conf.Load succeeded. + } + if path == dst { + continue + } + if newPath, ok := importMap[path]; ok { + path = newPath + } + + var name string + if imp.Name != nil { + name = imp.Name.Name + } + spec := fmt.Sprintf("%s %q", name, path) + if isStandardImportPath(path) { + pkgStd[spec] = true + } else { + if *underscore { + spec = strings.Replace(spec, "golang.org/", "golang_org/", 1) + } + pkgExt[spec] = true + } + } + } + + // Print a single declaration that imports all necessary packages. + fmt.Fprintln(&out, "import (") + for p := range pkgStd { + fmt.Fprintf(&out, "\t%s\n", p) + } + if len(pkgExt) > 0 { + fmt.Fprintln(&out) + } + for p := range pkgExt { + fmt.Fprintf(&out, "\t%s\n", p) + } + fmt.Fprint(&out, ")\n\n") + + // Modify and print each file. + for _, f := range info.Files { + // Update renamed identifiers. + for id, obj := range info.Defs { + if objsToUpdate[obj] { + id.Name = prefix + obj.Name() + } + } + for id, obj := range info.Uses { + if objsToUpdate[obj] { + id.Name = prefix + obj.Name() + } + } + + // For each qualified identifier that refers to the + // destination package, remove the qualifier. + // The "@@@." strings are removed in postprocessing. + ast.Inspect(f, func(n ast.Node) bool { + if sel, ok := n.(*ast.SelectorExpr); ok { + if id, ok := sel.X.(*ast.Ident); ok { + if obj, ok := info.Uses[id].(*types.PkgName); ok { + if obj.Imported().Path() == dst { + id.Name = "@@@" + } + } + } + } + return true + }) + + last := f.Package + if len(f.Imports) > 0 { + imp := f.Imports[len(f.Imports)-1] + last = imp.End() + if imp.Comment != nil { + if e := imp.Comment.End(); e > last { + last = e + } + } + } + + // Pretty-print package-level declarations. + // but no package or import declarations. + var buf bytes.Buffer + for _, decl := range f.Decls { + if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT { + continue + } + + beg, end := sourceRange(decl) + + printComments(&out, f.Comments, last, beg) + + buf.Reset() + format.Node(&buf, lprog.Fset, &printer.CommentedNode{Node: decl, Comments: f.Comments}) + // Remove each "@@@." in the output. + // TODO(adonovan): not hygienic. + out.Write(bytes.Replace(buf.Bytes(), []byte("@@@."), nil, -1)) + + last = printSameLineComment(&out, f.Comments, lprog.Fset, end) + + out.WriteString("\n\n") + } + + printLastComments(&out, f.Comments, last) + } + + // Now format the entire thing. + result, err := format.Source(out.Bytes()) + if err != nil { + log.Fatalf("formatting failed: %v", err) + } + + return result, nil +} + +// sourceRange returns the [beg, end) interval of source code +// belonging to decl (incl. associated comments). +func sourceRange(decl ast.Decl) (beg, end token.Pos) { + beg = decl.Pos() + end = decl.End() + + var doc, com *ast.CommentGroup + + switch d := decl.(type) { + case *ast.GenDecl: + doc = d.Doc + if len(d.Specs) > 0 { + switch spec := d.Specs[len(d.Specs)-1].(type) { + case *ast.ValueSpec: + com = spec.Comment + case *ast.TypeSpec: + com = spec.Comment + } + } + case *ast.FuncDecl: + doc = d.Doc + } + + if doc != nil { + beg = doc.Pos() + } + if com != nil && com.End() > end { + end = com.End() + } + + return beg, end +} + +func printComments(out *bytes.Buffer, comments []*ast.CommentGroup, pos, end token.Pos) { + for _, cg := range comments { + if pos <= cg.Pos() && cg.Pos() < end { + for _, c := range cg.List { + fmt.Fprintln(out, c.Text) + } + fmt.Fprintln(out) + } + } +} + +const infinity = 1 << 30 + +func printLastComments(out *bytes.Buffer, comments []*ast.CommentGroup, pos token.Pos) { + printComments(out, comments, pos, infinity) +} + +func printSameLineComment(out *bytes.Buffer, comments []*ast.CommentGroup, fset *token.FileSet, pos token.Pos) token.Pos { + tf := fset.File(pos) + for _, cg := range comments { + if pos <= cg.Pos() && tf.Line(cg.Pos()) == tf.Line(pos) { + for _, c := range cg.List { + fmt.Fprintln(out, c.Text) + } + return cg.End() + } + } + return pos +} + +type flagFunc func(string) + +func (f flagFunc) Set(s string) error { + f(s) + return nil +} + +func (f flagFunc) String() string { return "" } diff --git a/vendor/golang.org/x/tools/cmd/bundle/main_test.go b/vendor/golang.org/x/tools/cmd/bundle/main_test.go new file mode 100644 index 00000000..b96f7d9d --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/main_test.go @@ -0,0 +1,74 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.9 + +package main + +import ( + "bytes" + "io/ioutil" + "os" + "os/exec" + "runtime" + "testing" + + "golang.org/x/tools/go/buildutil" +) + +func TestBundle(t *testing.T) { + load := func(name string) string { + data, err := ioutil.ReadFile(name) + if err != nil { + t.Fatal(err) + } + return string(data) + } + + ctxt = buildutil.FakeContext(map[string]map[string]string{ + "initial": { + "a.go": load("testdata/src/initial/a.go"), + "b.go": load("testdata/src/initial/b.go"), + "c.go": load("testdata/src/initial/c.go"), + }, + "domain.name/importdecl": { + "p.go": load("testdata/src/domain.name/importdecl/p.go"), + }, + "fmt": { + "print.go": `package fmt; func Println(...interface{})`, + }, + }) + + os.Args = os.Args[:1] // avoid e.g. -test=short in the output + out, err := bundle("initial", "github.com/dest", "dest", "prefix") + if err != nil { + t.Fatal(err) + } + if got, want := string(out), load("testdata/out.golden"); got != want { + t.Errorf("-- got --\n%s\n-- want --\n%s\n-- diff --", got, want) + + if err := ioutil.WriteFile("testdata/out.got", out, 0644); err != nil { + t.Fatal(err) + } + t.Log(diff("testdata/out.golden", "testdata/out.got")) + } +} + +func diff(a, b string) string { + var cmd *exec.Cmd + switch runtime.GOOS { + case "plan9": + cmd = exec.Command("/bin/diff", "-c", a, b) + default: + cmd = exec.Command("/usr/bin/diff", "-u", a, b) + } + var out bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = &out + cmd.Run() // nonzero exit is expected + if out.Len() == 0 { + return "(failed to compute diff)" + } + return out.String() +} diff --git a/vendor/golang.org/x/tools/cmd/bundle/testdata/out.golden b/vendor/golang.org/x/tools/cmd/bundle/testdata/out.golden new file mode 100644 index 00000000..5260fdd1 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/testdata/out.golden @@ -0,0 +1,62 @@ +// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. +// $ bundle + +// The package doc comment +// + +package dest + +import ( + "fmt" + . "fmt" + _ "fmt" + renamedfmt "fmt" + renamedfmt2 "fmt" + + "domain.name/importdecl" +) + +// init functions are not renamed +func init() { prefixfoo() } + +// Type S. +type prefixS struct { + prefixt + u int +} /* multi-line +comment +*/ + +// non-associated comment + +/* + non-associated comment2 +*/ + +// Function bar. +func prefixbar(s *prefixS) { + fmt.Println(s.prefixt, s.u) // comment inside function +} + +// file-end comment + +type prefixt int // type1 + +// const1 +const prefixc = 1 // const2 + +func prefixfoo() { + fmt.Println(importdecl.F()) +} + +// zinit +const ( + prefixz1 = iota // z1 + prefixz2 // z2 +) // zend + +func prefixbaz() { + renamedfmt.Println() + renamedfmt2.Println() + Println() +} diff --git a/vendor/golang.org/x/tools/cmd/bundle/testdata/src/domain.name/importdecl/p.go b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/domain.name/importdecl/p.go new file mode 100644 index 00000000..36dfd154 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/domain.name/importdecl/p.go @@ -0,0 +1,3 @@ +package importdecl + +func F() int { return 1 } diff --git a/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/a.go b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/a.go new file mode 100644 index 00000000..ded6c64c --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/a.go @@ -0,0 +1,27 @@ +package initial + +import "fmt" // this comment should not be visible + +// init functions are not renamed +func init() { foo() } + +// Type S. +type S struct { + t + u int +} /* multi-line +comment +*/ + +// non-associated comment + +/* + non-associated comment2 +*/ + +// Function bar. +func bar(s *S) { + fmt.Println(s.t, s.u) // comment inside function +} + +// file-end comment diff --git a/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/b.go b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/b.go new file mode 100644 index 00000000..31d5cabe --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/b.go @@ -0,0 +1,23 @@ +// The package doc comment +package initial + +import ( + "fmt" + + "domain.name/importdecl" +) + +type t int // type1 + +// const1 +const c = 1 // const2 + +func foo() { + fmt.Println(importdecl.F()) +} + +// zinit +const ( + z1 = iota // z1 + z2 // z2 +) // zend diff --git a/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/c.go b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/c.go new file mode 100644 index 00000000..6a9cbc69 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/bundle/testdata/src/initial/c.go @@ -0,0 +1,12 @@ +package initial + +import _ "fmt" +import renamedfmt "fmt" +import renamedfmt2 "fmt" +import . "fmt" + +func baz() { + renamedfmt.Println() + renamedfmt2.Println() + Println() +} diff --git a/vendor/golang.org/x/tools/cmd/callgraph/main.go b/vendor/golang.org/x/tools/cmd/callgraph/main.go new file mode 100644 index 00000000..8ef4597c --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/callgraph/main.go @@ -0,0 +1,361 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// callgraph: a tool for reporting the call graph of a Go program. +// See Usage for details, or run with -help. +package main // import "golang.org/x/tools/cmd/callgraph" + +// TODO(adonovan): +// +// Features: +// - restrict graph to a single package +// - output +// - functions reachable from root (use digraph tool?) +// - unreachable functions (use digraph tool?) +// - dynamic (runtime) types +// - indexed output (numbered nodes) +// - JSON output +// - additional template fields: +// callee file/line/col + +import ( + "bufio" + "bytes" + "flag" + "fmt" + "go/build" + "go/token" + "io" + "log" + "os" + "runtime" + "text/template" + + "golang.org/x/tools/go/buildutil" + "golang.org/x/tools/go/callgraph" + "golang.org/x/tools/go/callgraph/cha" + "golang.org/x/tools/go/callgraph/rta" + "golang.org/x/tools/go/callgraph/static" + "golang.org/x/tools/go/loader" + "golang.org/x/tools/go/pointer" + "golang.org/x/tools/go/ssa" + "golang.org/x/tools/go/ssa/ssautil" +) + +// flags +var ( + algoFlag = flag.String("algo", "rta", + `Call graph construction algorithm (static, cha, rta, pta)`) + + testFlag = flag.Bool("test", false, + "Loads test code (*_test.go) for imported packages") + + formatFlag = flag.String("format", + "{{.Caller}}\t--{{.Dynamic}}-{{.Line}}:{{.Column}}-->\t{{.Callee}}", + "A template expression specifying how to format an edge") + + ptalogFlag = flag.String("ptalog", "", + "Location of the points-to analysis log file, or empty to disable logging.") +) + +func init() { + flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) +} + +const Usage = `callgraph: display the the call graph of a Go program. + +Usage: + + callgraph [-algo=static|cha|rta|pta] [-test] [-format=...] ... + +Flags: + +-algo Specifies the call-graph construction algorithm, one of: + + static static calls only (unsound) + cha Class Hierarchy Analysis + rta Rapid Type Analysis + pta inclusion-based Points-To Analysis + + The algorithms are ordered by increasing precision in their + treatment of dynamic calls (and thus also computational cost). + RTA and PTA require a whole program (main or test), and + include only functions reachable from main. + +-test Include the package's tests in the analysis. + +-format Specifies the format in which each call graph edge is displayed. + One of: + + digraph output suitable for input to + golang.org/x/tools/cmd/digraph. + graphviz output in AT&T GraphViz (.dot) format. + + All other values are interpreted using text/template syntax. + The default value is: + + {{.Caller}}\t--{{.Dynamic}}-{{.Line}}:{{.Column}}-->\t{{.Callee}} + + The structure passed to the template is (effectively): + + type Edge struct { + Caller *ssa.Function // calling function + Callee *ssa.Function // called function + + // Call site: + Filename string // containing file + Offset int // offset within file of '(' + Line int // line number + Column int // column number of call + Dynamic string // "static" or "dynamic" + Description string // e.g. "static method call" + } + + Caller and Callee are *ssa.Function values, which print as + "(*sync/atomic.Mutex).Lock", but other attributes may be + derived from them, e.g. Caller.Pkg.Pkg.Path yields the + import path of the enclosing package. Consult the go/ssa + API documentation for details. + +` + loader.FromArgsUsage + ` + +Examples: + + Show the call graph of the trivial web server application: + + callgraph -format digraph $GOROOT/src/net/http/triv.go + + Same, but show only the packages of each function: + + callgraph -format '{{.Caller.Pkg.Pkg.Path}} -> {{.Callee.Pkg.Pkg.Path}}' \ + $GOROOT/src/net/http/triv.go | sort | uniq + + Show functions that make dynamic calls into the 'fmt' test package, + using the pointer analysis algorithm: + + callgraph -format='{{.Caller}} -{{.Dynamic}}-> {{.Callee}}' -test -algo=pta fmt | + sed -ne 's/-dynamic-/--/p' | + sed -ne 's/-->.*fmt_test.*$//p' | sort | uniq + + Show all functions directly called by the callgraph tool's main function: + + callgraph -format=digraph golang.org/x/tools/cmd/callgraph | + digraph succs golang.org/x/tools/cmd/callgraph.main +` + +func init() { + // If $GOMAXPROCS isn't set, use the full capacity of the machine. + // For small machines, use at least 4 threads. + if os.Getenv("GOMAXPROCS") == "" { + n := runtime.NumCPU() + if n < 4 { + n = 4 + } + runtime.GOMAXPROCS(n) + } +} + +func main() { + flag.Parse() + if err := doCallgraph(&build.Default, *algoFlag, *formatFlag, *testFlag, flag.Args()); err != nil { + fmt.Fprintf(os.Stderr, "callgraph: %s\n", err) + os.Exit(1) + } +} + +var stdout io.Writer = os.Stdout + +func doCallgraph(ctxt *build.Context, algo, format string, tests bool, args []string) error { + conf := loader.Config{Build: ctxt} + + if len(args) == 0 { + fmt.Fprintln(os.Stderr, Usage) + return nil + } + + // Use the initial packages from the command line. + _, err := conf.FromArgs(args, tests) + if err != nil { + return err + } + + // Load, parse and type-check the whole program. + iprog, err := conf.Load() + if err != nil { + return err + } + + // Create and build SSA-form program representation. + prog := ssautil.CreateProgram(iprog, 0) + prog.Build() + + // -- call graph construction ------------------------------------------ + + var cg *callgraph.Graph + + switch algo { + case "static": + cg = static.CallGraph(prog) + + case "cha": + cg = cha.CallGraph(prog) + + case "pta": + // Set up points-to analysis log file. + var ptalog io.Writer + if *ptalogFlag != "" { + if f, err := os.Create(*ptalogFlag); err != nil { + log.Fatalf("Failed to create PTA log file: %s", err) + } else { + buf := bufio.NewWriter(f) + ptalog = buf + defer func() { + if err := buf.Flush(); err != nil { + log.Printf("flush: %s", err) + } + if err := f.Close(); err != nil { + log.Printf("close: %s", err) + } + }() + } + } + + mains, err := mainPackages(prog, tests) + if err != nil { + return err + } + config := &pointer.Config{ + Mains: mains, + BuildCallGraph: true, + Log: ptalog, + } + ptares, err := pointer.Analyze(config) + if err != nil { + return err // internal error in pointer analysis + } + cg = ptares.CallGraph + + case "rta": + mains, err := mainPackages(prog, tests) + if err != nil { + return err + } + var roots []*ssa.Function + for _, main := range mains { + roots = append(roots, main.Func("init"), main.Func("main")) + } + rtares := rta.Analyze(roots, true) + cg = rtares.CallGraph + + // NB: RTA gives us Reachable and RuntimeTypes too. + + default: + return fmt.Errorf("unknown algorithm: %s", algo) + } + + cg.DeleteSyntheticNodes() + + // -- output------------------------------------------------------------ + + var before, after string + + // Pre-canned formats. + switch format { + case "digraph": + format = `{{printf "%q %q" .Caller .Callee}}` + + case "graphviz": + before = "digraph callgraph {\n" + after = "}\n" + format = ` {{printf "%q" .Caller}} -> {{printf "%q" .Callee}}` + } + + tmpl, err := template.New("-format").Parse(format) + if err != nil { + return fmt.Errorf("invalid -format template: %v", err) + } + + // Allocate these once, outside the traversal. + var buf bytes.Buffer + data := Edge{fset: prog.Fset} + + fmt.Fprint(stdout, before) + if err := callgraph.GraphVisitEdges(cg, func(edge *callgraph.Edge) error { + data.position.Offset = -1 + data.edge = edge + data.Caller = edge.Caller.Func + data.Callee = edge.Callee.Func + + buf.Reset() + if err := tmpl.Execute(&buf, &data); err != nil { + return err + } + stdout.Write(buf.Bytes()) + if len := buf.Len(); len == 0 || buf.Bytes()[len-1] != '\n' { + fmt.Fprintln(stdout) + } + return nil + }); err != nil { + return err + } + fmt.Fprint(stdout, after) + return nil +} + +// mainPackages returns the main packages to analyze. +// Each resulting package is named "main" and has a main function. +func mainPackages(prog *ssa.Program, tests bool) ([]*ssa.Package, error) { + pkgs := prog.AllPackages() // TODO(adonovan): use only initial packages + + // If tests, create a "testmain" package for each test. + var mains []*ssa.Package + if tests { + for _, pkg := range pkgs { + if main := prog.CreateTestMainPackage(pkg); main != nil { + mains = append(mains, main) + } + } + if mains == nil { + return nil, fmt.Errorf("no tests") + } + return mains, nil + } + + // Otherwise, use the main packages. + mains = append(mains, ssautil.MainPackages(pkgs)...) + if len(mains) == 0 { + return nil, fmt.Errorf("no main packages") + } + return mains, nil +} + +type Edge struct { + Caller *ssa.Function + Callee *ssa.Function + + edge *callgraph.Edge + fset *token.FileSet + position token.Position // initialized lazily +} + +func (e *Edge) pos() *token.Position { + if e.position.Offset == -1 { + e.position = e.fset.Position(e.edge.Pos()) // called lazily + } + return &e.position +} + +func (e *Edge) Filename() string { return e.pos().Filename } +func (e *Edge) Column() int { return e.pos().Column } +func (e *Edge) Line() int { return e.pos().Line } +func (e *Edge) Offset() int { return e.pos().Offset } + +func (e *Edge) Dynamic() string { + if e.edge.Site != nil && e.edge.Site.Common().StaticCallee() == nil { + return "dynamic" + } + return "static" +} + +func (e *Edge) Description() string { return e.edge.Description() } diff --git a/vendor/golang.org/x/tools/cmd/callgraph/main_test.go b/vendor/golang.org/x/tools/cmd/callgraph/main_test.go new file mode 100644 index 00000000..c42f56da --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/callgraph/main_test.go @@ -0,0 +1,81 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// No testdata on Android. + +// +build !android + +package main + +import ( + "bytes" + "fmt" + "go/build" + "reflect" + "sort" + "strings" + "testing" +) + +func TestCallgraph(t *testing.T) { + ctxt := build.Default // copy + ctxt.GOPATH = "testdata" + + const format = "{{.Caller}} --> {{.Callee}}" + + for _, test := range []struct { + algo, format string + tests bool + want []string + }{ + {"rta", format, false, []string{ + // rta imprecisely shows cross product of {main,main2} x {C,D} + `pkg.main --> (pkg.C).f`, + `pkg.main --> (pkg.D).f`, + `pkg.main --> pkg.main2`, + `pkg.main2 --> (pkg.C).f`, + `pkg.main2 --> (pkg.D).f`, + }}, + {"pta", format, false, []string{ + // pta distinguishes main->C, main2->D. Also has a root node. + ` --> pkg.init`, + ` --> pkg.main`, + `pkg.main --> (pkg.C).f`, + `pkg.main --> pkg.main2`, + `pkg.main2 --> (pkg.D).f`, + }}, + // tests: main is not called. + {"rta", format, true, []string{ + `pkg$testmain.init --> pkg.init`, + `pkg.Example --> (pkg.C).f`, + }}, + {"pta", format, true, []string{ + ` --> pkg$testmain.init`, + ` --> pkg.Example`, + `pkg$testmain.init --> pkg.init`, + `pkg.Example --> (pkg.C).f`, + }}, + } { + stdout = new(bytes.Buffer) + if err := doCallgraph(&ctxt, test.algo, test.format, test.tests, []string{"pkg"}); err != nil { + t.Error(err) + continue + } + + got := sortedLines(fmt.Sprint(stdout)) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("callgraph(%q, %q, %t):\ngot:\n%s\nwant:\n%s", + test.algo, test.format, test.tests, + strings.Join(got, "\n"), + strings.Join(test.want, "\n")) + } + } +} + +func sortedLines(s string) []string { + s = strings.TrimSpace(s) + lines := strings.Split(s, "\n") + sort.Strings(lines) + return lines +} diff --git a/vendor/golang.org/x/tools/cmd/callgraph/testdata/src/pkg/pkg.go b/vendor/golang.org/x/tools/cmd/callgraph/testdata/src/pkg/pkg.go new file mode 100644 index 00000000..b81c97fb --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/callgraph/testdata/src/pkg/pkg.go @@ -0,0 +1,25 @@ +package main + +type I interface { + f() +} + +type C int + +func (C) f() {} + +type D int + +func (D) f() {} + +func main() { + var i I = C(0) + i.f() // dynamic call + + main2() +} + +func main2() { + var i I = D(0) + i.f() // dynamic call +} diff --git a/vendor/golang.org/x/tools/cmd/callgraph/testdata/src/pkg/pkg_test.go b/vendor/golang.org/x/tools/cmd/callgraph/testdata/src/pkg/pkg_test.go new file mode 100644 index 00000000..d6247577 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/callgraph/testdata/src/pkg/pkg_test.go @@ -0,0 +1,7 @@ +package main + +// Don't import "testing", it adds a lot of callgraph edges. + +func Example() { + C(0).f() +} diff --git a/vendor/golang.org/x/tools/cmd/compilebench/main.go b/vendor/golang.org/x/tools/cmd/compilebench/main.go new file mode 100644 index 00000000..d2cd70b2 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/compilebench/main.go @@ -0,0 +1,360 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Compilebench benchmarks the speed of the Go compiler. +// +// Usage: +// +// compilebench [options] +// +// It times the compilation of various packages and prints results in +// the format used by package testing (and expected by golang.org/x/perf/cmd/benchstat). +// +// The options are: +// +// -alloc +// Report allocations. +// +// -compile exe +// Use exe as the path to the cmd/compile binary. +// +// -compileflags 'list' +// Pass the space-separated list of flags to the compilation. +// +// -count n +// Run each benchmark n times (default 1). +// +// -cpuprofile file +// Write a CPU profile of the compiler to file. +// +// -memprofile file +// Write a memory profile of the compiler to file. +// +// -memprofilerate rate +// Set runtime.MemProfileRate during compilation. +// +// -obj +// Report object file statistics. +// +// -pkg +// Benchmark compiling a single package. +// +// -run regexp +// Only run benchmarks with names matching regexp. +// +// Although -cpuprofile and -memprofile are intended to write a +// combined profile for all the executed benchmarks to file, +// today they write only the profile for the last benchmark executed. +// +// The default memory profiling rate is one profile sample per 512 kB +// allocated (see ``go doc runtime.MemProfileRate''). +// Lowering the rate (for example, -memprofilerate 64000) produces +// a more fine-grained and therefore accurate profile, but it also incurs +// execution cost. For benchmark comparisons, never use timings +// obtained with a low -memprofilerate option. +// +// Example +// +// Assuming the base version of the compiler has been saved with +// ``toolstash save,'' this sequence compares the old and new compiler: +// +// compilebench -count 10 -compile $(toolstash -n compile) >old.txt +// compilebench -count 10 >new.txt +// benchstat old.txt new.txt +// +package main + +import ( + "bytes" + "flag" + "fmt" + "go/build" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strconv" + "strings" + "time" +) + +var ( + goroot string + compiler string + runRE *regexp.Regexp + is6g bool +) + +var ( + flagGoCmd = flag.String("go", "go", "path to \"go\" command") + flagAlloc = flag.Bool("alloc", false, "report allocations") + flagObj = flag.Bool("obj", false, "report object file stats") + flagCompiler = flag.String("compile", "", "use `exe` as the cmd/compile binary") + flagCompilerFlags = flag.String("compileflags", "", "additional `flags` to pass to compile") + flagRun = flag.String("run", "", "run benchmarks matching `regexp`") + flagCount = flag.Int("count", 1, "run benchmarks `n` times") + flagCpuprofile = flag.String("cpuprofile", "", "write CPU profile to `file`") + flagMemprofile = flag.String("memprofile", "", "write memory profile to `file`") + flagMemprofilerate = flag.Int64("memprofilerate", -1, "set memory profile `rate`") + flagPackage = flag.String("pkg", "", "if set, benchmark the package at path `pkg`") + flagShort = flag.Bool("short", false, "skip long-running benchmarks") +) + +var tests = []struct { + name string + dir string + long bool +}{ + {"BenchmarkTemplate", "html/template", false}, + {"BenchmarkUnicode", "unicode", false}, + {"BenchmarkGoTypes", "go/types", false}, + {"BenchmarkCompiler", "cmd/compile/internal/gc", false}, + {"BenchmarkSSA", "cmd/compile/internal/ssa", false}, + {"BenchmarkFlate", "compress/flate", false}, + {"BenchmarkGoParser", "go/parser", false}, + {"BenchmarkReflect", "reflect", false}, + {"BenchmarkTar", "archive/tar", false}, + {"BenchmarkXML", "encoding/xml", false}, + {"BenchmarkStdCmd", "", true}, + {"BenchmarkHelloSize", "", false}, + {"BenchmarkCmdGoSize", "", true}, +} + +func usage() { + fmt.Fprintf(os.Stderr, "usage: compilebench [options]\n") + fmt.Fprintf(os.Stderr, "options:\n") + flag.PrintDefaults() + os.Exit(2) +} + +func main() { + log.SetFlags(0) + log.SetPrefix("compilebench: ") + flag.Usage = usage + flag.Parse() + if flag.NArg() != 0 { + usage() + } + + s, err := exec.Command(*flagGoCmd, "env", "GOROOT").CombinedOutput() + if err != nil { + log.Fatalf("%s env GOROOT: %v", *flagGoCmd, err) + } + goroot = strings.TrimSpace(string(s)) + + compiler = *flagCompiler + if compiler == "" { + out, err := exec.Command(*flagGoCmd, "tool", "-n", "compile").CombinedOutput() + if err != nil { + out, err = exec.Command(*flagGoCmd, "tool", "-n", "6g").CombinedOutput() + is6g = true + if err != nil { + out, err = exec.Command(*flagGoCmd, "tool", "-n", "compile").CombinedOutput() + log.Fatalf("go tool -n compiler: %v\n%s", err, out) + } + } + compiler = strings.TrimSpace(string(out)) + } + + if *flagRun != "" { + r, err := regexp.Compile(*flagRun) + if err != nil { + log.Fatalf("invalid -run argument: %v", err) + } + runRE = r + } + + for i := 0; i < *flagCount; i++ { + if *flagPackage != "" { + runBuild("BenchmarkPkg", *flagPackage, i) + continue + } + for _, tt := range tests { + if tt.long && *flagShort { + continue + } + if runRE == nil || runRE.MatchString(tt.name) { + runBuild(tt.name, tt.dir, i) + } + } + } +} + +func runCmd(name string, cmd *exec.Cmd) { + start := time.Now() + out, err := cmd.CombinedOutput() + if err != nil { + log.Printf("%v: %v\n%s", name, err, out) + return + } + fmt.Printf("%s 1 %d ns/op\n", name, time.Since(start).Nanoseconds()) +} + +func runStdCmd() { + args := []string{"build", "-a"} + if *flagCompilerFlags != "" { + args = append(args, "-gcflags", *flagCompilerFlags) + } + args = append(args, "std", "cmd") + cmd := exec.Command(*flagGoCmd, args...) + cmd.Dir = filepath.Join(goroot, "src") + runCmd("BenchmarkStdCmd", cmd) +} + +// path is either a path to a file ("$GOROOT/test/helloworld.go") or a package path ("cmd/go"). +func runSize(name, path string) { + cmd := exec.Command(*flagGoCmd, "build", "-o", "_compilebenchout_", path) + cmd.Stdout = os.Stderr + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + log.Print(err) + return + } + defer os.Remove("_compilebenchout_") + info, err := os.Stat("_compilebenchout_") + if err != nil { + log.Print(err) + return + } + out, err := exec.Command("size", "_compilebenchout_").CombinedOutput() + if err != nil { + log.Printf("size: %v\n%s", err, out) + return + } + lines := strings.Split(string(out), "\n") + if len(lines) < 2 { + log.Printf("not enough output from size: %s", out) + return + } + f := strings.Fields(lines[1]) + if strings.HasPrefix(lines[0], "__TEXT") && len(f) >= 2 { // OS X + fmt.Printf("%s 1 %s text-bytes %s data-bytes %v exe-bytes\n", name, f[0], f[1], info.Size()) + } else if strings.Contains(lines[0], "bss") && len(f) >= 3 { + fmt.Printf("%s 1 %s text-bytes %s data-bytes %s bss-bytes %v exe-bytes\n", name, f[0], f[1], f[2], info.Size()) + } +} + +func runBuild(name, dir string, count int) { + switch name { + case "BenchmarkStdCmd": + runStdCmd() + return + case "BenchmarkCmdGoSize": + runSize("BenchmarkCmdGoSize", "cmd/go") + return + case "BenchmarkHelloSize": + runSize("BenchmarkHelloSize", filepath.Join(goroot, "test/helloworld.go")) + return + } + + pkg, err := build.Import(dir, ".", 0) + if err != nil { + log.Print(err) + return + } + args := []string{"-o", "_compilebench_.o"} + if is6g { + *flagMemprofilerate = -1 + *flagAlloc = false + *flagCpuprofile = "" + *flagMemprofile = "" + } + if *flagMemprofilerate >= 0 { + args = append(args, "-memprofilerate", fmt.Sprint(*flagMemprofilerate)) + } + args = append(args, strings.Fields(*flagCompilerFlags)...) + if *flagAlloc || *flagCpuprofile != "" || *flagMemprofile != "" { + if *flagAlloc || *flagMemprofile != "" { + args = append(args, "-memprofile", "_compilebench_.memprof") + } + if *flagCpuprofile != "" { + args = append(args, "-cpuprofile", "_compilebench_.cpuprof") + } + } + args = append(args, pkg.GoFiles...) + cmd := exec.Command(compiler, args...) + cmd.Dir = pkg.Dir + cmd.Stdout = os.Stderr + cmd.Stderr = os.Stderr + start := time.Now() + err = cmd.Run() + if err != nil { + log.Printf("%v: %v", name, err) + return + } + end := time.Now() + + var allocs, allocbytes int64 + if *flagAlloc || *flagMemprofile != "" { + out, err := ioutil.ReadFile(pkg.Dir + "/_compilebench_.memprof") + if err != nil { + log.Print("cannot find memory profile after compilation") + } + for _, line := range strings.Split(string(out), "\n") { + f := strings.Fields(line) + if len(f) < 4 || f[0] != "#" || f[2] != "=" { + continue + } + val, err := strconv.ParseInt(f[3], 0, 64) + if err != nil { + continue + } + switch f[1] { + case "TotalAlloc": + allocbytes = val + case "Mallocs": + allocs = val + } + } + + if *flagMemprofile != "" { + if err := ioutil.WriteFile(*flagMemprofile, out, 0666); err != nil { + log.Print(err) + } + } + os.Remove(pkg.Dir + "/_compilebench_.memprof") + } + + if *flagCpuprofile != "" { + out, err := ioutil.ReadFile(pkg.Dir + "/_compilebench_.cpuprof") + if err != nil { + log.Print(err) + } + outpath := *flagCpuprofile + if *flagCount != 1 { + outpath = fmt.Sprintf("%s_%d", outpath, count) + } + if err := ioutil.WriteFile(outpath, out, 0666); err != nil { + log.Print(err) + } + os.Remove(pkg.Dir + "/_compilebench_.cpuprof") + } + + wallns := end.Sub(start).Nanoseconds() + userns := cmd.ProcessState.UserTime().Nanoseconds() + + fmt.Printf("%s 1 %d ns/op %d user-ns/op", name, wallns, userns) + if *flagAlloc { + fmt.Printf(" %d B/op %d allocs/op", allocbytes, allocs) + } + + opath := pkg.Dir + "/_compilebench_.o" + if *flagObj { + // TODO(josharian): object files are big; just read enough to find what we seek. + data, err := ioutil.ReadFile(opath) + if err != nil { + log.Print(err) + } + // Find start of export data. + i := bytes.Index(data, []byte("\n$$B\n")) + len("\n$$B\n") + // Count bytes to end of export data. + nexport := bytes.Index(data[i:], []byte("\n$$\n")) + fmt.Printf(" %d object-bytes %d export-bytes", len(data), nexport) + } + fmt.Println() + + os.Remove(opath) +} diff --git a/vendor/golang.org/x/tools/cmd/cover/README b/vendor/golang.org/x/tools/cmd/cover/README new file mode 100644 index 00000000..ff9523d4 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/README @@ -0,0 +1,2 @@ +NOTE: For Go releases 1.5 and later, this tool lives in the +standard repository. The code here is not maintained. diff --git a/vendor/golang.org/x/tools/cmd/cover/cover.go b/vendor/golang.org/x/tools/cmd/cover/cover.go new file mode 100644 index 00000000..e0933649 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/cover.go @@ -0,0 +1,722 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "flag" + "fmt" + "go/ast" + "go/parser" + "go/printer" + "go/token" + "io" + "io/ioutil" + "log" + "os" + "path/filepath" + "sort" + "strconv" + "strings" +) + +const usageMessage = "" + + `Usage of 'go tool cover': +Given a coverage profile produced by 'go test': + go test -coverprofile=c.out + +Open a web browser displaying annotated source code: + go tool cover -html=c.out + +Write out an HTML file instead of launching a web browser: + go tool cover -html=c.out -o coverage.html + +Display coverage percentages to stdout for each function: + go tool cover -func=c.out + +Finally, to generate modified source code with coverage annotations +(what go test -cover does): + go tool cover -mode=set -var=CoverageVariableName program.go +` + +func usage() { + fmt.Fprintln(os.Stderr, usageMessage) + fmt.Fprintln(os.Stderr, "Flags:") + flag.PrintDefaults() + fmt.Fprintln(os.Stderr, "\n Only one of -html, -func, or -mode may be set.") + os.Exit(2) +} + +var ( + mode = flag.String("mode", "", "coverage mode: set, count, atomic") + varVar = flag.String("var", "GoCover", "name of coverage variable to generate") + output = flag.String("o", "", "file for output; default: stdout") + htmlOut = flag.String("html", "", "generate HTML representation of coverage profile") + funcOut = flag.String("func", "", "output coverage profile information for each function") +) + +var profile string // The profile to read; the value of -html or -func + +var counterStmt func(*File, ast.Expr) ast.Stmt + +const ( + atomicPackagePath = "sync/atomic" + atomicPackageName = "_cover_atomic_" +) + +func main() { + flag.Usage = usage + flag.Parse() + + // Usage information when no arguments. + if flag.NFlag() == 0 && flag.NArg() == 0 { + flag.Usage() + } + + err := parseFlags() + if err != nil { + fmt.Fprintln(os.Stderr, err) + fmt.Fprintln(os.Stderr, `For usage information, run "go tool cover -help"`) + os.Exit(2) + } + + // Generate coverage-annotated source. + if *mode != "" { + annotate(flag.Arg(0)) + return + } + + // Output HTML or function coverage information. + if *htmlOut != "" { + err = htmlOutput(profile, *output) + } else { + err = funcOutput(profile, *output) + } + + if err != nil { + fmt.Fprintf(os.Stderr, "cover: %v\n", err) + os.Exit(2) + } +} + +// parseFlags sets the profile and counterStmt globals and performs validations. +func parseFlags() error { + profile = *htmlOut + if *funcOut != "" { + if profile != "" { + return fmt.Errorf("too many options") + } + profile = *funcOut + } + + // Must either display a profile or rewrite Go source. + if (profile == "") == (*mode == "") { + return fmt.Errorf("too many options") + } + + if *mode != "" { + switch *mode { + case "set": + counterStmt = setCounterStmt + case "count": + counterStmt = incCounterStmt + case "atomic": + counterStmt = atomicCounterStmt + default: + return fmt.Errorf("unknown -mode %v", *mode) + } + + if flag.NArg() == 0 { + return fmt.Errorf("missing source file") + } else if flag.NArg() == 1 { + return nil + } + } else if flag.NArg() == 0 { + return nil + } + return fmt.Errorf("too many arguments") +} + +// Block represents the information about a basic block to be recorded in the analysis. +// Note: Our definition of basic block is based on control structures; we don't break +// apart && and ||. We could but it doesn't seem important enough to bother. +type Block struct { + startByte token.Pos + endByte token.Pos + numStmt int +} + +// File is a wrapper for the state of a file used in the parser. +// The basic parse tree walker is a method of this type. +type File struct { + fset *token.FileSet + name string // Name of file. + astFile *ast.File + blocks []Block + atomicPkg string // Package name for "sync/atomic" in this file. +} + +// Visit implements the ast.Visitor interface. +func (f *File) Visit(node ast.Node) ast.Visitor { + switch n := node.(type) { + case *ast.BlockStmt: + // If it's a switch or select, the body is a list of case clauses; don't tag the block itself. + if len(n.List) > 0 { + switch n.List[0].(type) { + case *ast.CaseClause: // switch + for _, n := range n.List { + clause := n.(*ast.CaseClause) + clause.Body = f.addCounters(clause.Pos(), clause.End(), clause.Body, false) + } + return f + case *ast.CommClause: // select + for _, n := range n.List { + clause := n.(*ast.CommClause) + clause.Body = f.addCounters(clause.Pos(), clause.End(), clause.Body, false) + } + return f + } + } + n.List = f.addCounters(n.Lbrace, n.Rbrace+1, n.List, true) // +1 to step past closing brace. + case *ast.IfStmt: + ast.Walk(f, n.Body) + if n.Else == nil { + return nil + } + // The elses are special, because if we have + // if x { + // } else if y { + // } + // we want to cover the "if y". To do this, we need a place to drop the counter, + // so we add a hidden block: + // if x { + // } else { + // if y { + // } + // } + switch stmt := n.Else.(type) { + case *ast.IfStmt: + block := &ast.BlockStmt{ + Lbrace: n.Body.End(), // Start at end of the "if" block so the covered part looks like it starts at the "else". + List: []ast.Stmt{stmt}, + Rbrace: stmt.End(), + } + n.Else = block + case *ast.BlockStmt: + stmt.Lbrace = n.Body.End() // Start at end of the "if" block so the covered part looks like it starts at the "else". + default: + panic("unexpected node type in if") + } + ast.Walk(f, n.Else) + return nil + case *ast.SelectStmt: + // Don't annotate an empty select - creates a syntax error. + if n.Body == nil || len(n.Body.List) == 0 { + return nil + } + case *ast.SwitchStmt: + // Don't annotate an empty switch - creates a syntax error. + if n.Body == nil || len(n.Body.List) == 0 { + return nil + } + case *ast.TypeSwitchStmt: + // Don't annotate an empty type switch - creates a syntax error. + if n.Body == nil || len(n.Body.List) == 0 { + return nil + } + } + return f +} + +// unquote returns the unquoted string. +func unquote(s string) string { + t, err := strconv.Unquote(s) + if err != nil { + log.Fatalf("cover: improperly quoted string %q\n", s) + } + return t +} + +// addImport adds an import for the specified path, if one does not already exist, and returns +// the local package name. +func (f *File) addImport(path string) string { + // Does the package already import it? + for _, s := range f.astFile.Imports { + if unquote(s.Path.Value) == path { + if s.Name != nil { + return s.Name.Name + } + return filepath.Base(path) + } + } + newImport := &ast.ImportSpec{ + Name: ast.NewIdent(atomicPackageName), + Path: &ast.BasicLit{ + Kind: token.STRING, + Value: fmt.Sprintf("%q", path), + }, + } + impDecl := &ast.GenDecl{ + Tok: token.IMPORT, + Specs: []ast.Spec{ + newImport, + }, + } + // Make the new import the first Decl in the file. + astFile := f.astFile + astFile.Decls = append(astFile.Decls, nil) + copy(astFile.Decls[1:], astFile.Decls[0:]) + astFile.Decls[0] = impDecl + astFile.Imports = append(astFile.Imports, newImport) + + // Now refer to the package, just in case it ends up unused. + // That is, append to the end of the file the declaration + // var _ = _cover_atomic_.AddUint32 + reference := &ast.GenDecl{ + Tok: token.VAR, + Specs: []ast.Spec{ + &ast.ValueSpec{ + Names: []*ast.Ident{ + ast.NewIdent("_"), + }, + Values: []ast.Expr{ + &ast.SelectorExpr{ + X: ast.NewIdent(atomicPackageName), + Sel: ast.NewIdent("AddUint32"), + }, + }, + }, + }, + } + astFile.Decls = append(astFile.Decls, reference) + return atomicPackageName +} + +var slashslash = []byte("//") + +// initialComments returns the prefix of content containing only +// whitespace and line comments. Any +build directives must appear +// within this region. This approach is more reliable than using +// go/printer to print a modified AST containing comments. +// +func initialComments(content []byte) []byte { + // Derived from go/build.Context.shouldBuild. + end := 0 + p := content + for len(p) > 0 { + line := p + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, p = line[:i], p[i+1:] + } else { + p = p[len(p):] + } + line = bytes.TrimSpace(line) + if len(line) == 0 { // Blank line. + end = len(content) - len(p) + continue + } + if !bytes.HasPrefix(line, slashslash) { // Not comment line. + break + } + } + return content[:end] +} + +func annotate(name string) { + fset := token.NewFileSet() + content, err := ioutil.ReadFile(name) + if err != nil { + log.Fatalf("cover: %s: %s", name, err) + } + parsedFile, err := parser.ParseFile(fset, name, content, parser.ParseComments) + if err != nil { + log.Fatalf("cover: %s: %s", name, err) + } + parsedFile.Comments = trimComments(parsedFile, fset) + + file := &File{ + fset: fset, + name: name, + astFile: parsedFile, + } + if *mode == "atomic" { + file.atomicPkg = file.addImport(atomicPackagePath) + } + ast.Walk(file, file.astFile) + fd := os.Stdout + if *output != "" { + var err error + fd, err = os.Create(*output) + if err != nil { + log.Fatalf("cover: %s", err) + } + } + fd.Write(initialComments(content)) // Retain '// +build' directives. + file.print(fd) + // After printing the source tree, add some declarations for the counters etc. + // We could do this by adding to the tree, but it's easier just to print the text. + file.addVariables(fd) +} + +// trimComments drops all but the //go: comments, some of which are semantically important. +// We drop all others because they can appear in places that cause our counters +// to appear in syntactically incorrect places. //go: appears at the beginning of +// the line and is syntactically safe. +func trimComments(file *ast.File, fset *token.FileSet) []*ast.CommentGroup { + var comments []*ast.CommentGroup + for _, group := range file.Comments { + var list []*ast.Comment + for _, comment := range group.List { + if strings.HasPrefix(comment.Text, "//go:") && fset.Position(comment.Slash).Column == 1 { + list = append(list, comment) + } + } + if list != nil { + comments = append(comments, &ast.CommentGroup{List: list}) + } + } + return comments +} + +func (f *File) print(w io.Writer) { + printer.Fprint(w, f.fset, f.astFile) +} + +// intLiteral returns an ast.BasicLit representing the integer value. +func (f *File) intLiteral(i int) *ast.BasicLit { + node := &ast.BasicLit{ + Kind: token.INT, + Value: fmt.Sprint(i), + } + return node +} + +// index returns an ast.BasicLit representing the number of counters present. +func (f *File) index() *ast.BasicLit { + return f.intLiteral(len(f.blocks)) +} + +// setCounterStmt returns the expression: __count[23] = 1. +func setCounterStmt(f *File, counter ast.Expr) ast.Stmt { + return &ast.AssignStmt{ + Lhs: []ast.Expr{counter}, + Tok: token.ASSIGN, + Rhs: []ast.Expr{f.intLiteral(1)}, + } +} + +// incCounterStmt returns the expression: __count[23]++. +func incCounterStmt(f *File, counter ast.Expr) ast.Stmt { + return &ast.IncDecStmt{ + X: counter, + Tok: token.INC, + } +} + +// atomicCounterStmt returns the expression: atomic.AddUint32(&__count[23], 1) +func atomicCounterStmt(f *File, counter ast.Expr) ast.Stmt { + return &ast.ExprStmt{ + X: &ast.CallExpr{ + Fun: &ast.SelectorExpr{ + X: ast.NewIdent(f.atomicPkg), + Sel: ast.NewIdent("AddUint32"), + }, + Args: []ast.Expr{&ast.UnaryExpr{ + Op: token.AND, + X: counter, + }, + f.intLiteral(1), + }, + }, + } +} + +// newCounter creates a new counter expression of the appropriate form. +func (f *File) newCounter(start, end token.Pos, numStmt int) ast.Stmt { + counter := &ast.IndexExpr{ + X: &ast.SelectorExpr{ + X: ast.NewIdent(*varVar), + Sel: ast.NewIdent("Count"), + }, + Index: f.index(), + } + stmt := counterStmt(f, counter) + f.blocks = append(f.blocks, Block{start, end, numStmt}) + return stmt +} + +// addCounters takes a list of statements and adds counters to the beginning of +// each basic block at the top level of that list. For instance, given +// +// S1 +// if cond { +// S2 +// } +// S3 +// +// counters will be added before S1 and before S3. The block containing S2 +// will be visited in a separate call. +// TODO: Nested simple blocks get unnecessary (but correct) counters +func (f *File) addCounters(pos, blockEnd token.Pos, list []ast.Stmt, extendToClosingBrace bool) []ast.Stmt { + // Special case: make sure we add a counter to an empty block. Can't do this below + // or we will add a counter to an empty statement list after, say, a return statement. + if len(list) == 0 { + return []ast.Stmt{f.newCounter(pos, blockEnd, 0)} + } + // We have a block (statement list), but it may have several basic blocks due to the + // appearance of statements that affect the flow of control. + var newList []ast.Stmt + for { + // Find first statement that affects flow of control (break, continue, if, etc.). + // It will be the last statement of this basic block. + var last int + end := blockEnd + for last = 0; last < len(list); last++ { + end = f.statementBoundary(list[last]) + if f.endsBasicSourceBlock(list[last]) { + extendToClosingBrace = false // Block is broken up now. + last++ + break + } + } + if extendToClosingBrace { + end = blockEnd + } + if pos != end { // Can have no source to cover if e.g. blocks abut. + newList = append(newList, f.newCounter(pos, end, last)) + } + newList = append(newList, list[0:last]...) + list = list[last:] + if len(list) == 0 { + break + } + pos = list[0].Pos() + } + return newList +} + +// hasFuncLiteral reports the existence and position of the first func literal +// in the node, if any. If a func literal appears, it usually marks the termination +// of a basic block because the function body is itself a block. +// Therefore we draw a line at the start of the body of the first function literal we find. +// TODO: what if there's more than one? Probably doesn't matter much. +func hasFuncLiteral(n ast.Node) (bool, token.Pos) { + if n == nil { + return false, 0 + } + var literal funcLitFinder + ast.Walk(&literal, n) + return literal.found(), token.Pos(literal) +} + +// statementBoundary finds the location in s that terminates the current basic +// block in the source. +func (f *File) statementBoundary(s ast.Stmt) token.Pos { + // Control flow statements are easy. + switch s := s.(type) { + case *ast.BlockStmt: + // Treat blocks like basic blocks to avoid overlapping counters. + return s.Lbrace + case *ast.IfStmt: + found, pos := hasFuncLiteral(s.Init) + if found { + return pos + } + found, pos = hasFuncLiteral(s.Cond) + if found { + return pos + } + return s.Body.Lbrace + case *ast.ForStmt: + found, pos := hasFuncLiteral(s.Init) + if found { + return pos + } + found, pos = hasFuncLiteral(s.Cond) + if found { + return pos + } + found, pos = hasFuncLiteral(s.Post) + if found { + return pos + } + return s.Body.Lbrace + case *ast.LabeledStmt: + return f.statementBoundary(s.Stmt) + case *ast.RangeStmt: + found, pos := hasFuncLiteral(s.X) + if found { + return pos + } + return s.Body.Lbrace + case *ast.SwitchStmt: + found, pos := hasFuncLiteral(s.Init) + if found { + return pos + } + found, pos = hasFuncLiteral(s.Tag) + if found { + return pos + } + return s.Body.Lbrace + case *ast.SelectStmt: + return s.Body.Lbrace + case *ast.TypeSwitchStmt: + found, pos := hasFuncLiteral(s.Init) + if found { + return pos + } + return s.Body.Lbrace + } + // If not a control flow statement, it is a declaration, expression, call, etc. and it may have a function literal. + // If it does, that's tricky because we want to exclude the body of the function from this block. + // Draw a line at the start of the body of the first function literal we find. + // TODO: what if there's more than one? Probably doesn't matter much. + found, pos := hasFuncLiteral(s) + if found { + return pos + } + return s.End() +} + +// endsBasicSourceBlock reports whether s changes the flow of control: break, if, etc., +// or if it's just problematic, for instance contains a function literal, which will complicate +// accounting due to the block-within-an expression. +func (f *File) endsBasicSourceBlock(s ast.Stmt) bool { + switch s := s.(type) { + case *ast.BlockStmt: + // Treat blocks like basic blocks to avoid overlapping counters. + return true + case *ast.BranchStmt: + return true + case *ast.ForStmt: + return true + case *ast.IfStmt: + return true + case *ast.LabeledStmt: + return f.endsBasicSourceBlock(s.Stmt) + case *ast.RangeStmt: + return true + case *ast.SwitchStmt: + return true + case *ast.SelectStmt: + return true + case *ast.TypeSwitchStmt: + return true + case *ast.ExprStmt: + // Calls to panic change the flow. + // We really should verify that "panic" is the predefined function, + // but without type checking we can't and the likelihood of it being + // an actual problem is vanishingly small. + if call, ok := s.X.(*ast.CallExpr); ok { + if ident, ok := call.Fun.(*ast.Ident); ok && ident.Name == "panic" && len(call.Args) == 1 { + return true + } + } + } + found, _ := hasFuncLiteral(s) + return found +} + +// funcLitFinder implements the ast.Visitor pattern to find the location of any +// function literal in a subtree. +type funcLitFinder token.Pos + +func (f *funcLitFinder) Visit(node ast.Node) (w ast.Visitor) { + if f.found() { + return nil // Prune search. + } + switch n := node.(type) { + case *ast.FuncLit: + *f = funcLitFinder(n.Body.Lbrace) + return nil // Prune search. + } + return f +} + +func (f *funcLitFinder) found() bool { + return token.Pos(*f) != token.NoPos +} + +// Sort interface for []block1; used for self-check in addVariables. + +type block1 struct { + Block + index int +} + +type blockSlice []block1 + +func (b blockSlice) Len() int { return len(b) } +func (b blockSlice) Less(i, j int) bool { return b[i].startByte < b[j].startByte } +func (b blockSlice) Swap(i, j int) { b[i], b[j] = b[j], b[i] } + +// offset translates a token position into a 0-indexed byte offset. +func (f *File) offset(pos token.Pos) int { + return f.fset.Position(pos).Offset +} + +// addVariables adds to the end of the file the declarations to set up the counter and position variables. +func (f *File) addVariables(w io.Writer) { + // Self-check: Verify that the instrumented basic blocks are disjoint. + t := make([]block1, len(f.blocks)) + for i := range f.blocks { + t[i].Block = f.blocks[i] + t[i].index = i + } + sort.Sort(blockSlice(t)) + for i := 1; i < len(t); i++ { + if t[i-1].endByte > t[i].startByte { + fmt.Fprintf(os.Stderr, "cover: internal error: block %d overlaps block %d\n", t[i-1].index, t[i].index) + // Note: error message is in byte positions, not token positions. + fmt.Fprintf(os.Stderr, "\t%s:#%d,#%d %s:#%d,#%d\n", + f.name, f.offset(t[i-1].startByte), f.offset(t[i-1].endByte), + f.name, f.offset(t[i].startByte), f.offset(t[i].endByte)) + } + } + + // Declare the coverage struct as a package-level variable. + fmt.Fprintf(w, "\nvar %s = struct {\n", *varVar) + fmt.Fprintf(w, "\tCount [%d]uint32\n", len(f.blocks)) + fmt.Fprintf(w, "\tPos [3 * %d]uint32\n", len(f.blocks)) + fmt.Fprintf(w, "\tNumStmt [%d]uint16\n", len(f.blocks)) + fmt.Fprintf(w, "} {\n") + + // Initialize the position array field. + fmt.Fprintf(w, "\tPos: [3 * %d]uint32{\n", len(f.blocks)) + + // A nice long list of positions. Each position is encoded as follows to reduce size: + // - 32-bit starting line number + // - 32-bit ending line number + // - (16 bit ending column number << 16) | (16-bit starting column number). + for i, block := range f.blocks { + start := f.fset.Position(block.startByte) + end := f.fset.Position(block.endByte) + fmt.Fprintf(w, "\t\t%d, %d, %#x, // [%d]\n", start.Line, end.Line, (end.Column&0xFFFF)<<16|(start.Column&0xFFFF), i) + } + + // Close the position array. + fmt.Fprintf(w, "\t},\n") + + // Initialize the position array field. + fmt.Fprintf(w, "\tNumStmt: [%d]uint16{\n", len(f.blocks)) + + // A nice long list of statements-per-block, so we can give a conventional + // valuation of "percent covered". To save space, it's a 16-bit number, so we + // clamp it if it overflows - won't matter in practice. + for i, block := range f.blocks { + n := block.numStmt + if n > 1<<16-1 { + n = 1<<16 - 1 + } + fmt.Fprintf(w, "\t\t%d, // %d\n", n, i) + } + + // Close the statements-per-block array. + fmt.Fprintf(w, "\t},\n") + + // Close the struct initialization. + fmt.Fprintf(w, "}\n") +} diff --git a/vendor/golang.org/x/tools/cmd/cover/cover_test.go b/vendor/golang.org/x/tools/cmd/cover/cover_test.go new file mode 100644 index 00000000..a18778b5 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/cover_test.go @@ -0,0 +1,94 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// No testdata on Android. + +// +build !android + +package main_test + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) + +const ( + // Data directory, also the package directory for the test. + testdata = "testdata" + + // Binaries we compile. + testcover = "./testcover.exe" +) + +var ( + // Files we use. + testMain = filepath.Join(testdata, "main.go") + testTest = filepath.Join(testdata, "test.go") + coverInput = filepath.Join(testdata, "test_line.go") + coverOutput = filepath.Join(testdata, "test_cover.go") +) + +var debug = false // Keeps the rewritten files around if set. + +// Run this shell script, but do it in Go so it can be run by "go test". +// +// replace the word LINE with the line number < testdata/test.go > testdata/test_line.go +// go build -o ./testcover +// ./testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go +// go run ./testdata/main.go ./testdata/test.go +// +func TestCover(t *testing.T) { + // Read in the test file (testTest) and write it, with LINEs specified, to coverInput. + file, err := ioutil.ReadFile(testTest) + if err != nil { + t.Fatal(err) + } + lines := bytes.Split(file, []byte("\n")) + for i, line := range lines { + lines[i] = bytes.Replace(line, []byte("LINE"), []byte(fmt.Sprint(i+1)), -1) + } + err = ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666) + if err != nil { + t.Fatal(err) + } + + // defer removal of test_line.go + if !debug { + defer os.Remove(coverInput) + } + + // go build -o testcover + cmd := exec.Command("go", "build", "-o", testcover) + run(cmd, t) + + // defer removal of testcover + defer os.Remove(testcover) + + // ./testcover -mode=count -var=coverTest -o ./testdata/test_cover.go testdata/test_line.go + cmd = exec.Command(testcover, "-mode=count", "-var=coverTest", "-o", coverOutput, coverInput) + run(cmd, t) + + // defer removal of ./testdata/test_cover.go + if !debug { + defer os.Remove(coverOutput) + } + + // go run ./testdata/main.go ./testdata/test.go + cmd = exec.Command("go", "run", testMain, coverOutput) + run(cmd, t) +} + +func run(c *exec.Cmd, t *testing.T) { + c.Stdout = os.Stdout + c.Stderr = os.Stderr + err := c.Run() + if err != nil { + t.Fatal(err) + } +} diff --git a/vendor/golang.org/x/tools/cmd/cover/doc.go b/vendor/golang.org/x/tools/cmd/cover/doc.go new file mode 100644 index 00000000..b74d5b3c --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/doc.go @@ -0,0 +1,27 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Cover is a program for analyzing the coverage profiles generated by +'go test -coverprofile=cover.out'. + +Cover is also used by 'go test -cover' to rewrite the source code with +annotations to track which parts of each function are executed. +It operates on one Go source file at a time, computing approximate +basic block information by studying the source. It is thus more portable +than binary-rewriting coverage tools, but also a little less capable. +For instance, it does not probe inside && and || expressions, and can +be mildly confused by single statements with multiple function literals. + +For usage information, please see: + go help testflag + go tool cover -help + +No longer maintained: + +For Go releases 1.5 and later, this tool lives in the +standard repository. The code here is not maintained. + +*/ +package main // import "golang.org/x/tools/cmd/cover" diff --git a/vendor/golang.org/x/tools/cmd/cover/func.go b/vendor/golang.org/x/tools/cmd/cover/func.go new file mode 100644 index 00000000..41d9fcec --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/func.go @@ -0,0 +1,166 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements the visitor that computes the (line, column)-(line-column) range for each function. + +package main + +import ( + "bufio" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/token" + "os" + "path/filepath" + "text/tabwriter" + + "golang.org/x/tools/cover" +) + +// funcOutput takes two file names as arguments, a coverage profile to read as input and an output +// file to write ("" means to write to standard output). The function reads the profile and produces +// as output the coverage data broken down by function, like this: +// +// fmt/format.go:30: init 100.0% +// fmt/format.go:57: clearflags 100.0% +// ... +// fmt/scan.go:1046: doScan 100.0% +// fmt/scan.go:1075: advance 96.2% +// fmt/scan.go:1119: doScanf 96.8% +// total: (statements) 91.9% + +func funcOutput(profile, outputFile string) error { + profiles, err := cover.ParseProfiles(profile) + if err != nil { + return err + } + + var out *bufio.Writer + if outputFile == "" { + out = bufio.NewWriter(os.Stdout) + } else { + fd, err := os.Create(outputFile) + if err != nil { + return err + } + defer fd.Close() + out = bufio.NewWriter(fd) + } + defer out.Flush() + + tabber := tabwriter.NewWriter(out, 1, 8, 1, '\t', 0) + defer tabber.Flush() + + var total, covered int64 + for _, profile := range profiles { + fn := profile.FileName + file, err := findFile(fn) + if err != nil { + return err + } + funcs, err := findFuncs(file) + if err != nil { + return err + } + // Now match up functions and profile blocks. + for _, f := range funcs { + c, t := f.coverage(profile) + fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n", fn, f.startLine, f.name, 100.0*float64(c)/float64(t)) + total += t + covered += c + } + } + fmt.Fprintf(tabber, "total:\t(statements)\t%.1f%%\n", 100.0*float64(covered)/float64(total)) + + return nil +} + +// findFuncs parses the file and returns a slice of FuncExtent descriptors. +func findFuncs(name string) ([]*FuncExtent, error) { + fset := token.NewFileSet() + parsedFile, err := parser.ParseFile(fset, name, nil, 0) + if err != nil { + return nil, err + } + visitor := &FuncVisitor{ + fset: fset, + name: name, + astFile: parsedFile, + } + ast.Walk(visitor, visitor.astFile) + return visitor.funcs, nil +} + +// FuncExtent describes a function's extent in the source by file and position. +type FuncExtent struct { + name string + startLine int + startCol int + endLine int + endCol int +} + +// FuncVisitor implements the visitor that builds the function position list for a file. +type FuncVisitor struct { + fset *token.FileSet + name string // Name of file. + astFile *ast.File + funcs []*FuncExtent +} + +// Visit implements the ast.Visitor interface. +func (v *FuncVisitor) Visit(node ast.Node) ast.Visitor { + switch n := node.(type) { + case *ast.FuncDecl: + start := v.fset.Position(n.Pos()) + end := v.fset.Position(n.End()) + fe := &FuncExtent{ + name: n.Name.Name, + startLine: start.Line, + startCol: start.Column, + endLine: end.Line, + endCol: end.Column, + } + v.funcs = append(v.funcs, fe) + } + return v +} + +// coverage returns the fraction of the statements in the function that were covered, as a numerator and denominator. +func (f *FuncExtent) coverage(profile *cover.Profile) (num, den int64) { + // We could avoid making this n^2 overall by doing a single scan and annotating the functions, + // but the sizes of the data structures is never very large and the scan is almost instantaneous. + var covered, total int64 + // The blocks are sorted, so we can stop counting as soon as we reach the end of the relevant block. + for _, b := range profile.Blocks { + if b.StartLine > f.endLine || (b.StartLine == f.endLine && b.StartCol >= f.endCol) { + // Past the end of the function. + break + } + if b.EndLine < f.startLine || (b.EndLine == f.startLine && b.EndCol <= f.startCol) { + // Before the beginning of the function + continue + } + total += int64(b.NumStmt) + if b.Count > 0 { + covered += int64(b.NumStmt) + } + } + if total == 0 { + total = 1 // Avoid zero denominator. + } + return covered, total +} + +// findFile finds the location of the named file in GOROOT, GOPATH etc. +func findFile(file string) (string, error) { + dir, file := filepath.Split(file) + pkg, err := build.Import(dir, ".", build.FindOnly) + if err != nil { + return "", fmt.Errorf("can't find %q: %v", file, err) + } + return filepath.Join(pkg.Dir, file), nil +} diff --git a/vendor/golang.org/x/tools/cmd/cover/html.go b/vendor/golang.org/x/tools/cmd/cover/html.go new file mode 100644 index 00000000..ef50e2bf --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/html.go @@ -0,0 +1,284 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bufio" + "bytes" + "fmt" + "html/template" + "io" + "io/ioutil" + "math" + "os" + "os/exec" + "path/filepath" + "runtime" + + "golang.org/x/tools/cover" +) + +// htmlOutput reads the profile data from profile and generates an HTML +// coverage report, writing it to outfile. If outfile is empty, +// it writes the report to a temporary file and opens it in a web browser. +func htmlOutput(profile, outfile string) error { + profiles, err := cover.ParseProfiles(profile) + if err != nil { + return err + } + + var d templateData + + for _, profile := range profiles { + fn := profile.FileName + if profile.Mode == "set" { + d.Set = true + } + file, err := findFile(fn) + if err != nil { + return err + } + src, err := ioutil.ReadFile(file) + if err != nil { + return fmt.Errorf("can't read %q: %v", fn, err) + } + var buf bytes.Buffer + err = htmlGen(&buf, src, profile.Boundaries(src)) + if err != nil { + return err + } + d.Files = append(d.Files, &templateFile{ + Name: fn, + Body: template.HTML(buf.String()), + Coverage: percentCovered(profile), + }) + } + + var out *os.File + if outfile == "" { + var dir string + dir, err = ioutil.TempDir("", "cover") + if err != nil { + return err + } + out, err = os.Create(filepath.Join(dir, "coverage.html")) + } else { + out, err = os.Create(outfile) + } + if err != nil { + return err + } + err = htmlTemplate.Execute(out, d) + if err == nil { + err = out.Close() + } + if err != nil { + return err + } + + if outfile == "" { + if !startBrowser("file://" + out.Name()) { + fmt.Fprintf(os.Stderr, "HTML output written to %s\n", out.Name()) + } + } + + return nil +} + +// percentCovered returns, as a percentage, the fraction of the statements in +// the profile covered by the test run. +// In effect, it reports the coverage of a given source file. +func percentCovered(p *cover.Profile) float64 { + var total, covered int64 + for _, b := range p.Blocks { + total += int64(b.NumStmt) + if b.Count > 0 { + covered += int64(b.NumStmt) + } + } + if total == 0 { + return 0 + } + return float64(covered) / float64(total) * 100 +} + +// htmlGen generates an HTML coverage report with the provided filename, +// source code, and tokens, and writes it to the given Writer. +func htmlGen(w io.Writer, src []byte, boundaries []cover.Boundary) error { + dst := bufio.NewWriter(w) + for i := range src { + for len(boundaries) > 0 && boundaries[0].Offset == i { + b := boundaries[0] + if b.Start { + n := 0 + if b.Count > 0 { + n = int(math.Floor(b.Norm*9)) + 1 + } + fmt.Fprintf(dst, ``, n, b.Count) + } else { + dst.WriteString("") + } + boundaries = boundaries[1:] + } + switch b := src[i]; b { + case '>': + dst.WriteString(">") + case '<': + dst.WriteString("<") + case '&': + dst.WriteString("&") + case '\t': + dst.WriteString(" ") + default: + dst.WriteByte(b) + } + } + return dst.Flush() +} + +// startBrowser tries to open the URL in a browser +// and reports whether it succeeds. +func startBrowser(url string) bool { + // try to start the browser + var args []string + switch runtime.GOOS { + case "darwin": + args = []string{"open"} + case "windows": + args = []string{"cmd", "/c", "start"} + default: + args = []string{"xdg-open"} + } + cmd := exec.Command(args[0], append(args[1:], url)...) + return cmd.Start() == nil +} + +// rgb returns an rgb value for the specified coverage value +// between 0 (no coverage) and 10 (max coverage). +func rgb(n int) string { + if n == 0 { + return "rgb(192, 0, 0)" // Red + } + // Gradient from gray to green. + r := 128 - 12*(n-1) + g := 128 + 12*(n-1) + b := 128 + 3*(n-1) + return fmt.Sprintf("rgb(%v, %v, %v)", r, g, b) +} + +// colors generates the CSS rules for coverage colors. +func colors() template.CSS { + var buf bytes.Buffer + for i := 0; i < 11; i++ { + fmt.Fprintf(&buf, ".cov%v { color: %v }\n", i, rgb(i)) + } + return template.CSS(buf.String()) +} + +var htmlTemplate = template.Must(template.New("html").Funcs(template.FuncMap{ + "colors": colors, +}).Parse(tmplHTML)) + +type templateData struct { + Files []*templateFile + Set bool +} + +type templateFile struct { + Name string + Body template.HTML + Coverage float64 +} + +const tmplHTML = ` + + + + + + + +
+ +
+ not tracked + {{if .Set}} + not covered + covered + {{else}} + no coverage + low coverage + * + * + * + * + * + * + * + * + high coverage + {{end}} +
+
+
+ {{range $i, $f := .Files}} +
{{$f.Body}}
+ {{end}} +
+ + + +` diff --git a/vendor/golang.org/x/tools/cmd/cover/testdata/main.go b/vendor/golang.org/x/tools/cmd/cover/testdata/main.go new file mode 100644 index 00000000..6ed39c4f --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/testdata/main.go @@ -0,0 +1,112 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test runner for coverage test. This file is not coverage-annotated; test.go is. +// It knows the coverage counter is called "coverTest". + +package main + +import ( + "fmt" + "os" +) + +func main() { + testAll() + verify() +} + +type block struct { + count uint32 + line uint32 +} + +var counters = make(map[block]bool) + +// check records the location and expected value for a counter. +func check(line, count uint32) { + b := block{ + count, + line, + } + counters[b] = true +} + +// checkVal is a version of check that returns its extra argument, +// so it can be used in conditionals. +func checkVal(line, count uint32, val int) int { + b := block{ + count, + line, + } + counters[b] = true + return val +} + +var PASS = true + +// verify checks the expected counts against the actual. It runs after the test has completed. +func verify() { + for b := range counters { + got, index := count(b.line) + if b.count == anything && got != 0 { + got = anything + } + if got != b.count { + fmt.Fprintf(os.Stderr, "test_go:%d expected count %d got %d [counter %d]\n", b.line, b.count, got, index) + PASS = false + } + } + verifyPanic() + if !PASS { + fmt.Fprintf(os.Stderr, "FAIL\n") + os.Exit(2) + } +} + +// verifyPanic is a special check for the known counter that should be +// after the panic call in testPanic. +func verifyPanic() { + if coverTest.Count[panicIndex-1] != 1 { + // Sanity check for test before panic. + fmt.Fprintf(os.Stderr, "bad before panic") + PASS = false + } + if coverTest.Count[panicIndex] != 0 { + fmt.Fprintf(os.Stderr, "bad at panic: %d should be 0\n", coverTest.Count[panicIndex]) + PASS = false + } + if coverTest.Count[panicIndex+1] != 1 { + fmt.Fprintf(os.Stderr, "bad after panic") + PASS = false + } +} + +// count returns the count and index for the counter at the specified line. +func count(line uint32) (uint32, int) { + // Linear search is fine. Choose perfect fit over approximate. + // We can have a closing brace for a range on the same line as a condition for an "else if" + // and we don't want that brace to steal the count for the condition on the "if". + // Therefore we test for a perfect (lo==line && hi==line) match, but if we can't + // find that we take the first imperfect match. + index := -1 + indexLo := uint32(1e9) + for i := range coverTest.Count { + lo, hi := coverTest.Pos[3*i], coverTest.Pos[3*i+1] + if lo == line && line == hi { + return coverTest.Count[i], i + } + // Choose the earliest match (the counters are in unpredictable order). + if lo <= line && line <= hi && indexLo > lo { + index = i + indexLo = lo + } + } + if index == -1 { + fmt.Fprintln(os.Stderr, "cover_test: no counter for line", line) + PASS = false + return 0, 0 + } + return coverTest.Count[index], index +} diff --git a/vendor/golang.org/x/tools/cmd/cover/testdata/test.go b/vendor/golang.org/x/tools/cmd/cover/testdata/test.go new file mode 100644 index 00000000..9013950a --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/cover/testdata/test.go @@ -0,0 +1,218 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This program is processed by the cover command, and then testAll is called. +// The test driver in main.go can then compare the coverage statistics with expectation. + +// The word LINE is replaced by the line number in this file. When the file is executed, +// the coverage processing has changed the line numbers, so we can't use runtime.Caller. + +package main + +const anything = 1e9 // Just some unlikely value that means "we got here, don't care how often" + +func testAll() { + testSimple() + testBlockRun() + testIf() + testFor() + testRange() + testSwitch() + testTypeSwitch() + testSelect1() + testSelect2() + testPanic() + testEmptySwitches() +} + +// The indexes of the counters in testPanic are known to main.go +const panicIndex = 3 + +// This test appears first because the index of its counters is known to main.go +func testPanic() { + defer func() { + recover() + }() + check(LINE, 1) + panic("should not get next line") + check(LINE, 0) // this is GoCover.Count[panicIndex] + // The next counter is in testSimple and it will be non-zero. + // If the panic above does not trigger a counter, the test will fail + // because GoCover.Count[panicIndex] will be the one in testSimple. +} + +func testSimple() { + check(LINE, 1) +} + +func testIf() { + if true { + check(LINE, 1) + } else { + check(LINE, 0) + } + if false { + check(LINE, 0) + } else { + check(LINE, 1) + } + for i := 0; i < 3; i++ { + if checkVal(LINE, 3, i) <= 2 { + check(LINE, 3) + } + if checkVal(LINE, 3, i) <= 1 { + check(LINE, 2) + } + if checkVal(LINE, 3, i) <= 0 { + check(LINE, 1) + } + } + for i := 0; i < 3; i++ { + if checkVal(LINE, 3, i) <= 1 { + check(LINE, 2) + } else { + check(LINE, 1) + } + } + for i := 0; i < 3; i++ { + if checkVal(LINE, 3, i) <= 0 { + check(LINE, 1) + } else if checkVal(LINE, 2, i) <= 1 { + check(LINE, 1) + } else if checkVal(LINE, 1, i) <= 2 { + check(LINE, 1) + } else if checkVal(LINE, 0, i) <= 3 { + check(LINE, 0) + } + } + if func(a, b int) bool { return a < b }(3, 4) { + check(LINE, 1) + } +} + +func testFor() { + for i := 0; i < 10; func() { i++; check(LINE, 10) }() { + check(LINE, 10) + } +} + +func testRange() { + for _, f := range []func(){ + func() { check(LINE, 1) }, + } { + f() + check(LINE, 1) + } +} + +func testBlockRun() { + check(LINE, 1) + { + check(LINE, 1) + } + { + check(LINE, 1) + } + check(LINE, 1) + { + check(LINE, 1) + } + { + check(LINE, 1) + } + check(LINE, 1) +} + +func testSwitch() { + for i := 0; i < 5; func() { i++; check(LINE, 5) }() { + switch i { + case 0: + check(LINE, 1) + case 1: + check(LINE, 1) + case 2: + check(LINE, 1) + default: + check(LINE, 2) + } + } +} + +func testTypeSwitch() { + var x = []interface{}{1, 2.0, "hi"} + for _, v := range x { + switch func() { check(LINE, 3) }(); v.(type) { + case int: + check(LINE, 1) + case float64: + check(LINE, 1) + case string: + check(LINE, 1) + case complex128: + check(LINE, 0) + default: + check(LINE, 0) + } + } +} + +func testSelect1() { + c := make(chan int) + go func() { + for i := 0; i < 1000; i++ { + c <- i + } + }() + for { + select { + case <-c: + check(LINE, anything) + case <-c: + check(LINE, anything) + default: + check(LINE, 1) + return + } + } +} + +func testSelect2() { + c1 := make(chan int, 1000) + c2 := make(chan int, 1000) + for i := 0; i < 1000; i++ { + c1 <- i + c2 <- i + } + for { + select { + case <-c1: + check(LINE, 1000) + case <-c2: + check(LINE, 1000) + default: + check(LINE, 1) + return + } + } +} + +// Empty control statements created syntax errors. This function +// is here just to be sure that those are handled correctly now. +func testEmptySwitches() { + check(LINE, 1) + switch 3 { + } + check(LINE, 1) + switch i := (interface{})(3).(int); i { + } + check(LINE, 1) + c := make(chan int) + go func() { + check(LINE, 1) + c <- 1 + select {} + }() + <-c + check(LINE, 1) +} diff --git a/vendor/golang.org/x/tools/cmd/digraph/digraph.go b/vendor/golang.org/x/tools/cmd/digraph/digraph.go new file mode 100644 index 00000000..3ad29500 --- /dev/null +++ b/vendor/golang.org/x/tools/cmd/digraph/digraph.go @@ -0,0 +1,540 @@ +// The digraph command performs queries over unlabelled directed graphs +// represented in text form. It is intended to integrate nicely with +// typical UNIX command pipelines. +// +// Since directed graphs (import graphs, reference graphs, call graphs, +// etc) often arise during software tool development and debugging, this +// command is included in the go.tools repository. +// +// TODO(adonovan): +// - support input files other than stdin +// - suport alternative formats (AT&T GraphViz, CSV, etc), +// a comment syntax, etc. +// - allow queries to nest, like Blaze query language. +// +package main // import "golang.org/x/tools/cmd/digraph" + +import ( + "bufio" + "bytes" + "errors" + "flag" + "fmt" + "io" + "os" + "sort" + "strconv" + "unicode" + "unicode/utf8" +) + +const Usage = `digraph: queries over directed graphs in text form. + +Graph format: + + Each line contains zero or more words. Words are separated by + unquoted whitespace; words may contain Go-style double-quoted portions, + allowing spaces and other characters to be expressed. + + Each field declares a node, and if there are more than one, + an edge from the first to each subsequent one. + The graph is provided on the standard input. + + For instance, the following (acyclic) graph specifies a partial order + among the subtasks of getting dressed: + + % cat clothes.txt + socks shoes + "boxer shorts" pants + pants belt shoes + shirt tie sweater + sweater jacket + hat + + The line "shirt tie sweater" indicates the two edges shirt -> tie and + shirt -> sweater, not shirt -> tie -> sweater. + +Supported queries: + + nodes + the set of all nodes + degree + the in-degree and out-degree of each node. + preds