Compare commits

...

418 Commits

Author SHA1 Message Date
adf2b8d01d Merge branch 'release/1.1.0' of github.com-obscure:ethereum/go-ethereum into release/1.1.0 2015-10-21 16:07:52 +02:00
4bf0cbcdd3 cmd/geth: version 1.1.3 2015-10-21 16:07:14 +02:00
33099eaeb6 core, tests: get_hash fix
Make sure that we're fetching the hash from the current chain and not
the canonical chain.

Conflicts:
	core/vm/environment.go
2015-10-21 16:06:36 +02:00
59d25c0c2c cmd/geth: bump 1.1.3 2015-09-09 18:48:35 +02:00
cde06b4009 Merge pull request #1781 from Gustav-Simonsson/state_object_copy
core/state: deleted field in StateObject Copy() and unit test
(cherry picked from commit 90f1fe0ed2)
2015-09-09 18:46:27 +02:00
587669215b cmd/geth: bump 1.1.2 2015-09-03 00:52:42 +02:00
fc3941d1fd fix block time issue
currently, under normal circumstances, you always set the timestamp to previous.Time() + 1.
credits to https://www.reddit.com/r/ethereum/comments/3jcs5r/code_avg_block_time_vs_difficulty_adjustment/cuoi4op

style
2015-09-03 00:16:59 +02:00
8f09242d7f Bump version to 1.1.1 2015-09-01 23:43:22 +02:00
042dcf1b28 Merge pull request #1755 from fjl/coinbase
core: improve block gas tracking
(cherry picked from commit e9b031b88b)
2015-09-01 23:41:51 +02:00
fd512fa12c Merge pull request #1711 from Gustav-Simonsson/timestamp_big_int
Add tests for uncle timestamps and refactor timestamp type
(cherry picked from commit abce09954b)
2015-08-25 15:54:57 +02:00
dc3fb69dce Merge pull request #1710 from bas-vk/useragent
user agent messages were dumped in some cases
(cherry picked from commit a219159e7e)
2015-08-25 15:54:26 +02:00
d51d0022ce cmd/geth: bumped version 1.1.0 2015-08-20 21:43:36 +02:00
3793991c0e remove 0x 2015-08-20 18:50:47 +02:00
b884d6ebaa canary update 2015-08-20 18:38:21 +02:00
36f7fe61c3 core, tests: Double SUICIDE fix 2015-08-20 18:22:50 +02:00
54088b0b8b cmd/geth: bumped version 1.0.3 2015-08-20 13:08:08 +02:00
9fb7bc7443 geth: bumped version 1.0.2 2015-08-19 23:05:39 +02:00
e2d44814a5 Merge pull request #1694 from obscuren/hide-fdtrack
fdtrack: hide message
2015-08-19 13:50:54 -07:00
bd3a44cac9 Merge pull request #1652 from bas-vk/autoreconnect
rpc/comms: reconnect ipc client after write error
2015-08-19 13:29:51 -07:00
61a6911eeb Merge pull request #1689 from fjl/discover-ignore-temp-errors
p2p, p2p/discover: small fixes
2015-08-19 12:55:40 -07:00
9bf17eb05a rpc/comms reconnect ipc client after write error 2015-08-19 21:48:56 +02:00
269c5c7107 Revert "fdtrack: temporary hack for tracking file descriptor usage"
This reverts commit 5c949d3b3b.
2015-08-19 21:46:01 +02:00
382d35bf40 Merge pull request #1688 from karalabe/fix-double-imports
eth: fix an issue with pulling and inserting blocks twice
2015-08-19 08:19:37 -07:00
dd54fef898 p2p/discover: don't attempt to replace nodes that are being replaced
PR #1621 changed Table locking so the mutex is not held while a
contested node is being pinged. If multiple nodes ping the local node
during this time window, multiple ping packets will be sent to the
contested node. The changes in this commit prevent multiple packets by
tracking whether the node is being replaced.
2015-08-19 14:57:16 +02:00
edccc7ae34 p2p: continue listening after temporary errors 2015-08-19 14:39:04 +02:00
7d5ff770e2 p2p/discover: continue reading after temporary errors
Might solve #1579
2015-08-19 14:38:55 +02:00
c6a11fe372 Merge pull request #1680 from maran/fix_removedb
cmd/geth: Fix chain purging from cmd line
2015-08-19 05:17:22 -07:00
941920f2aa eth: fix an issue with pulling and inserting blocks twice 2015-08-19 15:14:26 +03:00
3b997c3e16 Merge pull request #1454 from ethersphere/frozen-cryptoclean
crypto: remove obsolete code
2015-08-19 02:39:02 -07:00
0737cbc5c1 Merge pull request #1683 from ethereum/travis
Switch from Coveralls to Codecov code coverage service
2015-08-18 14:26:14 -07:00
227ff4d2d6 Merge pull request #1682 from obscuren/readme-improvements
Updated README, Added CONTRIBUTING
2015-08-18 14:16:42 -07:00
18d450b2d0 Updated README, Added CONTRIBUTING 2015-08-18 23:00:15 +02:00
cc87551edc Codecov integration 2015-08-18 22:46:48 +02:00
d0dc1b4a60 Merge pull request #1681 from obscuren/miner-receipt-fix
core, miner: write miner receipts
2015-08-18 12:53:26 -07:00
b4369e1015 core, miner: write miner receipts 2015-08-18 21:46:26 +02:00
4d5501c46a cmd/geth: Fix chain purging from cmd line 2015-08-18 15:56:37 +02:00
d4da2f630e crypto: remove obsolete key files 2015-08-18 01:25:04 +02:00
e1da124415 Merge pull request #1675 from obscuren/submithashrate-change
rpc/api: return boolean value for eth_submitHashrate
2015-08-17 11:49:15 -07:00
36081505c4 Merge pull request #1673 from karalabe/fix-api-xeth-responses
rpc: update the xeth over RPC API to use the success/failure messages
2015-08-17 11:47:55 -07:00
2497f28aa9 Merge pull request #1627 from zsfelfoldi/gpo
GPO update
2015-08-17 06:37:58 -07:00
49ece3155c GPO update 2015-08-17 15:20:33 +02:00
8839fee415 rpc/api: return boolean value for eth_submitHashrate 2015-08-17 15:09:30 +02:00
ff1f6fa09d Merge pull request #1649 from maran/pending_tx_response
rpc/api: format pendingTx response. Fixes #1648
2015-08-17 06:02:08 -07:00
7ea30f18f9 Merge pull request #1674 from tgerring/bootnodes
Added SG bootnode
2015-08-17 05:56:38 -07:00
12805c738c Merge pull request #1667 from fjl/pretty-printer-improvements
jsre: pretty printer improvements
2015-08-17 05:55:09 -07:00
80b294c3c7 Update CPP pubkey 2015-08-17 14:51:27 +02:00
8884f856ef Added SG bootnode 2015-08-17 14:36:57 +02:00
309788de37 rpc: update the xeth over RPC API to use the success/failure messages 2015-08-17 14:04:20 +03:00
f6367548e4 Merge pull request #1654 from obscuren/call-gas
xeth: call fix when doing 'create'-like calls
2015-08-16 16:33:29 -07:00
1c3ca3ce6a xeth: max gas limit 2015-08-16 15:27:30 +02:00
8603ec7055 rpc/api: format pendingTx response. Fixes #1648 2015-08-16 11:12:22 +02:00
1086e2f298 jsre: fix annoying indentation when printing arrays of objects
The pretty printer, dumb as it is, printed arrays of objects as

  [{
    ...
    }]

With this change, they now print as:

  [{
    ...
  }]
2015-08-16 00:35:00 +01:00
49703bea0a jsre: bind the pretty printer to "inspect" in JS 2015-08-15 23:55:42 +01:00
59b28cfa31 Merge pull request #1663 from obscuren/issue-1662
xeth: added a transact mu
2015-08-15 14:55:04 -07:00
5c5c3930b7 Merge pull request #1659 from bas-vk/exec-output
Javascript --exec output
2015-08-15 06:23:29 -07:00
7bb5ac045e xeth: added a transact mu
Added a transact mutex. The transact mutex will fix an issue where
transactions were created with the same nonce resulting in some
transactions being dropped. This happened when two concurrent calls
would call the `Transact` method (which is OK) which would both call
`GetNonce`. While the managed is thread safe it does not help us in this
case.
2015-08-15 00:33:52 +02:00
cd81356ace Merge pull request #1658 from bas-vk/liner-ctrl-c
Clear current line on ctrl-C
2015-08-14 04:36:15 -07:00
c472b8f725 main clear current line on ctrl-C 2015-08-14 13:23:41 +02:00
3a66c4ed47 Merge pull request #1642 from ethereum/fix-js-console-windows
cmd/geth, jsre: restore command line editing on windows
2015-08-14 04:14:11 -07:00
29181003d4 Merge pull request #1655 from obscuren/db-merge-fix
eth, trie: removed key prefixing from state entries & merge db fix
2015-08-14 04:12:33 -07:00
87d1cde7e4 main print console output for js statement given by the exec argument 2015-08-14 13:06:34 +02:00
28b14d3e6d Merge pull request #1635 from bas-vk/useragent
support for user agents
2015-08-13 16:25:33 -07:00
73c4e6005c Merge pull request #1638 from obscuren/jit-fixes
core/vm: fixed jit error & added inline docs
2015-08-13 11:49:01 -07:00
b8ca0a830e eth, trie: removed key prefixing from state entries & merge db fix
Fixed database merge strategy to use the correct database. Due to a copy
paste fail when doing type evaluation the same database was being
iterated (chain), all others were ignored.

Removed state prefixing because {H(code): code} is stored in the same
database as the rest of the state.
2015-08-13 20:44:03 +02:00
a89cfe92cc Merge pull request #1470 from ebuchman/encHandshake
p2p: validate recovered ephemeral pubkey
2015-08-13 11:59:27 +02:00
0b0b31c7d2 Merge pull request #1651 from karalabe/rlp-boolean-support
rlp: boolean support
2015-08-13 11:10:26 +02:00
1d2420323c rlp: add support for boolean encoding/decoding 2015-08-13 12:05:39 +03:00
0dd6911c62 Merge pull request #1647 from fjl/fix-disc-reason
p2p: fix value of DiscSubprotocolError
2015-08-12 21:20:21 +02:00
28feafe7af Merge pull request #1646 from fjl/fix-client-identifier
cmd/geth: remove spaces in client identifier
2015-08-12 14:38:48 +02:00
0d10d5a0a5 p2p: fix value of DiscSubprotocolError
We had the wrong value (12) since forever.
2015-08-12 14:15:54 +02:00
31a2793662 cmd/geth: remove spaces in client identifier 2015-08-12 13:32:52 +02:00
f9cbd16f27 support for user agents 2015-08-12 12:22:16 +02:00
0ef80bb3d0 cmd/geth, jsre: restore command line editing on windows
PR #856 broke command line editing by wrapping stdout with a filter that
interprets ANSI escape sequences to fix colored printing on windows.
Implement the printer in Go instead so it can do its own
platform-dependent coloring.

As a nice side effect, the JS console is now noticeably more responsive
when printing results.

Fixes #1608
Fixes #1612
2015-08-12 12:04:00 +02:00
05c66529b2 Merge pull request #1621 from ethereum/fix-discover-hangs
p2p/discover: fix two major bugs in reply packet handling
2015-08-11 12:17:13 -07:00
9cacec70f9 cmd/evm, core/vm, tests: changed DisableVm to EnableVm 2015-08-11 18:43:22 +02:00
94b6f38869 Merge pull request #1641 from obscuren/web3-update
web3: updated
2015-08-11 08:55:55 -07:00
bf6ea2919d web3: updated 2015-08-11 17:17:20 +02:00
c32d6fdf74 Merge pull request #1640 from obscuren/trace-flag-ethtest
cmd/ethtest: added trace flag for debugging
2015-08-11 02:53:02 -07:00
67c8ccc309 cmd/ethtest: added trace flag for debugging 2015-08-11 11:46:52 +02:00
590c99a98f p2p/discover: fix UDP reply packet timeout handling
If the timeout fired (even just nanoseconds) before the deadline of the
next pending reply, the timer was not rescheduled. The timer would've
been rescheduled anyway once the next packet was sent, but there were
cases where no next packet could ever be sent due to the locking issue
fixed in the previous commit.

As timing-related bugs go, this issue had been present for a long time
and I could never reproduce it. The test added in this commit did
reproduce the issue on about one out of 15 runs.
2015-08-11 11:42:17 +02:00
01ed3fa1a9 p2p/discover: unlock the table during ping replacement
Table.mutex was being held while waiting for a reply packet, which
effectively made many parts of the whole stack block on that packet,
including the net_peerCount RPC call.
2015-08-11 11:42:17 +02:00
32395ddb89 core/vm: fixed jit error & added inline docs
opNumber did not create a new big int which could lead to the block's
number being modified.
2015-08-11 00:16:38 +02:00
2fcf7f1241 Merge pull request #1604 from obscuren/db-merge
core, eth, trie, xeth: merged state, chain, extra databases in one
2015-08-09 05:16:37 -07:00
07cb8092e7 Merge pull request #1611 from obscuren/expdiff-olympic-fix
cmd/utils, core: disable exp diff for olympic net
2015-08-09 05:15:13 -07:00
1cbd53add8 Merge pull request #1626 from obscuren/defaults-fix
cmd/geth, core/vm: setup vm settings and defaulted JIT disabled
2015-08-08 17:11:28 -07:00
eec38c5853 cmd/geth, core/vm: setup vm settings and defaulted JIT disabled 2015-08-09 02:06:16 +02:00
c93f0b9f4b Merge pull request #1490 from obscuren/jit-vm
core/vm: jit vm
2015-08-08 06:36:26 -07:00
a23478c0be core, eth, trie, xeth: merged state, chain, extra databases in one 2015-08-07 22:29:02 +02:00
312128384b Merge pull request #1620 from caktux/develop
string version for build server
2015-08-07 11:41:41 -07:00
3ccab5a1e8 string version for build server 2015-08-07 14:13:33 -04:00
dcb23bc3ab Merge pull request #1615 from obscuren/contract-addr-fix
xeth: fixed contract addr check
2015-08-07 05:38:02 -07:00
b6c5b3b4a7 xeth: fixed contract addr check 2015-08-07 14:32:06 +02:00
d7580f21f6 Merge pull request #1595 from obscuren/extra-data
cmd/geth, eth: added canonical extra data
2015-08-07 05:00:36 -07:00
b1fac4270d Merge pull request #1614 from obscuren/web3-finite-fix
web3: regression. Fixes #1613
2015-08-07 04:59:15 -07:00
ac697326a6 core/vm: reduced big int allocations
Reduced big int allocation by making stack items modifiable. Instead of
adding items such as `common.Big0` to the stack, `new(big.Int)` is
added instead. One must expect that any item that is added to the stack
might change.
2015-08-07 12:52:23 +02:00
184e9ae9a8 core, tests: reduced state copy by N calls
Reduced the amount of state copied that are required by N calls by doing
a balance check prior to any state modifications.
2015-08-07 12:52:23 +02:00
846f34f78b core/vm, tests: implemented semi-jit vm
* changed stack and removed stack ptr. Let go decide on slice reuse.
2015-08-07 12:52:17 +02:00
a33726b7db web3: regression. Fixes #1613 2015-08-07 12:33:12 +02:00
132df860d9 miner, rpc: added length check for extra data 2015-08-07 12:24:44 +02:00
785b3e7a57 cmd/geth, eth: added canonical extra data
Implemented canonical extra data according to
https://github.com/ethereum/wiki/wiki/Extra-Data
2015-08-07 12:24:32 +02:00
e89536ca0b Merge pull request #1596 from obscuren/submit-hashrate
miner, rpc: added submit hashrate for remote agents
2015-08-07 03:08:48 -07:00
ac10c9352e Merge pull request #1610 from obscuren/address-check
xeth: added address hex check and length check
2015-08-07 02:05:54 -07:00
cf7cef4293 xeth: added address hex check and length check 2015-08-07 09:52:12 +02:00
698e98d981 Merge pull request #1600 from ethereum/fix-tests-windows
Fix tests on windows
2015-08-06 12:39:29 -07:00
a3b8169938 Merge pull request #1603 from ebuchman/trie_hex_fix
trie: hex fix
2015-08-06 12:02:55 -07:00
46c9594081 trie: run codec tests, add benchmarks, faster 2015-08-06 14:04:16 -04:00
7baa5977c8 Merge pull request #1594 from ebuchman/trie_hex_fix
faster hex-prefix codec and string -> []byte
2015-08-06 08:44:19 -07:00
803096ca0f .gitattributes: add 2015-08-06 17:18:59 +02:00
6ee908848c p2p/nat: disable UPnP test on windows 2015-08-06 17:18:59 +02:00
3832019964 common/compiler, common/docserver, jsre: fix tests on windows 2015-08-06 17:18:59 +02:00
eae1191904 cmd/utils: fix path expansion on windows 2015-08-06 17:18:59 +02:00
78b101e15d common: remove windows path functions
They were unused and their tests failed on Windows.
2015-08-06 16:43:43 +02:00
74f6d90153 cmd/utils, core: disable exp diff for olympic net 2015-08-06 13:29:06 +02:00
c32073b11f miner, rpc: added submit hashrate for remote agents 2015-08-06 12:58:54 +02:00
b23b4dbd79 p2p/discover: close Table during testing
Not closing the table used to be fine, but now the table has a database.
2015-08-06 12:27:59 +02:00
c1d516546d faster hex-prefix codec and string -> []byte 2015-08-06 03:17:59 -04:00
82ef26f600 Merge branch 'develop' 2015-08-05 18:41:08 +02:00
ee5728ec03 fake commit for build server :( 2015-08-05 18:41:00 +02:00
9a02f53726 Merge branch 'develop' 2015-08-05 18:35:28 +02:00
98100f472c cmd/geth: bumped version number 2015-08-05 18:35:23 +02:00
80e5f50713 Merge branch 'develop' 2015-08-05 18:08:52 +02:00
26f838796b Merge pull request #1583 from obscuren/miner-price-order
miner, core: sort txs by price, nonce
2015-08-05 09:03:18 -07:00
35f271b264 miner, core: sort txs by price, nonce 2015-08-05 17:44:19 +02:00
f12e0161ca Merge pull request #1588 from obscuren/diff-bomb
core, miner: added difficulty bomb
2015-08-05 04:26:57 -07:00
71d32f54f7 core, miner: added difficulty bomb 2015-08-05 13:09:09 +02:00
1f4ac6b05a Merge pull request #1587 from obscuren/miner-race
miner: fixed worker race condition
2015-08-05 01:50:49 -07:00
d8590d9790 miner: fixed worker race condition 2015-08-04 20:54:21 +02:00
56219a5e7a Merge pull request #1578 from Gustav-Simonsson/frontier_thawing
miner: gas limit strategy, target 3141592 & def gas price 50 Shannon
2015-08-04 11:53:39 -07:00
26c6e3b206 miner: gas limit strategy, target 3141592 & def gas price 50 Shannon 2015-08-04 15:20:28 +02:00
b01f2c29ae Merge pull request #1574 from fjl/fdtrack
fdtrack: hack to track file descriptor usage
2015-08-04 03:51:16 -07:00
ff66e8fa29 Merge pull request #1562 from ethersphere/blankpasswd
jsre: leave out lines from history possibly containing passwords
2015-08-04 03:10:59 -07:00
17b481e3c3 Merge pull request #1581 from obscuren/olympic
cmd, core, eth: support for the olympic network
2015-08-04 00:54:07 -07:00
5c949d3b3b fdtrack: temporary hack for tracking file descriptor usage
Package fdtrack logs statistics about open file descriptors.
This should help identify the source of #1549.
2015-08-04 03:10:27 +02:00
dcdb7059cc cmd, core, eth: support for the olympic network
Added a --olympic flag which initialiser the olympic protocol settings
2015-08-03 18:15:48 +02:00
bf48ed32dd metrics: fix file descriptor leak when reading disk stats on linux
The disk stats file was not closed after reading.
2015-08-03 16:27:36 +02:00
ba14957cf3 rpc/comms: use ConnState to track HTTP connections
The JSON-RPC server wraps TCP connections in order to be able to shut
down them down when RPC is stopped. This is rather scary code. Go 1.3
introduced the http.Server.ConnState hook for such purposes. We can use
this facility now that we depend on Go 1.4.

There are multiple reasons for the switch apart from making the code
less scary:

* the TCP listener no longer ticks every second to check a channel
* pending requests are allowed to finish after stopping the server
* we can time out idle keep-alive connections
2015-08-03 16:27:36 +02:00
97cdf84899 Merge pull request #1479 from tgerring/ethtest
Update ethtest default path for BlockTests
2015-08-03 07:18:48 -07:00
98db08c42f Merge pull request #1548 from fjl/accounts-test-deflake
accounts: bump timeout in TestSignRace
2015-08-03 07:16:36 -07:00
cc6c5846e5 Merge pull request #1568 from obscuren/issue-1559
core: added a running flag to prevent panics in the chainmanager
2015-08-03 07:15:19 -07:00
db988a46dd Merge pull request #1569 from obscuren/default-genesis
core: added default genesis block
2015-08-03 04:49:30 -07:00
7a75da63c6 core: added default genesis block
When a user runs a freshly setup geth w/o a database initialised the
default genesis block is decoded and inserted in to the database.
2015-08-02 01:23:02 +02:00
33efb3381c Merge pull request #1461 from bas-vk/eth_resend
Old transaction after resend was not removed from pool
2015-08-01 16:18:54 -07:00
5aec1d94ad accounts: bump timeout and spin less in TestSignRace
This should fix the flakeyness.
2015-08-02 00:49:53 +02:00
a8b39b5cc0 Merge pull request #1541 from bas-vk/issue1518
Improved error handling for NewTransactionFromBytes
2015-08-01 08:47:32 -07:00
acd2c4e520 core: added a running flag to prevent panics in the chainmanager
The running flag will determine whether the chain manager is still
running or not. This will prevent the quit channel from being closed
twice resulting in a panic. This PR should fix this issue.

Closes #1559
2015-08-01 12:32:28 +02:00
ab85a3593a Merge pull request #1545 from obscuren/log-index
core/state: Set log index. Closes #1226
2015-07-31 10:36:42 -07:00
c1c06fffcb Merge pull request #1561 from karalabe/add-missing-autocompletes
rpc/api: add missing autocomplete commands
2015-07-31 03:09:08 -07:00
6628eeb6ca jsre: leave out lines from history containing methods of the personal module 2015-07-31 11:51:18 +02:00
0d3a8ad6dd rpc/api: add missing autocomplete commands 2015-07-31 12:46:16 +03:00
4231de3914 Merge pull request #1553 from prusnak/develop
remove elliptic.P224 usage
2015-07-30 03:59:25 -07:00
3f07afbbd2 remove elliptic.P224 usage
Fedora/RedHat distros comply with US patent law and remove this curve,
which makes it impossible to run ethereum with distro provided Golang.

File crypto/ecies/README claims it is unsupported anyway.
2015-07-30 12:47:45 +02:00
64e2f52c2e Merge pull request #1534 from obscuren/issue-1040
rpc: to in eth_call no longer required. Fixed eth_estimateGas
2015-07-30 03:25:47 -07:00
d261c3f455 rpc: to in Call no longer required. Fixed eth_estimateGas 2015-07-29 15:12:12 +02:00
e7f4232b10 Merge pull request #1544 from karalabe/fix-stall-detector
eth, eth/downloader: don't report stall if fetcher filled the block
2015-07-29 06:11:43 -07:00
f715547fc7 core/state: Set log index. Closes #1226 2015-07-29 15:08:59 +02:00
fa286688ab Merge pull request #1546 from obscuren/tests-update
tests: updated
2015-07-29 06:07:19 -07:00
03c39d4fc0 tests: updated 2015-07-29 15:01:42 +02:00
6adbaabc65 eth, eth/downloader: don't report stall if fetcher filled the block 2015-07-29 15:39:08 +03:00
81e2124ea2 improved error detection and handling for NewTransactionFromBytes
integrated review comments
2015-07-29 10:30:00 +02:00
cc27be9d44 Merge pull request #1543 from enriquefynn/develop
FreeBSD support
2015-07-28 16:20:13 -07:00
7065ebd2ed FreeBSD support 2015-07-28 19:16:16 -03:00
a281df783d Merge pull request #1533 from ethersphere/frontier/etherbase
Etherbase defaults to first account even if it is created during the session
2015-07-28 05:11:43 -07:00
1fad8798ec Merge pull request #1515 from fjl/license-fixes
all: fix license headers one more time
2015-07-28 04:29:42 -07:00
7e31df3987 bugfix, pending transaction was resend with new gas price/limit but not removed from transaction pool 2015-07-28 10:42:31 +02:00
572e78cee0 Merge pull request #1536 from fjl/fix-go1.5-build
crypto: fix build with Go 1.5
2015-07-28 00:59:52 +02:00
453d2c9ce1 crypto: fix build with Go 1.5 2015-07-27 19:13:45 +02:00
1356daad27 etherbase defaults to first account even if created during the session 2015-07-27 10:50:29 +02:00
d18d256442 Merge pull request #1529 from obscuren/extra-data-fix
core: genesis extra data field fix
2015-07-26 15:15:36 -07:00
3530acb9e2 core: genesis extra data field fix 2015-07-26 14:44:54 +02:00
8a5ea466e4 Merge pull request #1528 from obscuren/reduce-extra-data
params: reduce extra data to 32 bytes & target block time
2015-07-26 04:04:10 -07:00
1e241e84f7 params: reduce extra data to 32 bytes 2015-07-26 12:47:57 +02:00
e86233abc9 Merge pull request #1525 from obscuren/genesis-write-fix
core: fixed genesis write out to write only canon number
2015-07-25 13:13:27 -07:00
c1c895a36b core: fixed genesis write out to write only canon number 2015-07-25 21:48:53 +02:00
73a576c9af Merge pull request #1524 from obscuren/default-extra
eth: set default miner extra to client name
2015-07-25 08:58:08 -07:00
665eaff9b9 Merge pull request #1520 from obscuren/reward-5eth
core: 5 ether block reward
2015-07-25 08:57:33 -07:00
9afda6ab8c core: 5 ether block reward 2015-07-25 17:47:20 +02:00
3adaeb1dbc eth: set default miner extra to client name 2015-07-25 17:36:56 +02:00
0efcd7ed05 Merge pull request #1521 from obscuren/client-update
cmd/geth, core, eth: Version 1.0.0
2015-07-25 08:36:04 -07:00
4019e2a6f2 Merge pull request #1497 from obscuren/remove-rle
ethdb, trie: removed RLE compression
2015-07-25 08:35:40 -07:00
f6097f4a0a Merge pull request #1522 from obscuren/genesis-block-check
core: check genesis block before writeout
2015-07-25 08:10:08 -07:00
d4428cc77f Merge pull request #1523 from obscuren/lower-gasprice
cmd/util: lowered default gas price
2015-07-25 08:09:55 -07:00
ba15f9d282 cmd/util: lowered default gas price 2015-07-25 17:03:10 +02:00
0c718afe90 core: check genesis block before writeout 2015-07-25 16:53:35 +02:00
036e6301af cmd/geth, core, eth: Version 1.0.0
Genesis release. Closes #1402

Conflicts:
	cmd/geth/main.go
2015-07-25 13:55:56 +02:00
6cffa743ee Merge pull request #1519 from obscuren/develop
web3: updated 0.9.1
2015-07-25 04:06:43 -07:00
5001f778aa web3: updated 0.9.1 2015-07-25 12:22:39 +02:00
cd657b9878 Godeps: use BSD-licensed version of gopkg.in/karalabe/cookiejar.v2 2015-07-24 14:23:02 +02:00
67598d9d08 crypto/sha3: add full license headers 2015-07-24 12:32:58 +02:00
fd2356c620 common: remove config.go
The code in config.go is unused. The main reason for removing it is to
get rid github.com/rakyll/goini in Godeps (it has no license).
2015-07-24 11:43:32 +02:00
bfbcfbe4a9 all: fix license headers one more time
I forgot to update one instance of "go-ethereum" in commit 3f047be5a.
2015-07-23 18:35:11 +02:00
adc7ab0dd6 Merge pull request #1507 from obscuren/batch-write
cmd/core,xeth: removed unneeded states & added batch writes
2015-07-23 07:50:07 -07:00
8f56eea77d ethdb, trie: removed RLE compression 2015-07-23 12:57:33 +02:00
8fc9830971 cmd/core,xeth: removed unneeded states & added batch writes 2015-07-23 10:45:31 +02:00
0cff61beda Merge pull request #1510 from fjl/license-fixes
all: license fixes
2015-07-23 01:43:11 -07:00
b403b9e4c3 Merge pull request #1508 from karalabe/database-caching
cmd, core, eth, ethdb: cache flag to allocate memory for db internal use
2015-07-23 01:17:18 -07:00
26a269ea09 Merge pull request #1511 from karalabe/rlp-data-race
core: fix an RLP encoding data race due to deep struct copy
2015-07-22 20:10:41 +02:00
04bb89604e core: fix an RLP encoding data race due to deep struct copy 2015-07-22 20:54:53 +03:00
0428cae226 remove LICENSE files 2015-07-22 18:54:45 +02:00
3f047be5aa all: update license headers to distiguish GPL/LGPL
All code outside of cmd/ is licensed as LGPL. The headers
now reflect this by calling the whole work "the go-ethereum library".
2015-07-22 18:51:45 +02:00
f4acdea402 crypto: fix license of curve.go
crypto/curve.go is not our code and has its own license. This commit
excludes it in update-license.go and removes our GPL header.
2015-07-22 18:50:31 +02:00
c7e7778f2a cmd, core, eth, ethdb: cache flag to allocate memory for db internal use 2015-07-22 14:00:52 +03:00
d1d45aa839 Merge pull request #1503 from fjl/fix-accounts-race
accounts: fix data race when key is locked after the unlock timeout
2015-07-22 13:00:09 +02:00
d103af5dd4 Disassociate test directory from test name 2015-07-22 11:39:36 +01:00
ed1d2f858e Merge pull request #1481 from tgerring/legalese
Legalese updates
2015-07-22 03:35:33 -07:00
482cc4957d Merge pull request #1500 from karalabe/fix-miner-race
miner: fix current work data race
2015-07-22 03:16:13 -07:00
f1daed65b1 Merge pull request #1502 from ethereum/canaryFix
Fixed canary to require 2+ nonzero, not sum 2+
2015-07-20 16:17:48 -07:00
cf5313f13e Update disclaimer 2015-07-20 18:49:25 +02:00
06d5898d6a crypto: remove debug print call after decrypting a key from disk 2015-07-20 18:04:23 +02:00
7662dd9bbb accounts: fix data race when key is locked after the unlock timeout
While here, also improve the docs and speed up the tests.
The tests used the scrypt keystore with ridiculous settins and took 20s
each.
2015-07-20 18:04:23 +02:00
8160b8618d Fixed canary to require 2+ nonzero, not sum 2+ 2015-07-20 16:28:28 +02:00
3029349761 miner: fix current work data race 2015-07-20 14:37:43 +03:00
02c5022742 Merge pull request #1496 from karalabe/fix-xeth-races
xeth: fix #1485, data race in fiilter creation and event firing
2015-07-20 04:27:10 -07:00
3642441ca3 xeth: fix #1485, data race in fiilter creation and event firing 2015-07-20 14:02:02 +03:00
12bb743b35 Merge pull request #1484 from fjl/rlp-json-tests
cmd/ethtest, tests: add support for RLP JSON tests
2015-07-19 05:05:16 -07:00
26c0fa1cb0 Merge pull request #1480 from obscuren/miner-state-sync
miner: moved state sync
2015-07-19 05:03:59 -07:00
a38f3740d6 Merge pull request #1488 from ethereum/travis
Travis container support
2015-07-18 09:05:29 -07:00
345590f27f rlp: fix check for canonical byte array size
Decoding did not reject byte arrays of length one with a single element
b where 55 < b < 128. Such byte arrays must be rejected because
they must be encoded as the single byte b instead.
2015-07-18 16:23:35 +02:00
5a41326521 Travis container support 2015-07-18 16:12:48 +02:00
cefd948267 rlp: reject trailing data when using DecodeBytes 2015-07-18 01:47:17 +02:00
593b1b65e7 tests: document RLP tests 2015-07-17 15:42:23 +02:00
5da82077d1 cmd/ethtest, tests: add support for RLP JSON tests 2015-07-17 15:13:24 +02:00
1b9ef0e52d miner: moved state sync
Moved the state sync so it only syncs the state when the block mining yield a possitive result
2015-07-16 14:19:27 +02:00
a75b95b876 Merge pull request #1477 from tgerring/legalese
Prompt user to accept legalese when datadir doesn't exist
2015-07-16 04:40:15 -07:00
e954375109 Merge pull request #1469 from obscuren/smart-mining
miner: smart mining
2015-07-16 04:39:07 -07:00
618991f136 Move text to separate file 2015-07-16 13:34:34 +02:00
bc6b6932d0 Merge pull request #1476 from obscuren/deadlock-logs
xeth: removed mutex lock
2015-07-16 03:35:43 -07:00
1909d26fe2 Prompt user to accept legalese when datadir doesn't exist 2015-07-16 12:27:42 +02:00
b1d0d3c0ed xeth: removed unneeded mutex lock 2015-07-16 11:04:53 +02:00
9addb3df3a Merge pull request #1475 from obscuren/issue1473
core: during chain reorg rewrite receipts and transactions
2015-07-15 13:17:07 -07:00
e870e61bc9 miner: smart mining
Work is now handled and carried over multiple sessions. Previously one
session only was assumed, potentially resulting in invalid (outdated)
work

* Larger work / result queue
* Full validation option
2015-07-15 20:37:12 +02:00
cecc9cdd2f Merge pull request #1468 from Gustav-Simonsson/xeth_transact_logging
xeth: log signed tx hash
2015-07-15 11:35:51 -07:00
e17d8ddbeb core: during chain reorg rewrite receipts and transactions
Added PutBlockReceipts; storing receipts by blocks. Eventually this will
require pruning during some cleanup cycle. During forks the receipts by
block are used to get the new canonical receipts and transactions.

This PR fixes #1473 by rewriting transactions and receipts from the point
of where the fork occured.
2015-07-14 18:40:03 +02:00
37efd08b42 p2p: validate recovered ephemeral pubkey against checksum in decodeAuthMsg 2015-07-14 03:06:44 +00:00
afba798357 xeth: log signed tx hash 2015-07-13 03:09:02 +02:00
796c18db93 Merge pull request #1462 from obscuren/genesis
core: genesis preparation
2015-07-12 03:45:45 -07:00
a32c51effd cmd, core, eth, common: genesis preparation
Implemented the --genesis flag thru which we can set a custom genesis
block, including the official Ethereum genesis block.
2015-07-10 17:37:41 +02:00
5a810758db cmd/geth: bump version 0.9.39 2015-07-09 18:07:52 +02:00
6f9377475c Merge branch 'release/0.9.38' into develop 2015-07-09 18:06:49 +02:00
98f4c936f2 Merge branch 'release/0.9.38' 2015-07-09 18:06:39 +02:00
344277d026 cmd/geth: version bump 0.9.38 2015-07-09 17:43:45 +02:00
3add8cfdb0 Merge pull request #1452 from obscuren/develop
core/vm: added str to op
2015-07-09 08:42:38 -07:00
8b5a65c14a core/vm: added str to op 2015-07-09 17:08:33 +02:00
0646cc8d14 Merge pull request #1453 from ethersphere/frozen-accounts
accounts, crypto: fixed file naming for windows
2015-07-09 08:08:09 -07:00
97d22be318 Merge pull request #1441 from obscuren/logs-return-fix
miner, xeth: fire log event during mining. Fix return raw tx
2015-07-09 07:24:35 -07:00
4c62ce831b Merge pull request #1451 from karalabe/handle-potential-TD-forge-attack
eth/downloader: drop peer if advertised TD but won't delvier
2015-07-09 07:23:50 -07:00
b041aed660 Merge pull request #1450 from karalabe/fix-propagation-td
eth: calculate the correct TD, only update if better
2015-07-09 07:23:16 -07:00
cd6d703e94 Merge pull request #1447 from karalabe/fix-database-metrics-race-3
eth, ethdb: fix a data race during startup/shutdown
2015-07-09 07:22:54 -07:00
dd140beb73 Merge pull request #1443 from Gustav-Simonsson/core_uint64_ts
Core uint64 ts
2015-07-09 07:22:38 -07:00
06afabb631 Merge pull request #1436 from bas-vk/net_version
added net.version
2015-07-09 07:22:20 -07:00
505b77a0d5 Merge pull request #1432 from tgerring/develop
Adjust .mailmap
2015-07-09 07:21:41 -07:00
c3f5403b64 fix wallet key duplicate write - how did it get there? mystery. fixes #1411 2015-07-09 14:07:35 +01:00
589f1c85b9 : colon => dash - in keyfile name - slight deviation from ISO8601 for WIN FS compatibility 2015-07-09 13:55:09 +01:00
492d5454b1 eth/downloader: drop peer if advertised TD but won't delvier 2015-07-09 14:40:18 +03:00
4f95e2f9ec eth: calculate the correct TD, only update if better 2015-07-09 13:55:06 +03:00
eb2d168710 eth, ethdb: fix a data race during startup/shutdown 2015-07-09 12:44:07 +03:00
d25634662b web3: updated 2015-07-08 15:47:33 +02:00
819ecd4508 miner, xeth: fire log event during mining. Fix return raw tx 2015-07-08 15:34:11 +02:00
5d6d40f329 Use uint64 on ts in chain_manager, block_processor 2015-07-08 13:21:06 +02:00
b08abe64e4 Unskip SimpleTx3, check err in pre/post state validations 2015-07-08 13:09:22 +02:00
0b53a5c673 Update Ethereum JSON test files and wrappers 2015-07-08 13:08:42 +02:00
e84f3ec1d4 added net.version 2015-07-08 08:03:20 +02:00
b1af5af30e Adjust .mailmap 2015-07-07 11:50:49 -05:00
423c2f499c Merge branch 'release/0.9.36' 2015-07-07 15:33:55 +02:00
a2333bcbb4 Merge pull request #1430 from obscuren/web3-0.8.0
web3 update
2015-07-07 06:33:38 -07:00
c6578d2336 Merge branch 'release/0.9.36' 2015-07-07 15:32:04 +02:00
c5972b4ac7 web3 update 2015-07-07 15:21:24 +02:00
0c9c5439d4 Merge branch 'release/0.9.36' into develop 2015-07-07 15:13:11 +02:00
193c62fdba Merge branch 'release/0.9.36' 2015-07-07 15:12:56 +02:00
d673c34c8d Merge branch 'release/0.9.36' of github.com-obscure:ethereum/go-ethereum into release/0.9.36 2015-07-07 14:55:39 +02:00
df54510e3e common/natspec: fixed test 2015-07-07 14:55:27 +02:00
ee04b71887 cmd/geth, cmd/utils: changed ParamsToAddress to return error
ParamsToAddress no longer aborts the process, it now returns an error
instead so that the caller can handle the error properly.
2015-07-07 14:55:27 +02:00
4b5c99d97f cmd/geth: version number 0.9.36 2015-07-07 14:55:27 +02:00
9e7d5d9d3b Merge pull request #1426 from fjl/license
all: update license information and godoc comments
2015-07-07 05:55:06 -07:00
b2d18393c4 README.md: update copyright 2015-07-07 14:12:45 +02:00
335d7f4855 LICENSE, cmd/LICENSE: the go-ethereum authors have copyright 2015-07-07 14:12:45 +02:00
4fb28e0dab all: goimports -w 2015-07-07 14:12:45 +02:00
bdae4fd573 all: add some godoc synopsis comments 2015-07-07 14:12:45 +02:00
e813626ee1 all: remove @author comments 2015-07-07 14:12:44 +02:00
7bb77c02da build: change license regexp for // comments 2015-07-07 14:12:44 +02:00
ea54283b30 all: update license information 2015-07-07 14:12:44 +02:00
46fbd34c70 .mailmap: update 2015-07-07 14:01:33 +02:00
3ff5cfd028 build: new update-license.go
This version is less clever. All names are listed in a single file,
AUTHORS. All source files have the same header. This is an improvement
over the previous version, which attempted to list copyright holders in
each source file.
2015-07-07 14:01:33 +02:00
922f881c3d common/natspec: fixed test 2015-07-07 13:01:39 +02:00
bfcac89881 cmd/geth, cmd/utils: changed ParamsToAddress to return error
ParamsToAddress no longer aborts the process, it now returns an error
instead so that the caller can handle the error properly.
2015-07-07 12:53:36 +02:00
db06906c4f cmd/geth: version number 0.9.36 2015-07-07 12:21:36 +02:00
3016f23864 cmd/geth: fixed test 2015-07-07 12:18:05 +02:00
e5fba8fd70 Merge pull request #1428 from obscuren/coinbase-fixes
cmd,eth,rpc,tests: default coinbase
2015-07-07 02:55:33 -07:00
916d155467 Merge pull request #1429 from obscuren/rebase-registrar
Rebase registrar
2015-07-07 02:55:23 -07:00
c5cb6e8e70 fix/skip tests, adapt registrar to no contract address
registry initialisers now return the txhash which caller can use to retrieve receipt
2015-07-07 11:30:55 +02:00
3791831081 rebase with zelig/frontier/registrar 2015-07-07 11:30:45 +02:00
7e6c1f8024 corrected input formatters as suggested during review 2015-07-07 11:30:23 +02:00
ceb0739ba1 fixed web3 formatters mismatch 2015-07-07 11:30:11 +02:00
37c1a8f69d eth,miner,rpc: set coinbase 2015-07-07 10:58:47 +02:00
6ea28f93b9 output BigNumbers objects in console as strings 2015-07-07 10:43:49 +02:00
1208ac83d5 fix natspec test
* registar url string retrieval chop leading zeros now
* rewrite test using test mining
* remove temporary applyTxs from xeth
2015-07-07 10:43:49 +02:00
aa22cf323e fix js arguments and TestContract passes 2015-07-07 10:43:49 +02:00
492e5049d7 rename js methods in js_test for new console API
+ rebase fixes
2015-07-07 10:43:49 +02:00
042c3290b3 fix GPO missing flags 2015-07-07 10:43:49 +02:00
518dc87db3 fix sleepBlocks, implement sleep 2015-07-07 10:43:49 +02:00
6391ec0c8f add missing method to api/admin 2015-07-07 10:43:31 +02:00
2739233719 Registrar and contractInfo handling
* resolver -> common/registrar
  * global registrar name registry interface
  * add Call to resolver backend interface
  * the hashReg and UrlHing contracts now initialised from global registry
  * initialization of contracts uniform
  * improve errors and more econsistent method names
* common/registrar/ethreg: versioned registrar
* integrate new naming and registrar in natspec
* js console api: setGlobalRegistrar, setHashReg, setUrlHint
* js test TestContract uses mining - tests fixed all pass
* eth/backend: allow PoW test mode (small ethash DAG)
* console jsre refers to resolver.abi/addr,
* cmd/geth/contracts.go moved to common/registrar
2015-07-07 10:43:31 +02:00
83ee39448e Registrar and contractInfo handling
* resolver -> common/registrar
  * global registrar name registry interface
  * add Call to resolver backend interface
  * the hashReg and UrlHing contracts now initialised from global registry
  * initialization of contracts uniform
  * improve errors and more econsistent method names
* common/registrar/ethreg: versioned registrar
* integrate new naming and registrar in natspec
* js console api: setGlobalRegistrar, setHashReg, setUrlHint
* js test TestContract uses mining - tests fixed all pass
* eth/backend: allow PoW test mode (small ethash DAG)
* console jsre refers to resolver.abi/addr,
* cmd/geth/contracts.go moved to common/registrar
2015-07-07 10:43:31 +02:00
35cd355c14 cmd,eth,rpc,tests: default coinbase 2015-07-07 10:32:05 +02:00
d764bd0584 Merge pull request #1423 from obscuren/gasused-receipt-fix
core, eth, rpc: proper gas used. Closes #1422
2015-07-06 12:41:55 -07:00
666a7dda36 core, eth, rpc: proper gas used. Closes #1417
Added some additional backward compatibility code for old receipts
2015-07-06 21:18:24 +02:00
45618d5f6b Merge pull request #1418 from fjl/one-interrupt
cmd/utils: fix interrupt handling to actually see subsequent interrupts
2015-07-06 11:05:54 -07:00
d4c2e9de32 cmd/utils: fix interrupt handling to actually see subsequent interrupts 2015-07-06 16:48:34 +02:00
6220707e03 Merge pull request #1414 from Gustav-Simonsson/update_tests
Add TestBcGasPricer, comments and unskip tests
2015-07-06 06:39:19 -07:00
4c30f0f9ac Merge pull request #1416 from fjl/one-interrupt
cmd/geth, cmd/utils: improve interrupt handling
2015-07-06 06:32:24 -07:00
5615fc4714 cmd/geth, cmd/utils: improve interrupt handling
The new strategy for interrupts is to handle them explicitly.
Ethereum.Stop is now only called once, even if multiple interrupts
are sent. Interrupting ten times in a row forces a panic.

Fixes #869
Fixes #1359
2015-07-06 15:06:11 +02:00
fa7b3b7276 Merge pull request #1415 from obscuren/web3-update
web3: updated
2015-07-06 05:01:39 -07:00
b0aec6402a web3: updated 2015-07-06 14:01:03 +02:00
cc29b4bc27 Merge pull request #1413 from obscuren/receipt-fix
rpc, xeth: fixed returned tx hash & receipt logs
2015-07-06 05:00:17 -07:00
b7e8d954ef Add TestBcGasPricer, comments and unskip tests 2015-07-06 13:56:56 +02:00
4f7fc7b23f rpc, xeth: fixed returned tx hash & receipt logs 2015-07-06 13:43:02 +02:00
457a3c8f76 Merge pull request #1410 from obscuren/newerrors-fix
core, miner: adopted new style errors
2015-07-06 04:00:37 -07:00
e6bb9c1cad core, miner: removed vm errors from consensus err checking
Removed VM errors from the consensus errors. They now used for output
only.
2015-07-06 12:43:05 +02:00
aa4502060b Merge pull request #1400 from obscuren/badblock-reporting
core, miner, tests: added test, implemented bad block reporting
2015-07-06 02:03:50 -07:00
b533aaa765 Merge pull request #1409 from fjl/fix-tx-hash
core/types, xeth: separate tx hash and tx signature hash
2015-07-06 01:59:41 -07:00
35add89c87 Merge pull request #1397 from tgerring/rpcreceipt
getTransactionReceipt RPC support
2015-07-06 01:53:21 -07:00
46e7c8512e Merge pull request #1395 from Gustav-Simonsson/fix_core_errors_in_apply_txs
Fix core errors in apply txs
2015-07-06 01:51:14 -07:00
ec9620fb2f core/types, xeth: separate tx hash and tx signature hash 2015-07-06 10:45:45 +02:00
6c7f5e3d0e Add autocomplete support for console 2015-07-05 15:42:04 -05:00
dd521ece3f Always return transaction hash 2015-07-05 12:25:44 -05:00
bcc1660abc core, miner, tests: added test, implemented bad block reporting 2015-07-05 15:14:31 +02:00
62559ac330 Cleanup 2015-07-04 12:14:06 -05:00
30afd37604 Compose additional fields 2015-07-04 12:03:37 -05:00
cd4cc309ae Remove redundant function 2015-07-04 11:28:30 -05:00
3be9046c21 Rename local variable for clarity 2015-07-04 10:24:52 -05:00
9c3db1be1d Merge pull request #1369 from obscuren/statedb-update-cleanup
core, core/state: throw out intermediate state
2015-07-04 03:42:13 -07:00
9bb575be7d Merge pull request #1283 from ethersphere/frontier/accounts
Account management improvements
2015-07-04 03:40:23 -07:00
0f04af5916 Fix core error forwarding, unify OOG VM err 2015-07-04 09:27:42 +02:00
481b221279 Decode full receipt storage 2015-07-04 00:00:23 -05:00
80eb8f46b7 Fix hex conversion 2015-07-03 23:46:59 -05:00
3a983d2419 Initial getTransactionReceipt support 2015-07-03 23:03:11 -05:00
47460b3b4a trie: removed shallow copies (thanks to @fjl) 2015-07-04 02:51:37 +02:00
0a1ff68c11 trie: dirty tracking 2015-07-04 02:51:36 +02:00
ab16ce70fc core, miner, tests: renamed state methods
* Update => SyncIntermediate
* Added SyncObjects

SyncIntermediate only updates whatever has changed, but, as a side
effect, requires much more disk space.

SyncObjects will only sync whatever is required for a block and will not
save intermediate state to disk. As drawback this requires more time
when more txs come in.
2015-07-04 02:51:36 +02:00
08caeedd84 core, core/state: only write necessary state. Skip intermediate 2015-07-04 02:51:36 +02:00
6f69b4d61f Merge pull request #1399 from obscuren/receipts-storing-fix
core, eth, miner, xeth: receipt storage fix
2015-07-03 17:50:46 -07:00
2feb23c1da core, eth, miner, xeth: receipt storage fix
* Added GetReceiptsFromBlock, GetReceipt, PutReceipts
* Added ContractAddress to receipt. See #1042
2015-07-04 02:32:10 +02:00
efd7da0ce8 Merge pull request #1385 from Gustav-Simonsson/update_tests
Update Ethereum JSON test files, skip failing tests
2015-07-03 09:20:21 -07:00
acd85fe95f Merge pull request #1393 from bas-vk/issue1377
Upgrade web3 to version 0.7.1
2015-07-03 08:27:04 -07:00
4dfcd6012b Merge pull request #1392 from bas-vk/ipcpipelining
Several bugfixes to IPC channel
2015-07-03 08:26:57 -07:00
546c0f631c Merge pull request #1394 from obscuren/develop
miner: ignore future errors
2015-07-03 08:22:30 -07:00
0e33fbdcb9 miner: ignore future errors 2015-07-03 17:21:23 +02:00
8150c0a726 upgrade web3 to version 0.7.1 2015-07-03 17:08:41 +02:00
e8c1399bbf fixed unittest after new implementation 2015-07-03 16:57:40 +02:00
1cbab291a9 Merge pull request #1389 from obscuren/txpool-issues
core, miner: miner header validation, transaction & receipt writing
2015-07-03 07:50:30 -07:00
8181929c9a Merge pull request #1391 from tgerring/consolefalse
Prevent false from printing on console
2015-07-03 07:46:49 -07:00
d9efaf754c simplified implementation and improved performance 2015-07-03 15:44:35 +02:00
6afdc52483 Prevent debug value from printing on console 2015-07-03 07:40:47 -05:00
29e2fb38f8 core, miner: miner header validation, transaction & receipt writing
* Miners do now verify their own header, not their state.
* Changed old putTx and putReceipts to be exported
* Moved writing of transactions and receipts out of the block processer
  in to the chain manager. Closes #1386
* Miner post ChainHeadEvent & ChainEvent. Closes #1388
2015-07-03 13:56:50 +02:00
03129e7c93 Merge pull request #1390 from karalabe/fix-downloader-test-race
eth/downloader: fix a rare test race on the OSX CI
2015-07-03 04:22:14 -07:00
f0e94b4d71 display rpc error in console 2015-07-03 12:22:20 +02:00
f857fb7600 eth/downloader: fix a rare test race on the OSX CI 2015-07-03 13:01:22 +03:00
ff97059a99 Update Ethereum JSON tests, skip failing 2015-07-03 09:40:07 +02:00
1959346793 account update: migrate or change password
* account.Update
* KeyStore.Cleanup
* fix dir rm for old format deleteKey
2015-07-03 07:52:37 +01:00
fc17a527bc fix account ordering
* chronological order of creation
* new naming scheme keystore/UTC--<created_at UTC ISO8601>-<address hex>
* KeyStore2 -> KeyStore
* backward compatibility
* refactor keyStore methods
2015-07-03 03:19:32 +01:00
a4df9d74ea accounts order by keyfile ctime 2015-07-02 23:29:07 +01:00
eb82ca4563 rpc/js coinbase returns null if no etherbase set 2015-07-02 23:28:12 +01:00
09b6983175 no primary when listing accounts 2015-07-02 23:28:12 +01:00
65a26e40a8 require explicit etherbase address for mining. Falling back to primary is risky given it is inconsistent if keys are imported/merged/created or copied/transfered 2015-07-02 23:28:12 +01:00
fc2e33c594 unlock multiple passes and obsolete primary
* multiple passwords allowed in password file
* split on "\n", sideeffect: chop trailing slashes. fixes common mistake <(echo 'pass')
* remove accounts.Primary method
* do not fall back to primary account for mining
2015-07-02 23:28:11 +01:00
1d72aaa0cd simplify account unlocking 2015-07-02 23:28:11 +01:00
cf66826223 merge conflict 2015-07-02 17:33:21 +02:00
56ed408436 ipcpath issue fix 2015-07-02 17:25:11 +02:00
6be527dd52 prevent discarding requests when parsing fails 2015-07-02 17:25:11 +02:00
effe9cc2cf added pipelining support 2015-07-02 17:25:11 +02:00
89525fcb4e ipcpath issue fix 2015-07-02 17:20:58 +02:00
c2590af7fd prevent discarding requests when parsing fails 2015-07-02 15:26:55 +02:00
9f6016e877 Merge branch 'develop' of github.com:ethereum/go-ethereum into develop 2015-07-02 05:27:31 -04:00
75f41dedca Merge pull request #1378 from obscuren/issue1367
core, xeth: core.AddressFromMessage removed => crypto.CreateAddress
2015-07-02 02:27:20 -07:00
744af9f497 Switched canary addresses 2015-07-02 05:27:19 -04:00
529fb7a7d7 core, xeth: core.AddressFromMessage removed => crypto.CreateAddress 2015-07-02 11:19:10 +02:00
5caff3bc24 Merge pull request #1351 from karalabe/eth61
Implement eth/61
2015-07-01 08:16:44 -07:00
507869bff1 Merge pull request #1373 from obscuren/recovery-tools
core, cmd/geth: improved recover functionality
2015-07-01 08:09:33 -07:00
70d5d791cc core, cmd/geth: improved recover functionality
`geth recover` now accepts both hashes and numbers using "#" and no
longer requires the ethereum instance.
2015-07-01 16:34:35 +02:00
d6f2c0a76f eth, eth/downloader: fix #1231, DOS vulnerability in hash queueing 2015-07-01 15:21:35 +03:00
bb418a43c1 Merge pull request #1370 from obscuren/force-checkpoint
core, cmd/geth: recover by number
2015-07-01 03:57:13 -07:00
2e5242f9bb Merge pull request #1355 from Gustav-Simonsson/block_header_ts_uint64
Use uint64 for block header timestamp
2015-07-01 03:57:02 -07:00
1ae80aaf64 eth: fix #1371, double lock during block/txn known set limitation 2015-07-01 11:12:05 +03:00
41de1cb723 added pipelining support 2015-07-01 08:23:17 +02:00
29ab1fa8a5 core, cmd/geth: recover by number 2015-07-01 00:52:44 +02:00
60454da650 eth/downloader: reduce hash fetches in prep for eth/61 2015-07-01 01:20:49 +03:00
cb2c10d862 Merge pull request #1366 from ethers/rpcRequest
fix logging jsonrpc request #1365
2015-06-30 12:17:59 -07:00
d05305473e fix logging jsonrpc request #1365 2015-06-30 12:14:16 -07:00
be935bff84 Merge pull request #1363 from obscuren/safeguard
core: added checkpoint for last block
2015-06-30 09:25:10 -07:00
f43c07cb3c eth, eth/downloader: transition to eth 61 2015-06-30 19:05:06 +03:00
af51dc4d63 eth, eth/downloader: pass the eth protocol version through 2015-06-30 19:00:01 +03:00
aac2b6ae4c eth: add the blocks from numbers protocol message 2015-06-30 19:00:01 +03:00
5db8f447d5 eth: fix #1319, put an upper limit on the known txns and blocks 2015-06-30 19:00:01 +03:00
6fc85f1ec2 eth: clean up peer struct a bit, fix double txn bcast 2015-06-30 19:00:01 +03:00
2c8ed76e01 eth: start cleaning up old protocol implementation, add metrics 2015-06-30 19:00:00 +03:00
393d675690 cmd/geth, cmd/utils, eth: advertise both eth/60 and eth/61 2015-06-30 19:00:00 +03:00
a748afce03 core: txpool listen for ChainHeadEvent instead of ChainEvent
Changed the transaction pool to listen for ChainHeadEvent when resetting
the state instead of ChainEvent. It makes very little sense to burst
through transactions while we are catching up (e.g., have more than one
block to process)
2015-06-30 17:27:47 +02:00
c14f0a4471 core: added checkpoint for last block
* Add a checkpoint every X blocks
* Removed queued write
2015-06-30 17:27:47 +02:00
ba95e445e1 Merge pull request #1328 from bas-vk/issue1327
Add pendingTransactions and resend
2015-06-30 08:27:03 -07:00
8c4d493c66 solved merge conflicts 2015-06-30 15:32:02 +02:00
a5d5387dee rebase with develop 2015-06-30 15:27:27 +02:00
130f3b270a Merge pull request #1362 from obscuren/txpool-cleanup
core: reduce CPU load by reducing calls to checkQueue
2015-06-30 05:18:51 -07:00
61ca780f3b core: reduce CPU load by reducing calls to checkQueue
* Reduced maxQueue count
* Added proper deletion past maxQueue limit
* Added cheap stats method to txpool

queueCheck was called for **every** transaction instead of:
1. add all txs
2. check queue

previously

1. add txs[i]
2. check queue
3. if i < len(txs) goto 1.
2015-06-30 14:01:12 +02:00
57dff6f1d7 initialize fields to prevent nil pointer exception 2015-06-30 11:20:31 +02:00
7ffabf1d39 add json parsing method for resend transaction 2015-06-30 11:20:31 +02:00
6fdddc5ac9 improved error handling in parsing request 2015-06-30 11:20:31 +02:00
02c6af66bf fixed unittest compilation issue 2015-06-30 11:20:31 +02:00
ec866b066a added eth.resend 2015-06-30 11:20:31 +02:00
056e9dd393 added eth.pendingTransactions 2015-06-30 11:20:31 +02:00
9226369b5d Merge branch 'hotfix/0.9.34-1' into develop 2015-06-30 11:15:08 +02:00
4c490db6af Use uint64 for block header timestamp 2015-06-30 10:52:11 +02:00
b047f05e7e cmd/geth: version bump 0.9.35 2015-06-30 02:30:26 +02:00
8d016ced6b Merge branch 'release/0.9.34' into develop 2015-06-30 02:22:40 +02:00
61ccc39b56 initialize fields to prevent nil pointer exception 2015-06-29 12:42:47 +02:00
f9264e87ec add json parsing method for resend transaction 2015-06-29 12:32:01 +02:00
a355777ff8 improved error handling in parsing request 2015-06-29 11:13:28 +02:00
ee73f09727 fixed unittest compilation issue 2015-06-24 16:07:44 +02:00
dc58568a25 added eth.resend 2015-06-24 14:56:53 +02:00
f1a4a6e563 added eth.pendingTransactions 2015-06-24 13:53:37 +02:00
1155 changed files with 34841 additions and 24878 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

View File

@ -11,4 +11,51 @@ Nick Savers <nicksavers@gmail.com>
Maran Hidskes <maran.hidskes@gmail.com>
Taylor Gerring <taylor.gerring@gmail.com>
Taylor Gerring <taylor.gerring@gmail.com> <taylor.gerring@ethereum.org>
Bas van Kervel <bas@ethdev.com>
Bas van Kervel <bas@ethdev.com> <basvankervel@ziggo.nl>
Bas van Kervel <bas@ethdev.com> <basvankervel@gmail.com>
Sven Ehlert <sven@ethdev.com>
Vitalik Buterin <v@buterin.com>
Marian Oancea <contact@siteshop.ro>
Christoph Jentzsch <jentzsch.software@gmail.com>
Heiko Hees <heiko@heiko.org>
Alex Leverington <alex@ethdev.com>
Alex Leverington <alex@ethdev.com> <subtly@users.noreply.github.com>
Zsolt Felföldi <zsfelfoldi@gmail.com>
Gavin Wood <i@gavwood.com>
Martin Becze <mjbecze@gmail.com>
Martin Becze <mjbecze@gmail.com> <wanderer@users.noreply.github.com>
Dimitry Khokhlov <winsvega@mail.ru>
Roman Mandeleil <roman.mandeleil@gmail.com>
Alec Perseghin <aperseghin@gmail.com>
Alon Muroch <alonmuroch@gmail.com>
Arkadiy Paronyan <arkadiy@ethdev.com>
Jae Kwon <jkwon.work@gmail.com>
Aaron Kumavis <kumavis@users.noreply.github.com>
Nick Dodson <silentcicero@outlook.com>
Jason Carver <jacarver@linkedin.com>
Jason Carver <jacarver@linkedin.com> <ut96caarrs@snkmail.com>
Joseph Chow <ethereum@outlook.com>
Joseph Chow <ethereum@outlook.com> ethers <TODO>

View File

@ -1,14 +1,11 @@
language: go
go:
- 1.4.2
before_install:
- sudo apt-get update -qq
- sudo apt-get install -yqq libgmp3-dev
install:
# - go get code.google.com/p/go.tools/cmd/goimports
# - go get github.com/golang/lint/golint
# - go get golang.org/x/tools/cmd/vet
- go get golang.org/x/tools/cmd/cover github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
before_script:
# - gofmt -l -w .
# - goimports -l -w .
@ -18,11 +15,15 @@ before_script:
script:
- make travis-test-with-coverage
after_success:
- if [ "$COVERALLS_TOKEN" ]; then goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
- bash <(curl -s https://codecov.io/bash)
env:
global:
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
sudo: false
addons:
apt:
packages:
- libgmp3-dev
notifications:
webhooks:
urls:

24
AUTHORS Normal file
View File

@ -0,0 +1,24 @@
# This is the official list of go-ethereum authors for copyright purposes.
Alex Leverington <alex@ethdev.com>
Alexandre Van de Sande <alex.vandesande@ethdev.com>
Bas van Kervel <bas@ethdev.com>
Daniel A. Nagy <nagy.da@gmail.com>
Ethan Buchman <ethan@coinculture.info>
Fabian Vogelsteller <fabian@frozeman.de>
Felix Lange <fjl@twurst.com>
Gustav Simonsson <gustav.simonsson@gmail.com>
Jae Kwon <jkwon.work@gmail.com>
Jason Carver <jacarver@linkedin.com>
Jeffrey Wilcke <jeffrey@ethereum.org>
Joseph Chow <ethereum@outlook.com>
Kobi Gurkan <kobigurk@gmail.com>
Maran Hidskes <maran.hidskes@gmail.com>
Marek Kotewicz <marek.kotewicz@gmail.com>
Matthew Wampler-Doty <matthew.wampler.doty@gmail.com>
Nick Dodson <silentcicero@outlook.com>
Péter Szilágyi <peterke@gmail.com>
Taylor Gerring <taylor.gerring@gmail.com>
Viktor Trón <viktor.tron@gmail.com>
Vitalik Buterin <v@buterin.com>
Zsolt Felföldi <zsfelfoldi@gmail.com>

9
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,9 @@
If you'd like to contribute to go-ethereum please fork, fix, commit and
send a pull request. Commits who do not comply with the coding standards
are ignored (use gofmt!). If you send pull requests make absolute sure that you
commit on the `develop` branch and that you do not merge to master.
Commits that are directly based on master are simply ignored.
See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
for more details on configuring your environment, testing, and
dependency management.

619
COPYING Normal file
View File

@ -0,0 +1,619 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2014 The go-ethereum Authors.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

165
COPYING.LESSER Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

28
Godeps/Godeps.json generated
View File

@ -24,14 +24,18 @@
"Comment": "v23.1-227-g8f6ccaa",
"Rev": "8f6ccaaef9b418553807a73a95cb5f49cd3ea39f"
},
{
"ImportPath": "github.com/fatih/color",
"Comment": "v0.1-5-gf773d4c",
"Rev": "f773d4c806cc8e4a5749d6a35e2a4bbcd71443d6"
},
{
"ImportPath": "github.com/gizak/termui",
"Rev": "bab8dce01c193d82bc04888a0a9a7814d505f532"
},
{
"ImportPath": "github.com/howeyc/fsnotify",
"Comment": "v0.9.0-11-g6b1ef89",
"Rev": "6b1ef893dc11e0447abda6da20a5203481878dda"
"ImportPath": "github.com/hashicorp/golang-lru",
"Rev": "7f9ef20a0256f494e24126014135cf893ab71e9e"
},
{
"ImportPath": "github.com/huin/goupnp",
@ -45,10 +49,6 @@
"ImportPath": "github.com/kardianos/osext",
"Rev": "ccfcd0245381f0c94c68f50626665eed3c6b726a"
},
{
"ImportPath": "github.com/mattn/go-colorable",
"Rev": "043ae16291351db8465272edf465c9f388161627"
},
{
"ImportPath": "github.com/mattn/go-isatty",
"Rev": "fdbe02a1b44e75977b2690062b83cf507d70c013"
@ -66,14 +66,6 @@
"ImportPath": "github.com/peterh/liner",
"Rev": "29f6a646557d83e2b6e9ba05c45fbea9c006dbe8"
},
{
"ImportPath": "github.com/rakyll/globalconf",
"Rev": "415abc325023f1a00cd2d9fa512e0e71745791a2"
},
{
"ImportPath": "github.com/rakyll/goini",
"Rev": "907cca0f578a5316fb864ec6992dc3d9730ec58c"
},
{
"ImportPath": "github.com/rcrowley/go-metrics",
"Rev": "a5cfc242a56ba7fa70b785f678d6214837bf93b9"
@ -86,6 +78,10 @@
"ImportPath": "github.com/rs/cors",
"Rev": "6e0c3cb65fc0fdb064c743d176a620e3ca446dfb"
},
{
"ImportPath": "github.com/shiena/ansicolor",
"Rev": "a5e2b567a4dd6cc74545b8a4f27c9d63b9e7735b"
},
{
"ImportPath": "github.com/syndtr/goleveldb/leveldb",
"Rev": "4875955338b0a434238a31165cb87255ab6e9e4a"
@ -129,7 +125,7 @@
},
{
"ImportPath": "gopkg.in/karalabe/cookiejar.v2/collections/prque",
"Rev": "0b2e270613f5d7ba262a5749b9e32270131497a2"
"Rev": "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57"
}
]
}

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Fatih Arslan
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.

151
Godeps/_workspace/src/github.com/fatih/color/README.md generated vendored Normal file
View File

@ -0,0 +1,151 @@
# Color [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/color) [![Build Status](http://img.shields.io/travis/fatih/color.svg?style=flat-square)](https://travis-ci.org/fatih/color)
Color lets you use colorized outputs in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It has support for Windows too! The API can be used in several ways, pick one that suits you.
![Color](http://i.imgur.com/c1JI0lA.png)
## Install
```bash
go get github.com/fatih/color
```
## Examples
### Standard colors
```go
// Print with default helper functions
color.Cyan("Prints text in cyan.")
// A newline will be appended automatically
color.Blue("Prints %s in blue.", "text")
// These are using the default foreground colors
color.Red("We have red")
color.Magenta("And many others ..")
```
### Mix and reuse colors
```go
// Create a new color object
c := color.New(color.FgCyan).Add(color.Underline)
c.Println("Prints cyan text with an underline.")
// Or just add them to New()
d := color.New(color.FgCyan, color.Bold)
d.Printf("This prints bold cyan %s\n", "too!.")
// Mix up foreground and background colors, create new mixes!
red := color.New(color.FgRed)
boldRed := red.Add(color.Bold)
boldRed.Println("This will print text in bold red.")
whiteBackground := red.Add(color.BgWhite)
whiteBackground.Println("Red text with white background.")
```
### Custom print functions (PrintFunc)
```go
// Create a custom print function for convenience
red := color.New(color.FgRed).PrintfFunc()
red("Warning")
red("Error: %s", err)
// Mix up multiple attributes
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
notice("Don't forget this...")
```
### Insert into noncolor strings (SprintFunc)
```go
// Create SprintXxx functions to mix strings with other non-colorized strings:
yellow := color.New(color.FgYellow).SprintFunc()
red := color.New(color.FgRed).SprintFunc()
fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
fmt.Printf("This %s rocks!\n", info("package"))
// Use helper functions
fmt.Printf("This", color.RedString("warning"), "should be not neglected.")
fmt.Printf(color.GreenString("Info:"), "an important message." )
// Windows supported too! Just don't forget to change the output to color.Output
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
```
### Plug into existing code
```go
// Use handy standard colors
color.Set(color.FgYellow)
fmt.Println("Existing text will now be in yellow")
fmt.Printf("This one %s\n", "too")
color.Unset() // Don't forget to unset
// You can mix up parameters
color.Set(color.FgMagenta, color.Bold)
defer color.Unset() // Use it in your function
fmt.Println("All text will now be bold magenta.")
```
### Disable color
There might be a case where you want to disable color output (for example to
pipe the standard output of your app to somewhere else). `Color` has support to
disable colors both globally and for single color definition. For example
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
the color output with:
```go
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
if *flagNoColor {
color.NoColor = true // disables colorized output
}
```
It also has support for single color definitions (local). You can
disable/enable color output on the fly:
```go
c := color.New(color.FgCyan)
c.Println("Prints cyan text")
c.DisableColor()
c.Println("This is printed without any color")
c.EnableColor()
c.Println("This prints again cyan...")
```
## Todo
* Save/Return previous values
* Evaluate fmt.Formatter interface
## Credits
* [Fatih Arslan](https://github.com/fatih)
* Windows support via @shiena: [ansicolor](https://github.com/shiena/ansicolor)
## License
The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details

353
Godeps/_workspace/src/github.com/fatih/color/color.go generated vendored Normal file
View File

@ -0,0 +1,353 @@
package color
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/mattn/go-isatty"
"github.com/shiena/ansicolor"
)
// NoColor defines if the output is colorized or not. It's dynamically set to
// false or true based on the stdout's file descriptor referring to a terminal
// or not. This is a global option and affects all colors. For more control
// over each color block use the methods DisableColor() individually.
var NoColor = !isatty.IsTerminal(os.Stdout.Fd())
// Color defines a custom color object which is defined by SGR parameters.
type Color struct {
params []Attribute
noColor *bool
}
// Attribute defines a single SGR Code
type Attribute int
const escape = "\x1b"
// Base attributes
const (
Reset Attribute = iota
Bold
Faint
Italic
Underline
BlinkSlow
BlinkRapid
ReverseVideo
Concealed
CrossedOut
)
// Foreground text colors
const (
FgBlack Attribute = iota + 30
FgRed
FgGreen
FgYellow
FgBlue
FgMagenta
FgCyan
FgWhite
)
// Background text colors
const (
BgBlack Attribute = iota + 40
BgRed
BgGreen
BgYellow
BgBlue
BgMagenta
BgCyan
BgWhite
)
// New returns a newly created color object.
func New(value ...Attribute) *Color {
c := &Color{params: make([]Attribute, 0)}
c.Add(value...)
return c
}
// Set sets the given parameters immediately. It will change the color of
// output with the given SGR parameters until color.Unset() is called.
func Set(p ...Attribute) *Color {
c := New(p...)
c.Set()
return c
}
// Unset resets all escape attributes and clears the output. Usually should
// be called after Set().
func Unset() {
if NoColor {
return
}
fmt.Fprintf(Output, "%s[%dm", escape, Reset)
}
// Set sets the SGR sequence.
func (c *Color) Set() *Color {
if c.isNoColorSet() {
return c
}
fmt.Fprintf(Output, c.format())
return c
}
func (c *Color) unset() {
if c.isNoColorSet() {
return
}
Unset()
}
// Add is used to chain SGR parameters. Use as many as parameters to combine
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
func (c *Color) Add(value ...Attribute) *Color {
c.params = append(c.params, value...)
return c
}
func (c *Color) prepend(value Attribute) {
c.params = append(c.params, 0)
copy(c.params[1:], c.params[0:])
c.params[0] = value
}
// Output defines the standard output of the print functions. By default
// os.Stdout is used.
var Output = ansicolor.NewAnsiColorWriter(os.Stdout)
// Print formats using the default formats for its operands and writes to
// standard output. Spaces are added between operands when neither is a
// string. It returns the number of bytes written and any write error
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Print(a ...interface{}) (n int, err error) {
c.Set()
defer c.unset()
return fmt.Fprint(Output, a...)
}
// Printf formats according to a format specifier and writes to standard output.
// It returns the number of bytes written and any write error encountered.
// This is the standard fmt.Printf() method wrapped with the given color.
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
c.Set()
defer c.unset()
return fmt.Fprintf(Output, format, a...)
}
// Println formats using the default formats for its operands and writes to
// standard output. Spaces are always added between operands and a newline is
// appended. It returns the number of bytes written and any write error
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Println(a ...interface{}) (n int, err error) {
c.Set()
defer c.unset()
return fmt.Fprintln(Output, a...)
}
// PrintFunc returns a new function that prints the passed arguments as
// colorized with color.Print().
func (c *Color) PrintFunc() func(a ...interface{}) {
return func(a ...interface{}) { c.Print(a...) }
}
// PrintfFunc returns a new function that prints the passed arguments as
// colorized with color.Printf().
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
return func(format string, a ...interface{}) { c.Printf(format, a...) }
}
// PrintlnFunc returns a new function that prints the passed arguments as
// colorized with color.Println().
func (c *Color) PrintlnFunc() func(a ...interface{}) {
return func(a ...interface{}) { c.Println(a...) }
}
// SprintFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprint(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output, example:
//
// put := New(FgYellow).SprintFunc()
// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
func (c *Color) SprintFunc() func(a ...interface{}) string {
return func(a ...interface{}) string {
return c.wrap(fmt.Sprint(a...))
}
}
// SprintfFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprintf(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output.
func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
return func(format string, a ...interface{}) string {
return c.wrap(fmt.Sprintf(format, a...))
}
}
// SprintlnFunc returns a new function that returns colorized strings for the
// given arguments with fmt.Sprintln(). Useful to put into or mix into other
// string. Windows users should use this in conjuction with color.Output.
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
return func(a ...interface{}) string {
return c.wrap(fmt.Sprintln(a...))
}
}
// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
// an example output might be: "1;36" -> bold cyan
func (c *Color) sequence() string {
format := make([]string, len(c.params))
for i, v := range c.params {
format[i] = strconv.Itoa(int(v))
}
return strings.Join(format, ";")
}
// wrap wraps the s string with the colors attributes. The string is ready to
// be printed.
func (c *Color) wrap(s string) string {
if c.isNoColorSet() {
return s
}
return c.format() + s + c.unformat()
}
func (c *Color) format() string {
return fmt.Sprintf("%s[%sm", escape, c.sequence())
}
func (c *Color) unformat() string {
return fmt.Sprintf("%s[%dm", escape, Reset)
}
// DisableColor disables the color output. Useful to not change any existing
// code and still being able to output. Can be used for flags like
// "--no-color". To enable back use EnableColor() method.
func (c *Color) DisableColor() {
c.noColor = boolPtr(true)
}
// EnableColor enables the color output. Use it in conjuction with
// DisableColor(). Otherwise this method has no side effects.
func (c *Color) EnableColor() {
c.noColor = boolPtr(false)
}
func (c *Color) isNoColorSet() bool {
// check first if we have user setted action
if c.noColor != nil {
return *c.noColor
}
// if not return the global option, which is disabled by default
return NoColor
}
func boolPtr(v bool) *bool {
return &v
}
// Black is an convenient helper function to print with black foreground. A
// newline is appended to format by default.
func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) }
// Red is an convenient helper function to print with red foreground. A
// newline is appended to format by default.
func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) }
// Green is an convenient helper function to print with green foreground. A
// newline is appended to format by default.
func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) }
// Yellow is an convenient helper function to print with yellow foreground.
// A newline is appended to format by default.
func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) }
// Blue is an convenient helper function to print with blue foreground. A
// newline is appended to format by default.
func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) }
// Magenta is an convenient helper function to print with magenta foreground.
// A newline is appended to format by default.
func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) }
// Cyan is an convenient helper function to print with cyan foreground. A
// newline is appended to format by default.
func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) }
// White is an convenient helper function to print with white foreground. A
// newline is appended to format by default.
func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) }
func printColor(format string, p Attribute, a ...interface{}) {
if !strings.HasSuffix(format, "\n") {
format += "\n"
}
c := &Color{params: []Attribute{p}}
c.Printf(format, a...)
}
// BlackString is an convenient helper function to return a string with black
// foreground.
func BlackString(format string, a ...interface{}) string {
return New(FgBlack).SprintfFunc()(format, a...)
}
// RedString is an convenient helper function to return a string with red
// foreground.
func RedString(format string, a ...interface{}) string {
return New(FgRed).SprintfFunc()(format, a...)
}
// GreenString is an convenient helper function to return a string with green
// foreground.
func GreenString(format string, a ...interface{}) string {
return New(FgGreen).SprintfFunc()(format, a...)
}
// YellowString is an convenient helper function to return a string with yellow
// foreground.
func YellowString(format string, a ...interface{}) string {
return New(FgYellow).SprintfFunc()(format, a...)
}
// BlueString is an convenient helper function to return a string with blue
// foreground.
func BlueString(format string, a ...interface{}) string {
return New(FgBlue).SprintfFunc()(format, a...)
}
// MagentaString is an convenient helper function to return a string with magenta
// foreground.
func MagentaString(format string, a ...interface{}) string {
return New(FgMagenta).SprintfFunc()(format, a...)
}
// CyanString is an convenient helper function to return a string with cyan
// foreground.
func CyanString(format string, a ...interface{}) string {
return New(FgCyan).SprintfFunc()(format, a...)
}
// WhiteString is an convenient helper function to return a string with white
// foreground.
func WhiteString(format string, a ...interface{}) string {
return New(FgWhite).SprintfFunc()(format, a...)
}

View File

@ -0,0 +1,176 @@
package color
import (
"bytes"
"fmt"
"os"
"testing"
"github.com/shiena/ansicolor"
)
// Testing colors is kinda different. First we test for given colors and their
// escaped formatted results. Next we create some visual tests to be tested.
// Each visual test includes the color name to be compared.
func TestColor(t *testing.T) {
rb := new(bytes.Buffer)
Output = rb
testColors := []struct {
text string
code Attribute
}{
{text: "black", code: FgBlack},
{text: "red", code: FgRed},
{text: "green", code: FgGreen},
{text: "yellow", code: FgYellow},
{text: "blue", code: FgBlue},
{text: "magent", code: FgMagenta},
{text: "cyan", code: FgCyan},
{text: "white", code: FgWhite},
}
for _, c := range testColors {
New(c.code).Print(c.text)
line, _ := rb.ReadString('\n')
scannedLine := fmt.Sprintf("%q", line)
colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text)
escapedForm := fmt.Sprintf("%q", colored)
fmt.Printf("%s\t: %s\n", c.text, line)
if scannedLine != escapedForm {
t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine)
}
}
}
func TestNoColor(t *testing.T) {
rb := new(bytes.Buffer)
Output = rb
testColors := []struct {
text string
code Attribute
}{
{text: "black", code: FgBlack},
{text: "red", code: FgRed},
{text: "green", code: FgGreen},
{text: "yellow", code: FgYellow},
{text: "blue", code: FgBlue},
{text: "magent", code: FgMagenta},
{text: "cyan", code: FgCyan},
{text: "white", code: FgWhite},
}
for _, c := range testColors {
p := New(c.code)
p.DisableColor()
p.Print(c.text)
line, _ := rb.ReadString('\n')
if line != c.text {
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
}
}
// global check
NoColor = true
defer func() {
NoColor = false
}()
for _, c := range testColors {
p := New(c.code)
p.Print(c.text)
line, _ := rb.ReadString('\n')
if line != c.text {
t.Errorf("Expecting %s, got '%s'\n", c.text, line)
}
}
}
func TestColorVisual(t *testing.T) {
// First Visual Test
fmt.Println("")
Output = ansicolor.NewAnsiColorWriter(os.Stdout)
New(FgRed).Printf("red\t")
New(BgRed).Print(" ")
New(FgRed, Bold).Println(" red")
New(FgGreen).Printf("green\t")
New(BgGreen).Print(" ")
New(FgGreen, Bold).Println(" green")
New(FgYellow).Printf("yellow\t")
New(BgYellow).Print(" ")
New(FgYellow, Bold).Println(" yellow")
New(FgBlue).Printf("blue\t")
New(BgBlue).Print(" ")
New(FgBlue, Bold).Println(" blue")
New(FgMagenta).Printf("magenta\t")
New(BgMagenta).Print(" ")
New(FgMagenta, Bold).Println(" magenta")
New(FgCyan).Printf("cyan\t")
New(BgCyan).Print(" ")
New(FgCyan, Bold).Println(" cyan")
New(FgWhite).Printf("white\t")
New(BgWhite).Print(" ")
New(FgWhite, Bold).Println(" white")
fmt.Println("")
// Second Visual test
Black("black")
Red("red")
Green("green")
Yellow("yellow")
Blue("blue")
Magenta("magenta")
Cyan("cyan")
White("white")
// Third visual test
fmt.Println()
Set(FgBlue)
fmt.Println("is this blue?")
Unset()
Set(FgMagenta)
fmt.Println("and this magenta?")
Unset()
// Fourth Visual test
fmt.Println()
blue := New(FgBlue).PrintlnFunc()
blue("blue text with custom print func")
red := New(FgRed).PrintfFunc()
red("red text with a printf func: %d\n", 123)
put := New(FgYellow).SprintFunc()
warn := New(FgRed).SprintFunc()
fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error"))
info := New(FgWhite, BgGreen).SprintFunc()
fmt.Fprintf(Output, "this %s rocks!\n", info("package"))
// Fifth Visual Test
fmt.Println()
fmt.Fprintln(Output, BlackString("black"))
fmt.Fprintln(Output, RedString("red"))
fmt.Fprintln(Output, GreenString("green"))
fmt.Fprintln(Output, YellowString("yellow"))
fmt.Fprintln(Output, BlueString("blue"))
fmt.Fprintln(Output, MagentaString("magenta"))
fmt.Fprintln(Output, CyanString("cyan"))
fmt.Fprintln(Output, WhiteString("white"))
}

114
Godeps/_workspace/src/github.com/fatih/color/doc.go generated vendored Normal file
View File

@ -0,0 +1,114 @@
/*
Package color is an ANSI color package to output colorized or SGR defined
output to the standard output. The API can be used in several way, pick one
that suits you.
Use simple and default helper functions with predefined foreground colors:
color.Cyan("Prints text in cyan.")
// a newline will be appended automatically
color.Blue("Prints %s in blue.", "text")
// More default foreground colors..
color.Red("We have red")
color.Yellow("Yellow color too!")
color.Magenta("And many others ..")
However there are times where custom color mixes are required. Below are some
examples to create custom color objects and use the print functions of each
separate color object.
// Create a new color object
c := color.New(color.FgCyan).Add(color.Underline)
c.Println("Prints cyan text with an underline.")
// Or just add them to New()
d := color.New(color.FgCyan, color.Bold)
d.Printf("This prints bold cyan %s\n", "too!.")
// Mix up foreground and background colors, create new mixes!
red := color.New(color.FgRed)
boldRed := red.Add(color.Bold)
boldRed.Println("This will print text in bold red.")
whiteBackground := red.Add(color.BgWhite)
whiteBackground.Println("Red text with White background.")
You can create PrintXxx functions to simplify even more:
// Create a custom print function for convenient
red := color.New(color.FgRed).PrintfFunc()
red("warning")
red("error: %s", err)
// Mix up multiple attributes
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
notice("don't forget this...")
Or create SprintXxx functions to mix strings with other non-colorized strings:
yellow := New(FgYellow).SprintFunc()
red := New(FgRed).SprintFunc()
fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
info := New(FgWhite, BgGreen).SprintFunc()
fmt.Printf("this %s rocks!\n", info("package"))
Windows support is enabled by default. All Print functions works as intended.
However only for color.SprintXXX functions, user should use fmt.FprintXXX and
set the output to color.Output:
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
info := New(FgWhite, BgGreen).SprintFunc()
fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
Using with existing code is possible. Just use the Set() method to set the
standard output to the given parameters. That way a rewrite of an existing
code is not required.
// Use handy standard colors.
color.Set(color.FgYellow)
fmt.Println("Existing text will be now in Yellow")
fmt.Printf("This one %s\n", "too")
color.Unset() // don't forget to unset
// You can mix up parameters
color.Set(color.FgMagenta, color.Bold)
defer color.Unset() // use it in your function
fmt.Println("All text will be now bold magenta.")
There might be a case where you want to disable color output (for example to
pipe the standard output of your app to somewhere else). `Color` has support to
disable colors both globally and for single color definition. For example
suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
the color output with:
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
if *flagNoColor {
color.NoColor = true // disables colorized output
}
It also has support for single color definitions (local). You can
disable/enable color output on the fly:
c := color.New(color.FgCyan)
c.Println("Prints cyan text")
c.DisableColor()
c.Println("This is printed without any color")
c.EnableColor()
c.Println("This prints again cyan...")
*/
package color

View File

@ -1,42 +0,0 @@
# go-colorable
Colorable writer for windows.
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)
This package is possible to handle escape sequence for ansi color on windows.
## Too Bad!
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)
## So Good!
![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)
## Usage
```go
logrus.SetOutput(colorable.NewColorableStdout())
logrus.Info("succeeded")
logrus.Warn("not correct")
logrus.Error("something error")
logrus.Fatal("panic")
```
You can compile above code on non-windows OSs.
## Installation
```
$ go get github.com/mattn/go-colorable
```
# License
MIT
# Author
Yasuhiro Matsumoto (a.k.a mattn)

View File

@ -1,16 +0,0 @@
// +build !windows
package colorable
import (
"io"
"os"
)
func NewColorableStdout() io.Writer {
return os.Stdout
}
func NewColorableStderr() io.Writer {
return os.Stderr
}

View File

@ -1,594 +0,0 @@
package colorable
import (
"bytes"
"fmt"
"io"
"os"
"strconv"
"strings"
"syscall"
"unsafe"
"github.com/mattn/go-isatty"
)
const (
foregroundBlue = 0x1
foregroundGreen = 0x2
foregroundRed = 0x4
foregroundIntensity = 0x8
foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)
backgroundBlue = 0x10
backgroundGreen = 0x20
backgroundRed = 0x40
backgroundIntensity = 0x80
backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
)
type wchar uint16
type short int16
type dword uint32
type word uint16
type coord struct {
x short
y short
}
type smallRect struct {
left short
top short
right short
bottom short
}
type consoleScreenBufferInfo struct {
size coord
cursorPosition coord
attributes word
window smallRect
maximumWindowSize coord
}
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
)
type Writer struct {
out io.Writer
handle syscall.Handle
lastbuf bytes.Buffer
oldattr word
}
func NewColorableStdout() io.Writer {
var csbi consoleScreenBufferInfo
out := os.Stdout
if !isatty.IsTerminal(out.Fd()) {
return out
}
handle := syscall.Handle(out.Fd())
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
}
func NewColorableStderr() io.Writer {
var csbi consoleScreenBufferInfo
out := os.Stderr
if !isatty.IsTerminal(out.Fd()) {
return out
}
handle := syscall.Handle(out.Fd())
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
return &Writer{out: out, handle: handle, oldattr: csbi.attributes}
}
var color256 = map[int]int{
0: 0x000000,
1: 0x800000,
2: 0x008000,
3: 0x808000,
4: 0x000080,
5: 0x800080,
6: 0x008080,
7: 0xc0c0c0,
8: 0x808080,
9: 0xff0000,
10: 0x00ff00,
11: 0xffff00,
12: 0x0000ff,
13: 0xff00ff,
14: 0x00ffff,
15: 0xffffff,
16: 0x000000,
17: 0x00005f,
18: 0x000087,
19: 0x0000af,
20: 0x0000d7,
21: 0x0000ff,
22: 0x005f00,
23: 0x005f5f,
24: 0x005f87,
25: 0x005faf,
26: 0x005fd7,
27: 0x005fff,
28: 0x008700,
29: 0x00875f,
30: 0x008787,
31: 0x0087af,
32: 0x0087d7,
33: 0x0087ff,
34: 0x00af00,
35: 0x00af5f,
36: 0x00af87,
37: 0x00afaf,
38: 0x00afd7,
39: 0x00afff,
40: 0x00d700,
41: 0x00d75f,
42: 0x00d787,
43: 0x00d7af,
44: 0x00d7d7,
45: 0x00d7ff,
46: 0x00ff00,
47: 0x00ff5f,
48: 0x00ff87,
49: 0x00ffaf,
50: 0x00ffd7,
51: 0x00ffff,
52: 0x5f0000,
53: 0x5f005f,
54: 0x5f0087,
55: 0x5f00af,
56: 0x5f00d7,
57: 0x5f00ff,
58: 0x5f5f00,
59: 0x5f5f5f,
60: 0x5f5f87,
61: 0x5f5faf,
62: 0x5f5fd7,
63: 0x5f5fff,
64: 0x5f8700,
65: 0x5f875f,
66: 0x5f8787,
67: 0x5f87af,
68: 0x5f87d7,
69: 0x5f87ff,
70: 0x5faf00,
71: 0x5faf5f,
72: 0x5faf87,
73: 0x5fafaf,
74: 0x5fafd7,
75: 0x5fafff,
76: 0x5fd700,
77: 0x5fd75f,
78: 0x5fd787,
79: 0x5fd7af,
80: 0x5fd7d7,
81: 0x5fd7ff,
82: 0x5fff00,
83: 0x5fff5f,
84: 0x5fff87,
85: 0x5fffaf,
86: 0x5fffd7,
87: 0x5fffff,
88: 0x870000,
89: 0x87005f,
90: 0x870087,
91: 0x8700af,
92: 0x8700d7,
93: 0x8700ff,
94: 0x875f00,
95: 0x875f5f,
96: 0x875f87,
97: 0x875faf,
98: 0x875fd7,
99: 0x875fff,
100: 0x878700,
101: 0x87875f,
102: 0x878787,
103: 0x8787af,
104: 0x8787d7,
105: 0x8787ff,
106: 0x87af00,
107: 0x87af5f,
108: 0x87af87,
109: 0x87afaf,
110: 0x87afd7,
111: 0x87afff,
112: 0x87d700,
113: 0x87d75f,
114: 0x87d787,
115: 0x87d7af,
116: 0x87d7d7,
117: 0x87d7ff,
118: 0x87ff00,
119: 0x87ff5f,
120: 0x87ff87,
121: 0x87ffaf,
122: 0x87ffd7,
123: 0x87ffff,
124: 0xaf0000,
125: 0xaf005f,
126: 0xaf0087,
127: 0xaf00af,
128: 0xaf00d7,
129: 0xaf00ff,
130: 0xaf5f00,
131: 0xaf5f5f,
132: 0xaf5f87,
133: 0xaf5faf,
134: 0xaf5fd7,
135: 0xaf5fff,
136: 0xaf8700,
137: 0xaf875f,
138: 0xaf8787,
139: 0xaf87af,
140: 0xaf87d7,
141: 0xaf87ff,
142: 0xafaf00,
143: 0xafaf5f,
144: 0xafaf87,
145: 0xafafaf,
146: 0xafafd7,
147: 0xafafff,
148: 0xafd700,
149: 0xafd75f,
150: 0xafd787,
151: 0xafd7af,
152: 0xafd7d7,
153: 0xafd7ff,
154: 0xafff00,
155: 0xafff5f,
156: 0xafff87,
157: 0xafffaf,
158: 0xafffd7,
159: 0xafffff,
160: 0xd70000,
161: 0xd7005f,
162: 0xd70087,
163: 0xd700af,
164: 0xd700d7,
165: 0xd700ff,
166: 0xd75f00,
167: 0xd75f5f,
168: 0xd75f87,
169: 0xd75faf,
170: 0xd75fd7,
171: 0xd75fff,
172: 0xd78700,
173: 0xd7875f,
174: 0xd78787,
175: 0xd787af,
176: 0xd787d7,
177: 0xd787ff,
178: 0xd7af00,
179: 0xd7af5f,
180: 0xd7af87,
181: 0xd7afaf,
182: 0xd7afd7,
183: 0xd7afff,
184: 0xd7d700,
185: 0xd7d75f,
186: 0xd7d787,
187: 0xd7d7af,
188: 0xd7d7d7,
189: 0xd7d7ff,
190: 0xd7ff00,
191: 0xd7ff5f,
192: 0xd7ff87,
193: 0xd7ffaf,
194: 0xd7ffd7,
195: 0xd7ffff,
196: 0xff0000,
197: 0xff005f,
198: 0xff0087,
199: 0xff00af,
200: 0xff00d7,
201: 0xff00ff,
202: 0xff5f00,
203: 0xff5f5f,
204: 0xff5f87,
205: 0xff5faf,
206: 0xff5fd7,
207: 0xff5fff,
208: 0xff8700,
209: 0xff875f,
210: 0xff8787,
211: 0xff87af,
212: 0xff87d7,
213: 0xff87ff,
214: 0xffaf00,
215: 0xffaf5f,
216: 0xffaf87,
217: 0xffafaf,
218: 0xffafd7,
219: 0xffafff,
220: 0xffd700,
221: 0xffd75f,
222: 0xffd787,
223: 0xffd7af,
224: 0xffd7d7,
225: 0xffd7ff,
226: 0xffff00,
227: 0xffff5f,
228: 0xffff87,
229: 0xffffaf,
230: 0xffffd7,
231: 0xffffff,
232: 0x080808,
233: 0x121212,
234: 0x1c1c1c,
235: 0x262626,
236: 0x303030,
237: 0x3a3a3a,
238: 0x444444,
239: 0x4e4e4e,
240: 0x585858,
241: 0x626262,
242: 0x6c6c6c,
243: 0x767676,
244: 0x808080,
245: 0x8a8a8a,
246: 0x949494,
247: 0x9e9e9e,
248: 0xa8a8a8,
249: 0xb2b2b2,
250: 0xbcbcbc,
251: 0xc6c6c6,
252: 0xd0d0d0,
253: 0xdadada,
254: 0xe4e4e4,
255: 0xeeeeee,
}
func (w *Writer) Write(data []byte) (n int, err error) {
var csbi consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
er := bytes.NewBuffer(data)
loop:
for {
r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
if r1 == 0 {
break loop
}
c1, _, err := er.ReadRune()
if err != nil {
break loop
}
if c1 != 0x1b {
fmt.Fprint(w.out, string(c1))
continue
}
c2, _, err := er.ReadRune()
if err != nil {
w.lastbuf.WriteRune(c1)
break loop
}
if c2 != 0x5b {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
continue
}
var buf bytes.Buffer
var m rune
for {
c, _, err := er.ReadRune()
if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.Write(buf.Bytes())
break loop
}
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
m = c
break
}
buf.Write([]byte(string(c)))
}
switch m {
case 'm':
attr := csbi.attributes
cs := buf.String()
if cs == "" {
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
continue
}
token := strings.Split(cs, ";")
for i, ns := range token {
if n, err = strconv.Atoi(ns); err == nil {
switch {
case n == 0 || n == 100:
attr = w.oldattr
case 1 <= n && n <= 5:
attr |= foregroundIntensity
case n == 7:
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
case 22 == n || n == 25 || n == 25:
attr |= foregroundIntensity
case n == 27:
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
case 30 <= n && n <= 37:
attr = (attr & backgroundMask)
if (n-30)&1 != 0 {
attr |= foregroundRed
}
if (n-30)&2 != 0 {
attr |= foregroundGreen
}
if (n-30)&4 != 0 {
attr |= foregroundBlue
}
case n == 38: // set foreground color.
if i < len(token)-2 && token[i+1] == "5" {
if n256, err := strconv.Atoi(token[i+2]); err == nil {
if n256foreAttr == nil {
n256setup()
}
attr &= backgroundMask
attr |= n256foreAttr[n256]
i += 2
}
} else {
attr = attr & (w.oldattr & backgroundMask)
}
case n == 39: // reset foreground color.
attr &= backgroundMask
attr |= w.oldattr & foregroundMask
case 40 <= n && n <= 47:
attr = (attr & foregroundMask)
if (n-40)&1 != 0 {
attr |= backgroundRed
}
if (n-40)&2 != 0 {
attr |= backgroundGreen
}
if (n-40)&4 != 0 {
attr |= backgroundBlue
}
case n == 48: // set background color.
if i < len(token)-2 && token[i+1] == "5" {
if n256, err := strconv.Atoi(token[i+2]); err == nil {
if n256backAttr == nil {
n256setup()
}
attr &= foregroundMask
attr |= n256backAttr[n256]
i += 2
}
} else {
attr = attr & (w.oldattr & foregroundMask)
}
case n == 49: // reset foreground color.
attr &= foregroundMask
attr |= w.oldattr & backgroundMask
}
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
}
}
}
}
return len(data) - w.lastbuf.Len(), nil
}
type consoleColor struct {
red bool
green bool
blue bool
intensity bool
}
func minmax3(a, b, c int) (min, max int) {
if a < b {
if b < c {
return a, c
} else if a < c {
return a, b
} else {
return c, b
}
} else {
if a < c {
return b, c
} else if b < c {
return b, a
} else {
return c, a
}
}
}
func toConsoleColor(rgb int) (c consoleColor) {
r, g, b := (rgb&0xFF0000)>>16, (rgb&0x00FF00)>>8, rgb&0x0000FF
min, max := minmax3(r, g, b)
a := (min + max) / 2
if r < 128 && g < 128 && b < 128 {
if r >= a {
c.red = true
}
if g >= a {
c.green = true
}
if b >= a {
c.blue = true
}
// non-intensed white is lighter than intensed black, so swap those.
if c.red && c.green && c.blue {
c.red, c.green, c.blue = false, false, false
c.intensity = true
}
} else {
if min < 128 {
min = 128
a = (min + max) / 2
}
if r >= a {
c.red = true
}
if g >= a {
c.green = true
}
if b >= a {
c.blue = true
}
c.intensity = true
// intensed black is darker than non-intensed white, so swap those.
if !c.red && !c.green && !c.blue {
c.red, c.green, c.blue = true, true, true
c.intensity = false
}
}
return c
}
func (c consoleColor) foregroundAttr() (attr word) {
if c.red {
attr |= foregroundRed
}
if c.green {
attr |= foregroundGreen
}
if c.blue {
attr |= foregroundBlue
}
if c.intensity {
attr |= foregroundIntensity
}
return
}
func (c consoleColor) backgroundAttr() (attr word) {
if c.red {
attr |= backgroundRed
}
if c.green {
attr |= backgroundGreen
}
if c.blue {
attr |= backgroundBlue
}
if c.intensity {
attr |= backgroundIntensity
}
return
}
var n256foreAttr []word
var n256backAttr []word
func n256setup() {
n256foreAttr = make([]word, 256)
n256backAttr = make([]word, 256)
for i, rgb := range color256 {
c := toConsoleColor(rgb)
n256foreAttr[i] = c.foregroundAttr()
n256backAttr[i] = c.backgroundAttr()
}
}

View File

@ -1,144 +0,0 @@
# globalconf
[![Build Status](https://travis-ci.org/rakyll/globalconf.png?branch=master)](https://travis-ci.org/rakyll/globalconf)
Effortlessly persist/retrieve flags of your Golang programs. If you need global configuration instead of requiring user always to set command line flags, you are looking at the right package. `globalconf` allows your users to not only provide flags, but config files and environment variables as well.
## Usage
~~~ go
import "github.com/rakyll/globalconf"
~~~
### Loading a config file
By default, globalconf provides you a config file under `~/.config/<yourappname>/config.ini`.
~~~ go
globalconf.New("appname") // loads from ~/.config/<appname>/config.ini
~~~
If you don't prefer the default location you can load from a specified path as well.
~~~ go
globalconf.NewWithOptions(&globalconf.Options{
Filename: "/path/to/config/file",
})
~~~
You may like to override configuration with env variables. See "Environment variables" header to see how to it works.
~~~ go
globalconf.NewWithOptions(&globalconf.Options{
Filename: "/path/to/config/file",
EnvPrefix: "APPCONF_",
})
~~~
### Parsing flag values
`globalconf` populates flags with data in the config file if they are not already set.
~~~ go
var (
flagName = flag.String("name", "", "Name of the person.")
flagAddress = flag.String("addr", "", "Address of the person.")
)
~~~
Assume the configuration file to be loaded contains the following lines.
name = Burcu
addr = Brandschenkestrasse 110, 8002
And your program is being started, `$ myapp -name=Jane`
~~~ go
conf, err := globalconf.New("myapp")
conf.ParseAll()
~~~
`*flagName` is going to be equal to `Jane`, whereas `*flagAddress` is `Brandschenkestrasse 110, 8002`, what is provided in the configuration file.
### Custom flag sets
Custom flagsets are supported, but required registration before parse is done. The default flagset `flag.CommandLine` is automatically registered.
~~~ go
globalconf.Register("termopts", termOptsFlagSet)
conf.ParseAll() // parses command line and all registered flag sets
~~~
Custom flagset values should be provided in their own segment. Getting back to the sample ini config file, termopts values will have their own segment.
name = Burcu
addr = Brandschenkestrasse 110, 8002
[termopts]
color = true
background = ff0000
### Environment variables
If an EnvPrefix is provided, environment variables will take precedence over values in the configuration file.
Set the `EnvPrefix` option when calling `globalconf.NewWithOptions`.
An `EnvPrefix` will only be used if it is a non-empty string.
Command line flags will override the environment variables.
~~~ go
opts := globalconf.Options{
EnvPrefix: "MYAPP_",
Filename: "/path/to/config",
}
conf, err := globalconf.NewWithOptions(&opts)
conf.ParseAll()
~~~
With environment variables:
APPCONF_NAME = Burcu
and configuration:
name = Jane
addr = Brandschenkestrasse 110, 8002
`name` will be set to "burcu" and `addr` will be set to "Brandschenkestrasse 110, 8002".
### Modifying stored flags
Modifications are persisted as long as you set a new flag and your GlobalConf
object was configured with a filename.
~~~ go
f := &flag.Flag{Name: "name", Value: val}
conf.Set("", f) // if you are modifying a command line flag
f := &flag.Flag{Name: "color", Value: val}
conf.Set("termopts", color) // if you are modifying a custom flag set flag
~~~
### Deleting stored flags
Like Set, Deletions are persisted as long as you delete a flag's value and your
GlobalConf object was configured with a filename.
~~~ go
conf.Delete("", "name") // removes command line flag "name"s value from config
conf.Delete("termopts", "color") // removes "color"s value from the custom flag set
~~~
## License
Copyright 2014 Google Inc. All Rights Reserved.
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. ![Analytics](https://ga-beacon.appspot.com/UA-46881978-1/globalconf?pixel)

View File

@ -1,179 +0,0 @@
package globalconf
import (
"flag"
"io/ioutil"
"os"
"os/user"
"path"
"strings"
ini "github.com/rakyll/goini"
)
const (
defaultConfigFileName = "config.ini"
)
var flags map[string]*flag.FlagSet = make(map[string]*flag.FlagSet)
// Represents a GlobalConf context.
type GlobalConf struct {
Filename string
EnvPrefix string
dict *ini.Dict
}
type Options struct {
Filename string
EnvPrefix string
}
// NewWithOptions creates a GlobalConf from the provided
// Options. The caller is responsible for creating any
// referenced config files.
func NewWithOptions(opts *Options) (g *GlobalConf, err error) {
Register("", flag.CommandLine)
var dict ini.Dict
if opts.Filename != "" {
dict, err = ini.Load(opts.Filename)
if err != nil {
return nil, err
}
} else {
dict = make(ini.Dict, 0)
}
return &GlobalConf{
Filename: opts.Filename,
EnvPrefix: opts.EnvPrefix,
dict: &dict,
}, nil
}
// Opens/creates a config file for the specified appName.
// The path to config file is ~/.config/appName/config.ini.
func New(appName string) (g *GlobalConf, err error) {
var u *user.User
if u, err = user.Current(); u == nil {
return
}
// Create config file's directory.
dirPath := path.Join(u.HomeDir, ".config", appName)
if err = os.MkdirAll(dirPath, 0755); err != nil {
return
}
// Touch a config file if it doesn't exit.
filePath := path.Join(dirPath, defaultConfigFileName)
if _, err = os.Stat(filePath); err != nil {
if !os.IsNotExist(err) {
return
}
// create file
if err = ioutil.WriteFile(filePath, []byte{}, 0644); err != nil {
return
}
}
opts := Options{Filename: filePath}
return NewWithOptions(&opts)
}
// Sets a flag's value and persists the changes to the disk.
func (g *GlobalConf) Set(flagSetName string, f *flag.Flag) error {
g.dict.SetString(flagSetName, f.Name, f.Value.String())
if g.Filename != "" {
return ini.Write(g.Filename, g.dict)
}
return nil
}
// Deletes a flag from config file and persists the changes
// to the disk.
func (g *GlobalConf) Delete(flagSetName, flagName string) error {
g.dict.Delete(flagSetName, flagName)
if g.Filename != "" {
return ini.Write(g.Filename, g.dict)
}
return nil
}
// Parses the config file for the provided flag set.
// If the flags are already set, values are overwritten
// by the values in the config file. Defaults are not set
// if the flag is not in the file.
func (g *GlobalConf) ParseSet(flagSetName string, set *flag.FlagSet) {
set.VisitAll(func(f *flag.Flag) {
val := getEnv(g.EnvPrefix, flagSetName, f.Name)
if val != "" {
set.Set(f.Name, val)
return
}
val, found := g.dict.GetString(flagSetName, f.Name)
if found {
set.Set(f.Name, val)
}
})
}
// Parses all the registered flag sets, including the command
// line set and sets values from the config file if they are
// not already set.
func (g *GlobalConf) Parse() {
for name, set := range flags {
alreadySet := make(map[string]bool)
set.Visit(func(f *flag.Flag) {
alreadySet[f.Name] = true
})
set.VisitAll(func(f *flag.Flag) {
// if not already set, set it from dict if exists
if alreadySet[f.Name] {
return
}
val := getEnv(g.EnvPrefix, name, f.Name)
if val != "" {
set.Set(f.Name, val)
return
}
val, found := g.dict.GetString(name, f.Name)
if found {
set.Set(f.Name, val)
}
})
}
}
// Parses command line flags and then, all of the registered
// flag sets with the values provided in the config file.
func (g *GlobalConf) ParseAll() {
if !flag.Parsed() {
flag.Parse()
}
g.Parse()
}
// Looks up variable in environment
func getEnv(envPrefix, flagSetName, flagName string) string {
// If we haven't set an EnvPrefix, don't lookup vals in the ENV
if envPrefix == "" {
return ""
}
// Append a _ to flagSetName if it exists.
if flagSetName != "" {
flagSetName += "_"
}
flagName = strings.Replace(flagName, ".", "_", -1)
flagName = strings.Replace(flagName, "-", "_", -1)
envKey := strings.ToUpper(envPrefix + flagSetName + flagName)
return os.Getenv(envKey)
}
// Registers a flag set to be parsed. Register all flag sets
// before calling this function. flag.CommandLine is automatically
// registered.
func Register(flagSetName string, set *flag.FlagSet) {
flags[flagSetName] = set
}

View File

@ -1,267 +0,0 @@
package globalconf
import (
"flag"
"io/ioutil"
"os"
"testing"
)
const envTestPrefix = "CONFTEST_"
func TestNewWithOptionsNoFilename(t *testing.T) {
opts := Options{EnvPrefix: envTestPrefix}
os.Setenv(envTestPrefix+"D", "EnvD")
flagD := flag.String("d", "default", "")
flagE := flag.Bool("e", true, "")
conf, err := NewWithOptions(&opts)
if err != nil {
t.Fatal(err)
}
conf.ParseAll()
if *flagD != "EnvD" {
t.Errorf("flagD found %v, expected 'EnvD'", *flagD)
}
if !*flagE {
t.Errorf("flagE found %v, expected true", *flagE)
}
}
func TestParse_Global(t *testing.T) {
resetForTesting("")
os.Setenv(envTestPrefix+"D", "EnvD")
os.Setenv(envTestPrefix+"E", "true")
os.Setenv(envTestPrefix+"F", "5.5")
flagA := flag.Bool("a", false, "")
flagB := flag.Float64("b", 0.0, "")
flagC := flag.String("c", "", "")
flagD := flag.String("d", "", "")
flagE := flag.Bool("e", false, "")
flagF := flag.Float64("f", 0.0, "")
parse(t, "./testdata/global.ini", envTestPrefix)
if !*flagA {
t.Errorf("flagA found %v, expected true", *flagA)
}
if *flagB != 5.6 {
t.Errorf("flagB found %v, expected 5.6", *flagB)
}
if *flagC != "Hello world" {
t.Errorf("flagC found %v, expected 'Hello world'", *flagC)
}
if *flagD != "EnvD" {
t.Errorf("flagD found %v, expected 'EnvD'", *flagD)
}
if !*flagE {
t.Errorf("flagE found %v, expected true", *flagE)
}
if *flagF != 5.5 {
t.Errorf("flagF found %v, expected 5.5", *flagF)
}
}
func TestParse_DashConversion(t *testing.T) {
resetForTesting("")
flagFooBar := flag.String("foo-bar", "", "")
os.Setenv("PREFIX_FOO_BAR", "baz")
opts := Options{EnvPrefix: "PREFIX_"}
conf, err := NewWithOptions(&opts)
if err != nil {
t.Fatal(err)
}
conf.ParseAll()
if *flagFooBar != "baz" {
t.Errorf("flagFooBar found %v, expected 5.5", *flagFooBar)
}
}
func TestParse_GlobalWithDottedFlagname(t *testing.T) {
resetForTesting("")
os.Setenv(envTestPrefix+"SOME_VALUE", "some-value")
flagSomeValue := flag.String("some.value", "", "")
parse(t, "./testdata/global.ini", envTestPrefix)
if *flagSomeValue != "some-value" {
t.Errorf("flagSomeValue found %v, some-value expected", *flagSomeValue)
}
}
func TestParse_GlobalOverwrite(t *testing.T) {
resetForTesting("-b=7.6")
flagB := flag.Float64("b", 0.0, "")
parse(t, "./testdata/global.ini", "")
if *flagB != 7.6 {
t.Errorf("flagB found %v, expected 7.6", *flagB)
}
}
func TestParse_Custom(t *testing.T) {
resetForTesting("")
os.Setenv(envTestPrefix+"CUSTOM_E", "Hello Env")
flagB := flag.Float64("b", 5.0, "")
name := "custom"
custom := flag.NewFlagSet(name, flag.ExitOnError)
flagD := custom.String("d", "dd", "")
flagE := custom.String("e", "ee", "")
Register(name, custom)
parse(t, "./testdata/custom.ini", envTestPrefix)
if *flagB != 5.0 {
t.Errorf("flagB found %v, expected 5.0", *flagB)
}
if *flagD != "Hello d" {
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
}
if *flagE != "Hello Env" {
t.Errorf("flagE found %v, expected 'Hello Env'", *flagE)
}
}
func TestParse_CustomOverwrite(t *testing.T) {
resetForTesting("-b=6")
flagB := flag.Float64("b", 5.0, "")
name := "custom"
custom := flag.NewFlagSet(name, flag.ExitOnError)
flagD := custom.String("d", "dd", "")
Register(name, custom)
parse(t, "./testdata/custom.ini", "")
if *flagB != 6.0 {
t.Errorf("flagB found %v, expected 6.0", *flagB)
}
if *flagD != "Hello d" {
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
}
}
func TestParse_GlobalAndCustom(t *testing.T) {
resetForTesting("")
flagA := flag.Bool("a", false, "")
flagB := flag.Float64("b", 0.0, "")
flagC := flag.String("c", "", "")
name := "custom"
custom := flag.NewFlagSet(name, flag.ExitOnError)
flagD := custom.String("d", "", "")
Register(name, custom)
parse(t, "./testdata/globalandcustom.ini", "")
if !*flagA {
t.Errorf("flagA found %v, expected true", *flagA)
}
if *flagB != 5.6 {
t.Errorf("flagB found %v, expected 5.6", *flagB)
}
if *flagC != "Hello world" {
t.Errorf("flagC found %v, expected 'Hello world'", *flagC)
}
if *flagD != "Hello d" {
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
}
}
func TestParse_GlobalAndCustomOverwrite(t *testing.T) {
resetForTesting("-a=true", "-b=5", "-c=Hello")
flagA := flag.Bool("a", false, "")
flagB := flag.Float64("b", 0.0, "")
flagC := flag.String("c", "", "")
name := "custom"
custom := flag.NewFlagSet(name, flag.ExitOnError)
flagD := custom.String("d", "", "")
Register(name, custom)
parse(t, "./testdata/globalandcustom.ini", "")
if !*flagA {
t.Errorf("flagA found %v, expected true", *flagA)
}
if *flagB != 5.0 {
t.Errorf("flagB found %v, expected 5.0", *flagB)
}
if *flagC != "Hello" {
t.Errorf("flagC found %v, expected 'Hello'", *flagC)
}
if *flagD != "Hello d" {
t.Errorf("flagD found %v, expected 'Hello d'", *flagD)
}
}
func TestSet(t *testing.T) {
resetForTesting()
file, _ := ioutil.TempFile("", "")
conf := parse(t, file.Name(), "")
conf.Set("", &flag.Flag{Name: "a", Value: newFlagValue("test")})
flagA := flag.String("a", "", "")
parse(t, file.Name(), "")
if *flagA != "test" {
t.Errorf("flagA found %v, expected 'test'", *flagA)
}
}
func TestDelete(t *testing.T) {
resetForTesting()
file, _ := ioutil.TempFile("", "")
conf := parse(t, file.Name(), "")
conf.Set("", &flag.Flag{Name: "a", Value: newFlagValue("test")})
conf.Delete("", "a")
flagA := flag.String("a", "", "")
parse(t, file.Name(), "")
if *flagA != "" {
t.Errorf("flagNewA found %v, expected ''", *flagA)
}
}
func parse(t *testing.T, filename, envPrefix string) *GlobalConf {
opts := Options{
Filename: filename,
EnvPrefix: envPrefix,
}
conf, err := NewWithOptions(&opts)
if err != nil {
t.Error(err)
}
conf.ParseAll()
return conf
}
// Resets os.Args and the default flag set.
func resetForTesting(args ...string) {
os.Clearenv()
os.Args = append([]string{"cmd"}, args...)
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
}
type flagValue struct {
str string
}
func (f *flagValue) String() string {
return f.str
}
func (f *flagValue) Set(value string) error {
f.str = value
return nil
}
func newFlagValue(val string) *flagValue {
return &flagValue{str: val}
}

View File

@ -1,2 +0,0 @@
[custom]
d = Hello d

View File

@ -1,3 +0,0 @@
a = true
b = 5.6
c = Hello world

View File

@ -1,6 +0,0 @@
a = true
b = 5.6
c = Hello world
[custom]
d = Hello d

View File

@ -1,8 +0,0 @@
.*.swp
*.[689]
[689].out
_obj
_test
_testmain.go

View File

@ -1,7 +0,0 @@
test:
go test
format:
gofmt -w *.go
.PHONY: format test

View File

@ -1,18 +0,0 @@
#
# This is an example of ini file
#
[Pizza]
Ham = yes;
Mushrooms = TRUE;
Capres = 0;
Cheese = Non;
[Wine]
Grape = Cabernet Sauvignon;
Year = 1989;
Country = Spain;
Alcohol = 12.5;

View File

@ -1,241 +0,0 @@
package ini
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
"unicode"
)
type Dict map[string]map[string]string
type Error string
var (
regDoubleQuote = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*\"([^\"]*)\"$")
regSingleQuote = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*'([^']*)'$")
regNoQuote = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*([^#;]+)")
regNoValue = regexp.MustCompile("^([^= \t]+)[ \t]*=[ \t]*([#;].*)?")
)
func Load(filename string) (dict Dict, err error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
dict = make(map[string]map[string]string)
reader := bufio.NewReader(file)
lineno := 0
section := ""
dict[section] = make(map[string]string)
for err == nil {
l, _, err := reader.ReadLine()
if err != nil {
break
}
lineno++
if len(l) == 0 {
continue
}
line := strings.TrimFunc(string(l), unicode.IsSpace)
for line[len(line)-1] == '\\' {
line = line[:len(line)-1]
l, _, err := reader.ReadLine()
if err != nil {
return nil, err
}
line += strings.TrimFunc(string(l), unicode.IsSpace)
}
section, err = dict.parseLine(section, line)
if err != nil {
return nil, newError(
err.Error() + fmt.Sprintf("'%s:%d'.", filename, lineno))
}
}
return
}
func Write(filename string, dict *Dict) error {
buffer := dict.format()
return ioutil.WriteFile(filename, buffer.Bytes(), 0644)
}
func (e Error) Error() string {
return string(e)
}
func (dict Dict) parseLine(section, line string) (string, error) {
// commets
if line[0] == '#' || line[0] == ';' {
return section, nil
}
// section name
if line[0] == '[' && line[len(line)-1] == ']' {
section := strings.TrimFunc(line[1:len(line)-1], unicode.IsSpace)
section = strings.ToLower(section)
dict[section] = make(map[string]string)
return section, nil
}
// key = value
if m := regDoubleQuote.FindAllStringSubmatch(line, 1); m != nil {
dict.add(section, m[0][1], m[0][2])
return section, nil
} else if m = regSingleQuote.FindAllStringSubmatch(line, 1); m != nil {
dict.add(section, m[0][1], m[0][2])
return section, nil
} else if m = regNoQuote.FindAllStringSubmatch(line, 1); m != nil {
dict.add(section, m[0][1], strings.TrimFunc(m[0][2], unicode.IsSpace))
return section, nil
} else if m = regNoValue.FindAllStringSubmatch(line, 1); m != nil {
dict.add(section, m[0][1], "")
return section, nil
}
return section, newError("iniparser: syntax error at ")
}
func (dict Dict) add(section, key, value string) {
key = strings.ToLower(key)
dict[section][key] = value
}
func (dict Dict) GetBool(section, key string) (bool, bool) {
sec, ok := dict[section]
if !ok {
return false, false
}
value, ok := sec[key]
if !ok {
return false, false
}
v := value[0]
if v == 'y' || v == 'Y' || v == '1' || v == 't' || v == 'T' {
return true, true
}
if v == 'n' || v == 'N' || v == '0' || v == 'f' || v == 'F' {
return false, true
}
return false, false
}
func (dict Dict) SetBool(section, key string, value bool) {
dict.SetString(section, key, strconv.FormatBool(value))
}
func (dict Dict) GetString(section, key string) (string, bool) {
sec, ok := dict[section]
if !ok {
return "", false
}
value, ok := sec[key]
if !ok {
return "", false
}
return value, true
}
func (dict Dict) SetString(section, key, value string) {
_, ok := dict[section]
if !ok {
dict[section] = make(map[string]string)
}
dict[section][key] = value
}
func (dict Dict) GetInt(section, key string) (int, bool) {
sec, ok := dict[section]
if !ok {
return 0, false
}
value, ok := sec[key]
if !ok {
return 0, false
}
i, err := strconv.Atoi(value)
if err != nil {
return 0, false
}
return i, true
}
func (dict Dict) SetInt(section, key string, value int) {
dict.SetString(section, key, strconv.FormatInt(int64(value), 10))
}
func (dict Dict) GetDouble(section, key string) (float64, bool) {
sec, ok := dict[section]
if !ok {
return 0, false
}
value, ok := sec[key]
if !ok {
return 0, false
}
d, err := strconv.ParseFloat(value, 64)
if err != nil {
return 0, false
}
return d, true
}
func (dict Dict) SetDouble(section, key string, value float64) {
dict.SetString(section, key, strconv.FormatFloat(value, 'f', -1, 64))
}
func (dict Dict) Delete(section, key string) {
_, ok := dict[section]
if !ok {
return
}
delete(dict[section], key)
// If there are no items left in the section,
// delete the section.
if len(dict[section]) == 0 {
delete(dict, section)
}
}
func (dict Dict) GetSections() []string {
size := len(dict)
sections := make([]string, size)
i := 0
for section, _ := range dict {
sections[i] = section
i++
}
return sections
}
func (dict Dict) String() string {
return (*dict.format()).String()
}
func (dict Dict) format() *bytes.Buffer {
var buffer bytes.Buffer
for section, vals := range dict {
if section != "" {
buffer.WriteString(fmt.Sprintf("[%s]\n", section))
}
for key, val := range vals {
buffer.WriteString(fmt.Sprintf("%s = %s\n", key, val))
}
buffer.WriteString("\n")
}
return &buffer
}
func newError(message string) (e error) {
return Error(message)
}

View File

@ -1,169 +0,0 @@
package ini
import (
"io/ioutil"
"testing"
)
const (
exampleStr = `key1 = true
[section1]
key1 = value2
key2 = 5
key3 = 1.3
[section2]
key1 = 5
`
)
var (
dict Dict
err error
)
func init() {
dict, err = Load("example.ini")
}
func TestLoad(t *testing.T) {
if err != nil {
t.Error("Example: load error:", err)
}
}
func TestWrite(t *testing.T) {
d, err := Load("empty.ini")
if err != nil {
t.Error("Example: load error:", err)
}
d.SetString("", "key", "value")
tempFile, err := ioutil.TempFile("", "")
if err != nil {
t.Error("Write: Couldn't create temp file.", err)
}
err = Write(tempFile.Name(), &d)
if err != nil {
t.Error("Write: Couldn't write to temp config file.", err)
}
contents, err := ioutil.ReadFile(tempFile.Name())
if err != nil {
t.Error("Write: Couldn't read from the temp config file.", err)
}
if string(contents) != "key = value\n\n" {
t.Error("Write: Contents of the config file doesn't match the expected.")
}
}
func TestGetBool(t *testing.T) {
b, found := dict.GetBool("pizza", "ham")
if !found || !b {
t.Error("Example: parse error for key ham of section pizza.")
}
b, found = dict.GetBool("pizza", "mushrooms")
if !found || !b {
t.Error("Example: parse error for key mushrooms of section pizza.")
}
b, found = dict.GetBool("pizza", "capres")
if !found || b {
t.Error("Example: parse error for key capres of section pizza.")
}
b, found = dict.GetBool("pizza", "cheese")
if !found || b {
t.Error("Example: parse error for key cheese of section pizza.")
}
}
func TestGetStringIntAndDouble(t *testing.T) {
str, found := dict.GetString("wine", "grape")
if !found || str != "Cabernet Sauvignon" {
t.Error("Example: parse error for key grape of section wine.")
}
i, found := dict.GetInt("wine", "year")
if !found || i != 1989 {
t.Error("Example: parse error for key year of section wine.")
}
str, found = dict.GetString("wine", "country")
if !found || str != "Spain" {
t.Error("Example: parse error for key grape of section wine.")
}
d, found := dict.GetDouble("wine", "alcohol")
if !found || d != 12.5 {
t.Error("Example: parse error for key grape of section wine.")
}
}
func TestSetBoolAndStringAndIntAndDouble(t *testing.T) {
dict.SetBool("pizza", "ham", false)
b, found := dict.GetBool("pizza", "ham")
if !found || b {
t.Error("Example: bool set error for key ham of section pizza.")
}
dict.SetString("pizza", "ham", "no")
n, found := dict.GetString("pizza", "ham")
if !found || n != "no" {
t.Error("Example: string set error for key ham of section pizza.")
}
dict.SetInt("wine", "year", 1978)
i, found := dict.GetInt("wine", "year")
if !found || i != 1978 {
t.Error("Example: int set error for key year of section wine.")
}
dict.SetDouble("wine", "not-exists", 5.6)
d, found := dict.GetDouble("wine", "not-exists")
if !found || d != 5.6 {
t.Error("Example: float set error for not existing key for wine.")
}
}
func TestDelete(t *testing.T) {
d, err := Load("empty.ini")
if err != nil {
t.Error("Example: load error:", err)
}
d.SetString("pizza", "ham", "yes")
d.Delete("pizza", "ham")
_, found := d.GetString("pizza", "ham")
if found {
t.Error("Example: delete error for key ham of section pizza.")
}
if len(d.GetSections()) > 1 {
t.Error("Only a single section should exist after deletion.")
}
}
func TestGetNotExist(t *testing.T) {
_, found := dict.GetString("not", "exist")
if found {
t.Error("There is no key exist of section not.")
}
}
func TestGetSections(t *testing.T) {
sections := dict.GetSections()
if len(sections) != 3 {
t.Error("The number of sections is wrong:", len(sections))
}
for _, section := range sections {
if section != "" && section != "pizza" && section != "wine" {
t.Errorf("Section '%s' should not be exist.", section)
}
}
}
func TestString(t *testing.T) {
d, err := Load("empty.ini")
if err != nil {
t.Error("Example: load error:", err)
}
d.SetBool("", "key1", true)
d.SetString("section1", "key1", "value2")
d.SetInt("section1", "key2", 5)
d.SetDouble("section1", "key3", 1.3)
d.SetDouble("section2", "key1", 5.0)
if d.String() != exampleStr {
t.Errorf("Dict cannot be stringified as expected.")
}
}

View File

@ -0,0 +1,27 @@
# Created by http://www.gitignore.io
### 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

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) [2014] [shiena]
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.

View File

@ -0,0 +1,100 @@
[![GoDoc](https://godoc.org/github.com/shiena/ansicolor?status.svg)](https://godoc.org/github.com/shiena/ansicolor)
# ansicolor
Ansicolor library provides color console in Windows as ANSICON for Golang.
## Features
|Escape sequence|Text attributes|
|---------------|----|
|\x1b[0m|All attributes off(color at startup)|
|\x1b[1m|Bold on(enable foreground intensity)|
|\x1b[4m|Underline on|
|\x1b[5m|Blink on(enable background intensity)|
|\x1b[21m|Bold off(disable foreground intensity)|
|\x1b[24m|Underline off|
|\x1b[25m|Blink off(disable background intensity)|
|Escape sequence|Foreground colors|
|---------------|----|
|\x1b[30m|Black|
|\x1b[31m|Red|
|\x1b[32m|Green|
|\x1b[33m|Yellow|
|\x1b[34m|Blue|
|\x1b[35m|Magenta|
|\x1b[36m|Cyan|
|\x1b[37m|White|
|\x1b[39m|Default(foreground color at startup)|
|\x1b[90m|Light Gray|
|\x1b[91m|Light Red|
|\x1b[92m|Light Green|
|\x1b[93m|Light Yellow|
|\x1b[94m|Light Blue|
|\x1b[95m|Light Magenta|
|\x1b[96m|Light Cyan|
|\x1b[97m|Light White|
|Escape sequence|Background colors|
|---------------|----|
|\x1b[40m|Black|
|\x1b[41m|Red|
|\x1b[42m|Green|
|\x1b[43m|Yellow|
|\x1b[44m|Blue|
|\x1b[45m|Magenta|
|\x1b[46m|Cyan|
|\x1b[47m|White|
|\x1b[49m|Default(background color at startup)|
|\x1b[100m|Light Gray|
|\x1b[101m|Light Red|
|\x1b[102m|Light Green|
|\x1b[103m|Light Yellow|
|\x1b[104m|Light Blue|
|\x1b[105m|Light Magenta|
|\x1b[106m|Light Cyan|
|\x1b[107m|Light White|
## Example
```go
package main
import (
"fmt"
"os"
"github.com/shiena/ansicolor"
)
func main() {
w := ansicolor.NewAnsiColorWriter(os.Stdout)
text := "%sforeground %sbold%s %sbackground%s\n"
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
}
```
![screenshot](https://gist.githubusercontent.com/shiena/a1bada24b525314a7d5e/raw/c763aa7cda6e4fefaccf831e2617adc40b6151c7/main.png)
## See also:
- https://github.com/daviddengcn/go-colortext
- https://github.com/adoxa/ansicon
- https://github.com/aslakhellesoy/wac
- https://github.com/wsxiaoys/terminal
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

View File

@ -0,0 +1,20 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// Package ansicolor provides color console in Windows as ANSICON.
package ansicolor
import "io"
// NewAnsiColorWriter creates and initializes a new ansiColorWriter
// using io.Writer w as its initial contents.
// In the console of Windows, which change the foreground and background
// colors of the text by the escape sequence.
// In the console of other systems, which writes to w all text.
func NewAnsiColorWriter(w io.Writer) io.Writer {
if _, ok := w.(*ansiColorWriter); !ok {
return &ansiColorWriter{w: w}
}
return w
}

View File

@ -0,0 +1,27 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
/*
The ansicolor command colors a console text by ANSI escape sequence like wac.
$ go get github.com/shiena/ansicolor/ansicolor
See also:
https://github.com/aslakhellesoy/wac
*/
package main
import (
"io"
"os"
"github.com/shiena/ansicolor"
)
func main() {
w := ansicolor.NewAnsiColorWriter(os.Stdout)
io.Copy(w, os.Stdin)
}

View File

@ -0,0 +1,17 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// +build !windows
package ansicolor
import "io"
type ansiColorWriter struct {
w io.Writer
}
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
return cw.w.Write(p)
}

View File

@ -0,0 +1,25 @@
package ansicolor_test
import (
"bytes"
"testing"
"github.com/shiena/ansicolor"
)
func TestNewAnsiColor1(t *testing.T) {
inner := bytes.NewBufferString("")
w := ansicolor.NewAnsiColorWriter(inner)
if w == inner {
t.Errorf("Get %#v, want %#v", w, inner)
}
}
func TestNewAnsiColor2(t *testing.T) {
inner := bytes.NewBufferString("")
w1 := ansicolor.NewAnsiColorWriter(inner)
w2 := ansicolor.NewAnsiColorWriter(w1)
if w1 != w2 {
t.Errorf("Get %#v, want %#v", w1, w2)
}
}

View File

@ -0,0 +1,351 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// +build windows
package ansicolor
import (
"bytes"
"io"
"strings"
"syscall"
"unsafe"
)
type csiState int
const (
outsideCsiCode csiState = iota
firstCsiCode
secondCsiCode
)
type ansiColorWriter struct {
w io.Writer
state csiState
paramBuf bytes.Buffer
}
const (
firstCsiChar byte = '\x1b'
secondeCsiChar byte = '['
separatorChar byte = ';'
sgrCode byte = 'm'
)
const (
foregroundBlue = uint16(0x0001)
foregroundGreen = uint16(0x0002)
foregroundRed = uint16(0x0004)
foregroundIntensity = uint16(0x0008)
backgroundBlue = uint16(0x0010)
backgroundGreen = uint16(0x0020)
backgroundRed = uint16(0x0040)
backgroundIntensity = uint16(0x0080)
underscore = uint16(0x8000)
foregroundMask = foregroundBlue | foregroundGreen | foregroundRed | foregroundIntensity
backgroundMask = backgroundBlue | backgroundGreen | backgroundRed | backgroundIntensity
)
const (
ansiReset = "0"
ansiIntensityOn = "1"
ansiIntensityOff = "21"
ansiUnderlineOn = "4"
ansiUnderlineOff = "24"
ansiBlinkOn = "5"
ansiBlinkOff = "25"
ansiForegroundBlack = "30"
ansiForegroundRed = "31"
ansiForegroundGreen = "32"
ansiForegroundYellow = "33"
ansiForegroundBlue = "34"
ansiForegroundMagenta = "35"
ansiForegroundCyan = "36"
ansiForegroundWhite = "37"
ansiForegroundDefault = "39"
ansiBackgroundBlack = "40"
ansiBackgroundRed = "41"
ansiBackgroundGreen = "42"
ansiBackgroundYellow = "43"
ansiBackgroundBlue = "44"
ansiBackgroundMagenta = "45"
ansiBackgroundCyan = "46"
ansiBackgroundWhite = "47"
ansiBackgroundDefault = "49"
ansiLightForegroundGray = "90"
ansiLightForegroundRed = "91"
ansiLightForegroundGreen = "92"
ansiLightForegroundYellow = "93"
ansiLightForegroundBlue = "94"
ansiLightForegroundMagenta = "95"
ansiLightForegroundCyan = "96"
ansiLightForegroundWhite = "97"
ansiLightBackgroundGray = "100"
ansiLightBackgroundRed = "101"
ansiLightBackgroundGreen = "102"
ansiLightBackgroundYellow = "103"
ansiLightBackgroundBlue = "104"
ansiLightBackgroundMagenta = "105"
ansiLightBackgroundCyan = "106"
ansiLightBackgroundWhite = "107"
)
type drawType int
const (
foreground drawType = iota
background
)
type winColor struct {
code uint16
drawType drawType
}
var colorMap = map[string]winColor{
ansiForegroundBlack: {0, foreground},
ansiForegroundRed: {foregroundRed, foreground},
ansiForegroundGreen: {foregroundGreen, foreground},
ansiForegroundYellow: {foregroundRed | foregroundGreen, foreground},
ansiForegroundBlue: {foregroundBlue, foreground},
ansiForegroundMagenta: {foregroundRed | foregroundBlue, foreground},
ansiForegroundCyan: {foregroundGreen | foregroundBlue, foreground},
ansiForegroundWhite: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
ansiForegroundDefault: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
ansiBackgroundBlack: {0, background},
ansiBackgroundRed: {backgroundRed, background},
ansiBackgroundGreen: {backgroundGreen, background},
ansiBackgroundYellow: {backgroundRed | backgroundGreen, background},
ansiBackgroundBlue: {backgroundBlue, background},
ansiBackgroundMagenta: {backgroundRed | backgroundBlue, background},
ansiBackgroundCyan: {backgroundGreen | backgroundBlue, background},
ansiBackgroundWhite: {backgroundRed | backgroundGreen | backgroundBlue, background},
ansiBackgroundDefault: {0, background},
ansiLightForegroundGray: {foregroundIntensity, foreground},
ansiLightForegroundRed: {foregroundIntensity | foregroundRed, foreground},
ansiLightForegroundGreen: {foregroundIntensity | foregroundGreen, foreground},
ansiLightForegroundYellow: {foregroundIntensity | foregroundRed | foregroundGreen, foreground},
ansiLightForegroundBlue: {foregroundIntensity | foregroundBlue, foreground},
ansiLightForegroundMagenta: {foregroundIntensity | foregroundRed | foregroundBlue, foreground},
ansiLightForegroundCyan: {foregroundIntensity | foregroundGreen | foregroundBlue, foreground},
ansiLightForegroundWhite: {foregroundIntensity | foregroundRed | foregroundGreen | foregroundBlue, foreground},
ansiLightBackgroundGray: {backgroundIntensity, background},
ansiLightBackgroundRed: {backgroundIntensity | backgroundRed, background},
ansiLightBackgroundGreen: {backgroundIntensity | backgroundGreen, background},
ansiLightBackgroundYellow: {backgroundIntensity | backgroundRed | backgroundGreen, background},
ansiLightBackgroundBlue: {backgroundIntensity | backgroundBlue, background},
ansiLightBackgroundMagenta: {backgroundIntensity | backgroundRed | backgroundBlue, background},
ansiLightBackgroundCyan: {backgroundIntensity | backgroundGreen | backgroundBlue, background},
ansiLightBackgroundWhite: {backgroundIntensity | backgroundRed | backgroundGreen | backgroundBlue, background},
}
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
defaultAttr *textAttributes
)
func init() {
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
if screenInfo != nil {
colorMap[ansiForegroundDefault] = winColor{
screenInfo.WAttributes & (foregroundRed | foregroundGreen | foregroundBlue),
foreground,
}
colorMap[ansiBackgroundDefault] = winColor{
screenInfo.WAttributes & (backgroundRed | backgroundGreen | backgroundBlue),
background,
}
defaultAttr = convertTextAttr(screenInfo.WAttributes)
}
}
type coord struct {
X, Y int16
}
type smallRect struct {
Left, Top, Right, Bottom int16
}
type consoleScreenBufferInfo struct {
DwSize coord
DwCursorPosition coord
WAttributes uint16
SrWindow smallRect
DwMaximumWindowSize coord
}
func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
var csbi consoleScreenBufferInfo
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
hConsoleOutput,
uintptr(unsafe.Pointer(&csbi)))
if ret == 0 {
return nil
}
return &csbi
}
func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
ret, _, _ := procSetConsoleTextAttribute.Call(
hConsoleOutput,
uintptr(wAttributes))
return ret != 0
}
type textAttributes struct {
foregroundColor uint16
backgroundColor uint16
foregroundIntensity uint16
backgroundIntensity uint16
underscore uint16
otherAttributes uint16
}
func convertTextAttr(winAttr uint16) *textAttributes {
fgColor := winAttr & (foregroundRed | foregroundGreen | foregroundBlue)
bgColor := winAttr & (backgroundRed | backgroundGreen | backgroundBlue)
fgIntensity := winAttr & foregroundIntensity
bgIntensity := winAttr & backgroundIntensity
underline := winAttr & underscore
otherAttributes := winAttr &^ (foregroundMask | backgroundMask | underscore)
return &textAttributes{fgColor, bgColor, fgIntensity, bgIntensity, underline, otherAttributes}
}
func convertWinAttr(textAttr *textAttributes) uint16 {
var winAttr uint16 = 0
winAttr |= textAttr.foregroundColor
winAttr |= textAttr.backgroundColor
winAttr |= textAttr.foregroundIntensity
winAttr |= textAttr.backgroundIntensity
winAttr |= textAttr.underscore
winAttr |= textAttr.otherAttributes
return winAttr
}
func changeColor(param []byte) {
if defaultAttr == nil {
return
}
screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
if screenInfo == nil {
return
}
winAttr := convertTextAttr(screenInfo.WAttributes)
strParam := string(param)
if len(strParam) <= 0 {
strParam = "0"
}
csiParam := strings.Split(strParam, string(separatorChar))
for _, p := range csiParam {
c, ok := colorMap[p]
switch {
case !ok:
switch p {
case ansiReset:
winAttr.foregroundColor = defaultAttr.foregroundColor
winAttr.backgroundColor = defaultAttr.backgroundColor
winAttr.foregroundIntensity = defaultAttr.foregroundIntensity
winAttr.backgroundIntensity = defaultAttr.backgroundIntensity
winAttr.underscore = 0
winAttr.otherAttributes = 0
case ansiIntensityOn:
winAttr.foregroundIntensity = foregroundIntensity
case ansiIntensityOff:
winAttr.foregroundIntensity = 0
case ansiUnderlineOn:
winAttr.underscore = underscore
case ansiUnderlineOff:
winAttr.underscore = 0
case ansiBlinkOn:
winAttr.backgroundIntensity = backgroundIntensity
case ansiBlinkOff:
winAttr.backgroundIntensity = 0
default:
// unknown code
}
case c.drawType == foreground:
winAttr.foregroundColor = c.code
case c.drawType == background:
winAttr.backgroundColor = c.code
}
}
winTextAttribute := convertWinAttr(winAttr)
setConsoleTextAttribute(uintptr(syscall.Stdout), winTextAttribute)
}
func parseEscapeSequence(command byte, param []byte) {
switch command {
case sgrCode:
changeColor(param)
}
}
func isParameterChar(b byte) bool {
return ('0' <= b && b <= '9') || b == separatorChar
}
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
r, nw, nc, first, last := 0, 0, 0, 0, 0
var err error
for i, ch := range p {
switch cw.state {
case outsideCsiCode:
if ch == firstCsiChar {
nc++
cw.state = firstCsiCode
}
case firstCsiCode:
switch ch {
case firstCsiChar:
nc++
break
case secondeCsiChar:
nc++
cw.state = secondCsiCode
last = i - 1
default:
cw.state = outsideCsiCode
}
case secondCsiCode:
nc++
if isParameterChar(ch) {
cw.paramBuf.WriteByte(ch)
} else {
nw, err = cw.w.Write(p[first:last])
r += nw
if err != nil {
return r, err
}
first = i + 1
param := cw.paramBuf.Bytes()
cw.paramBuf.Reset()
parseEscapeSequence(ch, param)
cw.state = outsideCsiCode
}
default:
cw.state = outsideCsiCode
}
}
if cw.state == outsideCsiCode {
nw, err = cw.w.Write(p[first:len(p)])
}
return r + nw + nc, err
}

View File

@ -0,0 +1,236 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// +build windows
package ansicolor_test
import (
"bytes"
"fmt"
"syscall"
"testing"
"github.com/shiena/ansicolor"
. "github.com/shiena/ansicolor"
)
func TestWritePlanText(t *testing.T) {
inner := bytes.NewBufferString("")
w := ansicolor.NewAnsiColorWriter(inner)
expected := "plain text"
fmt.Fprintf(w, expected)
actual := inner.String()
if actual != expected {
t.Errorf("Get %s, want %s", actual, expected)
}
}
func TestWriteParseText(t *testing.T) {
inner := bytes.NewBufferString("")
w := ansicolor.NewAnsiColorWriter(inner)
inputTail := "\x1b[0mtail text"
expectedTail := "tail text"
fmt.Fprintf(w, inputTail)
actualTail := inner.String()
inner.Reset()
if actualTail != expectedTail {
t.Errorf("Get %s, want %s", actualTail, expectedTail)
}
inputHead := "head text\x1b[0m"
expectedHead := "head text"
fmt.Fprintf(w, inputHead)
actualHead := inner.String()
inner.Reset()
if actualHead != expectedHead {
t.Errorf("Get %s, want %s", actualHead, expectedHead)
}
inputBothEnds := "both ends \x1b[0m text"
expectedBothEnds := "both ends text"
fmt.Fprintf(w, inputBothEnds)
actualBothEnds := inner.String()
inner.Reset()
if actualBothEnds != expectedBothEnds {
t.Errorf("Get %s, want %s", actualBothEnds, expectedBothEnds)
}
inputManyEsc := "\x1b\x1b\x1b\x1b[0m many esc"
expectedManyEsc := "\x1b\x1b\x1b many esc"
fmt.Fprintf(w, inputManyEsc)
actualManyEsc := inner.String()
inner.Reset()
if actualManyEsc != expectedManyEsc {
t.Errorf("Get %s, want %s", actualManyEsc, expectedManyEsc)
}
expectedSplit := "split text"
for _, ch := range "split \x1b[0m text" {
fmt.Fprintf(w, string(ch))
}
actualSplit := inner.String()
inner.Reset()
if actualSplit != expectedSplit {
t.Errorf("Get %s, want %s", actualSplit, expectedSplit)
}
}
type screenNotFoundError struct {
error
}
func writeAnsiColor(expectedText, colorCode string) (actualText string, actualAttributes uint16, err error) {
inner := bytes.NewBufferString("")
w := ansicolor.NewAnsiColorWriter(inner)
fmt.Fprintf(w, "\x1b[%sm%s", colorCode, expectedText)
actualText = inner.String()
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
if screenInfo != nil {
actualAttributes = screenInfo.WAttributes
} else {
err = &screenNotFoundError{}
}
return
}
type testParam struct {
text string
attributes uint16
ansiColor string
}
func TestWriteAnsiColorText(t *testing.T) {
screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
if screenInfo == nil {
t.Fatal("Could not get ConsoleScreenBufferInfo")
}
defer ChangeColor(screenInfo.WAttributes)
defaultFgColor := screenInfo.WAttributes & uint16(0x0007)
defaultBgColor := screenInfo.WAttributes & uint16(0x0070)
defaultFgIntensity := screenInfo.WAttributes & uint16(0x0008)
defaultBgIntensity := screenInfo.WAttributes & uint16(0x0080)
fgParam := []testParam{
{"foreground black ", uint16(0x0000 | 0x0000), "30"},
{"foreground red ", uint16(0x0004 | 0x0000), "31"},
{"foreground green ", uint16(0x0002 | 0x0000), "32"},
{"foreground yellow ", uint16(0x0006 | 0x0000), "33"},
{"foreground blue ", uint16(0x0001 | 0x0000), "34"},
{"foreground magenta", uint16(0x0005 | 0x0000), "35"},
{"foreground cyan ", uint16(0x0003 | 0x0000), "36"},
{"foreground white ", uint16(0x0007 | 0x0000), "37"},
{"foreground default", defaultFgColor | 0x0000, "39"},
{"foreground light gray ", uint16(0x0000 | 0x0008 | 0x0000), "90"},
{"foreground light red ", uint16(0x0004 | 0x0008 | 0x0000), "91"},
{"foreground light green ", uint16(0x0002 | 0x0008 | 0x0000), "92"},
{"foreground light yellow ", uint16(0x0006 | 0x0008 | 0x0000), "93"},
{"foreground light blue ", uint16(0x0001 | 0x0008 | 0x0000), "94"},
{"foreground light magenta", uint16(0x0005 | 0x0008 | 0x0000), "95"},
{"foreground light cyan ", uint16(0x0003 | 0x0008 | 0x0000), "96"},
{"foreground light white ", uint16(0x0007 | 0x0008 | 0x0000), "97"},
}
bgParam := []testParam{
{"background black ", uint16(0x0007 | 0x0000), "40"},
{"background red ", uint16(0x0007 | 0x0040), "41"},
{"background green ", uint16(0x0007 | 0x0020), "42"},
{"background yellow ", uint16(0x0007 | 0x0060), "43"},
{"background blue ", uint16(0x0007 | 0x0010), "44"},
{"background magenta", uint16(0x0007 | 0x0050), "45"},
{"background cyan ", uint16(0x0007 | 0x0030), "46"},
{"background white ", uint16(0x0007 | 0x0070), "47"},
{"background default", uint16(0x0007) | defaultBgColor, "49"},
{"background light gray ", uint16(0x0007 | 0x0000 | 0x0080), "100"},
{"background light red ", uint16(0x0007 | 0x0040 | 0x0080), "101"},
{"background light green ", uint16(0x0007 | 0x0020 | 0x0080), "102"},
{"background light yellow ", uint16(0x0007 | 0x0060 | 0x0080), "103"},
{"background light blue ", uint16(0x0007 | 0x0010 | 0x0080), "104"},
{"background light magenta", uint16(0x0007 | 0x0050 | 0x0080), "105"},
{"background light cyan ", uint16(0x0007 | 0x0030 | 0x0080), "106"},
{"background light white ", uint16(0x0007 | 0x0070 | 0x0080), "107"},
}
resetParam := []testParam{
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, "0"},
{"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, ""},
}
boldParam := []testParam{
{"bold on", uint16(0x0007 | 0x0008), "1"},
{"bold off", uint16(0x0007), "21"},
}
underscoreParam := []testParam{
{"underscore on", uint16(0x0007 | 0x8000), "4"},
{"underscore off", uint16(0x0007), "24"},
}
blinkParam := []testParam{
{"blink on", uint16(0x0007 | 0x0080), "5"},
{"blink off", uint16(0x0007), "25"},
}
mixedParam := []testParam{
{"both black, bold, underline, blink", uint16(0x0000 | 0x0000 | 0x0008 | 0x8000 | 0x0080), "30;40;1;4;5"},
{"both red, bold, underline, blink", uint16(0x0004 | 0x0040 | 0x0008 | 0x8000 | 0x0080), "31;41;1;4;5"},
{"both green, bold, underline, blink", uint16(0x0002 | 0x0020 | 0x0008 | 0x8000 | 0x0080), "32;42;1;4;5"},
{"both yellow, bold, underline, blink", uint16(0x0006 | 0x0060 | 0x0008 | 0x8000 | 0x0080), "33;43;1;4;5"},
{"both blue, bold, underline, blink", uint16(0x0001 | 0x0010 | 0x0008 | 0x8000 | 0x0080), "34;44;1;4;5"},
{"both magenta, bold, underline, blink", uint16(0x0005 | 0x0050 | 0x0008 | 0x8000 | 0x0080), "35;45;1;4;5"},
{"both cyan, bold, underline, blink", uint16(0x0003 | 0x0030 | 0x0008 | 0x8000 | 0x0080), "36;46;1;4;5"},
{"both white, bold, underline, blink", uint16(0x0007 | 0x0070 | 0x0008 | 0x8000 | 0x0080), "37;47;1;4;5"},
{"both default, bold, underline, blink", uint16(defaultFgColor | defaultBgColor | 0x0008 | 0x8000 | 0x0080), "39;49;1;4;5"},
}
assertTextAttribute := func(expectedText string, expectedAttributes uint16, ansiColor string) {
actualText, actualAttributes, err := writeAnsiColor(expectedText, ansiColor)
if actualText != expectedText {
t.Errorf("Get %s, want %s", actualText, expectedText)
}
if err != nil {
t.Fatal("Could not get ConsoleScreenBufferInfo")
}
if actualAttributes != expectedAttributes {
t.Errorf("Text: %s, Get 0x%04x, want 0x%04x", expectedText, actualAttributes, expectedAttributes)
}
}
for _, v := range fgParam {
ResetColor()
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
for _, v := range bgParam {
ChangeColor(uint16(0x0070 | 0x0007))
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
for _, v := range resetParam {
ChangeColor(uint16(0x0000 | 0x0070 | 0x0008))
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
ResetColor()
for _, v := range boldParam {
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
ResetColor()
for _, v := range underscoreParam {
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
ResetColor()
for _, v := range blinkParam {
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
for _, v := range mixedParam {
ResetColor()
assertTextAttribute(v.text, v.attributes, v.ansiColor)
}
}

View File

@ -0,0 +1,24 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package ansicolor_test
import (
"fmt"
"os"
"github.com/shiena/ansicolor"
)
func ExampleNewAnsiColorWriter() {
w := ansicolor.NewAnsiColorWriter(os.Stdout)
text := "%sforeground %sbold%s %sbackground%s\n"
fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
}

View File

@ -0,0 +1,19 @@
// Copyright 2014 shiena Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
// +build windows
package ansicolor
import "syscall"
var GetConsoleScreenBufferInfo = getConsoleScreenBufferInfo
func ChangeColor(color uint16) {
setConsoleTextAttribute(uintptr(syscall.Stdout), color)
}
func ResetColor() {
ChangeColor(uint16(0x0007))
}

View File

@ -1,19 +1,10 @@
// CookieJar - A contestant's algorithm toolbox
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
//
// CookieJar is dual licensed: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
// and conditions contained in a signed written agreement between you and the
// author(s).
// CookieJar is dual licensed: use of this source code is governed by a BSD
// license that can be found in the LICENSE file. Alternatively, the CookieJar
// toolbox may be used in accordance with the terms and conditions contained
// in a signed written agreement between you and the author(s).
// Package prque implements a priority queue data structure supporting arbitrary
// value types and float priorities.

View File

@ -1,19 +1,10 @@
// CookieJar - A contestant's algorithm toolbox
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
//
// CookieJar is dual licensed: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
// and conditions contained in a signed written agreement between you and the
// author(s).
// CookieJar is dual licensed: use of this source code is governed by a BSD
// license that can be found in the LICENSE file. Alternatively, the CookieJar
// toolbox may be used in accordance with the terms and conditions contained
// in a signed written agreement between you and the author(s).
package prque

View File

@ -1,19 +1,10 @@
// CookieJar - A contestant's algorithm toolbox
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
//
// CookieJar is dual licensed: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
// and conditions contained in a signed written agreement between you and the
// author(s).
// CookieJar is dual licensed: use of this source code is governed by a BSD
// license that can be found in the LICENSE file. Alternatively, the CookieJar
// toolbox may be used in accordance with the terms and conditions contained
// in a signed written agreement between you and the author(s).
package prque

View File

@ -1,19 +1,10 @@
// CookieJar - A contestant's algorithm toolbox
// Copyright (c) 2013 Peter Szilagyi. All rights reserved.
//
// CookieJar is dual licensed: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// The toolbox is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// Alternatively, the CookieJar toolbox may be used in accordance with the terms
// and conditions contained in a signed written agreement between you and the
// author(s).
// CookieJar is dual licensed: use of this source code is governed by a BSD
// license that can be found in the LICENSE file. Alternatively, the CookieJar
// toolbox may be used in accordance with the terms and conditions contained
// in a signed written agreement between you and the author(s).
package prque

16
LICENSE
View File

@ -1,16 +0,0 @@
Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA

View File

@ -2,7 +2,7 @@
# with Go source code. If you know what GOPATH is then you probably
# don't need to bother with make.
.PHONY: geth mist all test travis-test-with-coverage clean
.PHONY: geth evm mist all test travis-test-with-coverage clean
GOBIN = build/bin
geth:
@ -10,6 +10,10 @@ geth:
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."
evm:
build/env.sh $(GOROOT)/bin/go install -v $(shell build/ldflags.sh) ./cmd/evm
@echo "Done building."
@echo "Run \"$(GOBIN)/evm to start the evm."
mist:
build/env.sh go install -v $(shell build/ldflags.sh) ./cmd/mist
@echo "Done building."

View File

@ -1,19 +1,18 @@
## Ethereum Go
Ethereum Go Client © 2014 Jeffrey Wilcke.
Official golang implementation of the Ethereum protocol
| Linux | OSX | ARM | Windows | Tests
----------|---------|-----|-----|---------|------
develop | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=ARM%20Go%20develop%20branch)](https://build.ethdev.com/builders/ARM%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Windows%20Go%20develop%20branch)](https://build.ethdev.com/builders/Windows%20Go%20develop%20branch/builds/-1) | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) [![Coverage Status](https://coveralls.io/repos/ethereum/go-ethereum/badge.svg?branch=develop)](https://coveralls.io/r/ethereum/go-ethereum?branch=develop)
master | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=ARM%20Go%20master%20branch)](https://build.ethdev.com/builders/ARM%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Windows%20Go%20master%20branch)](https://build.ethdev.com/builders/Windows%20Go%20master%20branch/builds/-1) | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) [![Coverage Status](https://coveralls.io/repos/ethereum/go-ethereum/badge.svg?branch=master)](https://coveralls.io/r/ethereum/go-ethereum?branch=master)
develop | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=ARM%20Go%20develop%20branch)](https://build.ethdev.com/builders/ARM%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Windows%20Go%20develop%20branch)](https://build.ethdev.com/builders/Windows%20Go%20develop%20branch/builds/-1) | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) [![codecov.io](http://codecov.io/github/ethereum/go-ethereum/coverage.svg?branch=develop)](http://codecov.io/github/ethereum/go-ethereum?branch=develop)
master | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=ARM%20Go%20master%20branch)](https://build.ethdev.com/builders/ARM%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Windows%20Go%20master%20branch)](https://build.ethdev.com/builders/Windows%20Go%20master%20branch/builds/-1) | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) [![codecov.io](http://codecov.io/github/ethereum/go-ethereum/coverage.svg?branch=master)](http://codecov.io/github/ethereum/go-ethereum?branch=master)
[![Bugs](https://badge.waffle.io/ethereum/go-ethereum.png?label=bug&title=Bugs)](https://waffle.io/ethereum/go-ethereum)
[![Stories in Ready](https://badge.waffle.io/ethereum/go-ethereum.png?label=ready&title=Ready)](https://waffle.io/ethereum/go-ethereum)
[![Stories in Progress](https://badge.waffle.io/ethereum/go-ethereum.svg?label=in%20progress&title=In Progress)](http://waffle.io/ethereum/go-ethereum)
[![API Reference](
https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667
)](https://godoc.org/github.com/ethereum/go-ethereum)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Automated development builds
======================
## Automated development builds
The following builds are build automatically by our build servers after each push to the [develop](https://github.com/ethereum/go-ethereum/tree/develop) branch.
@ -25,8 +24,7 @@ The following builds are build automatically by our build servers after each pus
* [Windows 64-bit](https://build.ethdev.com/builds/Windows%20Go%20develop%20branch/Geth-Win64-latest.zip)
* [ARM](https://build.ethdev.com/builds/ARM%20Go%20develop%20branch/geth-ARM-latest.tar.bz2)
Building the source
===================
## Building the source
For prerequisites and detailed build instructions please read the
[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum)
@ -38,34 +36,31 @@ Once the dependencies are installed, run
make geth
Executables
===========
## Executables
Go Ethereum comes with several wrappers/executables found in
[the `cmd` directory](https://github.com/ethereum/go-ethereum/tree/develop/cmd):
* `geth` Ethereum CLI (ethereum command line interface client)
* `bootnode` runs a bootstrap node for the Discovery Protocol
* `ethtest` test tool which runs with the [tests](https://github.com/ethereum/tests) suite:
`/path/to/test.json > ethtest --test BlockTests --stdin`.
* `evm` is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas
10000 -price 0 -dump`. See `-h` for a detailed description.
* `disasm` disassembles EVM code: `echo "6001" | disasm`
* `rlpdump` prints RLP structures
Command | |
----------|---------|
`geth` | Ethereum CLI (ethereum command line interface client) |
`bootnode` | runs a bootstrap node for the Discovery Protocol |
`ethtest` | test tool which runs with the [tests](https://github.com/ethereum/tests) suite: `/path/to/test.json > ethtest --test BlockTests --stdin`.
`evm` | is a generic Ethereum Virtual Machine: `evm -code 60ff60ff -gas 10000 -price 0 -dump`. See `-h` for a detailed description. |
`disasm` | disassembles EVM code: `echo "6001" | disasm` |
`rlpdump` | prints RLP structures |
Command line options
====================
## Command line options
`geth` can be configured via command line options, environment variables and config files.
To get the options available:
geth --help
geth help
For further details on options, see the [wiki](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)
Contribution
============
## Contribution
If you'd like to contribute to go-ethereum please fork, fix, commit and
send a pull request. Commits who do not comply with the coding standards

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package abi
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package abi
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package abi implements the Ethereum ABI (Application Binary
// Interface).
//

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package abi
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package abi
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package abi
import (

View File

@ -1,41 +1,32 @@
/*
This file is part of go-ethereum
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors
* Gustav Simonsson <gustav.simonsson@gmail.com>
* @date 2015
*
*/
/*
This abstracts part of a user's interaction with an account she controls.
It's not an abstraction of core Ethereum accounts data type / logic -
for that see the core processing code of blocks / txs.
Currently this is pretty much a passthrough to the KeyStore2 interface,
and accounts persistence is derived from stored keys' addresses
*/
// Package implements a private key management facility.
//
// This abstracts part of a user's interaction with an account she controls.
package accounts
// Currently this is pretty much a passthrough to the KeyStore interface,
// and accounts persistence is derived from stored keys' addresses
import (
"crypto/ecdsa"
crand "crypto/rand"
"errors"
"fmt"
"os"
"sync"
"time"
@ -49,17 +40,12 @@ var (
ErrNoKeys = errors.New("no keys in store")
)
const (
// Default unlock duration (in seconds) when an account is unlocked from the console
DefaultAccountUnlockDuration = 300
)
type Account struct {
Address common.Address
}
type Manager struct {
keyStore crypto.KeyStore2
keyStore crypto.KeyStore
unlocked map[common.Address]*unlocked
mutex sync.RWMutex
}
@ -69,7 +55,7 @@ type unlocked struct {
abort chan struct{}
}
func NewManager(keyStore crypto.KeyStore2) *Manager {
func NewManager(keyStore crypto.KeyStore) *Manager {
return &Manager{
keyStore: keyStore,
unlocked: make(map[common.Address]*unlocked),
@ -86,27 +72,14 @@ func (am *Manager) HasAccount(addr common.Address) bool {
return false
}
func (am *Manager) Primary() (addr common.Address, err error) {
addrs, err := am.keyStore.GetKeyAddresses()
if os.IsNotExist(err) {
return common.Address{}, ErrNoKeys
} else if err != nil {
return common.Address{}, err
}
if len(addrs) == 0 {
return common.Address{}, ErrNoKeys
}
return addrs[0], nil
}
func (am *Manager) DeleteAccount(address common.Address, auth string) error {
return am.keyStore.DeleteKey(address, auth)
}
func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error) {
am.mutex.RLock()
defer am.mutex.RUnlock()
unlockedKey, found := am.unlocked[a.Address]
am.mutex.RUnlock()
if !found {
return nil, ErrLocked
}
@ -114,72 +87,44 @@ func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error)
return signature, err
}
// TimedUnlock unlocks the account with the given address.
// When timeout has passed, the account will be locked again.
// Unlock unlocks the given account indefinitely.
func (am *Manager) Unlock(addr common.Address, keyAuth string) error {
return am.TimedUnlock(addr, keyAuth, 0)
}
// TimedUnlock unlocks the account with the given address. The account
// stays unlocked for the duration of timeout. A timeout of 0 unlocks the account
// until the program exits.
//
// If the accout is already unlocked, TimedUnlock extends or shortens
// the active unlock timeout.
func (am *Manager) TimedUnlock(addr common.Address, keyAuth string, timeout time.Duration) error {
key, err := am.keyStore.GetKey(addr, keyAuth)
if err != nil {
return err
}
u := am.addUnlocked(addr, key)
go am.dropLater(addr, u, timeout)
return nil
}
// Unlock unlocks the account with the given address. The account
// stays unlocked until the program exits or until a TimedUnlock
// timeout (started after the call to Unlock) expires.
func (am *Manager) Unlock(addr common.Address, keyAuth string) error {
key, err := am.keyStore.GetKey(addr, keyAuth)
if err != nil {
return err
}
am.addUnlocked(addr, key)
return nil
}
func (am *Manager) NewAccount(auth string) (Account, error) {
key, err := am.keyStore.GenerateNewKey(crand.Reader, auth)
if err != nil {
return Account{}, err
}
return Account{Address: key.Address}, nil
}
func (am *Manager) Accounts() ([]Account, error) {
addresses, err := am.keyStore.GetKeyAddresses()
if os.IsNotExist(err) {
return nil, ErrNoKeys
} else if err != nil {
return nil, err
}
accounts := make([]Account, len(addresses))
for i, addr := range addresses {
accounts[i] = Account{
Address: addr,
}
}
return accounts, err
}
func (am *Manager) addUnlocked(addr common.Address, key *crypto.Key) *unlocked {
u := &unlocked{Key: key, abort: make(chan struct{})}
var u *unlocked
am.mutex.Lock()
prev, found := am.unlocked[addr]
defer am.mutex.Unlock()
var found bool
u, found = am.unlocked[addr]
if found {
// terminate dropLater for this key to avoid unexpected drops.
close(prev.abort)
// the key is zeroed here instead of in dropLater because
// there might not actually be a dropLater running for this
// key, i.e. when Unlock was used.
zeroKey(prev.PrivateKey)
if u.abort != nil {
close(u.abort)
}
}
if timeout > 0 {
u = &unlocked{Key: key, abort: make(chan struct{})}
go am.expire(addr, u, timeout)
} else {
u = &unlocked{Key: key}
}
am.unlocked[addr] = u
am.mutex.Unlock()
return u
return nil
}
func (am *Manager) dropLater(addr common.Address, u *unlocked, timeout time.Duration) {
func (am *Manager) expire(addr common.Address, u *unlocked, timeout time.Duration) {
t := time.NewTimer(timeout)
defer t.Stop()
select {
@ -199,6 +144,44 @@ func (am *Manager) dropLater(addr common.Address, u *unlocked, timeout time.Dura
}
}
func (am *Manager) NewAccount(auth string) (Account, error) {
key, err := am.keyStore.GenerateNewKey(crand.Reader, auth)
if err != nil {
return Account{}, err
}
return Account{Address: key.Address}, nil
}
func (am *Manager) AddressByIndex(index int) (addr string, err error) {
var addrs []common.Address
addrs, err = am.keyStore.GetKeyAddresses()
if err != nil {
return
}
if index < 0 || index >= len(addrs) {
err = fmt.Errorf("index out of range: %d (should be 0-%d)", index, len(addrs)-1)
} else {
addr = addrs[index].Hex()
}
return
}
func (am *Manager) Accounts() ([]Account, error) {
addresses, err := am.keyStore.GetKeyAddresses()
if os.IsNotExist(err) {
return nil, ErrNoKeys
} else if err != nil {
return nil, err
}
accounts := make([]Account, len(addresses))
for i, addr := range addresses {
accounts[i] = Account{
Address: addr,
}
}
return accounts, err
}
// zeroKey zeroes a private key in memory.
func zeroKey(k *ecdsa.PrivateKey) {
b := k.D.Bits()
@ -229,14 +212,24 @@ func (am *Manager) Import(path string, keyAuth string) (Account, error) {
return Account{Address: key.Address}, nil
}
func (am *Manager) Update(addr common.Address, authFrom, authTo string) (err error) {
var key *crypto.Key
key, err = am.keyStore.GetKey(addr, authFrom)
if err == nil {
err = am.keyStore.StoreKey(key, authTo)
if err == nil {
am.keyStore.Cleanup(addr)
}
}
return
}
func (am *Manager) ImportPreSaleKey(keyJSON []byte, password string) (acc Account, err error) {
var key *crypto.Key
key, err = crypto.ImportPreSaleKey(am.keyStore, keyJSON, password)
if err != nil {
return
}
if err = am.keyStore.StoreKey(key, password); err != nil {
return
}
return Account{Address: key.Address}, nil
}

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package accounts
import (
@ -7,9 +23,10 @@ import (
"time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/randentropy"
)
var testSigData = make([]byte, 32)
func TestSign(t *testing.T) {
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
defer os.RemoveAll(dir)
@ -17,26 +34,24 @@ func TestSign(t *testing.T) {
am := NewManager(ks)
pass := "" // not used but required by API
a1, err := am.NewAccount(pass)
toSign := randentropy.GetEntropyCSPRNG(32)
am.Unlock(a1.Address, "")
_, err = am.Sign(a1, toSign)
_, err = am.Sign(a1, testSigData)
if err != nil {
t.Fatal(err)
}
}
func TestTimedUnlock(t *testing.T) {
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePassphrase)
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
defer os.RemoveAll(dir)
am := NewManager(ks)
pass := "foo"
a1, err := am.NewAccount(pass)
toSign := randentropy.GetEntropyCSPRNG(32)
// Signing without passphrase fails because account is locked
_, err = am.Sign(a1, toSign)
_, err = am.Sign(a1, testSigData)
if err != ErrLocked {
t.Fatal("Signing should've failed with ErrLocked before unlocking, got ", err)
}
@ -47,20 +62,86 @@ func TestTimedUnlock(t *testing.T) {
}
// Signing without passphrase works because account is temp unlocked
_, err = am.Sign(a1, toSign)
_, err = am.Sign(a1, testSigData)
if err != nil {
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
}
// Signing fails again after automatic locking
time.Sleep(150 * time.Millisecond)
_, err = am.Sign(a1, toSign)
_, err = am.Sign(a1, testSigData)
if err != ErrLocked {
t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err)
}
}
func tmpKeyStore(t *testing.T, new func(string) crypto.KeyStore2) (string, crypto.KeyStore2) {
func TestOverrideUnlock(t *testing.T) {
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
defer os.RemoveAll(dir)
am := NewManager(ks)
pass := "foo"
a1, err := am.NewAccount(pass)
// Unlock indefinitely
if err = am.Unlock(a1.Address, pass); err != nil {
t.Fatal(err)
}
// Signing without passphrase works because account is temp unlocked
_, err = am.Sign(a1, testSigData)
if err != nil {
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
}
// reset unlock to a shorter period, invalidates the previous unlock
if err = am.TimedUnlock(a1.Address, pass, 100*time.Millisecond); err != nil {
t.Fatal(err)
}
// Signing without passphrase still works because account is temp unlocked
_, err = am.Sign(a1, testSigData)
if err != nil {
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
}
// Signing fails again after automatic locking
time.Sleep(150 * time.Millisecond)
_, err = am.Sign(a1, testSigData)
if err != ErrLocked {
t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err)
}
}
// This test should fail under -race if signing races the expiration goroutine.
func TestSignRace(t *testing.T) {
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
defer os.RemoveAll(dir)
// Create a test account.
am := NewManager(ks)
a1, err := am.NewAccount("")
if err != nil {
t.Fatal("could not create the test account", err)
}
if err := am.TimedUnlock(a1.Address, "", 15*time.Millisecond); err != nil {
t.Fatalf("could not unlock the test account", err)
}
end := time.Now().Add(500 * time.Millisecond)
for time.Now().Before(end) {
if _, err := am.Sign(a1, testSigData); err == ErrLocked {
return
} else if err != nil {
t.Errorf("Sign error: %v", err)
return
}
time.Sleep(1 * time.Millisecond)
}
t.Errorf("Account did not lock within the timeout")
}
func tmpKeyStore(t *testing.T, new func(string) crypto.KeyStore) (string, crypto.KeyStore) {
d, err := ioutil.TempDir("", "eth-keystore-test")
if err != nil {
t.Fatal(err)

View File

@ -1,26 +1,15 @@
#!/bin/bash
# This script runs all package tests and merges the resulting coverage
# profiles. Coverage is accounted per package under test.
#!/usr/bin/env bash
set -e
echo "" > coverage.txt
if [ ! -f "build/env.sh" ]; then
echo "$0 must be run from the root of the repository."
exit 2
fi
echo "mode: count" > profile.cov
for pkg in $(go list ./...); do
# drop the namespace prefix.
dir=${pkg##github.com/ethereum/go-ethereum/}
if [[ $dir != "tests" ]]; then
go test -covermode=count -coverprofile=$dir/profile.tmp $pkg
fi
if [[ -f $dir/profile.tmp ]]; then
tail -n +2 $dir/profile.tmp >> profile.cov
rm $dir/profile.tmp
for d in $(find ./* -maxdepth 10 -type d -not -path "./build" -not -path "./Godeps/*" ); do
if ls $d/*.go &> /dev/null; then
go test -coverprofile=profile.out -covermode=atomic $d
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
echo '<<<<<< EOF' >> coverage.txt
rm profile.out
fi
fi
done

356
build/update-license.go Normal file
View File

@ -0,0 +1,356 @@
// +build none
/*
This command generates GPL license headers on top of all source files.
You can run it once per month, before cutting a release or just
whenever you feel like it.
go run update-license.go
All authors (people who have contributed code) are listed in the
AUTHORS file. The author names are mapped and deduplicated using the
.mailmap file. You can use .mailmap to set the canonical name and
address for each author. See git-shortlog(1) for an explanation of the
.mailmap format.
Please review the resulting diff to check whether the correct
copyright assignments are performed.
*/
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"text/template"
"time"
)
var (
// only files with these extensions will be considered
extensions = []string{".go", ".js", ".qml"}
// paths with any of these prefixes will be skipped
skipPrefixes = []string{
// boring stuff
"Godeps/", "tests/files/", "build/",
// don't relicense vendored packages
"crypto/sha3/", "crypto/ecies/", "logger/glog/",
"crypto/curve.go",
}
// paths with this prefix are licensed as GPL. all other files are LGPL.
gplPrefixes = []string{"cmd/"}
// this regexp must match the entire license comment at the
// beginning of each file.
licenseCommentRE = regexp.MustCompile(`^//\s*(Copyright|This file is part of).*?\n(?://.*?\n)*\n*`)
// this text appears at the start of AUTHORS
authorsFileHeader = "# This is the official list of go-ethereum authors for copyright purposes.\n\n"
)
// this template generates the license comment.
// its input is an info structure.
var licenseT = template.Must(template.New("").Parse(`
// Copyright {{.Year}} The go-ethereum Authors
// This file is part of {{.Whole false}}.
//
// {{.Whole true}} is free software: you can redistribute it and/or modify
// it under the terms of the GNU {{.License}} as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// {{.Whole true}} is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU {{.License}} for more details.
//
// You should have received a copy of the GNU {{.License}}
// along with {{.Whole false}}. If not, see <http://www.gnu.org/licenses/>.
`[1:]))
type info struct {
file string
Year int64
}
func (i info) License() string {
if i.gpl() {
return "General Public License"
}
return "Lesser General Public License"
}
func (i info) ShortLicense() string {
if i.gpl() {
return "GPL"
}
return "LGPL"
}
func (i info) Whole(startOfSentence bool) string {
if i.gpl() {
return "go-ethereum"
}
if startOfSentence {
return "The go-ethereum library"
}
return "the go-ethereum library"
}
func (i info) gpl() bool {
for _, p := range gplPrefixes {
if strings.HasPrefix(i.file, p) {
return true
}
}
return false
}
func main() {
var (
files = getFiles()
filec = make(chan string)
infoc = make(chan *info, 20)
wg sync.WaitGroup
)
writeAuthors(files)
go func() {
for _, f := range files {
filec <- f
}
close(filec)
}()
for i := runtime.NumCPU(); i >= 0; i-- {
// getting file info is slow and needs to be parallel.
// it traverses git history for each file.
wg.Add(1)
go getInfo(filec, infoc, &wg)
}
go func() {
wg.Wait()
close(infoc)
}()
writeLicenses(infoc)
}
func getFiles() []string {
cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD")
var files []string
err := doLines(cmd, func(line string) {
for _, p := range skipPrefixes {
if strings.HasPrefix(line, p) {
return
}
}
ext := filepath.Ext(line)
for _, wantExt := range extensions {
if ext == wantExt {
goto keep
}
}
return
keep:
files = append(files, line)
})
if err != nil {
log.Fatalf("error getting files:", err)
}
return files
}
var authorRegexp = regexp.MustCompile(`\s*[0-9]+\s*(.*)`)
func gitAuthors(files []string) []string {
cmds := []string{"shortlog", "-s", "-n", "-e", "HEAD", "--"}
cmds = append(cmds, files...)
cmd := exec.Command("git", cmds...)
var authors []string
err := doLines(cmd, func(line string) {
m := authorRegexp.FindStringSubmatch(line)
if len(m) > 1 {
authors = append(authors, m[1])
}
})
if err != nil {
log.Fatalln("error getting authors:", err)
}
return authors
}
func readAuthors() []string {
content, err := ioutil.ReadFile("AUTHORS")
if err != nil && !os.IsNotExist(err) {
log.Fatalln("error reading AUTHORS:", err)
}
var authors []string
for _, a := range bytes.Split(content, []byte("\n")) {
if len(a) > 0 && a[0] != '#' {
authors = append(authors, string(a))
}
}
// Retranslate existing authors through .mailmap.
// This should catch email address changes.
authors = mailmapLookup(authors)
return authors
}
func mailmapLookup(authors []string) []string {
if len(authors) == 0 {
return nil
}
cmds := []string{"check-mailmap", "--"}
cmds = append(cmds, authors...)
cmd := exec.Command("git", cmds...)
var translated []string
err := doLines(cmd, func(line string) {
translated = append(translated, line)
})
if err != nil {
log.Fatalln("error translating authors:", err)
}
return translated
}
func writeAuthors(files []string) {
merge := make(map[string]bool)
// Add authors that Git reports as contributorxs.
// This is the primary source of author information.
for _, a := range gitAuthors(files) {
merge[a] = true
}
// Add existing authors from the file. This should ensure that we
// never lose authors, even if Git stops listing them. We can also
// add authors manually this way.
for _, a := range readAuthors() {
merge[a] = true
}
// Write sorted list of authors back to the file.
var result []string
for a := range merge {
result = append(result, a)
}
sort.Strings(result)
content := new(bytes.Buffer)
content.WriteString(authorsFileHeader)
for _, a := range result {
content.WriteString(a)
content.WriteString("\n")
}
fmt.Println("writing AUTHORS")
if err := ioutil.WriteFile("AUTHORS", content.Bytes(), 0644); err != nil {
log.Fatalln(err)
}
}
func getInfo(files <-chan string, out chan<- *info, wg *sync.WaitGroup) {
for file := range files {
stat, err := os.Lstat(file)
if err != nil {
fmt.Printf("ERROR %s: %v\n", file, err)
continue
}
if !stat.Mode().IsRegular() {
continue
}
info, err := fileInfo(file)
if err != nil {
fmt.Printf("ERROR %s: %v\n", file, err)
continue
}
out <- info
}
wg.Done()
}
// fileInfo finds the lowest year in which the given file was commited.
func fileInfo(file string) (*info, error) {
info := &info{file: file, Year: int64(time.Now().Year())}
cmd := exec.Command("git", "log", "--follow", "--find-copies", "--pretty=format:%ai", "--", file)
err := doLines(cmd, func(line string) {
y, err := strconv.ParseInt(line[:4], 10, 64)
if err != nil {
fmt.Printf("cannot parse year: %q", line[:4])
}
if y < info.Year {
info.Year = y
}
})
return info, err
}
func writeLicenses(infos <-chan *info) {
for i := range infos {
writeLicense(i)
}
}
func writeLicense(info *info) {
fi, err := os.Stat(info.file)
if os.IsNotExist(err) {
fmt.Println("skipping (does not exist)", info.file)
return
}
if err != nil {
log.Fatalf("error stat'ing %s: %v\n", info.file, err)
}
content, err := ioutil.ReadFile(info.file)
if err != nil {
log.Fatalf("error reading %s: %v\n", info.file, err)
}
// Construct new file content.
buf := new(bytes.Buffer)
licenseT.Execute(buf, info)
if m := licenseCommentRE.FindIndex(content); m != nil && m[0] == 0 {
buf.Write(content[:m[0]])
buf.Write(content[m[1]:])
} else {
buf.Write(content)
}
// Write it to the file.
if bytes.Equal(content, buf.Bytes()) {
fmt.Println("skipping (no changes)", info.file)
return
}
fmt.Println("writing", info.ShortLicense(), info.file)
if err := ioutil.WriteFile(info.file, buf.Bytes(), fi.Mode()); err != nil {
log.Fatalf("error writing %s: %v", info.file, err)
}
}
func doLines(cmd *exec.Cmd, f func(string)) error {
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
if err := cmd.Start(); err != nil {
return err
}
s := bufio.NewScanner(stdout)
for s.Scan() {
f(s.Text())
}
if s.Err() != nil {
return s.Err()
}
if err := cmd.Wait(); err != nil {
return fmt.Errorf("%v (for %s)", err, strings.Join(cmd.Args, " "))
}
return nil
}

View File

@ -1,16 +0,0 @@
Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA

View File

@ -1,21 +1,20 @@
/*
This file is part of go-ethereum
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
// Command bootnode runs a bootstrap node for the Discovery Protocol.
// bootnode runs a bootstrap node for the Ethereum Discovery Protocol.
package main
import (

View File

@ -1,3 +1,20 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// disasm is a pretty-printer for EVM bytecode.
package main
import (

View File

@ -1,25 +1,20 @@
/*
This file is part of go-ethereum
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors:
* Jeffrey Wilcke <i@jev.io>
* Taylor Gerring <taylor.gerring@gmail.com>
*/
// Copyright 2014 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// ethtest executes Ethereum JSON tests.
package main
import (
@ -31,6 +26,7 @@ import (
"strings"
"github.com/codegangsta/cli"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/tests"
)
@ -40,7 +36,8 @@ var (
testExtension = ".json"
defaultTest = "all"
defaultDir = "."
allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"}
allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests", "RLPTests"}
testDirMapping = map[string]string{"BlockTests": "BlockchainTests"}
skipTests = []string{}
TestFlag = cli.StringFlag{
@ -66,6 +63,10 @@ var (
Name: "skip",
Usage: "Tests names to skip",
}
TraceFlag = cli.BoolFlag{
Name: "trace",
Usage: "Enable VM tracing",
}
)
func runTestWithReader(test string, r io.Reader) error {
@ -80,6 +81,8 @@ func runTestWithReader(test string, r io.Reader) error {
err = tests.RunTransactionTestsWithReader(r, skipTests)
case "vm", "vmtest", "vmtests":
err = tests.RunVmTestWithReader(r, skipTests)
case "rlp", "rlptest", "rlptests":
err = tests.RunRLPTestWithReader(r, skipTests)
default:
err = fmt.Errorf("Invalid test type specified: %v", test)
}
@ -138,8 +141,13 @@ func runSuite(test, file string) {
var err error
var files []string
if test == defaultTest {
files, err = getFiles(filepath.Join(file, curTest))
// check if we have an explicit directory mapping for the test
if _, ok := testDirMapping[curTest]; ok {
files, err = getFiles(filepath.Join(file, testDirMapping[curTest]))
} else {
// otherwise assume test name
files, err = getFiles(filepath.Join(file, curTest))
}
} else {
files, err = getFiles(file)
}
@ -170,7 +178,6 @@ func runSuite(test, file string) {
glog.Fatalln(err)
}
}
}
}
}
@ -181,6 +188,7 @@ func setupApp(c *cli.Context) {
continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name)
useStdIn := c.GlobalBool(ReadStdInFlag.Name)
skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ")
vm.Debug = c.GlobalBool(TraceFlag.Name)
if !useStdIn {
runSuite(flagTest, flagFile)
@ -208,6 +216,7 @@ func main() {
ContinueOnErrorFlag,
ReadStdInFlag,
SkipTestsFlag,
TraceFlag,
}
if err := app.Run(os.Args); err != nil {

View File

@ -1,100 +1,160 @@
/*
This file is part of go-ethereum
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors
* Jeffrey Wilcke <i@jev.io>
*/
// Copyright 2014 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// evm executes EVM code snippets.
package main
import (
"flag"
"fmt"
"log"
"math/big"
"os"
"runtime"
"time"
"github.com/codegangsta/cli"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
)
var (
code = flag.String("code", "", "evm code")
loglevel = flag.Int("log", 4, "log level")
gas = flag.String("gas", "1000000000", "gas amount")
price = flag.String("price", "0", "gas price")
value = flag.String("value", "0", "tx value")
dump = flag.Bool("dump", false, "dump state after run")
data = flag.String("data", "", "data")
app *cli.App
DebugFlag = cli.BoolFlag{
Name: "debug",
Usage: "output full trace logs",
}
ForceJitFlag = cli.BoolFlag{
Name: "forcejit",
Usage: "forces jit compilation",
}
DisableJitFlag = cli.BoolFlag{
Name: "nojit",
Usage: "disabled jit compilation",
}
CodeFlag = cli.StringFlag{
Name: "code",
Usage: "EVM code",
}
GasFlag = cli.StringFlag{
Name: "gas",
Usage: "gas limit for the evm",
Value: "10000000000",
}
PriceFlag = cli.StringFlag{
Name: "price",
Usage: "price set for the evm",
Value: "0",
}
ValueFlag = cli.StringFlag{
Name: "value",
Usage: "value set for the evm",
Value: "0",
}
DumpFlag = cli.BoolFlag{
Name: "dump",
Usage: "dumps the state after the run",
}
InputFlag = cli.StringFlag{
Name: "input",
Usage: "input for the EVM",
}
SysStatFlag = cli.BoolFlag{
Name: "sysstat",
Usage: "display system stats",
}
)
func perr(v ...interface{}) {
fmt.Println(v...)
//os.Exit(1)
func init() {
app = utils.NewApp("0.2", "the evm command line interface")
app.Flags = []cli.Flag{
DebugFlag,
ForceJitFlag,
DisableJitFlag,
SysStatFlag,
CodeFlag,
GasFlag,
PriceFlag,
ValueFlag,
DumpFlag,
InputFlag,
}
app.Action = run
}
func main() {
flag.Parse()
func run(ctx *cli.Context) {
vm.Debug = ctx.GlobalBool(DebugFlag.Name)
vm.ForceJit = ctx.GlobalBool(ForceJitFlag.Name)
vm.EnableJit = !ctx.GlobalBool(DisableJitFlag.Name)
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(*loglevel)))
glog.SetToStderr(true)
vm.Debug = true
db, _ := ethdb.NewMemDatabase()
statedb := state.New(common.Hash{}, db)
sender := statedb.CreateAccount(common.StringToAddress("sender"))
receiver := statedb.CreateAccount(common.StringToAddress("receiver"))
receiver.SetCode(common.Hex2Bytes(*code))
receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name)))
vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(*value))
vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name)))
tstart := time.Now()
ret, e := vmenv.Call(
sender,
receiver.Address(),
common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)),
common.Big(ctx.GlobalString(GasFlag.Name)),
common.Big(ctx.GlobalString(PriceFlag.Name)),
common.Big(ctx.GlobalString(ValueFlag.Name)),
)
vmdone := time.Since(tstart)
ret, e := vmenv.Call(sender, receiver.Address(), common.Hex2Bytes(*data), common.Big(*gas), common.Big(*price), common.Big(*value))
logger.Flush()
if e != nil {
perr(e)
}
if *dump {
if ctx.GlobalBool(DumpFlag.Name) {
fmt.Println(string(statedb.Dump()))
}
vm.StdErrFormat(vmenv.StructLogs())
var mem runtime.MemStats
runtime.ReadMemStats(&mem)
fmt.Printf("vm took %v\n", time.Since(tstart))
fmt.Printf(`alloc: %d
if ctx.GlobalBool(SysStatFlag.Name) {
var mem runtime.MemStats
runtime.ReadMemStats(&mem)
fmt.Printf("vm took %v\n", vmdone)
fmt.Printf(`alloc: %d
tot alloc: %d
no. malloc: %d
heap alloc: %d
heap objs: %d
num gc: %d
`, mem.Alloc, mem.TotalAlloc, mem.Mallocs, mem.HeapAlloc, mem.HeapObjects, mem.NumGC)
}
fmt.Printf("%x\n", ret)
fmt.Printf("OUT: 0x%x", ret)
if e != nil {
fmt.Printf(" error: %v", e)
}
fmt.Println()
}
func main() {
if err := app.Run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
type VMEnv struct {
@ -106,7 +166,7 @@ type VMEnv struct {
depth int
Gas *big.Int
time int64
time *big.Int
logs []vm.StructLog
}
@ -115,7 +175,7 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int) *VM
state: state,
transactor: &transactor,
value: value,
time: time.Now().Unix(),
time: big.NewInt(time.Now().Unix()),
}
}
@ -123,7 +183,7 @@ func (self *VMEnv) State() *state.StateDB { return self.state }
func (self *VMEnv) Origin() common.Address { return *self.transactor }
func (self *VMEnv) BlockNumber() *big.Int { return common.Big0 }
func (self *VMEnv) Coinbase() common.Address { return *self.transactor }
func (self *VMEnv) Time() int64 { return self.time }
func (self *VMEnv) Time() *big.Int { return self.time }
func (self *VMEnv) Difficulty() *big.Int { return common.Big1 }
func (self *VMEnv) BlockHash() []byte { return make([]byte, 32) }
func (self *VMEnv) Value() *big.Int { return self.value }
@ -146,6 +206,9 @@ func (self *VMEnv) StructLogs() []vm.StructLog {
func (self *VMEnv) AddLog(log *state.Log) {
self.state.AddLog(log)
}
func (self *VMEnv) CanTransfer(from vm.Account, balance *big.Int) bool {
return from.Balance().Cmp(balance) >= 0
}
func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error {
return vm.Transfer(from, to, amount)
}

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
@ -86,7 +102,6 @@ func runBlockTest(ctx *cli.Context) {
}
func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*eth.Ethereum, error) {
// TODO remove in favor of logic contained in tests package
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() }
cfg.MaxPeers = 0 // disable network

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
@ -58,10 +74,10 @@ func importChain(ctx *cli.Context) {
if len(ctx.Args()) != 1 {
utils.Fatalf("This command requires an argument.")
}
chain, blockDB, stateDB, extraDB := utils.MakeChain(ctx)
chain, chainDb := utils.MakeChain(ctx)
start := time.Now()
err := utils.ImportChain(chain, ctx.Args().First())
closeAll(blockDB, stateDB, extraDB)
chainDb.Close()
if err != nil {
utils.Fatalf("Import error: %v", err)
}
@ -72,7 +88,7 @@ func exportChain(ctx *cli.Context) {
if len(ctx.Args()) < 1 {
utils.Fatalf("This command requires an argument.")
}
chain, _, _, _ := utils.MakeChain(ctx)
chain, _ := utils.MakeChain(ctx)
start := time.Now()
var err error
@ -99,17 +115,16 @@ func exportChain(ctx *cli.Context) {
}
func removeDB(ctx *cli.Context) {
confirm, err := utils.PromptConfirm("Remove local databases?")
confirm, err := utils.PromptConfirm("Remove local database?")
if err != nil {
utils.Fatalf("%v", err)
}
if confirm {
fmt.Println("Removing chain and state databases...")
fmt.Println("Removing chaindata...")
start := time.Now()
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata"))
fmt.Printf("Removed in %v\n", time.Since(start))
} else {
@ -120,8 +135,8 @@ func removeDB(ctx *cli.Context) {
func upgradeDB(ctx *cli.Context) {
glog.Infoln("Upgrading blockchain database")
chain, blockDB, stateDB, extraDB := utils.MakeChain(ctx)
v, _ := blockDB.Get([]byte("BlockchainVersion"))
chain, chainDb := utils.MakeChain(ctx)
v, _ := chainDb.Get([]byte("BlockchainVersion"))
bcVersion := int(common.NewValue(v).Uint())
if bcVersion == 0 {
bcVersion = core.BlockChainVersion
@ -133,15 +148,14 @@ func upgradeDB(ctx *cli.Context) {
if err := utils.ExportChain(chain, exportFile); err != nil {
utils.Fatalf("Unable to export chain for reimport %s", err)
}
closeAll(blockDB, stateDB, extraDB)
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "blockchain"))
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "state"))
chainDb.Close()
os.RemoveAll(filepath.Join(ctx.GlobalString(utils.DataDirFlag.Name), "chaindata"))
// Import the chain file.
chain, blockDB, stateDB, extraDB = utils.MakeChain(ctx)
blockDB.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes())
chain, chainDb = utils.MakeChain(ctx)
chainDb.Put([]byte("BlockchainVersion"), common.NewValue(core.BlockChainVersion).Bytes())
err := utils.ImportChain(chain, exportFile)
closeAll(blockDB, stateDB, extraDB)
chainDb.Close()
if err != nil {
utils.Fatalf("Import error %v (a backup is made in %s, use the import command to import it)", err, exportFile)
} else {
@ -151,7 +165,7 @@ func upgradeDB(ctx *cli.Context) {
}
func dump(ctx *cli.Context) {
chain, _, stateDB, _ := utils.MakeChain(ctx)
chain, chainDb := utils.MakeChain(ctx)
for _, arg := range ctx.Args() {
var block *types.Block
if hashish(arg) {
@ -164,10 +178,11 @@ func dump(ctx *cli.Context) {
fmt.Println("{}")
utils.Fatalf("block not found")
} else {
state := state.New(block.Root(), stateDB)
state := state.New(block.Root(), chainDb)
fmt.Printf("%s\n", state.Dump())
}
}
chainDb.Close()
}
// hashish returns true for strings that look like hashes.

View File

@ -1,6 +0,0 @@
package main
var (
globalRegistrar = `var GlobalRegistrar = web3.eth.contract([{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"}]);`
globalRegistrarAddr = "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
)

View File

@ -1,19 +1,18 @@
// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
// Copyright 2014 The go-ethereum Authors
// This file is part of go-ethereum.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301 USA
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
@ -24,6 +23,7 @@ import (
"os"
"os/signal"
"path/filepath"
"regexp"
"strings"
"sort"
@ -32,18 +32,23 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/eth"
re "github.com/ethereum/go-ethereum/jsre"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/comms"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/xeth"
"github.com/peterh/liner"
"github.com/robertkrimen/otto"
"github.com/ethereum/go-ethereum/rpc/shared"
)
var passwordRegexp = regexp.MustCompile("personal.[nu]")
const passwordRepl = ""
type prompter interface {
AppendHistory(string)
Prompt(p string) (string, error)
@ -69,6 +74,7 @@ func (r dumbterm) PasswordPrompt(p string) (string, error) {
func (r dumbterm) AppendHistory(string) {}
type jsre struct {
ds *docserver.DocServer
re *re.JSRE
ethereum *eth.Ethereum
xeth *xeth.XEth
@ -139,18 +145,15 @@ func apiWordCompleter(line string, pos int) (head string, completions []string,
return begin, completionWords, end
}
func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool, f xeth.Frontend) *jsre {
func newLightweightJSRE(libPath string, client comms.EthereumClient, interactive bool) *jsre {
js := &jsre{ps1: "> "}
js.wait = make(chan *big.Int)
js.client = client
if f == nil {
f = js
}
js.ds = docserver.New("/")
// update state in separare forever blocks
js.re = re.New(libPath)
if err := js.apiBindings(f); err != nil {
if err := js.apiBindings(js); err != nil {
utils.Fatalf("Unable to initialize console - %v", err)
}
@ -180,6 +183,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, client comms.Et
if f == nil {
f = js
}
js.ds = docserver.New("/")
js.xeth = xeth.New(ethereum, f)
js.wait = js.xeth.UpdateState()
js.client = client
@ -224,15 +228,10 @@ func (self *jsre) loadAutoCompletion() {
}
func (self *jsre) batch(statement string) {
val, err := self.re.Run(statement)
err := self.re.EvalAndPrettyPrint(statement)
if err != nil {
fmt.Printf("error: %v", err)
} else if val.IsDefined() && val.IsObject() {
obj, _ := self.re.Get("ret_result")
fmt.Printf("%v", obj)
} else if val.IsDefined() {
fmt.Printf("%v", val)
}
if self.atexit != nil {
@ -244,22 +243,22 @@ func (self *jsre) batch(statement string) {
// show summary of current geth instance
func (self *jsre) welcome() {
self.re.Eval(`console.log('instance: ' + web3.version.client);`)
self.re.Eval(`console.log(' datadir: ' + admin.datadir);`)
self.re.Eval(`console.log("coinbase: " + eth.coinbase);`)
self.re.Eval(`var lastBlockTimestamp = 1000 * eth.getBlock(eth.blockNumber).timestamp`)
self.re.Eval(`console.log("at block: " + eth.blockNumber + " (" + new Date(lastBlockTimestamp).toLocaleDateString()
+ " " + new Date(lastBlockTimestamp).toLocaleTimeString() + ")");`)
self.re.Run(`
(function () {
console.log('instance: ' + web3.version.client);
console.log(' datadir: ' + admin.datadir);
console.log("coinbase: " + eth.coinbase);
var ts = 1000 * eth.getBlock(eth.blockNumber).timestamp;
console.log("at block: " + eth.blockNumber + " (" + new Date(ts) + ")");
})();
`)
if modules, err := self.supportedApis(); err == nil {
loadedModules := make([]string, 0)
for api, version := range modules {
loadedModules = append(loadedModules, fmt.Sprintf("%s:%s", api, version))
}
sort.Strings(loadedModules)
self.re.Eval(fmt.Sprintf("var modules = '%s';", strings.Join(loadedModules, " ")))
self.re.Eval(`console.log(" modules: " + modules);`)
fmt.Println("modules:", strings.Join(loadedModules, " "))
}
}
@ -283,7 +282,7 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
utils.Fatalf("Unable to determine supported api's: %v", err)
}
jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client)
jeth := rpc.NewJeth(api.Merge(apiImpl...), js.re, js.client, f)
js.re.Set("jeth", struct{}{})
t, _ := js.re.Get("jeth")
jethObj := t.Object()
@ -301,12 +300,12 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
utils.Fatalf("Error loading web3.js: %v", err)
}
_, err = js.re.Eval("var web3 = require('web3');")
_, err = js.re.Run("var web3 = require('web3');")
if err != nil {
utils.Fatalf("Error requiring web3: %v", err)
}
_, err = js.re.Eval("web3.setProvider(jeth)")
_, err = js.re.Run("web3.setProvider(jeth)")
if err != nil {
utils.Fatalf("Error setting web3 provider: %v", err)
}
@ -325,21 +324,19 @@ func (js *jsre) apiBindings(f xeth.Frontend) error {
}
}
_, err = js.re.Eval(shortcuts)
_, err = js.re.Run(shortcuts)
if err != nil {
utils.Fatalf("Error setting namespaces: %v", err)
}
js.re.Eval(globalRegistrar + "registrar = GlobalRegistrar.at(\"" + globalRegistrarAddr + "\");")
js.re.Run(`var GlobalRegistrar = eth.contract(` + registrar.GlobalRegistrarAbi + `); registrar = GlobalRegistrar.at("` + registrar.GlobalRegistrarAddr + `");`)
return nil
}
var ds, _ = docserver.New("/")
func (self *jsre) ConfirmTransaction(tx string) bool {
if self.ethereum.NatSpec {
notice := natspec.GetNotice(self.xeth, tx, ds)
notice := natspec.GetNotice(self.xeth, tx, self.ds)
fmt.Println(notice)
answer, _ := self.Prompt("Confirm Transaction [y/n]")
return strings.HasPrefix(strings.Trim(answer, " "), "y")
@ -381,6 +378,11 @@ func (self *jsre) interactive() {
for {
line, err := self.Prompt(<-prompt)
if err != nil {
if err == liner.ErrPromptAborted { // ctrl-C
self.resetPrompt()
inputln <- ""
continue
}
return
}
inputln <- line
@ -412,8 +414,10 @@ func (self *jsre) interactive() {
str += input + "\n"
self.setIndent()
if indentCount <= 0 {
hist := str[:len(str)-1]
self.AppendHistory(hist)
hist := hidepassword(str[:len(str)-1])
if len(hist) > 0 {
self.AppendHistory(hist)
}
self.parseInput(str)
str = ""
}
@ -421,6 +425,14 @@ func (self *jsre) interactive() {
}
}
func hidepassword(input string) string {
if passwordRegexp.MatchString(input) {
return passwordRepl
} else {
return input
}
}
func (self *jsre) withHistory(op func(*os.File)) {
datadir := common.DefaultDataDir()
if self.ethereum != nil {
@ -442,8 +454,7 @@ func (self *jsre) parseInput(code string) {
fmt.Println("[native] error", r)
}
}()
value, err := self.re.Run(code)
if err != nil {
if err := self.re.EvalAndPrettyPrint(code); err != nil {
if ottoErr, ok := err.(*otto.Error); ok {
fmt.Println(ottoErr.String())
} else {
@ -451,12 +462,17 @@ func (self *jsre) parseInput(code string) {
}
return
}
self.printValue(value)
}
var indentCount = 0
var str = ""
func (self *jsre) resetPrompt() {
indentCount = 0
str = ""
self.ps1 = "> "
}
func (self *jsre) setIndent() {
open := strings.Count(str, "{")
open += strings.Count(str, "(")
@ -470,10 +486,3 @@ func (self *jsre) setIndent() {
self.ps1 += " "
}
}
func (self *jsre) printValue(v interface{}) {
val, err := self.re.PrettyPrint(v)
if err == nil {
fmt.Printf("%v", val)
}
}

View File

@ -1,27 +1,45 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (
"fmt"
"io/ioutil"
"math/big"
"os"
"path/filepath"
"regexp"
"runtime"
"strconv"
"testing"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/common/resolver"
"github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/rpc/comms"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/comms"
)
const (
@ -43,7 +61,6 @@ var (
type testjethre struct {
*jsre
stateDb *state.StateDB
lastConfirm string
ds *docserver.DocServer
}
@ -64,24 +81,34 @@ func (self *testjethre) ConfirmTransaction(tx string) bool {
}
func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
return testREPL(t, nil)
}
func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth.Ethereum) {
tmp, err := ioutil.TempDir("", "geth-test")
if err != nil {
t.Fatal(err)
}
// set up mock genesis with balance on the testAddress
core.GenesisAccounts = []byte(testGenesis)
db, _ := ethdb.NewMemDatabase()
core.WriteGenesisBlockForTesting(db, common.HexToAddress(testAddress), common.String2Big(testBalance))
ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keystore"))
am := accounts.NewManager(ks)
ethereum, err := eth.New(&eth.Config{
conf := &eth.Config{
NodeKey: testNodeKey,
DataDir: tmp,
AccountManager: am,
MaxPeers: 0,
Name: "test",
SolcPath: testSolcPath,
})
PowTest: true,
NewDB: func(path string) (common.Database, error) { return db, nil },
}
if config != nil {
config(conf)
}
ethereum, err := eth.New(conf)
if err != nil {
t.Fatal("%v", err)
}
@ -102,31 +129,23 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
}
assetPath := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext")
ds, err := docserver.New("/")
if err != nil {
t.Errorf("Error creating DocServer: %v", err)
}
tf := &testjethre{ds: ds, stateDb: ethereum.ChainManager().State().Copy()}
client := comms.NewInProcClient(codec.JSON)
ds := docserver.New("/")
tf := &testjethre{ds: ds}
repl := newJSRE(ethereum, assetPath, "", client, false, tf)
tf.jsre = repl
return tmp, tf, ethereum
}
// this line below is needed for transaction to be applied to the state in testing
// the heavy lifing is done in XEth.ApplyTestTxs
// this is fragile, overwriting xeth will result in
// process leaking since xeth loops cannot quit safely
// should be replaced by proper mining with testDAG for easy full integration tests
// txc, self.xeth = self.xeth.ApplyTestTxs(self.xeth.repl.stateDb, coinbase, txc)
func TestNodeInfo(t *testing.T) {
t.Skip("broken after p2p update")
tmp, repl, ethereum := testJEthRE(t)
if err := ethereum.Start(); err != nil {
t.Fatalf("error starting ethereum: %v", err)
}
defer ethereum.Stop()
defer os.RemoveAll(tmp)
want := `{"DiscPort":0,"IP":"0.0.0.0","ListenAddr":"","Name":"test","NodeID":"4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5","NodeUrl":"enode://4cb2fc32924e94277bf94b5e4c983beedb2eabd5a0bc941db32202735c6625d020ca14a5963d1738af43b6ac0a711d61b1a06de931a499fe2aa0b1a132a902b5@0.0.0.0:0","TCPPort":0,"Td":"131072"}`
checkEvalJSON(t, repl, `admin.nodeInfo`, want)
}
@ -141,7 +160,6 @@ func TestAccounts(t *testing.T) {
checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`"]`)
checkEvalJSON(t, repl, `eth.coinbase`, `"`+testAddress+`"`)
val, err := repl.re.Run(`personal.newAccount("password")`)
if err != nil {
t.Errorf("expected no error, got %v", err)
@ -151,9 +169,8 @@ func TestAccounts(t *testing.T) {
t.Errorf("address not hex: %q", addr)
}
// skip until order fixed #824
// checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`", "`+addr+`"]`)
// checkEvalJSON(t, repl, `eth.coinbase`, `"`+testAddress+`"`)
checkEvalJSON(t, repl, `eth.accounts`, `["`+testAddress+`","`+addr+`"]`)
}
func TestBlockChain(t *testing.T) {
@ -256,8 +273,12 @@ func TestSignature(t *testing.T) {
}
func TestContract(t *testing.T) {
t.Skip()
tmp, repl, ethereum := testJEthRE(t)
t.Skip("contract testing is implemented with mining in ethash test mode. This takes about 7seconds to run. Unskip and run on demand")
coinbase := common.HexToAddress(testAddress)
tmp, repl, ethereum := testREPL(t, func(conf *eth.Config) {
conf.Etherbase = coinbase
conf.PowTest = true
})
if err := ethereum.Start(); err != nil {
t.Errorf("error starting ethereum: %v", err)
return
@ -265,12 +286,26 @@ func TestContract(t *testing.T) {
defer ethereum.Stop()
defer os.RemoveAll(tmp)
var txc uint64
coinbase := common.HexToAddress(testAddress)
resolver.New(repl.xeth).CreateContracts(coinbase)
// time.Sleep(1000 * time.Millisecond)
reg := registrar.New(repl.xeth)
_, err := reg.SetGlobalRegistrar("", coinbase)
if err != nil {
t.Errorf("error setting HashReg: %v", err)
}
_, err = reg.SetHashReg("", coinbase)
if err != nil {
t.Errorf("error setting HashReg: %v", err)
}
_, err = reg.SetUrlHint("", coinbase)
if err != nil {
t.Errorf("error setting HashReg: %v", err)
}
/* TODO:
* lookup receipt and contract addresses by tx hash
* name registration for HashReg and UrlHint addresses
* mine those transactions
* then set once more SetHashReg SetUrlHint
*/
// checkEvalJSON(t, repl, `eth.getBlock("pending", true).transactions.length`, `2`)
source := `contract test {\n` +
" /// @notice Will multiply `a` by 7." + `\n` +
` function multiply(uint a) returns(uint d) {\n` +
@ -278,14 +313,20 @@ func TestContract(t *testing.T) {
` }\n` +
`}\n`
checkEvalJSON(t, repl, `admin.contractInfo.stop()`, `true`)
if checkEvalJSON(t, repl, `admin.stopNatSpec()`, `true`) != nil {
return
}
contractInfo, err := ioutil.ReadFile("info_test.json")
if err != nil {
t.Fatalf("%v", err)
}
checkEvalJSON(t, repl, `primary = eth.accounts[0]`, `"`+testAddress+`"`)
checkEvalJSON(t, repl, `source = "`+source+`"`, `"`+source+`"`)
if checkEvalJSON(t, repl, `primary = eth.accounts[0]`, `"`+testAddress+`"`) != nil {
return
}
if checkEvalJSON(t, repl, `source = "`+source+`"`, `"`+source+`"`) != nil {
return
}
// if solc is found with right version, test it, otherwise read from file
sol, err := compiler.New("")
@ -305,69 +346,160 @@ func TestContract(t *testing.T) {
t.Errorf("%v", err)
}
} else {
checkEvalJSON(t, repl, `contract = eth.compile.solidity(source).test`, string(contractInfo))
if checkEvalJSON(t, repl, `contract = eth.compile.solidity(source).test`, string(contractInfo)) != nil {
return
}
}
checkEvalJSON(t, repl, `contract.code`, `"0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"`)
if checkEvalJSON(t, repl, `contract.code`, `"0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"`) != nil {
return
}
checkEvalJSON(
if checkEvalJSON(
t, repl,
`contractaddress = eth.sendTransaction({from: primary, data: contract.code })`,
`"0x5dcaace5982778b409c524873b319667eba5d074"`,
)
`contractaddress = eth.sendTransaction({from: primary, data: contract.code})`,
`"0x46d69d55c3c4b86a924a92c9fc4720bb7bce1d74"`,
) != nil {
return
}
if !processTxs(repl, t, 8) {
return
}
callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
Multiply7 = eth.contract(abiDef);
multiply7 = Multiply7.at(contractaddress);
`
// time.Sleep(1500 * time.Millisecond)
_, err = repl.re.Run(callSetup)
if err != nil {
t.Errorf("unexpected error setting up contract, got %v", err)
return
}
// checkEvalJSON(t, repl, `eth.getBlock("pending", true).transactions.length`, `3`)
// why is this sometimes failing?
// checkEvalJSON(t, repl, `multiply7.multiply.call(6)`, `42`)
expNotice := ""
if repl.lastConfirm != expNotice {
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm)
return
}
txc, repl.xeth = repl.xeth.ApplyTestTxs(repl.stateDb, coinbase, txc)
if checkEvalJSON(t, repl, `admin.startNatSpec()`, `true`) != nil {
return
}
if checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary })`, `"0x4ef9088431a8033e4580d00e4eb2487275e031ff4163c7529df0ef45af17857b"`) != nil {
return
}
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`)
checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary, gas: "1000000", gasPrice: "100000" })`, `undefined`)
expNotice = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x87e2802265838c7f14bb69eecd2112911af6767907a702eeaa445239fb20711b'): {"params":[{"to":"0x5dcaace5982778b409c524873b319667eba5d074","data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}]}`
if !processTxs(repl, t, 1) {
return
}
expNotice = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x87e2802265838c7f14bb69eecd2112911af6767907a702eeaa445239fb20711b'): {"params":[{"to":"0x46d69d55c3c4b86a924a92c9fc4720bb7bce1d74","data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}]}`
if repl.lastConfirm != expNotice {
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm)
t.Errorf("incorrect confirmation message: expected\n%v, got\n%v", expNotice, repl.lastConfirm)
return
}
var contenthash = `"0x86d2b7cf1e72e9a7a3f8d96601f0151742a2f780f1526414304fbe413dc7f9bd"`
if sol != nil {
var contentHash = `"0x86d2b7cf1e72e9a7a3f8d96601f0151742a2f780f1526414304fbe413dc7f9bd"`
if sol != nil && solcVersion != sol.Version() {
modContractInfo := versionRE.ReplaceAll(contractInfo, []byte(`"compilerVersion":"`+sol.Version()+`"`))
_ = modContractInfo
// contenthash = crypto.Sha3(modContractInfo)
fmt.Printf("modified contractinfo:\n%s\n", modContractInfo)
contentHash = `"` + common.ToHex(crypto.Sha3([]byte(modContractInfo))) + `"`
}
checkEvalJSON(t, repl, `filename = "/tmp/info.json"`, `"/tmp/info.json"`)
checkEvalJSON(t, repl, `contenthash = admin.contractInfo.register(primary, contractaddress, contract, filename)`, contenthash)
checkEvalJSON(t, repl, `admin.contractInfo.registerUrl(primary, contenthash, "file://"+filename)`, `true`)
if err != nil {
t.Errorf("unexpected error registering, got %v", err)
if checkEvalJSON(t, repl, `filename = "/tmp/info.json"`, `"/tmp/info.json"`) != nil {
return
}
if checkEvalJSON(t, repl, `contentHash = admin.saveInfo(contract.info, filename)`, contentHash) != nil {
return
}
if checkEvalJSON(t, repl, `admin.register(primary, contractaddress, contentHash)`, `true`) != nil {
return
}
if checkEvalJSON(t, repl, `admin.registerUrl(primary, contentHash, "file://"+filename)`, `true`) != nil {
return
}
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`)
if checkEvalJSON(t, repl, `admin.startNatSpec()`, `true`) != nil {
return
}
// update state
txc, repl.xeth = repl.xeth.ApplyTestTxs(repl.stateDb, coinbase, txc)
if !processTxs(repl, t, 3) {
return
}
if checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary })`, `"0x66d7635c12ad0b231e66da2f987ca3dfdca58ffe49c6442aa55960858103fd0c"`) != nil {
return
}
if !processTxs(repl, t, 1) {
return
}
checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary, gas: "1000000", gasPrice: "100000" })`, `undefined`)
expNotice = "Will multiply 6 by 7."
if repl.lastConfirm != expNotice {
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm)
t.Errorf("incorrect confirmation message: expected\n%v, got\n%v", expNotice, repl.lastConfirm)
return
}
}
func pendingTransactions(repl *testjethre, t *testing.T) (txc int64, err error) {
txs := repl.ethereum.TxPool().GetTransactions()
return int64(len(txs)), nil
}
func processTxs(repl *testjethre, t *testing.T, expTxc int) bool {
var txc int64
var err error
for i := 0; i < 50; i++ {
txc, err = pendingTransactions(repl, t)
if err != nil {
t.Errorf("unexpected error checking pending transactions: %v", err)
return false
}
if expTxc < int(txc) {
t.Errorf("too many pending transactions: expected %v, got %v", expTxc, txc)
return false
} else if expTxc == int(txc) {
break
}
time.Sleep(100 * time.Millisecond)
}
if int(txc) != expTxc {
t.Errorf("incorrect number of pending transactions, expected %v, got %v", expTxc, txc)
return false
}
err = repl.ethereum.StartMining(runtime.NumCPU())
if err != nil {
t.Errorf("unexpected error mining: %v", err)
return false
}
defer repl.ethereum.StopMining()
timer := time.NewTimer(100 * time.Second)
height := new(big.Int).Add(repl.xeth.CurrentBlock().Number(), big.NewInt(1))
repl.wait <- height
select {
case <-timer.C:
// if times out make sure the xeth loop does not block
go func() {
select {
case repl.wait <- nil:
case <-repl.wait:
}
}()
case <-repl.wait:
}
txc, err = pendingTransactions(repl, t)
if err != nil {
t.Errorf("unexpected error checking pending transactions: %v", err)
return false
}
if txc != 0 {
t.Errorf("%d trasactions were not mined", txc)
return false
}
return true
}
func checkEvalJSON(t *testing.T, re *testjethre, expr, want string) error {

View File

@ -1,28 +1,24 @@
/*
This file is part of go-ethereum
// Copyright 2014 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors
* Jeffrey Wilcke <i@jev.io>
*/
// geth is the official command-line client for Ethereum.
package main
import (
"fmt"
"io"
"io/ioutil"
_ "net/http/pprof"
"os"
@ -37,22 +33,29 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/comms"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
)
const (
ClientIdentifier = "Geth"
Version = "0.9.34"
Version = "1.1.3"
VersionMajor = 1
VersionMinor = 1
VersionPatch = 3
)
var (
gitCommit string // set via linker flag
gitCommit string // set via linker flagg
nodeNameVersion string
app *cli.App
)
@ -68,6 +71,18 @@ func init() {
app.Action = run
app.HideVersion = true // we have a command to print the version
app.Commands = []cli.Command{
{
Action: blockRecovery,
Name: "recover",
Usage: "attempts to recover a corrupted database by setting a new block by number or hash. See help recover.",
Description: `
The recover commands will attempt to read out the last
block based on that.
recover #number recovers by number
recover <hex> recovers by hash
`,
},
blocktestCommand,
importCommand,
exportCommand,
@ -137,9 +152,12 @@ Note that exporting your key in unencrypted format is NOT supported.
Keys are stored under <DATADIR>/keys.
It is safe to transfer the entire directory or the individual keys therein
between ethereum nodes.
between ethereum nodes by simply copying.
Make sure you backup your keys regularly.
In order to use your account to send transactions, you need to unlock them using the
'--unlock' option. The argument is a comma
And finally. DO NOT FORGET YOUR PASSWORD.
`,
Subcommands: []cli.Command{
@ -170,6 +188,33 @@ Note, this is meant to be used for testing only, it is a bad idea to save your
password to file or expose in any other way.
`,
},
{
Action: accountUpdate,
Name: "update",
Usage: "update an existing account",
Description: `
ethereum account update <address>
Update an existing account.
The account is saved in the newest version in encrypted format, you are prompted
for a passphrase to unlock the account and another to save the updated file.
This same command can therefore be used to migrate an account of a deprecated
format to the newest format or change the password for an account.
For non-interactive use the passphrase can be specified with the --password flag:
ethereum --password <passwordfile> account new
Since only one password can be given, only format update can be performed,
changing your password is only possible interactively.
Note that account update has the a side effect that the order of your accounts
changes.
`,
},
{
Action: accountImport,
Name: "import",
@ -233,10 +278,12 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils.IdentityFlag,
utils.UnlockedAccountFlag,
utils.PasswordFileFlag,
utils.GenesisNonceFlag,
utils.GenesisFileFlag,
utils.BootnodesFlag,
utils.DataDirFlag,
utils.BlockchainVersionFlag,
utils.OlympicFlag,
utils.CacheFlag,
utils.JSpathFlag,
utils.ListenPortFlag,
utils.MaxPeersFlag,
@ -261,7 +308,9 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils.ExecFlag,
utils.WhisperEnabledFlag,
utils.VMDebugFlag,
utils.ProtocolVersionFlag,
utils.VMForceJitFlag,
utils.VMJitCacheFlag,
utils.VMEnableJitFlag,
utils.NetworkIdFlag,
utils.RPCCORSDomainFlag,
utils.VerbosityFlag,
@ -283,6 +332,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
}
app.Before = func(ctx *cli.Context) error {
utils.SetupLogger(ctx)
utils.SetupVM(ctx)
if ctx.GlobalBool(utils.PProfEanbledFlag.Name) {
utils.StartPProf(ctx)
}
@ -301,9 +351,36 @@ func main() {
}
}
func makeDefaultExtra() []byte {
var clientInfo = struct {
Version uint
Name string
GoVersion string
Os string
}{uint(VersionMajor<<16 | VersionMinor<<8 | VersionPatch), ClientIdentifier, runtime.Version(), runtime.GOOS}
extra, err := rlp.EncodeToBytes(clientInfo)
if err != nil {
glog.V(logger.Warn).Infoln("error setting canonical miner information:", err)
}
if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() {
glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
glog.V(logger.Debug).Infof("extra: %x\n", extra)
return nil
}
return extra
}
func run(ctx *cli.Context) {
utils.HandleInterrupt()
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
if ctx.GlobalBool(utils.OlympicFlag.Name) {
utils.InitOlympic()
}
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
cfg.ExtraData = makeDefaultExtra()
ethereum, err := eth.New(cfg)
if err != nil {
utils.Fatalf("%v", err)
@ -315,13 +392,7 @@ func run(ctx *cli.Context) {
}
func attach(ctx *cli.Context) {
// Wrap the standard output with a colorified stream (windows)
if isatty.IsTerminal(os.Stdout.Fd()) {
if pr, pw, err := os.Pipe(); err == nil {
go io.Copy(colorable.NewColorableStdout(), pr)
os.Stdout = pw
}
}
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
var client comms.EthereumClient
var err error
@ -342,7 +413,7 @@ func attach(ctx *cli.Context) {
ctx.GlobalString(utils.JSpathFlag.Name),
client,
true,
nil)
)
if ctx.GlobalString(utils.ExecFlag.Name) != "" {
repl.batch(ctx.GlobalString(utils.ExecFlag.Name))
@ -353,13 +424,7 @@ func attach(ctx *cli.Context) {
}
func console(ctx *cli.Context) {
// Wrap the standard output with a colorified stream (windows)
if isatty.IsTerminal(os.Stdout.Fd()) {
if pr, pw, err := os.Pipe(); err == nil {
go io.Copy(colorable.NewColorableStdout(), pr)
os.Stdout = pw
}
}
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
ethereum, err := eth.New(cfg)
@ -391,6 +456,8 @@ func console(ctx *cli.Context) {
}
func execJSFiles(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
ethereum, err := eth.New(cfg)
if err != nil {
@ -415,48 +482,78 @@ func execJSFiles(ctx *cli.Context) {
ethereum.WaitForShutdown()
}
func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (passphrase string) {
var err error
// Load startup keys. XXX we are going to need a different format
func unlockAccount(ctx *cli.Context, am *accounts.Manager, addr string, i int) (addrHex, auth string) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
if !((len(account) == 40) || (len(account) == 42)) { // with or without 0x
utils.Fatalf("Invalid account address '%s'", account)
}
// Attempt to unlock the account 3 times
attempts := 3
for tries := 0; tries < attempts; tries++ {
msg := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", account, tries+1, attempts)
passphrase = getPassPhrase(ctx, msg, false)
err = am.Unlock(common.HexToAddress(account), passphrase)
if err == nil {
break
var err error
addrHex, err = utils.ParamToAddress(addr, am)
if err == nil {
// Attempt to unlock the account 3 times
attempts := 3
for tries := 0; tries < attempts; tries++ {
msg := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", addr, tries+1, attempts)
auth = getPassPhrase(ctx, msg, false, i)
err = am.Unlock(common.HexToAddress(addrHex), auth)
if err == nil {
break
}
}
}
if err != nil {
utils.Fatalf("Unlock account failed '%v'", err)
}
fmt.Printf("Account '%s' unlocked.\n", account)
fmt.Printf("Account '%s' unlocked.\n", addr)
return
}
func blockRecovery(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
arg := ctx.Args().First()
if len(ctx.Args()) < 1 && len(arg) > 0 {
glog.Fatal("recover requires block number or hash")
}
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
utils.CheckLegalese(cfg.DataDir)
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache)
if err != nil {
glog.Fatalln("could not open db:", err)
}
var block *types.Block
if arg[0] == '#' {
block = core.GetBlockByNumber(blockDb, common.String2Big(arg[1:]).Uint64())
} else {
block = core.GetBlockByHash(blockDb, common.HexToHash(arg))
}
if block == nil {
glog.Fatalln("block not found. Recovery failed")
}
err = core.WriteHead(blockDb, block)
if err != nil {
glog.Fatalln("block write err", err)
}
glog.Infof("Recovery succesful. New HEAD %x\n", block.Hash())
}
func startEth(ctx *cli.Context, eth *eth.Ethereum) {
// Start Ethereum itself
utils.StartEthereum(eth)
am := eth.AccountManager()
am := eth.AccountManager()
account := ctx.GlobalString(utils.UnlockedAccountFlag.Name)
accounts := strings.Split(account, " ")
for _, account := range accounts {
for i, account := range accounts {
if len(account) > 0 {
if account == "primary" {
primaryAcc, err := am.Primary()
if err != nil {
utils.Fatalf("no primary account: %v", err)
}
account = primaryAcc.Hex()
utils.Fatalf("the 'primary' keyword is deprecated. You can use integer indexes, but the indexes are not permanent, they can change if you add external keys, export your keys or copy your keystore to another node.")
}
unlockAccount(ctx, am, account)
unlockAccount(ctx, am, account, i)
}
}
// Start auxiliary services if enabled.
@ -478,19 +575,19 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
}
func accountList(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
am := utils.MakeAccountManager(ctx)
accts, err := am.Accounts()
if err != nil {
utils.Fatalf("Could not list accounts: %v", err)
}
name := "Primary"
for i, acct := range accts {
fmt.Printf("%s #%d: %x\n", name, i, acct)
name = "Account"
fmt.Printf("Account #%d: %x\n", i, acct)
}
}
func getPassPhrase(ctx *cli.Context, desc string, confirmation bool) (passphrase string) {
func getPassPhrase(ctx *cli.Context, desc string, confirmation bool, i int) (passphrase string) {
passfile := ctx.GlobalString(utils.PasswordFileFlag.Name)
if len(passfile) == 0 {
fmt.Println(desc)
@ -514,14 +611,24 @@ func getPassPhrase(ctx *cli.Context, desc string, confirmation bool) (passphrase
if err != nil {
utils.Fatalf("Unable to read password file '%s': %v", passfile, err)
}
passphrase = string(passbytes)
// this is backwards compatible if the same password unlocks several accounts
// it also has the consequence that trailing newlines will not count as part
// of the password, so --password <(echo -n 'pass') will now work without -n
passphrases := strings.Split(string(passbytes), "\n")
if i >= len(passphrases) {
passphrase = passphrases[len(passphrases)-1]
} else {
passphrase = passphrases[i]
}
}
return
}
func accountCreate(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
am := utils.MakeAccountManager(ctx)
passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true)
passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0)
acct, err := am.NewAccount(passphrase)
if err != nil {
utils.Fatalf("Could not create the account: %v", err)
@ -529,7 +636,26 @@ func accountCreate(ctx *cli.Context) {
fmt.Printf("Address: %x\n", acct)
}
func accountUpdate(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
am := utils.MakeAccountManager(ctx)
arg := ctx.Args().First()
if len(arg) == 0 {
utils.Fatalf("account address or index must be given as argument")
}
addr, authFrom := unlockAccount(ctx, am, arg, 0)
authTo := getPassPhrase(ctx, "Please give a new password. Do not forget this password.", true, 0)
err := am.Update(common.HexToAddress(addr), authFrom, authTo)
if err != nil {
utils.Fatalf("Could not update the account: %v", err)
}
}
func importWallet(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
keyfile := ctx.Args().First()
if len(keyfile) == 0 {
utils.Fatalf("keyfile must be given as argument")
@ -540,7 +666,7 @@ func importWallet(ctx *cli.Context) {
}
am := utils.MakeAccountManager(ctx)
passphrase := getPassPhrase(ctx, "", false)
passphrase := getPassPhrase(ctx, "", false, 0)
acct, err := am.ImportPreSaleKey(keyJson, passphrase)
if err != nil {
@ -550,12 +676,14 @@ func importWallet(ctx *cli.Context) {
}
func accountImport(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
keyfile := ctx.Args().First()
if len(keyfile) == 0 {
utils.Fatalf("keyfile must be given as argument")
}
am := utils.MakeAccountManager(ctx)
passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true)
passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0)
acct, err := am.Import(keyfile, passphrase)
if err != nil {
utils.Fatalf("Could not create the account: %v", err)
@ -564,6 +692,8 @@ func accountImport(ctx *cli.Context) {
}
func makedag(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
args := ctx.Args()
wrongArgs := func() {
utils.Fatalf(`Usage: geth makedag <block number> <outputdir>`)
@ -598,7 +728,7 @@ func version(c *cli.Context) {
if gitCommit != "" {
fmt.Println("Git Commit:", gitCommit)
}
fmt.Println("Protocol Version:", c.GlobalInt(utils.ProtocolVersionFlag.Name))
fmt.Println("Protocol Versions:", eth.ProtocolVersions)
fmt.Println("Network Id:", c.GlobalInt(utils.NetworkIdFlag.Name))
fmt.Println("Go Version:", runtime.Version())
fmt.Println("OS:", runtime.GOOS)

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package main
import (

View File

@ -1,23 +1,18 @@
/*
This file is part of go-ethereum
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors
* Felix Lange <felix@ethdev.com>
*/
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// rlpdump is a pretty-printer for RLP data.
package main

View File

@ -1,30 +1,28 @@
/*
This file is part of go-ethereum
// Copyright 2014 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @authors
* Jeffrey Wilcke <i@jev.io>
* Viktor Tron <viktor@ethdev.com>
*/
// Package utils contains internal helper functions for go-ethereum commands.
package utils
import (
"bufio"
"fmt"
"io"
"math"
"math/big"
"os"
"os/signal"
"regexp"
@ -36,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/peterh/liner"
)
@ -46,29 +45,6 @@ const (
var interruptCallbacks = []func(os.Signal){}
// Register interrupt handlers callbacks
func RegisterInterrupt(cb func(os.Signal)) {
interruptCallbacks = append(interruptCallbacks, cb)
}
// go routine that call interrupt handlers in order of registering
func HandleInterrupt() {
c := make(chan os.Signal, 1)
go func() {
signal.Notify(c, os.Interrupt)
for sig := range c {
glog.V(logger.Error).Infof("Shutting down (%v) ... \n", sig)
RunInterruptCallbacks(sig)
}
}()
}
func RunInterruptCallbacks(sig os.Signal) {
for _, cb := range interruptCallbacks {
cb(sig)
}
}
func openLogFile(Datadir string, filename string) *os.File {
path := common.AbsolutePath(Datadir, filename)
file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
@ -85,15 +61,16 @@ func PromptConfirm(prompt string) (bool, error) {
)
prompt = prompt + " [y/N] "
if liner.TerminalSupported() {
lr := liner.NewLiner()
defer lr.Close()
input, err = lr.Prompt(prompt)
} else {
fmt.Print(prompt)
input, err = bufio.NewReader(os.Stdin).ReadString('\n')
fmt.Println()
}
// if liner.TerminalSupported() {
// fmt.Println("term")
// lr := liner.NewLiner()
// defer lr.Close()
// input, err = lr.Prompt(prompt)
// } else {
fmt.Print(prompt)
input, err = bufio.NewReader(os.Stdin).ReadString('\n')
fmt.Println()
// }
if len(input) > 0 && strings.ToUpper(input[:1]) == "Y" {
return true, nil
@ -119,12 +96,12 @@ func PromptPassword(prompt string, warnTerm bool) (string, error) {
return input, err
}
func initDataDir(Datadir string) {
_, err := os.Stat(Datadir)
if err != nil {
if os.IsNotExist(err) {
fmt.Printf("Data directory '%s' doesn't exist, creating it\n", Datadir)
os.Mkdir(Datadir, 0777)
func CheckLegalese(datadir string) {
// check "first run"
if !common.FileExist(datadir) {
r, _ := PromptConfirm(legalese)
if !r {
Fatalf("Must accept to continue. Shutting down...\n")
}
}
}
@ -149,19 +126,34 @@ func StartEthereum(ethereum *eth.Ethereum) {
if err := ethereum.Start(); err != nil {
Fatalf("Error starting Ethereum: %v", err)
}
RegisterInterrupt(func(sig os.Signal) {
ethereum.Stop()
go func() {
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, os.Interrupt)
defer signal.Stop(sigc)
<-sigc
glog.V(logger.Info).Infoln("Got interrupt, shutting down...")
go ethereum.Stop()
logger.Flush()
})
for i := 10; i > 0; i-- {
<-sigc
if i > 1 {
glog.V(logger.Info).Infoln("Already shutting down, please be patient.")
glog.V(logger.Info).Infoln("Interrupt", i-1, "more times to induce panic.")
}
}
glog.V(logger.Error).Infof("Force quitting: this might not end so well.")
panic("boom")
}()
}
func StartEthereumForTest(ethereum *eth.Ethereum) {
glog.V(logger.Info).Infoln("Starting ", ethereum.Name())
ethereum.StartForTest()
RegisterInterrupt(func(sig os.Signal) {
ethereum.Stop()
logger.Flush()
})
func InitOlympic() {
params.DurationLimit = big.NewInt(8)
params.GenesisGasLimit = big.NewInt(3141592)
params.MinGasLimit = big.NewInt(125000)
params.MaximumExtraDataSize = big.NewInt(1024)
NetworkIdFlag.Value = 0
core.BlockReward = big.NewInt(1.5e+18)
core.ExpDiffPeriod = big.NewInt(math.MaxInt64)
}
func FormatTransactionData(data string) []byte {
@ -224,6 +216,11 @@ func ImportChain(chain *core.ChainManager, fn string) error {
} else if err != nil {
return fmt.Errorf("at block %d: %v", n, err)
}
// don't import first block
if b.NumberU64() == 0 {
i--
continue
}
blocks[i] = &b
n++
}
@ -239,6 +236,7 @@ func ImportChain(chain *core.ChainManager, fn string) error {
batch, blocks[0].Hash().Bytes()[:4], blocks[i-1].Hash().Bytes()[:4])
continue
}
if _, err := chain.InsertChain(blocks[:i]); err != nil {
return fmt.Errorf("invalid block %d: %v", n, err)
}

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package utils
import (
@ -5,7 +21,7 @@ import (
"fmt"
"os"
"os/user"
"path/filepath"
"path"
"strings"
"github.com/codegangsta/cli"
@ -122,11 +138,8 @@ func (self *DirectoryFlag) Set(value string) {
func expandPath(p string) string {
if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
if user, err := user.Current(); err == nil {
if err == nil {
p = strings.Replace(p, "~", user.HomeDir, 1)
}
p = user.HomeDir + p[1:]
}
}
return filepath.Clean(os.ExpandEnv(p))
return path.Clean(os.ExpandEnv(p))
}

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package utils
import (
@ -7,18 +23,15 @@ import (
)
func TestPathExpansion(t *testing.T) {
user, _ := user.Current()
tests := map[string]string{
"/home/someuser/tmp": "/home/someuser/tmp",
"~/tmp": user.HomeDir + "/tmp",
"~thisOtherUser/b/": "~thisOtherUser/b",
"$DDDXXX/a/b": "/tmp/a/b",
"/a/b/": "/a/b",
}
os.Setenv("DDDXXX", "/tmp")
for test, expected := range tests {
got := expandPath(test)
if got != expected {

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package utils
import (
@ -5,28 +21,32 @@ import (
"fmt"
"log"
"math/big"
"net"
"net/http"
"os"
"path/filepath"
"runtime"
"github.com/ethereum/go-ethereum/metrics"
"strconv"
"github.com/codegangsta/cli"
"github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/rpc/api"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/comms"
"github.com/ethereum/go-ethereum/rpc/shared"
"github.com/ethereum/go-ethereum/rpc/useragent"
"github.com/ethereum/go-ethereum/xeth"
)
@ -82,11 +102,6 @@ var (
Usage: "Data directory to be used",
Value: DirectoryString{common.DefaultDataDir()},
}
ProtocolVersionFlag = cli.IntFlag{
Name: "protocolversion",
Usage: "ETH protocol version (integer)",
Value: eth.ProtocolVersion,
}
NetworkIdFlag = cli.IntFlag{
Name: "networkid",
Usage: "Network Id (integer)",
@ -102,6 +117,10 @@ var (
Usage: "Sets the genesis nonce",
Value: 42,
}
GenesisFileFlag = cli.StringFlag{
Name: "genesis",
Usage: "Inserts/Overwrites the genesis block (json format)",
}
IdentityFlag = cli.StringFlag{
Name: "identity",
Usage: "Custom node name",
@ -110,6 +129,15 @@ var (
Name: "natspec",
Usage: "Enable NatSpec confirmation notice",
}
CacheFlag = cli.IntFlag{
Name: "cache",
Usage: "Megabytes of memory allocated to internal caching",
Value: 0,
}
OlympicFlag = cli.BoolFlag{
Name: "olympic",
Usage: "Use olympic style protocol",
}
// miner settings
MinerThreadsFlag = cli.IntFlag{
@ -127,18 +155,18 @@ var (
}
EtherbaseFlag = cli.StringFlag{
Name: "etherbase",
Usage: "Public address for block mining rewards. By default the address of your primary account is used",
Value: "primary",
Usage: "Public address for block mining rewards. By default the address first created is used",
Value: "0",
}
GasPriceFlag = cli.StringFlag{
Name: "gasprice",
Usage: "Sets the minimal gasprice when mining transactions",
Value: new(big.Int).Mul(big.NewInt(1), common.Szabo).String(),
Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
}
UnlockedAccountFlag = cli.StringFlag{
Name: "unlock",
Usage: "Unlock the account given until this program exits (prompts for password). '--unlock primary' unlocks the primary account",
Usage: "Unlock the account given until this program exits (prompts for password). '--unlock n' unlocks the n-th account in order or creation.",
Value: "",
}
PasswordFileFlag = cli.StringFlag{
@ -147,6 +175,25 @@ var (
Value: "",
}
// vm flags
VMDebugFlag = cli.BoolFlag{
Name: "vmdebug",
Usage: "Virtual Machine debug output",
}
VMForceJitFlag = cli.BoolFlag{
Name: "forcejit",
Usage: "Force the JIT VM to take precedence",
}
VMJitCacheFlag = cli.IntFlag{
Name: "jitcache",
Usage: "Amount of cached JIT VM programs",
Value: 64,
}
VMEnableJitFlag = cli.BoolFlag{
Name: "jitvm",
Usage: "Enable the JIT VM",
}
// logging and debug settings
LogFileFlag = cli.StringFlag{
Name: "logfile",
@ -171,10 +218,6 @@ var (
Usage: "The syntax of the argument is a comma-separated list of pattern=N, where pattern is a literal file name (minus the \".go\" suffix) or \"glob\" pattern and N is a log verbosity level.",
Value: glog.GetVModule(),
}
VMDebugFlag = cli.BoolFlag{
Name: "vmdebug",
Usage: "Virtual Machine debug output",
}
BacktraceAtFlag = cli.GenericFlag{
Name: "backtrace_at",
Usage: "If set to a file and line number (e.g., \"block.go:271\") holding a logging statement, a stack trace will be logged",
@ -293,12 +336,12 @@ var (
GpoMinGasPriceFlag = cli.StringFlag{
Name: "gpomin",
Usage: "Minimum suggested gas price",
Value: new(big.Int).Mul(big.NewInt(1), common.Szabo).String(),
Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
}
GpoMaxGasPriceFlag = cli.StringFlag{
Name: "gpomax",
Usage: "Maximum suggested gas price",
Value: new(big.Int).Mul(big.NewInt(100), common.Szabo).String(),
Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(),
}
GpoFullBlockRatioFlag = cli.IntFlag{
Name: "gpofull",
@ -356,24 +399,32 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
if len(customName) > 0 {
clientID += "/" + customName
}
am := MakeAccountManager(ctx)
etherbase, err := ParamToAddress(ctx.GlobalString(EtherbaseFlag.Name), am)
if err != nil {
glog.V(logger.Error).Infoln("WARNING: No etherbase set and no accounts found as default")
}
return &eth.Config{
Name: common.MakeName(clientID, version),
DataDir: ctx.GlobalString(DataDirFlag.Name),
ProtocolVersion: ctx.GlobalInt(ProtocolVersionFlag.Name),
GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name),
GenesisFile: ctx.GlobalString(GenesisFileFlag.Name),
BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name),
DatabaseCache: ctx.GlobalInt(CacheFlag.Name),
SkipBcVersionCheck: false,
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
LogFile: ctx.GlobalString(LogFileFlag.Name),
Verbosity: ctx.GlobalInt(VerbosityFlag.Name),
LogJSON: ctx.GlobalString(LogJSONFlag.Name),
Etherbase: ctx.GlobalString(EtherbaseFlag.Name),
Etherbase: common.HexToAddress(etherbase),
MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
AccountManager: MakeAccountManager(ctx),
AccountManager: am,
VmDebug: ctx.GlobalBool(VMDebugFlag.Name),
MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name),
MaxPendingPeers: ctx.GlobalInt(MaxPendingPeersFlag.Name),
Port: ctx.GlobalString(ListenPortFlag.Name),
Olympic: ctx.GlobalBool(OlympicFlag.Name),
NAT: MakeNAT(ctx),
NatSpec: ctx.GlobalBool(NatspecEnabledFlag.Name),
Discovery: !ctx.GlobalBool(NoDiscoverFlag.Name),
@ -401,31 +452,41 @@ func SetupLogger(ctx *cli.Context) {
glog.SetLogDir(ctx.GlobalString(LogFileFlag.Name))
}
// SetupVM configured the VM package's global settings
func SetupVM(ctx *cli.Context) {
vm.EnableJit = ctx.GlobalBool(VMEnableJitFlag.Name)
vm.ForceJit = ctx.GlobalBool(VMForceJitFlag.Name)
vm.SetJITCacheSize(ctx.GlobalInt(VMJitCacheFlag.Name))
}
// MakeChain creates a chain manager from set command line flags.
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) {
dd := ctx.GlobalString(DataDirFlag.Name)
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, chainDb common.Database) {
datadir := ctx.GlobalString(DataDirFlag.Name)
cache := ctx.GlobalInt(CacheFlag.Name)
var err error
if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "blockchain")); err != nil {
if chainDb, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache); err != nil {
Fatalf("Could not open database: %v", err)
}
if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "state")); err != nil {
Fatalf("Could not open database: %v", err)
}
if extraDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "extra")); err != nil {
Fatalf("Could not open database: %v", err)
if ctx.GlobalBool(OlympicFlag.Name) {
InitOlympic()
_, err := core.WriteTestNetGenesisBlock(chainDb, 42)
if err != nil {
glog.Fatalln(err)
}
}
eventMux := new(event.TypeMux)
pow := ethash.New()
genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
chain, err = core.NewChainManager(genesis, blockDB, stateDB, pow, eventMux)
//genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
chain, err = core.NewChainManager(chainDb, pow, eventMux)
if err != nil {
Fatalf("Could not start chainmanager: %v", err)
}
proc := core.NewBlockProcessor(stateDB, extraDB, pow, chain, eventMux)
proc := core.NewBlockProcessor(chainDb, pow, chain, eventMux)
chain.SetProcessor(proc)
return chain, blockDB, stateDB, extraDB
return chain, chainDb
}
// MakeChain creates an account manager from set command line flags.
@ -436,19 +497,19 @@ func MakeAccountManager(ctx *cli.Context) *accounts.Manager {
}
func IpcSocketPath(ctx *cli.Context) (ipcpath string) {
if common.IsWindows() {
if runtime.GOOS == "windows" {
ipcpath = common.DefaultIpcPath()
if ipcpath != ctx.GlobalString(IPCPathFlag.Name) {
if ctx.GlobalIsSet(IPCPathFlag.Name) {
ipcpath = ctx.GlobalString(IPCPathFlag.Name)
}
} else {
ipcpath = common.DefaultIpcPath()
if ctx.GlobalString(IPCPathFlag.Name) != common.DefaultIpcPath() {
ipcpath = ctx.GlobalString(IPCPathFlag.Name)
} else if ctx.GlobalString(DataDirFlag.Name) != "" &&
ctx.GlobalString(DataDirFlag.Name) != common.DefaultDataDir() {
if ctx.GlobalIsSet(DataDirFlag.Name) {
ipcpath = filepath.Join(ctx.GlobalString(DataDirFlag.Name), "geth.ipc")
}
if ctx.GlobalIsSet(IPCPathFlag.Name) {
ipcpath = ctx.GlobalString(IPCPathFlag.Name)
}
}
return
@ -459,15 +520,20 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
Endpoint: IpcSocketPath(ctx),
}
xeth := xeth.New(eth, nil)
codec := codec.JSON
initializer := func(conn net.Conn) (shared.EthereumApi, error) {
fe := useragent.NewRemoteFrontend(conn, eth.AccountManager())
xeth := xeth.New(eth, fe)
codec := codec.JSON
apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
if err != nil {
return err
apis, err := api.ParseApiString(ctx.GlobalString(IPCApiFlag.Name), codec, xeth, eth)
if err != nil {
return nil, err
}
return api.Merge(apis...), nil
}
return comms.StartIpc(config, codec, api.Merge(apis...))
return comms.StartIpc(config, codec.JSON, initializer)
}
func StartRPC(eth *eth.Ethereum, ctx *cli.Context) error {
@ -494,3 +560,20 @@ func StartPProf(ctx *cli.Context) {
log.Println(http.ListenAndServe(address, nil))
}()
}
func ParamToAddress(addr string, am *accounts.Manager) (addrHex string, err error) {
if !((len(addr) == 40) || (len(addr) == 42)) { // with or without 0x
index, err := strconv.Atoi(addr)
if err != nil {
Fatalf("Invalid account address '%s'", addr)
}
addrHex, err = am.AddressByIndex(index)
if err != nil {
return "", err
}
} else {
addrHex = addr
}
return
}

41
cmd/utils/legalese.go Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
package utils
const (
legalese = `
=======================================
Disclaimer of Liabilites and Warranties
=======================================
THE USER EXPRESSLY KNOWS AND AGREES THAT THE USER IS USING THE ETHEREUM PLATFORM AT THE USERS SOLE
RISK. THE USER REPRESENTS THAT THE USER HAS AN ADEQUATE UNDERSTANDING OF THE RISKS, USAGE AND
INTRICACIES OF CRYPTOGRAPHIC TOKENS AND BLOCKCHAIN-BASED OPEN SOURCE SOFTWARE, ETH PLATFORM AND ETH.
THE USER ACKNOWLEDGES AND AGREES THAT, TO THE FULLEST EXTENT PERMITTED BY ANY APPLICABLE LAW, THE
DISCLAIMERS OF LIABILITY CONTAINED HEREIN APPLY TO ANY AND ALL DAMAGES OR INJURY WHATSOEVER CAUSED
BY OR RELATED TO RISKS OF, USE OF, OR INABILITY TO USE, ETH OR THE ETHEREUM PLATFORM UNDER ANY CAUSE
OR ACTION WHATSOEVER OF ANY KIND IN ANY JURISDICTION, INCLUDING, WITHOUT LIMITATION, ACTIONS FOR
BREACH OF WARRANTY, BREACH OF CONTRACT OR TORT (INCLUDING NEGLIGENCE) AND THAT NEITHER STIFTUNG
ETHEREUM NOR ETHEREUM TEAM SHALL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
CONSEQUENTIAL DAMAGES, INCLUDING FOR LOSS OF PROFITS, GOODWILL OR DATA. SOME JURISDICTIONS DO NOT
ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR THE LIMITATION OR EXCLUSION OF LIABILITY FOR CERTAIN
TYPES OF DAMAGES. THEREFORE, SOME OF THE ABOVE LIMITATIONS IN THIS SECTION MAY NOT APPLY TO A USER.
IN PARTICULAR, NOTHING IN THESE TERMS SHALL AFFECT THE STATUTORY RIGHTS OF ANY USER OR EXCLUDE
INJURY ARISING FROM ANY WILLFUL MISCONDUCT OR FRAUD OF STIFTUNG ETHEREUM.
Do you accept this agreement?`
)

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import "math/big"

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (

View File

@ -1,3 +1,20 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package common contains various helper functions.
package common
import (

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package compiler
import (
@ -185,12 +201,12 @@ func (sol *Solidity) Compile(source string) (contracts map[string]*Contract, err
return
}
func ExtractInfo(contract *Contract, filename string) (contenthash common.Hash, err error) {
contractInfo, err := json.Marshal(contract.Info)
func SaveInfo(info *ContractInfo, filename string) (contenthash common.Hash, err error) {
infojson, err := json.Marshal(info)
if err != nil {
return
}
contenthash = common.BytesToHash(crypto.Sha3(contractInfo))
err = ioutil.WriteFile(filename, contractInfo, 0600)
contenthash = common.BytesToHash(crypto.Sha3(infojson))
err = ioutil.WriteFile(filename, infojson, 0600)
return
}

View File

@ -1,9 +1,26 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package compiler
import (
"encoding/json"
"io/ioutil"
"os"
"path"
"testing"
"github.com/ethereum/go-ethereum/common"
@ -72,19 +89,15 @@ func TestNoCompiler(t *testing.T) {
}
}
func TestExtractInfo(t *testing.T) {
func TestSaveInfo(t *testing.T) {
var cinfo ContractInfo
err := json.Unmarshal([]byte(info), &cinfo)
if err != nil {
t.Errorf("%v", err)
}
contract := &Contract{
Code: "",
Info: cinfo,
}
filename := "/tmp/solctest.info.json"
filename := path.Join(os.TempDir(), "solctest.info.json")
os.Remove(filename)
cinfohash, err := ExtractInfo(contract, filename)
cinfohash, err := SaveInfo(&cinfo, filename)
if err != nil {
t.Errorf("error extracting info: %v", err)
}
@ -98,4 +111,4 @@ func TestExtractInfo(t *testing.T) {
if cinfohash != infohash {
t.Errorf("content hash for info is incorrect. expected %v, got %v", infohash.Hex(), cinfohash.Hex())
}
}
}

View File

@ -1,67 +0,0 @@
package common
import (
"flag"
"fmt"
"os"
"github.com/rakyll/globalconf"
)
// Config struct
type ConfigManager struct {
ExecPath string
Debug bool
Diff bool
DiffType string
Paranoia bool
VmType int
conf *globalconf.GlobalConf
}
// Read config
//
// Initialize Config from Config File
func ReadConfig(ConfigFile string, Datadir string, EnvPrefix string) *ConfigManager {
if !FileExist(ConfigFile) {
// create ConfigFile if it does not exist, otherwise
// globalconf will panic when trying to persist flags.
fmt.Printf("config file '%s' doesn't exist, creating it\n", ConfigFile)
os.Create(ConfigFile)
}
g, err := globalconf.NewWithOptions(&globalconf.Options{
Filename: ConfigFile,
EnvPrefix: EnvPrefix,
})
if err != nil {
fmt.Println(err)
} else {
g.ParseAll()
}
cfg := &ConfigManager{ExecPath: Datadir, Debug: true, conf: g, Paranoia: true}
return cfg
}
// provides persistence for flags
func (c *ConfigManager) Save(key string, value interface{}) {
f := &flag.Flag{Name: key, Value: newConfValue(value)}
c.conf.Set("", f)
}
func (c *ConfigManager) Delete(key string) {
c.conf.Delete("", key)
}
// private type implementing flag.Value
type confValue struct {
value string
}
// generic constructor to allow persising non-string values directly
func newConfValue(value interface{}) *confValue {
return &confValue{fmt.Sprintf("%v", value)}
}
func (self confValue) String() string { return self.value }
func (self confValue) Set(s string) error { self.value = s; return nil }

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
// Database interface

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (

View File

@ -1,37 +1,44 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package docserver
import (
"fmt"
"io/ioutil"
"net/http"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// http://golang.org/pkg/net/http/#RoundTripper
var (
schemes = map[string]func(*DocServer) http.RoundTripper{
// Simple File server from local disk file:///etc/passwd :)
"file": fileServerOnDocRoot,
}
)
func fileServerOnDocRoot(ds *DocServer) http.RoundTripper {
return http.NewFileTransport(http.Dir(ds.DocRoot))
}
type DocServer struct {
*http.Transport
DocRoot string
schemes []string
}
func New(docRoot string) (self *DocServer, err error) {
func New(docRoot string) (self *DocServer) {
self = &DocServer{
Transport: &http.Transport{},
DocRoot: docRoot,
schemes: []string{"file"},
}
err = self.RegisterProtocols(schemes)
self.RegisterProtocol("file", http.NewFileTransport(http.Dir(self.DocRoot)))
return
}
@ -45,16 +52,44 @@ func (self *DocServer) Client() *http.Client {
}
}
func (self *DocServer) RegisterProtocols(schemes map[string]func(*DocServer) http.RoundTripper) (err error) {
for scheme, rtf := range schemes {
self.RegisterProtocol(scheme, rtf(self))
func (self *DocServer) RegisterScheme(scheme string, rt http.RoundTripper) {
self.schemes = append(self.schemes, scheme)
self.RegisterProtocol(scheme, rt)
}
func (self *DocServer) HasScheme(scheme string) bool {
for _, s := range self.schemes {
if s == scheme {
return true
}
}
return
return false
}
func (self *DocServer) GetAuthContent(uri string, hash common.Hash) (content []byte, err error) {
// retrieve content
content, err = self.Get(uri, "")
if err != nil {
return
}
// check hash to authenticate content
chash := crypto.Sha3Hash(content)
if chash != hash {
content = nil
err = fmt.Errorf("content hash mismatch %x != %x (exp)", hash[:], chash[:])
}
return
}
// Get(uri, path) downloads the document at uri, if path is non-empty it
// is interpreted as a filepath to which the contents are saved
func (self *DocServer) Get(uri, path string) (content []byte, err error) {
// retrieve content
resp, err := self.Client().Get(uri)
defer func() {
if resp != nil {
resp.Body.Close()
@ -68,13 +103,10 @@ func (self *DocServer) GetAuthContent(uri string, hash common.Hash) (content []b
return
}
// check hash to authenticate content
hashbytes := crypto.Sha3(content)
var chash common.Hash
copy(chash[:], hashbytes)
if chash != hash {
content = nil
err = fmt.Errorf("content hash mismatch")
if path != "" {
var abspath string
abspath, err = filepath.Abs(path)
ioutil.WriteFile(abspath, content, 0700)
}
return

View File

@ -1,8 +1,26 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package docserver
import (
"io/ioutil"
"net/http"
"os"
"path"
"testing"
"github.com/ethereum/go-ethereum/common"
@ -10,12 +28,18 @@ import (
)
func TestGetAuthContent(t *testing.T) {
text := "test"
hash := common.Hash{}
copy(hash[:], crypto.Sha3([]byte(text)))
ioutil.WriteFile("/tmp/test.content", []byte(text), os.ModePerm)
dir, err := ioutil.TempDir("", "docserver-test")
if err != nil {
t.Fatal("cannot create temporary directory:", err)
}
defer os.RemoveAll(dir)
ds := New(dir)
ds, err := New("/tmp/")
text := "test"
hash := crypto.Sha3Hash([]byte(text))
if err := ioutil.WriteFile(path.Join(dir, "test.content"), []byte(text), os.ModePerm); err != nil {
t.Fatal("could not write test file", err)
}
content, err := ds.GetAuthContent("file:///test.content", hash)
if err != nil {
t.Errorf("no error expected, got %v", err)
@ -26,7 +50,7 @@ func TestGetAuthContent(t *testing.T) {
hash = common.Hash{}
content, err = ds.GetAuthContent("file:///test.content", hash)
expected := "content hash mismatch"
expected := "content hash mismatch 0000000000000000000000000000000000000000000000000000000000000000 != 9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658 (exp)"
if err == nil {
t.Errorf("expected error, got nothing")
} else {
@ -36,3 +60,18 @@ func TestGetAuthContent(t *testing.T) {
}
}
type rt struct{}
func (rt) RoundTrip(req *http.Request) (resp *http.Response, err error) { return }
func TestRegisterScheme(t *testing.T) {
ds := New("/tmp/")
if ds.HasScheme("scheme") {
t.Errorf("expected scheme not to be registered")
}
ds.RegisterScheme("scheme", rt{})
if !ds.HasScheme("scheme") {
t.Errorf("expected scheme to be registered")
}
}

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package math
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package math
import (

View File

@ -1,17 +1,33 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package natspec
import (
"bytes"
"encoding/json"
"fmt"
"github.com/robertkrimen/otto"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/resolver"
"github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/xeth"
"github.com/robertkrimen/otto"
)
type abi2method map[[8]byte]*method
@ -88,7 +104,7 @@ func New(xeth *xeth.XEth, jsontx string, http *docserver.DocServer) (self *NatSp
}
// also called by admin.contractInfo.get
func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, http *docserver.DocServer) (content []byte, err error) {
func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, ds *docserver.DocServer) (content []byte, err error) {
// retrieve contract hash from state
codehex := xeth.CodeAt(contractAddress)
codeb := xeth.CodeAtBytes(contractAddress)
@ -99,20 +115,32 @@ func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, http *docserv
}
codehash := common.BytesToHash(crypto.Sha3(codeb))
// set up nameresolver with natspecreg + urlhint contract addresses
res := resolver.New(xeth)
reg := registrar.New(xeth)
// resolve host via HashReg/UrlHint Resolver
uri, hash, err := res.KeyToUrl(codehash)
hash, err := reg.HashToHash(codehash)
if err != nil {
return
}
if ds.HasScheme("bzz") {
content, err = ds.Get("bzz://"+hash.Hex()[2:], "")
if err == nil { // non-fatal
return
}
err = nil
//falling back to urlhint
}
uri, err := reg.HashToUrl(hash)
if err != nil {
return
}
// get content via http client and authenticate content using hash
content, err = http.GetAuthContent(uri, hash)
content, err = ds.GetAuthContent(uri, hash)
if err != nil {
return
}
return
}

View File

@ -1,20 +1,39 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package natspec
import (
"fmt"
"io/ioutil"
"math/big"
"os"
"runtime"
"strings"
"testing"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/resolver"
"github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
xe "github.com/ethereum/go-ethereum/xeth"
)
@ -73,13 +92,10 @@ const (
)
type testFrontend struct {
t *testing.T
// resolver *resolver.Resolver
t *testing.T
ethereum *eth.Ethereum
xeth *xe.XEth
coinbase common.Address
stateDb *state.StateDB
txc uint64
wait chan *big.Int
lastConfirm string
wantNatSpec bool
}
@ -91,10 +107,7 @@ func (self *testFrontend) UnlockAccount(acc []byte) bool {
func (self *testFrontend) ConfirmTransaction(tx string) bool {
if self.wantNatSpec {
ds, err := docserver.New("/tmp/")
if err != nil {
self.t.Errorf("Error creating DocServer: %v", err)
}
ds := docserver.New("/tmp/")
self.lastConfirm = GetNotice(self.xeth, tx, ds)
}
return true
@ -116,18 +129,21 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
if err != nil {
panic(err)
}
testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x")
db, _ := ethdb.NewMemDatabase()
// set up mock genesis with balance on the testAddress
core.GenesisAccounts = []byte(`{
"` + testAddress + `": {"balance": "` + testBalance + `"}
}`)
core.WriteGenesisBlockForTesting(db, common.HexToAddress(testAddress), common.String2Big(testBalance))
// only use minimalistic stack with no networking
ethereum, err = eth.New(&eth.Config{
DataDir: "/tmp/eth-natspec",
AccountManager: am,
MaxPeers: 0,
PowTest: true,
Etherbase: common.HexToAddress(testAddress),
NewDB: func(path string) (common.Database, error) { return db, nil },
})
if err != nil {
@ -153,86 +169,106 @@ func testInit(t *testing.T) (self *testFrontend) {
// mock frontend
self = &testFrontend{t: t, ethereum: ethereum}
self.xeth = xe.New(ethereum, self)
addr, _ := ethereum.Etherbase()
self.coinbase = addr
self.stateDb = self.ethereum.ChainManager().State().Copy()
self.wait = self.xeth.UpdateState()
addr, _ := self.ethereum.Etherbase()
// initialise the registry contracts
// self.resolver.CreateContracts(addr)
resolver.New(self.xeth).CreateContracts(addr)
self.applyTxs()
// t.Logf("HashReg contract registered at %v", resolver.HashRegContractAddress)
// t.Logf("URLHint contract registered at %v", resolver.UrlHintContractAddress)
reg := registrar.New(self.xeth)
var registrarTxhash, hashRegTxhash, urlHintTxhash string
registrarTxhash, err = reg.SetGlobalRegistrar("", addr)
if err != nil {
t.Errorf("error creating GlobalRegistrar: %v", err)
}
hashRegTxhash, err = reg.SetHashReg("", addr)
if err != nil {
t.Errorf("error creating HashReg: %v", err)
}
urlHintTxhash, err = reg.SetUrlHint("", addr)
if err != nil {
t.Errorf("error creating UrlHint: %v", err)
}
if !processTxs(self, t, 3) {
t.Errorf("error mining txs")
}
_ = registrarTxhash
_ = hashRegTxhash
_ = urlHintTxhash
/* TODO:
* lookup receipt and contract addresses by tx hash
* name registration for HashReg and UrlHint addresses
* mine those transactions
* then set once more SetHashReg SetUrlHint
*/
return
}
// this is needed for transaction to be applied to the state in testing
// the heavy lifing is done in XEth.ApplyTestTxs
// this is fragile,
// and does process leaking since xeth loops cannot quit safely
// should be replaced by proper mining with testDAG for easy full integration tests
func (self *testFrontend) applyTxs() {
self.txc, self.xeth = self.xeth.ApplyTestTxs(self.stateDb, self.coinbase, self.txc)
return
}
// end to end test
func TestNatspecE2E(t *testing.T) {
t.Skip()
tf := testInit(t)
defer tf.ethereum.Stop()
addr, _ := tf.ethereum.Etherbase()
// create a contractInfo file (mock cloud-deployed contract metadocs)
// incidentally this is the info for the registry contract itself
ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
dochash := common.BytesToHash(crypto.Sha3([]byte(testContractInfo)))
dochash := crypto.Sha3Hash([]byte(testContractInfo))
// take the codehash for the contract we wanna test
// codehex := tf.xeth.CodeAt(resolver.HashRegContractAddress)
codeb := tf.xeth.CodeAtBytes(resolver.HashRegContractAddress)
codehash := common.BytesToHash(crypto.Sha3(codeb))
codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
codehash := crypto.Sha3Hash(codeb)
// use resolver to register codehash->dochash->url
registry := resolver.New(tf.xeth)
_, err := registry.Register(tf.coinbase, codehash, dochash, "file:///"+testFileName)
// test if globalregistry works
// registrar.HashRefAddr = "0x0"
// registrar.UrlHintAddr = "0x0"
reg := registrar.New(tf.xeth)
_, err := reg.SetHashToHash(addr, codehash, dochash)
if err != nil {
t.Errorf("error registering: %v", err)
}
// apply txs to the state
tf.applyTxs()
_, err = reg.SetUrlToHash(addr, dochash, "file:///"+testFileName)
if err != nil {
t.Errorf("error registering: %v", err)
}
if !processTxs(tf, t, 5) {
return
}
// NatSpec info for register method of HashReg contract installed
// now using the same transactions to check confirm messages
tf.wantNatSpec = true // this is set so now the backend uses natspec confirmation
_, err = registry.RegisterContentHash(tf.coinbase, codehash, dochash)
_, err = reg.SetHashToHash(addr, codehash, dochash)
if err != nil {
t.Errorf("error calling contract registry: %v", err)
}
fmt.Printf("GlobalRegistrar: %v, HashReg: %v, UrlHint: %v\n", registrar.GlobalRegistrarAddr, registrar.HashRegAddr, registrar.UrlHintAddr)
if tf.lastConfirm != testExpNotice {
t.Errorf("Wrong confirm message. expected '%v', got '%v'", testExpNotice, tf.lastConfirm)
t.Errorf("Wrong confirm message. expected\n'%v', got\n'%v'", testExpNotice, tf.lastConfirm)
}
// test unknown method
exp := fmt.Sprintf(testExpNotice2, resolver.HashRegContractAddress)
_, err = registry.SetOwner(tf.coinbase)
exp := fmt.Sprintf(testExpNotice2, registrar.HashRegAddr)
_, err = reg.SetOwner(addr)
if err != nil {
t.Errorf("error setting owner: %v", err)
}
if tf.lastConfirm != exp {
t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
t.Errorf("Wrong confirm message, expected\n'%v', got\n'%v'", exp, tf.lastConfirm)
}
// test unknown contract
exp = fmt.Sprintf(testExpNotice3, resolver.UrlHintContractAddress)
exp = fmt.Sprintf(testExpNotice3, registrar.UrlHintAddr)
_, err = registry.RegisterUrl(tf.coinbase, dochash, "file:///test.content")
_, err = reg.SetUrlToHash(addr, dochash, "file:///test.content")
if err != nil {
t.Errorf("error registering: %v", err)
}
@ -242,3 +278,63 @@ func TestNatspecE2E(t *testing.T) {
}
}
func pendingTransactions(repl *testFrontend, t *testing.T) (txc int64, err error) {
txs := repl.ethereum.TxPool().GetTransactions()
return int64(len(txs)), nil
}
func processTxs(repl *testFrontend, t *testing.T, expTxc int) bool {
var txc int64
var err error
for i := 0; i < 50; i++ {
txc, err = pendingTransactions(repl, t)
if err != nil {
t.Errorf("unexpected error checking pending transactions: %v", err)
return false
}
if expTxc < int(txc) {
t.Errorf("too many pending transactions: expected %v, got %v", expTxc, txc)
return false
} else if expTxc == int(txc) {
break
}
time.Sleep(100 * time.Millisecond)
}
if int(txc) != expTxc {
t.Errorf("incorrect number of pending transactions, expected %v, got %v", expTxc, txc)
return false
}
err = repl.ethereum.StartMining(runtime.NumCPU())
if err != nil {
t.Errorf("unexpected error mining: %v", err)
return false
}
defer repl.ethereum.StopMining()
timer := time.NewTimer(100 * time.Second)
height := new(big.Int).Add(repl.xeth.CurrentBlock().Number(), big.NewInt(1))
repl.wait <- height
select {
case <-timer.C:
// if times out make sure the xeth loop does not block
go func() {
select {
case repl.wait <- nil:
case <-repl.wait:
}
}()
case <-repl.wait:
}
txc, err = pendingTransactions(repl, t)
if err != nil {
t.Errorf("unexpected error checking pending transactions: %v", err)
return false
}
if txc != 0 {
t.Errorf("%d trasactions were not mined", txc)
return false
}
return true
}

View File

@ -0,0 +1,253 @@
package natspec
import (
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/registrar"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
xe "github.com/ethereum/go-ethereum/xeth"
)
const (
testBalance = "10000000000000000000"
testFileName = "long_file_name_for_testing_registration_of_URLs_longer_than_32_bytes.content"
testNotice = "Register key `utils.toHex(_key)` <- content `utils.toHex(_content)`"
testExpNotice = "Register key 0xadd1a7d961cff0242089674ec2ef6fca671ab15e1fe80e38859fc815b98d88ab <- content 0xb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7"
testExpNotice2 = `About to submit transaction (NatSpec notice error: abi key does not match any method): {"params":[{"to":"%s","data": "0x31e12c20"}]}`
testExpNotice3 = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x1392c62d05b2d149e22a339c531157ae06b44d39a674cce500064b12b9aeb019'): {"params":[{"to":"%s","data": "0x300a3bbfb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}`
)
const (
testUserDoc = `
{
"methods": {
"register(uint256,uint256)": {
"notice": "` + testNotice + `"
}
},
"invariants": [
{ "notice": "" }
],
"construction": [
{ "notice": "" }
]
}
`
testAbiDefinition = `
[{
"name": "register",
"constant": false,
"type": "function",
"inputs": [{
"name": "_key",
"type": "uint256"
}, {
"name": "_content",
"type": "uint256"
}],
"outputs": []
}]
`
testContractInfo = `
{
"userDoc": ` + testUserDoc + `,
"abiDefinition": ` + testAbiDefinition + `
}
`
)
type testFrontend struct {
t *testing.T
ethereum *eth.Ethereum
xeth *xe.XEth
coinbase common.Address
stateDb *state.StateDB
txc uint64
lastConfirm string
wantNatSpec bool
}
func (self *testFrontend) UnlockAccount(acc []byte) bool {
self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "password")
return true
}
func (self *testFrontend) ConfirmTransaction(tx string) bool {
if self.wantNatSpec {
ds := docserver.New("/tmp/")
self.lastConfirm = GetNotice(self.xeth, tx, ds)
}
return true
}
func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
os.RemoveAll("/tmp/eth-natspec/")
err = os.MkdirAll("/tmp/eth-natspec/keystore", os.ModePerm)
if err != nil {
panic(err)
}
// create a testAddress
ks := crypto.NewKeyStorePassphrase("/tmp/eth-natspec/keystore")
am := accounts.NewManager(ks)
testAccount, err := am.NewAccount("password")
if err != nil {
panic(err)
}
testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x")
// set up mock genesis with balance on the testAddress
core.GenesisAccounts = []byte(`{
"` + testAddress + `": {"balance": "` + testBalance + `"}
}`)
// only use minimalistic stack with no networking
ethereum, err = eth.New(&eth.Config{
DataDir: "/tmp/eth-natspec",
AccountManager: am,
MaxPeers: 0,
})
if err != nil {
panic(err)
}
return
}
func testInit(t *testing.T) (self *testFrontend) {
// initialise and start minimal ethereum stack
ethereum, err := testEth(t)
if err != nil {
t.Errorf("error creating ethereum: %v", err)
return
}
err = ethereum.Start()
if err != nil {
t.Errorf("error starting ethereum: %v", err)
return
}
// mock frontend
self = &testFrontend{t: t, ethereum: ethereum}
self.xeth = xe.New(ethereum, self)
addr, _ := ethereum.Etherbase()
self.coinbase = addr
self.stateDb = self.ethereum.ChainManager().State().Copy()
// initialise the registry contracts
reg := registrar.New(self.xeth)
err = reg.SetHashReg("", addr)
if err != nil {
t.Errorf("error creating HashReg: %v", err)
}
err = reg.SetUrlHint("", addr)
if err != nil {
t.Errorf("error creating UrlHint: %v", err)
}
self.applyTxs()
return
}
// this is needed for transaction to be applied to the state in testing
// the heavy lifing is done in XEth.ApplyTestTxs
// this is fragile,
// and does process leaking since xeth loops cannot quit safely
// should be replaced by proper mining with testDAG for easy full integration tests
func (self *testFrontend) applyTxs() {
self.txc, self.xeth = self.xeth.ApplyTestTxs(self.stateDb, self.coinbase, self.txc)
return
}
// end to end test
func TestNatspecE2E(t *testing.T) {
t.Skip()
tf := testInit(t)
defer tf.ethereum.Stop()
// create a contractInfo file (mock cloud-deployed contract metadocs)
// incidentally this is the info for the registry contract itself
ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
dochash := common.BytesToHash(crypto.Sha3([]byte(testContractInfo)))
// take the codehash for the contract we wanna test
// codehex := tf.xeth.CodeAt(registar.HashRegAddr)
codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
codehash := common.BytesToHash(crypto.Sha3(codeb))
// use resolver to register codehash->dochash->url
// test if globalregistry works
// registrar.HashRefAddr = "0x0"
// registrar.UrlHintAddr = "0x0"
reg := registrar.New(tf.xeth)
_, err := reg.SetHashToHash(tf.coinbase, codehash, dochash)
if err != nil {
t.Errorf("error registering: %v", err)
}
_, err = reg.SetUrlToHash(tf.coinbase, dochash, "file:///"+testFileName)
if err != nil {
t.Errorf("error registering: %v", err)
}
// apply txs to the state
tf.applyTxs()
// NatSpec info for register method of HashReg contract installed
// now using the same transactions to check confirm messages
tf.wantNatSpec = true // this is set so now the backend uses natspec confirmation
_, err = reg.SetHashToHash(tf.coinbase, codehash, dochash)
if err != nil {
t.Errorf("error calling contract registry: %v", err)
}
fmt.Printf("GlobalRegistrar: %v, HashReg: %v, UrlHint: %v\n", registrar.GlobalRegistrarAddr, registrar.HashRegAddr, registrar.UrlHintAddr)
if tf.lastConfirm != testExpNotice {
t.Errorf("Wrong confirm message. expected '%v', got '%v'", testExpNotice, tf.lastConfirm)
}
// test unknown method
exp := fmt.Sprintf(testExpNotice2, registrar.HashRegAddr)
_, err = reg.SetOwner(tf.coinbase)
if err != nil {
t.Errorf("error setting owner: %v", err)
}
if tf.lastConfirm != exp {
t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
}
// test unknown contract
exp = fmt.Sprintf(testExpNotice3, registrar.UrlHintAddr)
_, err = reg.SetUrlToHash(tf.coinbase, dochash, "file:///test.content")
if err != nil {
t.Errorf("error registering: %v", err)
}
if tf.lastConfirm != exp {
t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package natspec
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package number
import (

View File

@ -1,3 +1,19 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package number
import (

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (

View File

@ -1,3 +1,19 @@
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package common
import (
@ -100,14 +116,3 @@ func DefaultIpcPath() string {
}
return filepath.Join(DefaultDataDir(), "geth.ipc")
}
func IsWindows() bool {
return runtime.GOOS == "windows"
}
func WindonizePath(path string) string {
if string(path[0]) == "/" && IsWindows() {
path = path[1:]
}
return path
}

View File

@ -1,36 +0,0 @@
package common
import (
"os"
// "testing"
checker "gopkg.in/check.v1"
)
type CommonSuite struct{}
var _ = checker.Suite(&CommonSuite{})
func (s *CommonSuite) TestOS(c *checker.C) {
expwin := (os.PathSeparator == '\\' && os.PathListSeparator == ';')
res := IsWindows()
if !expwin {
c.Assert(res, checker.Equals, expwin, checker.Commentf("IsWindows is", res, "but path is", os.PathSeparator))
} else {
c.Assert(res, checker.Not(checker.Equals), expwin, checker.Commentf("IsWindows is", res, "but path is", os.PathSeparator))
}
}
func (s *CommonSuite) TestWindonziePath(c *checker.C) {
iswindowspath := os.PathSeparator == '\\'
path := "/opt/eth/test/file.ext"
res := WindonizePath(path)
ressep := string(res[0])
if !iswindowspath {
c.Assert(ressep, checker.Equals, "/")
} else {
c.Assert(ressep, checker.Not(checker.Equals), "/")
}
}

Some files were not shown because too many files have changed in this diff Show More