Compare commits

..

36 Commits

Author SHA1 Message Date
0cdc7647aa tests: updated 2015-07-29 15:59:33 +02:00
c5d7faefe9 eth, eth/downloader: don't report stall if fetcher filled the block 2015-07-29 15:39:01 +02:00
d7211dec79 etherbase defaults to first account even if created during the session 2015-07-28 14:12:49 +02:00
cea2c0eedf all: fix license headers one more time
I forgot to update one instance of "go-ethereum" in commit 3f047be5a.

Conflicts:
	common/config.go
2015-07-28 14:02:23 +02:00
b738172dcc Godeps: use BSD-licensed version of gopkg.in/karalabe/cookiejar.v2 2015-07-28 13:33:02 +02:00
abdc3d3c77 crypto/sha3: add full license headers 2015-07-28 13:32:52 +02:00
80901e8288 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).

Conflicts:
	common/config.go
2015-07-28 13:32:39 +02:00
465796c3a8 web3: fixed toHex 2015-07-27 12:21:30 +02:00
9c05284bd1 core: genesis extra data field fix 2015-07-26 14:46:07 +02:00
56edaa1653 xeth: fix #1485, data race in fiilter creation and event firing 2015-07-26 13:11:51 +02:00
8865fda872 params: reduce extra data to 32 bytes 2015-07-26 13:04:56 +02:00
b0df9b164c core: fixed genesis write out to write only canon number 2015-07-25 21:52:37 +02:00
72188234aa eth: set default miner extra to client name 2015-07-25 17:59:26 +02:00
8c0619d29c core: 5 ether block reward 2015-07-25 17:59:19 +02:00
16a3a4303f cmd/util: lowered default gas price 2015-07-25 17:16:26 +02:00
eaed7584f1 core: check genesis block before writeout 2015-07-25 16:54:51 +02:00
0262ba58cb web3: updated 0.9.1 2015-07-25 12:24:39 +02:00
e088998867 core: 5 ether block reward 2015-07-25 12:06:17 +02:00
db5ec711e8 cmd/geth, core, eth: Version 1.0.0
Genesis release. Closes #1402
2015-07-23 10:46:38 +02:00
9d49c80783 remove LICENSE files 2015-07-23 10:46:38 +02:00
b1fdb9f38e 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-23 10:46:37 +02:00
a606dc274b 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-23 10:46:37 +02:00
c9d6fba07d miner: fix current work data race 2015-07-23 10:41:49 +02:00
228fc5a83a xeth: removed unneeded mutex lock 2015-07-23 10:41:49 +02:00
c28dc03f6d xeth: log signed tx hash 2015-07-23 10:41:49 +02:00
dcb276a0dd Fixed canary to require 2+ nonzero, not sum 2+ 2015-07-22 14:36:33 +02:00
53864a73db Update disclaimer 2015-07-22 13:36:21 +02:00
cf65a127e1 Move text to separate file 2015-07-22 13:35:00 +02:00
fd64dce6a5 Prompt user to accept legalese when datadir doesn't exist 2015-07-22 13:35:00 +02:00
d60b07249c 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-22 13:34:16 +02:00
7b99278eb0 rlp: reject trailing data when using DecodeBytes 2015-07-22 13:34:16 +02:00
aaf8ae1d0b tests: document RLP tests 2015-07-22 13:34:16 +02:00
a83fdd0046 cmd/ethtest, tests: add support for RLP JSON tests 2015-07-22 13:33:05 +02:00
b1a219b0ec 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-22 13:27:19 +02:00
487b3b0f7b 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-22 13:26:27 +02:00
4ca3d49307 ethdb, trie: removed RLE compression 2015-07-22 13:24:30 +02:00
79 changed files with 789 additions and 2695 deletions

View File

@ -1,6 +1,9 @@
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
@ -19,11 +22,7 @@ after_success:
env:
global:
- secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64="
sudo: false
addons:
apt:
packages:
- libgmp3-dev
notifications:
webhooks:
urls:

View File

@ -9,8 +9,6 @@ import (
"net/http"
"sync"
"time"
"github.com/ethereum/go-ethereum/fdtrack"
)
// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical
@ -27,7 +25,6 @@ func NewHTTPUClient() (*HTTPUClient, error) {
if err != nil {
return nil, err
}
fdtrack.Open("upnp")
return &HTTPUClient{conn: conn}, nil
}
@ -36,7 +33,6 @@ func NewHTTPUClient() (*HTTPUClient, error) {
func (httpu *HTTPUClient) Close() error {
httpu.connLock.Lock()
defer httpu.connLock.Unlock()
fdtrack.Close("upnp")
return httpu.conn.Close()
}

View File

@ -7,12 +7,9 @@ import (
"encoding/xml"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"reflect"
"github.com/ethereum/go-ethereum/fdtrack"
)
const (
@ -29,17 +26,6 @@ type SOAPClient struct {
func NewSOAPClient(endpointURL url.URL) *SOAPClient {
return &SOAPClient{
EndpointURL: endpointURL,
HTTPClient: http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
c, err := net.Dial(network, addr)
if c != nil {
c = fdtrack.WrapConn("upnp", c)
}
return c, err
},
},
},
}
}

View File

@ -5,8 +5,6 @@ import (
"log"
"net"
"time"
"github.com/ethereum/go-ethereum/fdtrack"
)
// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
@ -104,8 +102,6 @@ func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) {
if err != nil {
return
}
fdtrack.Open("natpmp")
defer fdtrack.Close("natpmp")
defer conn.Close()
result = make([]byte, resultSize)

View File

@ -18,7 +18,6 @@ import (
"sync"
"time"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/syndtr/goleveldb/leveldb/util"
)
@ -370,8 +369,6 @@ func (fw fileWrap) Close() error {
err := fw.File.Close()
if err != nil {
f.fs.log(fmt.Sprintf("close %s.%d: %v", f.Type(), f.Num(), err))
} else {
fdtrack.Close("leveldb")
}
return err
}
@ -403,7 +400,6 @@ func (f *file) Open() (Reader, error) {
return nil, err
}
ok:
fdtrack.Open("leveldb")
f.open = true
f.fs.open++
return fileWrap{of, f}, nil
@ -422,7 +418,6 @@ func (f *file) Create() (Writer, error) {
if err != nil {
return nil, err
}
fdtrack.Open("leveldb")
f.open = true
f.fs.open++
return fileWrap{of, f}, nil

View File

@ -78,8 +78,8 @@ func (am *Manager) DeleteAccount(address common.Address, auth string) error {
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
}
@ -87,17 +87,14 @@ func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error)
return signature, err
}
// Unlock unlocks the given account indefinitely.
// unlock 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.
// Unlock unlocks the account with the given address. The account
// stays unlocked for the duration of timeout
// it timeout is 0 the account is unlocked for the entire session
func (am *Manager) TimedUnlock(addr common.Address, keyAuth string, timeout time.Duration) error {
key, err := am.keyStore.GetKey(addr, keyAuth)
if err != nil {

View File

@ -23,10 +23,9 @@ 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)
@ -34,24 +33,26 @@ 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, testSigData)
_, err = am.Sign(a1, toSign)
if err != nil {
t.Fatal(err)
}
}
func TestTimedUnlock(t *testing.T) {
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePassphrase)
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, testSigData)
_, err = am.Sign(a1, toSign)
if err != ErrLocked {
t.Fatal("Signing should've failed with ErrLocked before unlocking, got ", err)
}
@ -62,26 +63,28 @@ func TestTimedUnlock(t *testing.T) {
}
// Signing without passphrase works because account is temp unlocked
_, err = am.Sign(a1, testSigData)
_, err = am.Sign(a1, toSign)
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)
_, err = am.Sign(a1, toSign)
if err != ErrLocked {
t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err)
}
}
func TestOverrideUnlock(t *testing.T) {
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePlain)
dir, ks := tmpKeyStore(t, crypto.NewKeyStorePassphrase)
defer os.RemoveAll(dir)
am := NewManager(ks)
pass := "foo"
a1, err := am.NewAccount(pass)
toSign := randentropy.GetEntropyCSPRNG(32)
// Unlock indefinitely
if err = am.Unlock(a1.Address, pass); err != nil {
@ -89,7 +92,7 @@ func TestOverrideUnlock(t *testing.T) {
}
// Signing without passphrase works because account is temp unlocked
_, err = am.Sign(a1, testSigData)
_, err = am.Sign(a1, toSign)
if err != nil {
t.Fatal("Signing shouldn't return an error after unlocking, got ", err)
}
@ -100,46 +103,20 @@ func TestOverrideUnlock(t *testing.T) {
}
// Signing without passphrase still works because account is temp unlocked
_, err = am.Sign(a1, testSigData)
_, err = am.Sign(a1, toSign)
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)
_, err = am.Sign(a1, toSign)
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")

View File

@ -36,7 +36,6 @@ var (
defaultTest = "all"
defaultDir = "."
allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests", "RLPTests"}
testDirMapping = map[string]string{"BlockTests": "BlockchainTests"}
skipTests = []string{}
TestFlag = cli.StringFlag{
@ -136,13 +135,8 @@ func runSuite(test, file string) {
var err error
var files []string
if test == defaultTest {
// 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))
}
files, err = getFiles(filepath.Join(file, curTest))
} else {
files, err = getFiles(file)
}

View File

@ -18,129 +18,79 @@
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"
)
var (
app *cli.App
DebugFlag = cli.BoolFlag{
Name: "debug",
Usage: "output full trace logs",
}
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",
}
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")
)
func init() {
app = utils.NewApp("0.2", "the evm command line interface")
app.Flags = []cli.Flag{
DebugFlag,
SysStatFlag,
CodeFlag,
GasFlag,
PriceFlag,
ValueFlag,
DumpFlag,
InputFlag,
}
app.Action = run
func perr(v ...interface{}) {
fmt.Println(v...)
//os.Exit(1)
}
func run(ctx *cli.Context) {
vm.Debug = ctx.GlobalBool(DebugFlag.Name)
func main() {
flag.Parse()
logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(*loglevel)))
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(ctx.GlobalString(CodeFlag.Name)))
receiver.SetCode(common.Hex2Bytes(*code))
vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name)))
vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(*value))
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 {
fmt.Println(e)
os.Exit(1)
perr(e)
}
if ctx.GlobalBool(DumpFlag.Name) {
if *dump {
fmt.Println(string(statedb.Dump()))
}
vm.StdErrFormat(vmenv.StructLogs())
if ctx.GlobalBool(SysStatFlag.Name) {
var mem runtime.MemStats
runtime.ReadMemStats(&mem)
fmt.Printf("vm took %v\n", vmdone)
fmt.Printf(`alloc: %d
var mem runtime.MemStats
runtime.ReadMemStats(&mem)
fmt.Printf("vm took %v\n", time.Since(tstart))
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("OUT: 0x%x\n", ret)
}
func main() {
if err := app.Run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("%x\n", ret)
}
type VMEnv struct {
@ -152,7 +102,7 @@ type VMEnv struct {
depth int
Gas *big.Int
time *big.Int
time uint64
logs []vm.StructLog
}
@ -161,7 +111,7 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int) *VM
state: state,
transactor: &transactor,
value: value,
time: big.NewInt(time.Now().Unix()),
time: uint64(time.Now().Unix()),
}
}
@ -169,7 +119,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() *big.Int { return self.time }
func (self *VMEnv) Time() uint64 { 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 }

View File

@ -23,7 +23,6 @@ import (
"os"
"os/signal"
"path/filepath"
"regexp"
"strings"
"sort"
@ -45,10 +44,6 @@ import (
"github.com/robertkrimen/otto"
)
var passwordRegexp = regexp.MustCompile("personal.[nu]")
const passwordRepl = ""
type prompter interface {
AppendHistory(string)
Prompt(p string) (string, error)
@ -418,10 +413,8 @@ func (self *jsre) interactive() {
str += input + "\n"
self.setIndent()
if indentCount <= 0 {
hist := hidepassword(str[:len(str)-1])
if len(hist) > 0 {
self.AppendHistory(hist)
}
hist := str[:len(str)-1]
self.AppendHistory(hist)
self.parseInput(str)
str = ""
}
@ -429,14 +422,6 @@ 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 {

View File

@ -38,7 +38,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
@ -50,7 +49,7 @@ import (
const (
ClientIdentifier = "Geth"
Version = "1.0.6"
Version = "1.0.0"
)
var (
@ -281,8 +280,6 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils.BootnodesFlag,
utils.DataDirFlag,
utils.BlockchainVersionFlag,
utils.OlympicFlag,
utils.CacheFlag,
utils.JSpathFlag,
utils.ListenPortFlag,
utils.MaxPeersFlag,
@ -348,9 +345,6 @@ func main() {
func run(ctx *cli.Context) {
utils.CheckLegalese(ctx.GlobalString(utils.DataDirFlag.Name))
if ctx.GlobalBool(utils.OlympicFlag.Name) {
utils.InitOlympic()
}
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
ethereum, err := eth.New(cfg)
@ -506,7 +500,7 @@ func blockRecovery(ctx *cli.Context) {
cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx)
utils.CheckLegalese(cfg.DataDir)
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"), cfg.DatabaseCache)
blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain"))
if err != nil {
glog.Fatalln("could not open db:", err)
}
@ -533,9 +527,6 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
// Start Ethereum itself
utils.StartEthereum(eth)
// Start logging file descriptor stats.
fdtrack.Start()
am := eth.AccountManager()
account := ctx.GlobalString(utils.UnlockedAccountFlag.Name)
accounts := strings.Split(account, " ")

View File

@ -21,7 +21,6 @@ import (
"bufio"
"fmt"
"io"
"math/big"
"os"
"os/signal"
"regexp"
@ -33,7 +32,6 @@ 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"
)
@ -145,15 +143,6 @@ func StartEthereum(ethereum *eth.Ethereum) {
}()
}
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)
}
func FormatTransactionData(data string) []byte {
d := common.StringToByteFunc(data, func(s string) (ret []byte) {
slice := regexp.MustCompile("\\n|\\s").Split(s, 1000000000)
@ -214,11 +203,6 @@ 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++
}
@ -234,7 +218,6 @@ 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

@ -126,15 +126,6 @@ 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{
@ -158,7 +149,7 @@ var (
GasPriceFlag = cli.StringFlag{
Name: "gasprice",
Usage: "Sets the minimal gasprice when mining transactions",
Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(),
}
UnlockedAccountFlag = cli.StringFlag{
@ -318,12 +309,12 @@ var (
GpoMinGasPriceFlag = cli.StringFlag{
Name: "gpomin",
Usage: "Minimum suggested gas price",
Value: new(big.Int).Mul(big.NewInt(50), common.Shannon).String(),
Value: new(big.Int).Mul(big.NewInt(1), common.Szabo).String(),
}
GpoMaxGasPriceFlag = cli.StringFlag{
Name: "gpomax",
Usage: "Maximum suggested gas price",
Value: new(big.Int).Mul(big.NewInt(500), common.Shannon).String(),
Value: new(big.Int).Mul(big.NewInt(100), common.Szabo).String(),
}
GpoFullBlockRatioFlag = cli.IntFlag{
Name: "gpofull",
@ -393,7 +384,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
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),
@ -406,7 +396,6 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
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),
@ -436,26 +425,17 @@ func SetupLogger(ctx *cli.Context) {
// MakeChain creates a chain manager from set command line flags.
func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, extraDB common.Database) {
datadir := ctx.GlobalString(DataDirFlag.Name)
cache := ctx.GlobalInt(CacheFlag.Name)
dd := ctx.GlobalString(DataDirFlag.Name)
var err error
if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "blockchain"), cache); err != nil {
if blockDB, err = ethdb.NewLDBDatabase(filepath.Join(dd, "blockchain")); err != nil {
Fatalf("Could not open database: %v", err)
}
if stateDB, err = ethdb.NewLDBDatabase(filepath.Join(datadir, "state"), cache); err != nil {
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(datadir, "extra"), cache); err != nil {
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(stateDB, blockDB, 42)
if err != nil {
glog.Fatalln(err)
}
}
eventMux := new(event.TypeMux)
pow := ethash.New()

View File

@ -153,7 +153,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
b.Fatalf("cannot create temporary directory: %v", err)
}
defer os.RemoveAll(dir)
db, err = ethdb.NewLDBDatabase(dir, 0)
db, err = ethdb.NewLDBDatabase(dir)
if err != nil {
b.Fatalf("cannot create temporary database: %v", err)
}

View File

@ -57,18 +57,6 @@ type BlockProcessor struct {
eventMux *event.TypeMux
}
// TODO: type GasPool big.Int
//
// GasPool is implemented by state.StateObject. This is a historical
// coincidence. Gas tracking should move out of StateObject.
// GasPool tracks the amount of gas available during
// execution of the transactions in a block.
type GasPool interface {
AddGas(gas, price *big.Int)
SubGas(gas, price *big.Int) error
}
func NewBlockProcessor(db, extra common.Database, pow pow.PoW, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
sm := &BlockProcessor{
db: db,
@ -78,15 +66,16 @@ func NewBlockProcessor(db, extra common.Database, pow pow.PoW, chainManager *Cha
bc: chainManager,
eventMux: eventMux,
}
return sm
}
func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) {
gp := statedb.GetOrNewStateObject(block.Coinbase())
gp.SetGasLimit(block.GasLimit())
coinbase := statedb.GetOrNewStateObject(block.Coinbase())
coinbase.SetGasLimit(block.GasLimit())
// Process the transactions on to parent state
receipts, err = sm.ApplyTransactions(gp, statedb, block, block.Transactions(), transientProcess)
receipts, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess)
if err != nil {
return nil, err
}
@ -94,8 +83,11 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block
return receipts, nil
}
func (self *BlockProcessor) ApplyTransaction(gp GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, gp)
func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
// If we are mining this block and validating we want to set the logs back to 0
cb := statedb.GetStateObject(coinbase.Address())
_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, cb)
if err != nil {
return nil, nil, err
}
@ -130,7 +122,7 @@ func (self *BlockProcessor) ChainManager() *ChainManager {
return self.bc
}
func (self *BlockProcessor) ApplyTransactions(gp GasPool, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, error) {
func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, error) {
var (
receipts types.Receipts
totalUsedGas = big.NewInt(0)
@ -142,7 +134,7 @@ func (self *BlockProcessor) ApplyTransactions(gp GasPool, statedb *state.StateDB
for i, tx := range txs {
statedb.StartRecord(tx.Hash(), block.Hash(), i)
receipt, txGas, err := self.ApplyTransaction(gp, statedb, header, tx, totalUsedGas, transientProcess)
receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, header, tx, totalUsedGas, transientProcess)
if err != nil {
return nil, err
}
@ -215,7 +207,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
txs := block.Transactions()
// Block validation
if err = ValidateHeader(sm.Pow, header, parent, false, false); err != nil {
if err = ValidateHeader(sm.Pow, header, parent, false); err != nil {
return
}
@ -339,7 +331,7 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty
return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4])
}
if err := ValidateHeader(sm.Pow, uncle, ancestors[uncle.ParentHash], true, true); err != nil {
if err := ValidateHeader(sm.Pow, uncle, ancestors[uncle.ParentHash], true); err != nil {
return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err))
}
}
@ -382,25 +374,19 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro
// See YP section 4.3.4. "Block Header Validity"
// Validates a block. Returns an error if the block is invalid.
func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, checkPow, uncle bool) error {
func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, checkPow bool) error {
if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
}
if uncle {
if block.Time.Cmp(common.MaxBig) == 1 {
return BlockTSTooBigErr
}
} else {
if block.Time.Cmp(big.NewInt(time.Now().Unix())) == 1 {
return BlockFutureErr
}
if block.Time > uint64(time.Now().Unix()) {
return BlockFutureErr
}
if block.Time.Cmp(parent.Time()) != 1 {
if block.Time <= parent.Time() {
return BlockEqualTSErr
}
expd := CalcDifficulty(block.Time.Uint64(), parent.Time().Uint64(), parent.Number(), parent.Difficulty())
expd := CalcDifficulty(block.Time, parent.Time(), parent.Difficulty())
if expd.Cmp(block.Difficulty) != 0 {
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
}

View File

@ -48,13 +48,13 @@ func TestNumber(t *testing.T) {
statedb := state.New(chain.Genesis().Root(), chain.stateDb)
header := makeHeader(chain.Genesis(), statedb)
header.Number = big.NewInt(3)
err := ValidateHeader(pow, header, chain.Genesis(), false, false)
err := ValidateHeader(pow, header, chain.Genesis(), false)
if err != BlockNumberErr {
t.Errorf("expected block number error, got %q", err)
}
header = makeHeader(chain.Genesis(), statedb)
err = ValidateHeader(pow, header, chain.Genesis(), false, false)
err = ValidateHeader(pow, header, chain.Genesis(), false)
if err == BlockNumberErr {
t.Errorf("didn't expect block number error")
}

View File

@ -20,5 +20,8 @@ import "github.com/ethereum/go-ethereum/common"
// Set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{
common.HexToHash("05bef30ef572270f654746da22639a7a0c97dd97a7050b9e252391996aaeb689"): true,
common.HexToHash("f269c503aed286caaa0d114d6a5320e70abbc2febe37953207e76a2873f2ba79"): true,
common.HexToHash("38f5bbbffd74804820ffa4bab0cd540e9de229725afb98c1a7e57936f4a714bc"): true,
common.HexToHash("7064455b364775a16afbdecd75370e912c6e2879f202eda85b9beae547fff3ac"): true,
common.HexToHash("5b7c80070a6eff35f3eb3181edb023465c776d40af2885571e1bc4689f3a44d8"): true,
}

View File

@ -24,10 +24,10 @@ import (
)
var (
jeff = common.HexToAddress("959c33de5961820567930eccce51ea715c496f85")
vitalik = common.HexToAddress("c8158da0b567a8cc898991c2c2a073af67dc03a9")
christoph = common.HexToAddress("7a19a893f91d5b6e2cdf941b6acbba2cbcf431ee")
gav = common.HexToAddress("539dd9aaf45c3feb03f9c004f4098bd3268fef6b")
jeff = common.HexToAddress("a8edb1ac2c86d3d9d78f96cd18001f60df29e52c")
vitalik = common.HexToAddress("1baf27b88c48dd02b744999cf3522766929d2b2a")
christoph = common.HexToAddress("60d11b58744784dc97f878f7e3749c0f1381a004")
gav = common.HexToAddress("4bb7e8ae99b645c2b7860b8f3a2328aae28bd80a")
)
// Canary will check the 0'd address of the 4 contracts above.

View File

@ -166,21 +166,16 @@ func GenerateChain(parent *types.Block, db common.Database, n int, gen func(int,
}
func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
var time *big.Int
if parent.Time() == nil {
time = big.NewInt(10)
} else {
time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds
}
time := parent.Time() + 10 // block time is fixed at 10 seconds
return &types.Header{
Root: state.Root(),
ParentHash: parent.Hash(),
Coinbase: parent.Coinbase(),
Difficulty: CalcDifficulty(time.Uint64(), new(big.Int).Sub(time, big.NewInt(10)).Uint64(), parent.Number(), parent.Difficulty()),
Difficulty: CalcDifficulty(time, parent.Time(), parent.Difficulty()),
GasLimit: CalcGasLimit(parent),
GasUsed: new(big.Int),
Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time,
Time: uint64(time),
}
}

View File

@ -73,11 +73,13 @@ type ChainManager struct {
lastBlockHash common.Hash
currentGasLimit *big.Int
transState *state.StateDB
txState *state.ManagedState
cache *lru.Cache // cache is the LRU caching
futureBlocks *lru.Cache // future blocks are blocks added for later processing
quit chan struct{}
running int32 // running must be called automically
quit chan struct{}
// procInterrupt must be atomically called
procInterrupt int32 // interrupt signaler for block processing
wg sync.WaitGroup
@ -99,15 +101,7 @@ func NewChainManager(blockDb, stateDb, extraDb common.Database, pow pow.PoW, mux
bc.genesisBlock = bc.GetBlockByNumber(0)
if bc.genesisBlock == nil {
reader, err := NewDefaultGenesisReader()
if err != nil {
return nil, err
}
bc.genesisBlock, err = WriteGenesisBlock(stateDb, blockDb, reader)
if err != nil {
return nil, err
}
glog.V(logger.Info).Infoln("WARNING: Wrote default ethereum genesis block")
return nil, ErrNoGenesis
}
if err := bc.setLastState(); err != nil {
@ -128,7 +122,9 @@ func NewChainManager(blockDb, stateDb, extraDb common.Database, pow pow.PoW, mux
}
}
bc.transState = bc.State().Copy()
// Take ownership of this particular state
bc.txState = state.ManageState(bc.State().Copy())
bc.futureBlocks, _ = lru.New(maxFutureBlocks)
bc.makeCache()
@ -150,6 +146,9 @@ func (bc *ChainManager) SetHead(head *types.Block) {
bc.currentBlock = head
bc.makeCache()
statedb := state.New(head.Root(), bc.stateDb)
bc.txState = state.ManageState(statedb)
bc.transState = statedb.Copy()
bc.setTotalDifficulty(head.Td)
bc.insert(head)
bc.setLastState()
@ -198,6 +197,17 @@ func (self *ChainManager) State() *state.StateDB {
return state.New(self.CurrentBlock().Root(), self.stateDb)
}
func (self *ChainManager) TransState() *state.StateDB {
self.tsmu.RLock()
defer self.tsmu.RUnlock()
return self.transState
}
func (self *ChainManager) setTransState(statedb *state.StateDB) {
self.transState = statedb
}
func (bc *ChainManager) recover() bool {
data, _ := bc.blockDb.Get([]byte("checkpoint"))
if len(data) != 0 {
@ -452,9 +462,6 @@ func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
}
func (bc *ChainManager) Stop() {
if !atomic.CompareAndSwapInt32(&bc.running, 0, 1) {
return
}
close(bc.quit)
atomic.StoreInt32(&bc.procInterrupt, 1)
@ -516,6 +523,9 @@ func (self *ChainManager) WriteBlock(block *types.Block, queued bool) (status wr
self.insert(block)
self.mu.Unlock()
self.setTransState(state.New(block.Root(), self.stateDb))
self.txState.SetState(state.New(block.Root(), self.stateDb))
status = CanonStatTy
} else {
status = SideStatTy
@ -600,8 +610,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
// Allow up to MaxFuture second in the future blocks. If this limit
// is exceeded the chain is discarded and processed at a later time
// if given.
max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks)
if block.Time().Cmp(max) == 1 {
if max := uint64(time.Now().Unix()) + maxTimeFutureBlocks; block.Time() > max {
return i, fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max)
}

View File

@ -392,6 +392,7 @@ func chm(genesis *types.Block, db common.Database) *ChainManager {
bc.futureBlocks, _ = lru.New(100)
bc.processor = bproc{}
bc.ResetWithGenesisBlock(genesis)
bc.txState = state.ManageState(bc.State())
return bc
}

View File

@ -30,15 +30,14 @@ import (
)
var (
blockHashPre = []byte("block-hash-")
blockNumPre = []byte("block-num-")
expDiffPeriod = big.NewInt(100000)
blockHashPre = []byte("block-hash-")
blockNumPre = []byte("block-num-")
)
// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block b should have when created at time
// given the parent block's time and difficulty.
func CalcDifficulty(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
func CalcDifficulty(time, parentTime uint64, parentDiff *big.Int) *big.Int {
diff := new(big.Int)
adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
bigTime := new(big.Int)
@ -53,19 +52,8 @@ func CalcDifficulty(time, parentTime uint64, parentNumber, parentDiff *big.Int)
diff.Sub(parentDiff, adjust)
}
if diff.Cmp(params.MinimumDifficulty) < 0 {
diff = params.MinimumDifficulty
return params.MinimumDifficulty
}
periodCount := new(big.Int).Add(parentNumber, common.Big1)
periodCount.Div(periodCount, expDiffPeriod)
if periodCount.Cmp(common.Big1) > 0 {
// diff = diff + 2^(periodCount - 2)
expDiff := periodCount.Sub(periodCount, common.Big2)
expDiff.Exp(common.Big2, expDiff, nil)
diff.Add(diff, expDiff)
diff = common.BigMax(diff, params.MinimumDifficulty)
}
return diff
}
@ -81,30 +69,17 @@ func CalcTD(block, parent *types.Block) *big.Int {
// CalcGasLimit computes the gas limit of the next block after parent.
// The result may be modified by the caller.
// This is miner strategy, not consensus protocol.
func CalcGasLimit(parent *types.Block) *big.Int {
// contrib = (parentGasUsed * 3 / 2) / 1024
decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3))
contrib = contrib.Div(contrib, big.NewInt(2))
contrib = contrib.Div(contrib, params.GasLimitBoundDivisor)
// decay = parentGasLimit / 1024 -1
decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor)
decay.Sub(decay, big.NewInt(1))
/*
strategy: gasLimit of block-to-mine is set based on parent's
gasUsed value. if parentGasUsed > parentGasLimit * (2/3) then we
increase it, otherwise lower it (or leave it unchanged if it's right
at that usage) the amount increased/decreased depends on how far away
from parentGasLimit * (2/3) parentGasUsed is.
*/
gl := new(big.Int).Sub(parent.GasLimit(), decay)
gl = gl.Add(gl, contrib)
gl = gl.Add(gl, big.NewInt(1))
gl.Set(common.BigMax(gl, params.MinGasLimit))
// however, if we're now below the target (GenesisGasLimit) we increase the
// limit as much as we can (parentGasLimit / 1024 -1)
if gl.Cmp(params.GenesisGasLimit) < 0 {
gl.Add(parent.GasLimit(), decay)
gl.Set(common.BigMin(gl, params.GenesisGasLimit))

View File

@ -1,77 +0,0 @@
// 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 core
import (
"encoding/json"
"math/big"
"os"
"testing"
"github.com/ethereum/go-ethereum/common"
)
type diffTest struct {
ParentTimestamp uint64
ParentDifficulty *big.Int
CurrentTimestamp uint64
CurrentBlocknumber *big.Int
CurrentDifficulty *big.Int
}
func (d *diffTest) UnmarshalJSON(b []byte) (err error) {
var ext struct {
ParentTimestamp string
ParentDifficulty string
CurrentTimestamp string
CurrentBlocknumber string
CurrentDifficulty string
}
if err := json.Unmarshal(b, &ext); err != nil {
return err
}
d.ParentTimestamp = common.String2Big(ext.ParentTimestamp).Uint64()
d.ParentDifficulty = common.String2Big(ext.ParentDifficulty)
d.CurrentTimestamp = common.String2Big(ext.CurrentTimestamp).Uint64()
d.CurrentBlocknumber = common.String2Big(ext.CurrentBlocknumber)
d.CurrentDifficulty = common.String2Big(ext.CurrentDifficulty)
return nil
}
func TestDifficulty(t *testing.T) {
file, err := os.Open("../tests/files/BasicTests/difficulty.json")
if err != nil {
t.Fatal(err)
}
defer file.Close()
tests := make(map[string]diffTest)
err = json.NewDecoder(file).Decode(&tests)
if err != nil {
t.Fatal(err)
}
for name, test := range tests {
number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1))
diff := CalcDifficulty(test.CurrentTimestamp, test.ParentTimestamp, number, test.ParentDifficulty)
if diff.Cmp(test.CurrentDifficulty) != 0 {
t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff)
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -25,10 +25,9 @@ import (
)
var (
BlockNumberErr = errors.New("block number invalid")
BlockFutureErr = errors.New("block time is in the future")
BlockTSTooBigErr = errors.New("block time too big")
BlockEqualTSErr = errors.New("block time stamp equal to previous")
BlockNumberErr = errors.New("block number invalid")
BlockFutureErr = errors.New("block time is in the future")
BlockEqualTSErr = errors.New("block time stamp equal to previous")
)
// Parent error. In case a parent is unknown this error will be thrown

View File

@ -73,7 +73,7 @@ func WriteGenesisBlock(stateDb, blockDb common.Database, reader io.Reader) (*typ
difficulty := common.String2Big(genesis.Difficulty)
block := types.NewBlock(&types.Header{
Nonce: types.EncodeNonce(common.String2Big(genesis.Nonce).Uint64()),
Time: common.String2Big(genesis.Timestamp),
Time: common.String2Big(genesis.Timestamp).Uint64(),
ParentHash: common.HexToHash(genesis.ParentHash),
Extra: common.FromHex(genesis.ExtraData),
GasLimit: common.String2Big(genesis.GasLimit),

View File

@ -82,9 +82,8 @@ type StateObject struct {
// Mark for deletion
// When an object is marked for deletion it will be delete from the trie
// during the "update" phase of the state transition
remove bool
deleted bool
dirty bool
remove bool
dirty bool
}
func (self *StateObject) Reset() {
@ -263,7 +262,6 @@ func (self *StateObject) Copy() *StateObject {
stateObject.gasPool.Set(self.gasPool)
stateObject.remove = self.remove
stateObject.dirty = self.dirty
stateObject.deleted = self.deleted
return stateObject
}

View File

@ -17,7 +17,6 @@
package state
import (
"bytes"
"math/big"
"testing"
@ -118,106 +117,3 @@ func (s *StateSuite) TestSnapshot(c *checker.C) {
c.Assert(data1, checker.DeepEquals, res)
}
// use testing instead of checker because checker does not support
// printing/logging in tests (-check.vv does not work)
func TestSnapshot2(t *testing.T) {
db, _ := ethdb.NewMemDatabase()
state := New(common.Hash{}, db)
stateobjaddr0 := toAddr([]byte("so0"))
stateobjaddr1 := toAddr([]byte("so1"))
var storageaddr common.Hash
data0 := common.BytesToHash([]byte{17})
data1 := common.BytesToHash([]byte{18})
state.SetState(stateobjaddr0, storageaddr, data0)
state.SetState(stateobjaddr1, storageaddr, data1)
// db, trie are already non-empty values
so0 := state.GetStateObject(stateobjaddr0)
so0.balance = big.NewInt(42)
so0.nonce = 43
so0.gasPool = big.NewInt(44)
so0.code = []byte{'c', 'a', 'f', 'e'}
so0.codeHash = so0.CodeHash()
so0.remove = true
so0.deleted = false
so0.dirty = false
state.SetStateObject(so0)
// and one with deleted == true
so1 := state.GetStateObject(stateobjaddr1)
so1.balance = big.NewInt(52)
so1.nonce = 53
so1.gasPool = big.NewInt(54)
so1.code = []byte{'c', 'a', 'f', 'e', '2'}
so1.codeHash = so1.CodeHash()
so1.remove = true
so1.deleted = true
so1.dirty = true
state.SetStateObject(so1)
so1 = state.GetStateObject(stateobjaddr1)
if so1 != nil {
t.Fatalf("deleted object not nil when getting")
}
snapshot := state.Copy()
state.Set(snapshot)
so0Restored := state.GetStateObject(stateobjaddr0)
so1Restored := state.GetStateObject(stateobjaddr1)
// non-deleted is equal (restored)
compareStateObjects(so0Restored, so0, t)
// deleted should be nil, both before and after restore of state copy
if so1Restored != nil {
t.Fatalf("deleted object not nil after restoring snapshot")
}
}
func compareStateObjects(so0, so1 *StateObject, t *testing.T) {
if so0.address != so1.address {
t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address)
}
if so0.balance.Cmp(so1.balance) != 0 {
t.Fatalf("Balance mismatch: have %v, want %v", so0.balance, so1.balance)
}
if so0.nonce != so1.nonce {
t.Fatalf("Nonce mismatch: have %v, want %v", so0.nonce, so1.nonce)
}
if !bytes.Equal(so0.codeHash, so1.codeHash) {
t.Fatalf("CodeHash mismatch: have %v, want %v", so0.codeHash, so1.codeHash)
}
if !bytes.Equal(so0.code, so1.code) {
t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code)
}
if !bytes.Equal(so0.initCode, so1.initCode) {
t.Fatalf("InitCode mismatch: have %v, want %v", so0.initCode, so1.initCode)
}
for k, v := range so1.storage {
if so0.storage[k] != v {
t.Fatalf("Storage key %s mismatch: have %v, want %v", k, so0.storage[k], v)
}
}
for k, v := range so0.storage {
if so1.storage[k] != v {
t.Fatalf("Storage key %s mismatch: have %v, want none.", k, v)
}
}
if so0.gasPool.Cmp(so1.gasPool) != 0 {
t.Fatalf("GasPool mismatch: have %v, want %v", so0.gasPool, so1.gasPool)
}
if so0.remove != so1.remove {
t.Fatalf("Remove mismatch: have %v, want %v", so0.remove, so1.remove)
}
if so0.deleted != so1.deleted {
t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted)
}
if so0.dirty != so1.dirty {
t.Fatalf("Dirty mismatch: have %v, want %v", so0.dirty, so1.dirty)
}
}

View File

@ -44,7 +44,6 @@ type StateDB struct {
thash, bhash common.Hash
txIndex int
logs map[common.Hash]Logs
logSize uint
}
// Create a new state from a given trie
@ -67,9 +66,7 @@ func (self *StateDB) AddLog(log *Log) {
log.TxHash = self.thash
log.BlockHash = self.bhash
log.TxIndex = uint(self.txIndex)
log.Index = self.logSize
self.logs[self.thash] = append(self.logs[self.thash], log)
self.logSize++
}
func (self *StateDB) GetLogs(hash common.Hash) Logs {
@ -203,20 +200,18 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
// Delete the given state object and delete it from the state trie
func (self *StateDB) DeleteStateObject(stateObject *StateObject) {
stateObject.deleted = true
addr := stateObject.Address()
self.trie.Delete(addr[:])
//delete(self.stateObjects, addr.Str())
}
// Retrieve a state object given my the address. Nil if not found
func (self *StateDB) GetStateObject(addr common.Address) (stateObject *StateObject) {
stateObject = self.stateObjects[addr.Str()]
if stateObject != nil {
if stateObject.deleted {
stateObject = nil
}
func (self *StateDB) GetStateObject(addr common.Address) *StateObject {
//addr = common.Address(addr)
stateObject := self.stateObjects[addr.Str()]
if stateObject != nil {
return stateObject
}
@ -238,7 +233,7 @@ func (self *StateDB) SetStateObject(object *StateObject) {
// Retrieve a state object or create a new state object if nil
func (self *StateDB) GetOrNewStateObject(addr common.Address) *StateObject {
stateObject := self.GetStateObject(addr)
if stateObject == nil || stateObject.deleted {
if stateObject == nil {
stateObject = self.CreateAccount(addr)
}
@ -293,7 +288,6 @@ func (self *StateDB) Copy() *StateDB {
state.logs[hash] = make(Logs, len(logs))
copy(state.logs[hash], logs)
}
state.logSize = self.logSize
return state
}
@ -304,7 +298,6 @@ func (self *StateDB) Set(state *StateDB) {
self.refund = state.refund
self.logs = state.logs
self.logSize = state.logSize
}
func (s *StateDB) Root() common.Hash {

View File

@ -45,7 +45,7 @@ import (
* 6) Derive new state root
*/
type StateTransition struct {
gp GasPool
coinbase common.Address
msg Message
gas, gasPrice *big.Int
initialGas *big.Int
@ -53,6 +53,8 @@ type StateTransition struct {
data []byte
state *state.StateDB
cb, rec, sen *state.StateObject
env vm.Environment
}
@ -94,13 +96,13 @@ func IntrinsicGas(data []byte) *big.Int {
return igas
}
func ApplyMessage(env vm.Environment, msg Message, gp GasPool) ([]byte, *big.Int, error) {
return NewStateTransition(env, msg, gp).transitionState()
func ApplyMessage(env vm.Environment, msg Message, coinbase *state.StateObject) ([]byte, *big.Int, error) {
return NewStateTransition(env, msg, coinbase).transitionState()
}
func NewStateTransition(env vm.Environment, msg Message, gp GasPool) *StateTransition {
func NewStateTransition(env vm.Environment, msg Message, coinbase *state.StateObject) *StateTransition {
return &StateTransition{
gp: gp,
coinbase: coinbase.Address(),
env: env,
msg: msg,
gas: new(big.Int),
@ -109,9 +111,13 @@ func NewStateTransition(env vm.Environment, msg Message, gp GasPool) *StateTrans
value: msg.Value(),
data: msg.Data(),
state: env.State(),
cb: coinbase,
}
}
func (self *StateTransition) Coinbase() *state.StateObject {
return self.state.GetOrNewStateObject(self.coinbase)
}
func (self *StateTransition) From() (*state.StateObject, error) {
f, err := self.msg.From()
if err != nil {
@ -154,7 +160,7 @@ func (self *StateTransition) BuyGas() error {
if sender.Balance().Cmp(mgval) < 0 {
return fmt.Errorf("insufficient ETH for gas (%x). Req %v, has %v", sender.Address().Bytes()[:4], mgval, sender.Balance())
}
if err = self.gp.SubGas(mgas, self.gasPrice); err != nil {
if err = self.Coinbase().SubGas(mgas, self.gasPrice); err != nil {
return err
}
self.AddGas(mgas)
@ -235,12 +241,13 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
}
self.refundGas()
self.state.AddBalance(self.env.Coinbase(), new(big.Int).Mul(self.gasUsed(), self.gasPrice))
self.state.AddBalance(self.coinbase, new(big.Int).Mul(self.gasUsed(), self.gasPrice))
return ret, self.gasUsed(), err
}
func (self *StateTransition) refundGas() {
coinbase := self.Coinbase()
sender, _ := self.From() // err already checked
// Return remaining gas
remaining := new(big.Int).Mul(self.gas, self.gasPrice)
@ -251,7 +258,7 @@ func (self *StateTransition) refundGas() {
self.gas.Add(self.gas, refund)
self.state.AddBalance(sender.Address(), refund.Mul(refund, self.gasPrice))
self.gp.AddGas(self.gas, self.gasPrice)
coinbase.AddGas(self.gas, self.gasPrice)
}
func (self *StateTransition) gasUsed() *big.Int {

View File

@ -135,7 +135,7 @@ func (pool *TxPool) resetState() {
func (pool *TxPool) Stop() {
close(pool.quit)
pool.events.Unsubscribe()
glog.V(logger.Info).Infoln("Transaction pool stopped")
glog.V(logger.Info).Infoln("TX Pool stopped")
}
func (pool *TxPool) State() *state.ManagedState {
@ -356,12 +356,11 @@ func (self *TxPool) RemoveTransactions(txs types.Transactions) {
self.mu.Lock()
defer self.mu.Unlock()
for _, tx := range txs {
self.RemoveTx(tx.Hash())
self.removeTx(tx.Hash())
}
}
// RemoveTx removes the transaction with the given hash from the pool.
func (pool *TxPool) RemoveTx(hash common.Hash) {
func (pool *TxPool) removeTx(hash common.Hash) {
// delete from pending pool
delete(pool.pending, hash)
// delete from queue

View File

@ -130,7 +130,7 @@ func TestRemoveTx(t *testing.T) {
t.Error("expected txs to be 1, got", len(pool.pending))
}
pool.RemoveTx(tx.Hash())
pool.removeTx(tx.Hash())
if len(pool.queue) > 0 {
t.Error("expected queue to be 0, got", len(pool.queue))

View File

@ -19,11 +19,9 @@ package core
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rlp"
"github.com/syndtr/goleveldb/leveldb"
)
var (
@ -33,21 +31,13 @@ var (
// PutTransactions stores the transactions in the given database
func PutTransactions(db common.Database, block *types.Block, txs types.Transactions) {
batch := new(leveldb.Batch)
_, batchWrite := db.(*ethdb.LDBDatabase)
for i, tx := range block.Transactions() {
rlpEnc, err := rlp.EncodeToBytes(tx)
if err != nil {
glog.V(logger.Debug).Infoln("Failed encoding tx", err)
return
}
if batchWrite {
batch.Put(tx.Hash().Bytes(), rlpEnc)
} else {
db.Put(tx.Hash().Bytes(), rlpEnc)
}
db.Put(tx.Hash().Bytes(), rlpEnc)
var txExtra struct {
BlockHash common.Hash
@ -62,44 +52,20 @@ func PutTransactions(db common.Database, block *types.Block, txs types.Transacti
glog.V(logger.Debug).Infoln("Failed encoding tx meta data", err)
return
}
if batchWrite {
batch.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta)
} else {
db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta)
}
}
if db, ok := db.(*ethdb.LDBDatabase); ok {
if err := db.LDB().Write(batch, nil); err != nil {
glog.V(logger.Error).Infoln("db write err:", err)
}
db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta)
}
}
// PutReceipts stores the receipts in the current database
func PutReceipts(db common.Database, receipts types.Receipts) error {
batch := new(leveldb.Batch)
_, batchWrite := db.(*ethdb.LDBDatabase)
for _, receipt := range receipts {
storageReceipt := (*types.ReceiptForStorage)(receipt)
bytes, err := rlp.EncodeToBytes(storageReceipt)
if err != nil {
return err
}
if batchWrite {
batch.Put(append(receiptsPre, receipt.TxHash[:]...), bytes)
} else {
err = db.Put(append(receiptsPre, receipt.TxHash[:]...), bytes)
if err != nil {
return err
}
}
}
if db, ok := db.(*ethdb.LDBDatabase); ok {
if err := db.LDB().Write(batch, nil); err != nil {
err = db.Put(append(receiptsPre, receipt.TxHash[:]...), bytes)
if err != nil {
return err
}
}

View File

@ -60,7 +60,7 @@ type Header struct {
Number *big.Int // The block number
GasLimit *big.Int // Gas limit
GasUsed *big.Int // Gas used
Time *big.Int // Creation time
Time uint64 // Creation time
Extra []byte // Extra data
MixDigest common.Hash // for quick difficulty verification
Nonce BlockNonce
@ -94,7 +94,7 @@ func (h *Header) UnmarshalJSON(data []byte) error {
Coinbase string
Difficulty string
GasLimit string
Time *big.Int
Time uint64
Extra string
}
dec := json.NewDecoder(bytes.NewReader(data))
@ -210,9 +210,6 @@ func NewBlockWithHeader(header *Header) *Block {
func copyHeader(h *Header) *Header {
cpy := *h
if cpy.Time = new(big.Int); h.Time != nil {
cpy.Time.Set(h.Time)
}
if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
cpy.Difficulty.Set(h.Difficulty)
}
@ -260,7 +257,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
return nil
}
func (b *Block) EncodeRLP(w io.Writer) error {
func (b Block) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, extblock{
Header: b.header,
Txs: b.transactions,
@ -277,7 +274,7 @@ func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
return nil
}
func (b *StorageBlock) EncodeRLP(w io.Writer) error {
func (b StorageBlock) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, storageblock{
Header: b.header,
Txs: b.transactions,
@ -304,13 +301,13 @@ func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number)
func (b *Block) GasLimit() *big.Int { return new(big.Int).Set(b.header.GasLimit) }
func (b *Block) GasUsed() *big.Int { return new(big.Int).Set(b.header.GasUsed) }
func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) }
func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
func (b *Block) MixDigest() common.Hash { return b.header.MixDigest }
func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
func (b *Block) Bloom() Bloom { return b.header.Bloom }
func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
func (b *Block) Time() uint64 { return b.header.Time }
func (b *Block) Root() common.Hash { return b.header.Root }
func (b *Block) ParentHash() common.Hash { return b.header.ParentHash }
func (b *Block) TxHash() common.Hash { return b.header.TxHash }

View File

@ -47,7 +47,7 @@ func TestBlockEncoding(t *testing.T) {
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
check("Hash", block.Hash(), common.HexToHash("0a5843ac1cb04865017cb35a57b50b07084e5fcee39b5acadade33149f4fff9e"))
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
check("Time", block.Time(), big.NewInt(1426516743))
check("Time", block.Time(), uint64(1426516743))
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), big.NewInt(50000), big.NewInt(10), nil)

View File

@ -97,6 +97,15 @@ func NewTransaction(nonce uint64, to common.Address, amount, gasLimit, gasPrice
return &Transaction{data: d}
}
func NewTransactionFromBytes(data []byte) *Transaction {
// TODO: remove this function if possible. callers would
// much better off decoding into transaction directly.
// it's not that hard.
tx := new(Transaction)
rlp.DecodeBytes(data, tx)
return tx
}
func (tx *Transaction) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, &tx.data)
}
@ -289,22 +298,3 @@ type TxByNonce struct{ Transactions }
func (s TxByNonce) Less(i, j int) bool {
return s.Transactions[i].data.AccountNonce < s.Transactions[j].data.AccountNonce
}
type TxByPrice struct{ Transactions }
func (s TxByPrice) Less(i, j int) bool {
return s.Transactions[i].data.Price.Cmp(s.Transactions[j].data.Price) > 0
}
type TxByPriceAndNonce struct{ Transactions }
func (s TxByPriceAndNonce) Less(i, j int) bool {
// we can ignore the error here. Sorting shouldn't care about validness
ifrom, _ := s.Transactions[i].From()
jfrom, _ := s.Transactions[j].From()
// favour nonce if they are from the same recipient
if ifrom == jfrom {
return s.Transactions[i].data.AccountNonce < s.Transactions[j].data.AccountNonce
}
return s.Transactions[i].data.Price.Cmp(s.Transactions[j].data.Price) > 0
}

View File

@ -31,11 +31,9 @@ type Environment interface {
Origin() common.Address
BlockNumber() *big.Int
// The n'th hash ago from this block number
GetHash(uint64) common.Hash
// The handler's address
GetHash(n uint64) common.Hash
Coinbase() common.Address
Time() *big.Int
Time() uint64
Difficulty() *big.Int
GasLimit() *big.Int
Transfer(from, to Account, amount *big.Int) error

View File

@ -461,7 +461,7 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
case TIMESTAMP:
time := self.env.Time()
stack.push(new(big.Int).Set(time))
stack.push(new(big.Int).SetUint64(time))
case NUMBER:
number := self.env.BlockNumber()

View File

@ -49,7 +49,7 @@ func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, header *type
func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f }
func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number }
func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase }
func (self *VMEnv) Time() *big.Int { return self.header.Time }
func (self *VMEnv) Time() uint64 { return self.header.Time }
func (self *VMEnv) Difficulty() *big.Int { return self.header.Difficulty }
func (self *VMEnv) GasLimit() *big.Int { return self.header.GasLimit }
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
@ -59,10 +59,8 @@ func (self *VMEnv) SetDepth(i int) { self.depth = i }
func (self *VMEnv) VmType() vm.Type { return self.typ }
func (self *VMEnv) SetVmType(t vm.Type) { self.typ = t }
func (self *VMEnv) GetHash(n uint64) common.Hash {
for block := self.chain.GetBlock(self.header.ParentHash); block != nil; block = self.chain.GetBlock(block.ParentHash()) {
if block.NumberU64() == n {
return block.Hash()
}
if block := self.chain.GetBlockByNumber(n); block != nil {
return block.Hash()
}
return common.Hash{}

View File

@ -60,14 +60,7 @@ type BitCurve struct {
}
func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
return &elliptic.CurveParams{
P: BitCurve.P,
N: BitCurve.N,
B: BitCurve.B,
Gx: BitCurve.Gx,
Gy: BitCurve.Gy,
BitSize: BitCurve.BitSize,
}
return &elliptic.CurveParams{BitCurve.P, BitCurve.N, BitCurve.B, BitCurve.Gx, BitCurve.Gy, BitCurve.BitSize}
}
// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve.

View File

@ -81,9 +81,11 @@ func doScheme(base, v []int) asn1.ObjectIdentifier {
type secgNamedCurve asn1.ObjectIdentifier
var (
secgNamedCurveP224 = secgNamedCurve{1, 3, 132, 0, 33}
secgNamedCurveP256 = secgNamedCurve{1, 2, 840, 10045, 3, 1, 7}
secgNamedCurveP384 = secgNamedCurve{1, 3, 132, 0, 34}
secgNamedCurveP521 = secgNamedCurve{1, 3, 132, 0, 35}
rawCurveP224 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 3}
rawCurveP256 = []byte{6, 8, 4, 2, 1, 3, 4, 7, 2, 2, 0, 6, 6, 1, 3, 1, 7}
rawCurveP384 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 4}
rawCurveP521 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 5}
@ -91,6 +93,8 @@ var (
func rawCurve(curve elliptic.Curve) []byte {
switch curve {
case elliptic.P224():
return rawCurveP224
case elliptic.P256():
return rawCurveP256
case elliptic.P384():
@ -116,6 +120,8 @@ func (curve secgNamedCurve) Equal(curve2 secgNamedCurve) bool {
func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve {
switch {
case curve.Equal(secgNamedCurveP224):
return elliptic.P224()
case curve.Equal(secgNamedCurveP256):
return elliptic.P256()
case curve.Equal(secgNamedCurveP384):
@ -128,6 +134,8 @@ func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve {
func oidFromNamedCurve(curve elliptic.Curve) (secgNamedCurve, bool) {
switch curve {
case elliptic.P224():
return secgNamedCurveP224, true
case elliptic.P256():
return secgNamedCurveP256, true
case elliptic.P384():
@ -240,7 +248,7 @@ var idEcPublicKeySupplemented = doScheme(idPublicKeyType, []int{0})
func curveToRaw(curve elliptic.Curve) (rv asn1.RawValue, ok bool) {
switch curve {
case elliptic.P256(), elliptic.P384(), elliptic.P521():
case elliptic.P224(), elliptic.P256(), elliptic.P384(), elliptic.P521():
raw := rawCurve(curve)
return asn1.RawValue{
Tag: 30,

View File

@ -407,6 +407,11 @@ type testCase struct {
}
var testCases = []testCase{
testCase{
Curve: elliptic.P224(),
Name: "P224",
Expected: false,
},
testCase{
Curve: elliptic.P256(),
Name: "P256",

View File

@ -147,6 +147,7 @@ func (ks keyStorePassphrase) DeleteKey(keyAddr common.Address, auth string) (err
}
func decryptKeyFromFile(keysDirPath string, keyAddr common.Address, auth string) (keyBytes []byte, keyId []byte, err error) {
fmt.Printf("%v\n", keyAddr.Hex())
m := make(map[string]interface{})
err = getKey(keysDirPath, keyAddr, &m)
if err != nil {

View File

@ -21,11 +21,9 @@ package secp256k1
/*
#cgo CFLAGS: -I./secp256k1
#cgo darwin CFLAGS: -I/usr/local/include
#cgo freebsd CFLAGS: -I/usr/local/include
#cgo linux,arm CFLAGS: -I/usr/local/arm/include
#cgo LDFLAGS: -lgmp
#cgo darwin LDFLAGS: -L/usr/local/lib
#cgo freebsd LDFLAGS: -L/usr/local/lib
#cgo linux,arm LDFLAGS: -L/usr/local/arm/lib
#define USE_NUM_GMP
#define USE_FIELD_10X26

View File

@ -78,11 +78,9 @@ type Config struct {
GenesisNonce int
GenesisFile string
GenesisBlock *types.Block // used by block tests
Olympic bool
BlockChainVersion int
SkipBcVersionCheck bool // e.g. blockchain export
DatabaseCache int
DataDir string
LogFile string
@ -264,7 +262,7 @@ func New(config *Config) (*Ethereum, error) {
newdb := config.NewDB
if newdb == nil {
newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path, config.DatabaseCache) }
newdb = func(path string) (common.Database, error) { return ethdb.NewLDBDatabase(path) }
}
blockDb, err := newdb(filepath.Join(config.DataDir, "blockchain"))
if err != nil {
@ -303,14 +301,6 @@ func New(config *Config) (*Ethereum, error) {
glog.V(logger.Info).Infof("Successfully wrote genesis block. New genesis hash = %x\n", block.Hash())
}
if config.Olympic {
_, err := core.WriteTestNetGenesisBlock(stateDb, blockDb, 42)
if err != nil {
return nil, err
}
glog.V(logger.Error).Infoln("Starting Olympic network")
}
// This is for testing only.
if config.GenesisBlock != nil {
core.WriteBlock(blockDb, config.GenesisBlock)

View File

@ -28,13 +28,12 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
)
var (
testdb, _ = ethdb.NewMemDatabase()
genesis = core.GenesisBlockForTesting(testdb, common.Address{}, big.NewInt(0))
unknownBlock = types.NewBlock(&types.Header{GasLimit: params.GenesisGasLimit}, nil, nil, nil)
unknownBlock = types.NewBlock(&types.Header{}, nil, nil, nil)
)
// makeChain creates a chain of n blocks starting at and including parent.

View File

@ -117,7 +117,7 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po
manager.downloader = downloader.New(manager.eventMux, manager.chainman.HasBlock, manager.chainman.GetBlock, manager.chainman.CurrentBlock, manager.chainman.InsertChain, manager.removePeer)
validator := func(block *types.Block, parent *types.Block) error {
return core.ValidateHeader(pow, block.Header(), parent, true, false)
return core.ValidateHeader(pow, block.Header(), parent, true)
}
heighter := func() uint64 {
return manager.chainman.CurrentBlock().NumberU64()

View File

@ -17,7 +17,6 @@
package ethdb
import (
"path/filepath"
"strconv"
"strings"
"sync"
@ -36,14 +35,6 @@ import (
var OpenFileLimit = 64
// cacheRatio specifies how the total alloted cache is distributed between the
// various system databases.
var cacheRatio = map[string]float64{
"blockchain": 1.0 / 13.0,
"extra": 2.0 / 13.0,
"state": 10.0 / 13.0,
}
type LDBDatabase struct {
fn string // filename for reporting
db *leveldb.DB // LevelDB instance
@ -65,24 +56,14 @@ type LDBDatabase struct {
// NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by
// it self but requires a background poller which syncs every X. `Flush` should be called
// when data needs to be stored and written to disk.
func NewLDBDatabase(file string, cache int) (*LDBDatabase, error) {
// Calculate the cache allowance for this particular database
cache = int(float64(cache) * cacheRatio[filepath.Base(file)])
if cache < 16 {
cache = 16
}
glog.V(logger.Info).Infof("Alloted %dMB cache to %s", cache, file)
// Open the db and recover any potential corruptions
db, err := leveldb.OpenFile(file, &opt.Options{
OpenFilesCacheCapacity: OpenFileLimit,
BlockCacheCapacity: cache / 2 * opt.MiB,
WriteBuffer: cache / 4 * opt.MiB, // Two of these are used internally
})
if _, corrupted := err.(*errors.ErrCorrupted); corrupted {
func NewLDBDatabase(file string) (*LDBDatabase, error) {
// Open the db
db, err := leveldb.OpenFile(file, &opt.Options{OpenFilesCacheCapacity: OpenFileLimit})
// check for corruption and attempt to recover
if _, iscorrupted := err.(*errors.ErrCorrupted); iscorrupted {
db, err = leveldb.RecoverFile(file, nil)
}
// (Re)check for errors and abort if opening of the db failed
// (re) check for errors and abort if opening of the db failed
if err != nil {
return nil, err
}

View File

@ -28,7 +28,8 @@ func newDb() *LDBDatabase {
if common.FileExist(file) {
os.RemoveAll(file)
}
db, _ := NewLDBDatabase(file, 0)
db, _ := NewLDBDatabase(file)
return db
}

View File

@ -1,112 +0,0 @@
// 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 fdtrack logs statistics about open file descriptors.
package fdtrack
import (
"fmt"
"net"
"sort"
"sync"
"time"
"github.com/ethereum/go-ethereum/logger/glog"
)
var (
mutex sync.Mutex
all = make(map[string]int)
)
func Open(desc string) {
mutex.Lock()
all[desc] += 1
mutex.Unlock()
}
func Close(desc string) {
mutex.Lock()
defer mutex.Unlock()
if c, ok := all[desc]; ok {
if c == 1 {
delete(all, desc)
} else {
all[desc]--
}
}
}
func WrapListener(desc string, l net.Listener) net.Listener {
Open(desc)
return &wrappedListener{l, desc}
}
type wrappedListener struct {
net.Listener
desc string
}
func (w *wrappedListener) Accept() (net.Conn, error) {
c, err := w.Listener.Accept()
if err == nil {
c = WrapConn(w.desc, c)
}
return c, err
}
func (w *wrappedListener) Close() error {
err := w.Listener.Close()
if err == nil {
Close(w.desc)
}
return err
}
func WrapConn(desc string, conn net.Conn) net.Conn {
Open(desc)
return &wrappedConn{conn, desc}
}
type wrappedConn struct {
net.Conn
desc string
}
func (w *wrappedConn) Close() error {
err := w.Conn.Close()
if err == nil {
Close(w.desc)
}
return err
}
func Start() {
go func() {
for range time.Tick(15 * time.Second) {
mutex.Lock()
var sum, tracked = 0, []string{}
for what, n := range all {
sum += n
tracked = append(tracked, fmt.Sprintf("%s:%d", what, n))
}
mutex.Unlock()
used, _ := fdusage()
sort.Strings(tracked)
glog.Infof("fd usage %d/%d, tracked %d %v", used, fdlimit(), sum, tracked)
}
}()
}

View File

@ -1,29 +0,0 @@
// 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/>.
// +build !linux,!darwin
package fdtrack
import "errors"
func fdlimit() int {
return 0
}
func fdusage() (int, error) {
return 0, errors.New("not implemented")
}

View File

@ -1,72 +0,0 @@
// 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/>.
// +build darwin
package fdtrack
import (
"os"
"syscall"
"unsafe"
)
// #cgo CFLAGS: -lproc
// #include <libproc.h>
// #include <stdlib.h>
import "C"
func fdlimit() int {
var nofile syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &nofile); err != nil {
return 0
}
return int(nofile.Cur)
}
func fdusage() (int, error) {
pid := C.int(os.Getpid())
// Query for a rough estimate on the amout of data that
// proc_pidinfo will return.
rlen, err := C.proc_pidinfo(pid, C.PROC_PIDLISTFDS, 0, nil, 0)
if rlen <= 0 {
return 0, err
}
// Load the list of file descriptors. We don't actually care about
// the content, only about the size. Since the number of fds can
// change while we're reading them, the loop enlarges the buffer
// until proc_pidinfo says the result fitted.
var buf unsafe.Pointer
defer func() {
if buf != nil {
C.free(buf)
}
}()
for buflen := rlen; ; buflen *= 2 {
buf, err = C.reallocf(buf, C.size_t(buflen))
if buf == nil {
return 0, err
}
rlen, err = C.proc_pidinfo(pid, C.PROC_PIDLISTFDS, 0, buf, buflen)
if rlen <= 0 {
return 0, err
} else if rlen == buflen {
continue
}
return int(rlen / C.PROC_PIDLISTFD_SIZE), nil
}
panic("unreachable")
}

View File

@ -1,53 +0,0 @@
// 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/>.
// +build linux
package fdtrack
import (
"io"
"os"
"syscall"
)
func fdlimit() int {
var nofile syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &nofile); err != nil {
return 0
}
return int(nofile.Cur)
}
func fdusage() (int, error) {
f, err := os.Open("/proc/self/fd")
if err != nil {
return 0, err
}
defer f.Close()
const batchSize = 100
n := 0
for {
list, err := f.Readdirnames(batchSize)
n += len(list)
if err == io.EOF {
break
} else if err != nil {
return 0, err
}
}
return n, nil
}

View File

@ -1137,10 +1137,10 @@ var toHex = function (val) {
if (isString(val)) {
if (val.indexOf('-0x') === 0)
return fromDecimal(val);
else if (!isFinite(val))
return fromAscii(val);
else if(val.indexOf('0x') === 0)
return val;
else if (!isFinite(val))
return fromAscii(val);
}
return fromDecimal(val);

View File

@ -34,7 +34,6 @@ func ReadDiskStats(stats *DiskStats) error {
if err != nil {
return err
}
defer inf.Close()
in := bufio.NewReader(inf)
// Iterate over the IO counter, and extract what we need

View File

@ -20,6 +20,7 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/pow"
@ -28,10 +29,10 @@ import (
type CpuAgent struct {
mu sync.Mutex
workCh chan *Work
workCh chan *types.Block
quit chan struct{}
quitCurrentOp chan struct{}
returnCh chan<- *Result
returnCh chan<- *types.Block
index int
pow pow.PoW
@ -46,9 +47,9 @@ func NewCpuAgent(index int, pow pow.PoW) *CpuAgent {
return miner
}
func (self *CpuAgent) Work() chan<- *Work { return self.workCh }
func (self *CpuAgent) Pow() pow.PoW { return self.pow }
func (self *CpuAgent) SetReturnCh(ch chan<- *Result) { self.returnCh = ch }
func (self *CpuAgent) Work() chan<- *types.Block { return self.workCh }
func (self *CpuAgent) Pow() pow.PoW { return self.pow }
func (self *CpuAgent) SetReturnCh(ch chan<- *types.Block) { self.returnCh = ch }
func (self *CpuAgent) Stop() {
self.mu.Lock()
@ -64,7 +65,7 @@ func (self *CpuAgent) Start() {
self.quit = make(chan struct{})
// creating current op ch makes sure we're not closing a nil ch
// later on
self.workCh = make(chan *Work, 1)
self.workCh = make(chan *types.Block, 1)
go self.update()
}
@ -73,13 +74,13 @@ func (self *CpuAgent) update() {
out:
for {
select {
case work := <-self.workCh:
case block := <-self.workCh:
self.mu.Lock()
if self.quitCurrentOp != nil {
close(self.quitCurrentOp)
}
self.quitCurrentOp = make(chan struct{})
go self.mine(work, self.quitCurrentOp)
go self.mine(block, self.quitCurrentOp)
self.mu.Unlock()
case <-self.quit:
self.mu.Lock()
@ -105,14 +106,13 @@ done:
}
}
func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) {
func (self *CpuAgent) mine(block *types.Block, stop <-chan struct{}) {
glog.V(logger.Debug).Infof("(re)started agent[%d]. mining...\n", self.index)
// Mine
nonce, mixDigest := self.pow.Search(work.Block, stop)
nonce, mixDigest := self.pow.Search(block, stop)
if nonce != 0 {
block := work.Block.WithMiningResult(nonce, common.BytesToHash(mixDigest))
self.returnCh <- &Result{work, block}
self.returnCh <- block.WithMiningResult(nonce, common.BytesToHash(mixDigest))
} else {
self.returnCh <- nil
}

View File

@ -18,44 +18,39 @@ package miner
import (
"math/big"
"sync"
"time"
"github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/core/types"
)
type RemoteAgent struct {
mu sync.Mutex
work *types.Block
currentWork *types.Block
quit chan struct{}
workCh chan *Work
returnCh chan<- *Result
currentWork *Work
work map[common.Hash]*Work
workCh chan *types.Block
returnCh chan<- *types.Block
}
func NewRemoteAgent() *RemoteAgent {
agent := &RemoteAgent{work: make(map[common.Hash]*Work)}
agent := &RemoteAgent{}
return agent
}
func (a *RemoteAgent) Work() chan<- *Work {
func (a *RemoteAgent) Work() chan<- *types.Block {
return a.workCh
}
func (a *RemoteAgent) SetReturnCh(returnCh chan<- *Result) {
func (a *RemoteAgent) SetReturnCh(returnCh chan<- *types.Block) {
a.returnCh = returnCh
}
func (a *RemoteAgent) Start() {
a.quit = make(chan struct{})
a.workCh = make(chan *Work, 1)
go a.maintainLoop()
a.workCh = make(chan *types.Block, 1)
go a.run()
}
func (a *RemoteAgent) Stop() {
@ -65,72 +60,47 @@ func (a *RemoteAgent) Stop() {
func (a *RemoteAgent) GetHashRate() int64 { return 0 }
func (a *RemoteAgent) GetWork() [3]string {
a.mu.Lock()
defer a.mu.Unlock()
var res [3]string
if a.currentWork != nil {
block := a.currentWork.Block
res[0] = block.HashNoNonce().Hex()
seedHash, _ := ethash.GetSeedHash(block.NumberU64())
res[1] = common.BytesToHash(seedHash).Hex()
// Calculate the "target" to be returned to the external miner
n := big.NewInt(1)
n.Lsh(n, 255)
n.Div(n, block.Difficulty())
n.Lsh(n, 1)
res[2] = common.BytesToHash(n.Bytes()).Hex()
a.work[block.HashNoNonce()] = a.currentWork
}
return res
}
// Returns true or false, but does not indicate if the PoW was correct
func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, hash common.Hash) bool {
a.mu.Lock()
defer a.mu.Unlock()
// Make sure the work submitted is present
if a.work[hash] != nil {
block := a.work[hash].Block.WithMiningResult(nonce, mixDigest)
a.returnCh <- &Result{a.work[hash], block}
delete(a.work, hash)
return true
} else {
glog.V(logger.Info).Infof("Work was submitted for %x but no pending work found\n", hash)
}
return false
}
func (a *RemoteAgent) maintainLoop() {
ticker := time.Tick(5 * time.Second)
func (a *RemoteAgent) run() {
out:
for {
select {
case <-a.quit:
break out
case work := <-a.workCh:
a.mu.Lock()
a.currentWork = work
a.mu.Unlock()
case <-ticker:
// cleanup
a.mu.Lock()
for hash, work := range a.work {
if time.Since(work.createdAt) > 7*(12*time.Second) {
delete(a.work, hash)
}
}
a.mu.Unlock()
a.work = work
}
}
}
func (a *RemoteAgent) GetWork() [3]string {
var res [3]string
if a.work != nil {
a.currentWork = a.work
res[0] = a.work.HashNoNonce().Hex()
seedHash, _ := ethash.GetSeedHash(a.currentWork.NumberU64())
res[1] = common.BytesToHash(seedHash).Hex()
// Calculate the "target" to be returned to the external miner
n := big.NewInt(1)
n.Lsh(n, 255)
n.Div(n, a.work.Difficulty())
n.Lsh(n, 1)
res[2] = common.BytesToHash(n.Bytes()).Hex()
}
return res
}
func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, seedHash common.Hash) bool {
// Return true or false, but does not indicate if the PoW was correct
// Make sure the external miner was working on the right hash
if a.currentWork != nil && a.work != nil {
a.returnCh <- a.currentWork.WithMiningResult(nonce, mixDigest)
//a.returnCh <- Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
return true
}
return false
}

View File

@ -38,20 +38,25 @@ import (
var jsonlogger = logger.NewJsonLogger()
const (
resultQueueSize = 10
miningLogAtDepth = 5
)
// Work holds the current work
type Work struct {
Number uint64
Nonce uint64
MixDigest []byte
SeedHash []byte
}
// Agent can register themself with the worker
type Agent interface {
Work() chan<- *Work
SetReturnCh(chan<- *Result)
Work() chan<- *types.Block
SetReturnCh(chan<- *types.Block)
Stop()
Start()
GetHashRate() int64
}
const miningLogAtDepth = 5
type uint64RingBuffer struct {
ints []uint64 //array of all integers in buffer
next int //where is the next insertion? assert 0 <= next < len(ints)
@ -59,7 +64,7 @@ type uint64RingBuffer struct {
// environment is the workers current environment and holds
// all of the current state information
type Work struct {
type environment struct {
state *state.StateDB // apply state changes here
coinbase *state.StateObject // the miner's account
ancestors *set.Set // ancestor set (used for checking uncle parent validity)
@ -73,18 +78,11 @@ type Work struct {
lowGasTxs types.Transactions
localMinedBlocks *uint64RingBuffer // the most recent block numbers that were mined locally (used to check block inclusion)
Block *types.Block // the new block
block *types.Block // the new block
header *types.Header
txs []*types.Transaction
receipts []*types.Receipt
createdAt time.Time
}
type Result struct {
Work *Work
Block *types.Block
}
// worker is the main object which takes care of applying messages to the new state
@ -92,7 +90,7 @@ type worker struct {
mu sync.Mutex
agents []Agent
recv chan *Result
recv chan *types.Block
mux *event.TypeMux
quit chan struct{}
pow pow.PoW
@ -107,7 +105,7 @@ type worker struct {
extra []byte
currentMu sync.Mutex
current *Work
current *environment
uncleMu sync.Mutex
possibleUncles map[common.Hash]*types.Block
@ -118,8 +116,6 @@ type worker struct {
// atomic status counters
mining int32
atWork int32
fullValidation bool
}
func newWorker(coinbase common.Address, eth core.Backend) *worker {
@ -127,7 +123,7 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
eth: eth,
mux: eth.EventMux(),
extraDb: eth.ExtraDb(),
recv: make(chan *Result, resultQueueSize),
recv: make(chan *types.Block),
gasPrice: new(big.Int),
chain: eth.ChainManager(),
proc: eth.BlockProcessor(),
@ -135,7 +131,6 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
coinbase: coinbase,
txQueue: make(map[common.Hash]*types.Transaction),
quit: make(chan struct{}),
fullValidation: false,
}
go worker.update()
go worker.wait()
@ -169,7 +164,7 @@ func (self *worker) pendingBlock() *types.Block {
self.current.receipts,
)
}
return self.current.Block
return self.current.block
}
func (self *worker) start() {
@ -256,55 +251,34 @@ func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *uint64RingBuffer) (
func (self *worker) wait() {
for {
for result := range self.recv {
for block := range self.recv {
atomic.AddInt32(&self.atWork, -1)
if result == nil {
if block == nil {
continue
}
block := result.Block
work := result.Work
work.state.Sync()
if self.fullValidation {
if _, err := self.chain.InsertChain(types.Blocks{block}); err != nil {
glog.V(logger.Error).Infoln("mining err", err)
continue
}
go self.mux.Post(core.NewMinedBlockEvent{block})
} else {
parent := self.chain.GetBlock(block.ParentHash())
if parent == nil {
glog.V(logger.Error).Infoln("Invalid block found during mining")
continue
}
if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent, true, false); err != nil && err != core.BlockFutureErr {
glog.V(logger.Error).Infoln("Invalid header on mined block:", err)
continue
}
parent := self.chain.GetBlock(block.ParentHash())
if parent == nil {
glog.V(logger.Error).Infoln("Invalid block found during mining")
continue
}
if err := core.ValidateHeader(self.eth.BlockProcessor().Pow, block.Header(), parent, true); err != nil && err != core.BlockFutureErr {
glog.V(logger.Error).Infoln("Invalid header on mined block:", err)
continue
}
stat, err := self.chain.WriteBlock(block, false)
if err != nil {
glog.V(logger.Error).Infoln("error writing block to chain", err)
continue
}
// check if canon block and write transactions
if stat == core.CanonStatTy {
// This puts transactions in a extra db for rpc
core.PutTransactions(self.extraDb, block, block.Transactions())
// store the receipts
core.PutReceipts(self.extraDb, work.receipts)
}
// broadcast before waiting for validation
go func(block *types.Block, logs state.Logs) {
self.mux.Post(core.NewMinedBlockEvent{block})
self.mux.Post(core.ChainEvent{block, block.Hash(), logs})
if stat == core.CanonStatTy {
self.mux.Post(core.ChainHeadEvent{block})
self.mux.Post(logs)
}
}(block, work.state.Logs())
stat, err := self.chain.WriteBlock(block, false)
if err != nil {
glog.V(logger.Error).Infoln("error writing block to chain", err)
continue
}
// check if canon block and write transactions
if stat == core.CanonStatTy {
// This puts transactions in a extra db for rpc
core.PutTransactions(self.extraDb, block, block.Transactions())
// store the receipts
core.PutReceipts(self.extraDb, self.current.receipts)
}
// check staleness and display confirmation
@ -314,18 +288,29 @@ func (self *worker) wait() {
stale = "stale "
} else {
confirm = "Wait 5 blocks for confirmation"
work.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), work.localMinedBlocks)
self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks)
}
glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm)
// broadcast before waiting for validation
go func(block *types.Block, logs state.Logs) {
self.mux.Post(core.NewMinedBlockEvent{block})
self.mux.Post(core.ChainEvent{block, block.Hash(), logs})
if stat == core.CanonStatTy {
self.mux.Post(core.ChainHeadEvent{block})
self.mux.Post(logs)
}
}(block, self.current.state.Logs())
self.commitNewWork()
}
}
}
func (self *worker) push(work *Work) {
func (self *worker) push() {
if atomic.LoadInt32(&self.mining) == 1 {
if core.Canary(work.state) {
if core.Canary(self.current.state) {
glog.Infoln("Toxicity levels rising to deadly levels. Your canary has died. You can go back or continue down the mineshaft --more--")
glog.Infoln("You turn back and abort mining")
return
@ -336,7 +321,7 @@ func (self *worker) push(work *Work) {
atomic.AddInt32(&self.atWork, 1)
if agent.Work() != nil {
agent.Work() <- work
agent.Work() <- self.current.block
}
}
}
@ -345,36 +330,35 @@ func (self *worker) push(work *Work) {
// makeCurrent creates a new environment for the current cycle.
func (self *worker) makeCurrent(parent *types.Block, header *types.Header) {
state := state.New(parent.Root(), self.eth.StateDb())
work := &Work{
current := &environment{
state: state,
ancestors: set.New(),
family: set.New(),
uncles: set.New(),
header: header,
coinbase: state.GetOrNewStateObject(self.coinbase),
createdAt: time.Now(),
}
// when 08 is processed ancestors contain 07 (quick block)
for _, ancestor := range self.chain.GetBlocksFromHash(parent.Hash(), 7) {
for _, uncle := range ancestor.Uncles() {
work.family.Add(uncle.Hash())
current.family.Add(uncle.Hash())
}
work.family.Add(ancestor.Hash())
work.ancestors.Add(ancestor.Hash())
current.family.Add(ancestor.Hash())
current.ancestors.Add(ancestor.Hash())
}
accounts, _ := self.eth.AccountManager().Accounts()
// Keep track of transactions which return errors so they can be removed
work.remove = set.New()
work.tcount = 0
work.ignoredTransactors = set.New()
work.lowGasTransactors = set.New()
work.ownedAccounts = accountAddressesSet(accounts)
current.remove = set.New()
current.tcount = 0
current.ignoredTransactors = set.New()
current.lowGasTransactors = set.New()
current.ownedAccounts = accountAddressesSet(accounts)
if self.current != nil {
work.localMinedBlocks = self.current.localMinedBlocks
current.localMinedBlocks = self.current.localMinedBlocks
}
self.current = work
self.current = current
}
func (w *worker) setGasPrice(p *big.Int) {
@ -388,13 +372,13 @@ func (w *worker) setGasPrice(p *big.Int) {
w.mux.Post(core.GasPriceChanged{w.gasPrice})
}
func (self *worker) isBlockLocallyMined(current *Work, deepBlockNum uint64) bool {
func (self *worker) isBlockLocallyMined(deepBlockNum uint64) bool {
//Did this instance mine a block at {deepBlockNum} ?
var isLocal = false
for idx, blockNum := range current.localMinedBlocks.ints {
for idx, blockNum := range self.current.localMinedBlocks.ints {
if deepBlockNum == blockNum {
isLocal = true
current.localMinedBlocks.ints[idx] = 0 //prevent showing duplicate logs
self.current.localMinedBlocks.ints[idx] = 0 //prevent showing duplicate logs
break
}
}
@ -408,12 +392,12 @@ func (self *worker) isBlockLocallyMined(current *Work, deepBlockNum uint64) bool
return block != nil && block.Coinbase() == self.coinbase
}
func (self *worker) logLocalMinedBlocks(current, previous *Work) {
if previous != nil && current.localMinedBlocks != nil {
nextBlockNum := current.Block.NumberU64()
for checkBlockNum := previous.Block.NumberU64(); checkBlockNum < nextBlockNum; checkBlockNum++ {
func (self *worker) logLocalMinedBlocks(previous *environment) {
if previous != nil && self.current.localMinedBlocks != nil {
nextBlockNum := self.current.block.NumberU64()
for checkBlockNum := previous.block.NumberU64(); checkBlockNum < nextBlockNum; checkBlockNum++ {
inspectBlockNum := checkBlockNum - miningLogAtDepth
if self.isBlockLocallyMined(current, inspectBlockNum) {
if self.isBlockLocallyMined(inspectBlockNum) {
glog.V(logger.Info).Infof("🔨 🔗 Mined %d blocks back: block #%v", miningLogAtDepth, inspectBlockNum)
}
}
@ -431,8 +415,8 @@ func (self *worker) commitNewWork() {
tstart := time.Now()
parent := self.chain.CurrentBlock()
tstamp := tstart.Unix()
if parent.Time().Cmp(new(big.Int).SetInt64(tstamp)) >= 0 {
tstamp = parent.Time().Int64() + 1
if tstamp <= int64(parent.Time()) {
tstamp = int64(parent.Time()) + 1
}
// this will ensure we're not going off too far in the future
if now := time.Now().Unix(); tstamp > now+4 {
@ -445,57 +429,24 @@ func (self *worker) commitNewWork() {
header := &types.Header{
ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1),
Difficulty: core.CalcDifficulty(uint64(tstamp), parent.Time().Uint64(), parent.Number(), parent.Difficulty()),
Difficulty: core.CalcDifficulty(uint64(tstamp), parent.Time(), parent.Difficulty()),
GasLimit: core.CalcGasLimit(parent),
GasUsed: new(big.Int),
Coinbase: self.coinbase,
Extra: self.extra,
Time: big.NewInt(tstamp),
Time: uint64(tstamp),
}
previous := self.current
self.makeCurrent(parent, header)
work := self.current
current := self.current
/* //approach 1
// commit transactions for this run.
transactions := self.eth.TxPool().GetTransactions()
sort.Sort(types.TxByNonce{transactions})
*/
//approach 2
transactions := self.eth.TxPool().GetTransactions()
sort.Sort(types.TxByPriceAndNonce{transactions})
/* // approach 3
// commit transactions for this run.
txPerOwner := make(map[common.Address]types.Transactions)
// Sort transactions by owner
for _, tx := range self.eth.TxPool().GetTransactions() {
from, _ := tx.From() // we can ignore the sender error
txPerOwner[from] = append(txPerOwner[from], tx)
}
var (
singleTxOwner types.Transactions
multiTxOwner types.Transactions
)
// Categorise transactions by
// 1. 1 owner tx per block
// 2. multi txs owner per block
for _, txs := range txPerOwner {
if len(txs) == 1 {
singleTxOwner = append(singleTxOwner, txs[0])
} else {
multiTxOwner = append(multiTxOwner, txs...)
}
}
sort.Sort(types.TxByPrice{singleTxOwner})
sort.Sort(types.TxByNonce{multiTxOwner})
transactions := append(singleTxOwner, multiTxOwner...)
*/
work.coinbase.SetGasLimit(header.GasLimit)
work.commitTransactions(transactions, self.gasPrice, self.proc)
self.eth.TxPool().RemoveTransactions(work.lowGasTxs)
current.coinbase.SetGasLimit(header.GasLimit)
current.commitTransactions(transactions, self.gasPrice, self.proc)
self.eth.TxPool().RemoveTransactions(current.lowGasTxs)
// compute uncles for the new block.
var (
@ -506,7 +457,7 @@ func (self *worker) commitNewWork() {
if len(uncles) == 2 {
break
}
if err := self.commitUncle(work, uncle.Header()); err != nil {
if err := self.commitUncle(uncle.Header()); err != nil {
if glog.V(logger.Ridiculousness) {
glog.V(logger.Detail).Infof("Bad uncle found and will be removed (%x)\n", hash[:4])
glog.V(logger.Detail).Infoln(uncle)
@ -523,40 +474,41 @@ func (self *worker) commitNewWork() {
if atomic.LoadInt32(&self.mining) == 1 {
// commit state root after all state transitions.
core.AccumulateRewards(work.state, header, uncles)
work.state.SyncObjects()
header.Root = work.state.Root()
core.AccumulateRewards(self.current.state, header, uncles)
current.state.SyncObjects()
self.current.state.Sync()
header.Root = current.state.Root()
}
// create the new block whose nonce will be mined.
work.Block = types.NewBlock(header, work.txs, uncles, work.receipts)
work.Block.Td = new(big.Int).Set(core.CalcTD(work.Block, self.chain.GetBlock(work.Block.ParentHash())))
current.block = types.NewBlock(header, current.txs, uncles, current.receipts)
self.current.block.Td = new(big.Int).Set(core.CalcTD(self.current.block, self.chain.GetBlock(self.current.block.ParentHash())))
// We only care about logging if we're actually mining.
if atomic.LoadInt32(&self.mining) == 1 {
glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles. Took %v\n", work.Block.Number(), work.tcount, len(uncles), time.Since(tstart))
self.logLocalMinedBlocks(work, previous)
glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles. Took %v\n", current.block.Number(), current.tcount, len(uncles), time.Since(tstart))
self.logLocalMinedBlocks(previous)
}
self.push(work)
self.push()
}
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
func (self *worker) commitUncle(uncle *types.Header) error {
hash := uncle.Hash()
if work.uncles.Has(hash) {
if self.current.uncles.Has(hash) {
return core.UncleError("Uncle not unique")
}
if !work.ancestors.Has(uncle.ParentHash) {
if !self.current.ancestors.Has(uncle.ParentHash) {
return core.UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.ParentHash[0:4]))
}
if work.family.Has(hash) {
if self.current.family.Has(hash) {
return core.UncleError(fmt.Sprintf("Uncle already in family (%x)", hash))
}
work.uncles.Add(uncle.Hash())
self.current.uncles.Add(uncle.Hash())
return nil
}
func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *big.Int, proc *core.BlockProcessor) {
func (env *environment) commitTransactions(transactions types.Transactions, gasPrice *big.Int, proc *core.BlockProcessor) {
for _, tx := range transactions {
// We can skip err. It has already been validated in the tx pool
from, _ := tx.From()
@ -614,7 +566,7 @@ func (env *Work) commitTransactions(transactions types.Transactions, gasPrice *b
}
}
func (env *Work) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor) error {
func (env *environment) commitTransaction(tx *types.Transaction, proc *core.BlockProcessor) error {
snap := env.state.Copy()
receipt, _, err := proc.ApplyTransaction(env.coinbase, env.state, env.header, tx, env.header.GasUsed, true)
if err != nil {

View File

@ -23,7 +23,6 @@ import (
"net"
"time"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/p2p/discover"
@ -213,7 +212,6 @@ func (t *dialTask) Do(srv *Server) {
glog.V(logger.Detail).Infof("dial error: %v", err)
return
}
fd = fdtrack.WrapConn("p2p", fd)
mfd := newMeteredConn(fd, false)
srv.setupConn(mfd, t.flags, t.dest)

View File

@ -25,7 +25,6 @@ import (
"time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/p2p/nat"
@ -198,7 +197,6 @@ func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBP
if err != nil {
return nil, err
}
fdtrack.Open("p2p")
conn, err := net.ListenUDP("udp", addr)
if err != nil {
return nil, err
@ -236,7 +234,6 @@ func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath strin
func (t *udp) close() {
close(t.closing)
fdtrack.Close("p2p")
t.conn.Close()
// TODO: wait for the loops to end.
}

View File

@ -34,7 +34,7 @@ var (
// meteredConn is a wrapper around a network TCP connection that meters both the
// inbound and outbound network traffic.
type meteredConn struct {
net.Conn
*net.TCPConn // Network connection to wrap with metering
}
// newMeteredConn creates a new metered connection, also bumping the ingress or
@ -45,13 +45,13 @@ func newMeteredConn(conn net.Conn, ingress bool) net.Conn {
} else {
egressConnectMeter.Mark(1)
}
return &meteredConn{conn}
return &meteredConn{conn.(*net.TCPConn)}
}
// Read delegates a network read to the underlying connection, bumping the ingress
// traffic meter along the way.
func (c *meteredConn) Read(b []byte) (n int, err error) {
n, err = c.Conn.Read(b)
n, err = c.TCPConn.Read(b)
ingressTrafficMeter.Mark(int64(n))
return
}
@ -59,7 +59,7 @@ func (c *meteredConn) Read(b []byte) (n int, err error) {
// Write delegates a network write to the underlying connection, bumping the
// egress traffic meter along the way.
func (c *meteredConn) Write(b []byte) (n int, err error) {
n, err = c.Conn.Write(b)
n, err = c.TCPConn.Write(b)
egressTrafficMeter.Mark(int64(n))
return
}

View File

@ -25,7 +25,6 @@ import (
"sync"
"time"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/p2p/discover"
@ -373,7 +372,7 @@ func (srv *Server) startListening() error {
}
laddr := listener.Addr().(*net.TCPAddr)
srv.ListenAddr = laddr.String()
srv.listener = fdtrack.WrapListener("p2p", listener)
srv.listener = listener
srv.loopWG.Add(1)
go srv.listenLoop()
// Map the TCP listening port if NAT is configured.

View File

@ -39,8 +39,8 @@ var (
EcrecoverGas = big.NewInt(3000) //
Sha256WordGas = big.NewInt(12) //
MinGasLimit = big.NewInt(5000) // Minimum the gas limit may ever be.
GenesisGasLimit = big.NewInt(3141592) // Gas limit of the Genesis block.
MinGasLimit = big.NewInt(5000) // Minimum the gas limit may ever be.
GenesisGasLimit = big.NewInt(5000) // Gas limit of the Genesis block.
Sha3Gas = big.NewInt(30) // Once per SHA3 operation.
Sha256Gas = big.NewInt(60) //

View File

@ -935,9 +935,9 @@ func TestCallArgsNotStrings(t *testing.T) {
func TestCallArgsToEmpty(t *testing.T) {
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]`
args := new(CallArgs)
err := json.Unmarshal([]byte(input), &args)
if err != nil {
t.Error("Did not expect error. Got", err)
str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
if len(str) > 0 {
t.Error(str)
}
}

View File

@ -21,9 +21,8 @@ import (
"encoding/json"
"math/big"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
@ -323,7 +322,7 @@ func (self *ethApi) EstimateGas(req *shared.Request) (interface{}, error) {
if len(gas) == 0 {
return newHexNum(0), nil
} else {
return newHexNum(common.String2Big(gas)), err
return newHexNum(gas), nil
}
}
@ -579,17 +578,14 @@ func (self *ethApi) Resend(req *shared.Request) (interface{}, error) {
return nil, shared.NewDecodeParamError(err.Error())
}
from := common.HexToAddress(args.Tx.From)
pending := self.ethereum.TxPool().GetTransactions()
for _, p := range pending {
if pFrom, err := p.From(); err == nil && pFrom == from && p.SigHash() == args.Tx.tx.SigHash() {
self.ethereum.TxPool().RemoveTx(common.HexToHash(args.Tx.Hash))
return self.xeth.Transact(args.Tx.From, args.Tx.To, args.Tx.Nonce, args.Tx.Value, args.GasLimit, args.GasPrice, args.Tx.Data)
}
ret, err := self.xeth.Transact(args.Tx.From, args.Tx.To, args.Tx.Nonce, args.Tx.Value, args.GasLimit, args.GasPrice, args.Tx.Data)
if err != nil {
return nil, err
}
return nil, fmt.Errorf("Transaction %s not found", args.Tx.Hash)
self.ethereum.TxPool().RemoveTransactions(types.Transactions{args.Tx.tx})
return ret, nil
}
func (self *ethApi) PendingTransactions(req *shared.Request) (interface{}, error) {

View File

@ -469,6 +469,10 @@ func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
}
args.From = ext.From
if len(ext.To) == 0 {
return shared.NewValidationError("to", "is required")
}
args.To = ext.To
var num *big.Int
@ -884,7 +888,6 @@ type tx struct {
Data string
GasLimit string
GasPrice string
Hash string
}
func newTx(t *types.Transaction) *tx {
@ -903,7 +906,6 @@ func newTx(t *types.Transaction) *tx {
Data: "0x" + common.Bytes2Hex(t.Data()),
GasLimit: t.Gas().String(),
GasPrice: t.GasPrice().String(),
Hash: t.Hash().Hex(),
}
}
@ -929,12 +931,6 @@ func (tx *tx) UnmarshalJSON(b []byte) (err error) {
contractCreation = true
)
if val, found := fields["Hash"]; found {
if hashVal, ok := val.(string); ok {
tx.Hash = hashVal
}
}
if val, found := fields["To"]; found {
if strVal, ok := val.(string); ok && len(strVal) > 0 {
tx.To = strVal

View File

@ -32,22 +32,16 @@ var (
AutoCompletion = map[string][]string{
"admin": []string{
"addPeer",
"chainSyncStatus",
"datadir",
"exportChain",
"getContractInfo",
"importChain",
"nodeInfo",
"peers",
"register",
"registerUrl",
"setSolc",
"sleepBlocks",
"startNatSpec",
"startRPC",
"stopNatSpec",
"stopRPC",
"nodeInfo",
"exportChain",
"importChain",
"verbosity",
"chainSyncStatus",
"setSolc",
"datadir",
"startRPC",
"stopRPC",
},
"db": []string{
"getString",
@ -103,7 +97,6 @@ var (
"miner": []string{
"hashrate",
"makeDAG",
"setEtherbase",
"setExtra",
"setGasPrice",
"startAutoDAG",

View File

@ -17,19 +17,13 @@
package comms
import (
"encoding/json"
"fmt"
"net"
"net/http"
"strings"
"sync"
"time"
"bytes"
"io"
"io/ioutil"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rpc/codec"
@ -37,15 +31,10 @@ import (
"github.com/rs/cors"
)
const (
serverIdleTimeout = 10 * time.Second // idle keep-alive connections
serverReadTimeout = 15 * time.Second // per-request read timeout
serverWriteTimeout = 15 * time.Second // per-request read timeout
)
var (
httpServerMu sync.Mutex
httpServer *stopServer
// main HTTP rpc listener
httpListener *stoppableTCPListener
listenerStoppedError = fmt.Errorf("Listener has stopped")
)
type HttpConfig struct {
@ -54,172 +43,42 @@ type HttpConfig struct {
CorsDomain string
}
// stopServer augments http.Server with idle connection tracking.
// Idle keep-alive connections are shut down when Close is called.
type stopServer struct {
*http.Server
l net.Listener
// connection tracking state
mu sync.Mutex
shutdown bool // true when Stop has returned
idle map[net.Conn]struct{}
}
type handler struct {
codec codec.Codec
api shared.EthereumApi
}
// StartHTTP starts listening for RPC requests sent via HTTP.
func StartHttp(cfg HttpConfig, codec codec.Codec, api shared.EthereumApi) error {
httpServerMu.Lock()
defer httpServerMu.Unlock()
addr := fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort)
if httpServer != nil {
if addr != httpServer.Addr {
return fmt.Errorf("RPC service already running on %s ", httpServer.Addr)
if httpListener != nil {
if fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort) != httpListener.Addr().String() {
return fmt.Errorf("RPC service already running on %s ", httpListener.Addr().String())
}
return nil // RPC service already running on given host/port
}
// Set up the request handler, wrapping it with CORS headers if configured.
handler := http.Handler(&handler{codec, api})
if len(cfg.CorsDomain) > 0 {
opts := cors.Options{
AllowedMethods: []string{"POST"},
AllowedOrigins: strings.Split(cfg.CorsDomain, " "),
}
handler = cors.New(opts).Handler(handler)
}
// Start the server.
s, err := listenHTTP(addr, handler)
l, err := newStoppableTCPListener(fmt.Sprintf("%s:%d", cfg.ListenAddress, cfg.ListenPort))
if err != nil {
glog.V(logger.Error).Infof("Can't listen on %s:%d: %v", cfg.ListenAddress, cfg.ListenPort, err)
return err
}
httpServer = s
httpListener = l
var handler http.Handler
if len(cfg.CorsDomain) > 0 {
var opts cors.Options
opts.AllowedMethods = []string{"POST"}
opts.AllowedOrigins = strings.Split(cfg.CorsDomain, " ")
c := cors.New(opts)
handler = newStoppableHandler(c.Handler(gethHttpHandler(codec, api)), l.stop)
} else {
handler = newStoppableHandler(gethHttpHandler(codec, api), l.stop)
}
go http.Serve(l, handler)
return nil
}
func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
// Limit request size to resist DoS
if req.ContentLength > maxHttpSizeReqLength {
err := fmt.Errorf("Request too large")
response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err)
sendJSON(w, &response)
return
}
defer req.Body.Close()
payload, err := ioutil.ReadAll(req.Body)
if err != nil {
err := fmt.Errorf("Could not read request body")
response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err)
sendJSON(w, &response)
return
}
c := h.codec.New(nil)
var rpcReq shared.Request
if err = c.Decode(payload, &rpcReq); err == nil {
reply, err := h.api.Execute(&rpcReq)
res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err)
sendJSON(w, &res)
return
}
var reqBatch []shared.Request
if err = c.Decode(payload, &reqBatch); err == nil {
resBatch := make([]*interface{}, len(reqBatch))
resCount := 0
for i, rpcReq := range reqBatch {
reply, err := h.api.Execute(&rpcReq)
if rpcReq.Id != nil { // this leaves nil entries in the response batch for later removal
resBatch[i] = shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err)
resCount += 1
}
}
// make response omitting nil entries
sendJSON(w, resBatch[:resCount])
return
}
// invalid request
err = fmt.Errorf("Could not decode request")
res := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32600, err)
sendJSON(w, res)
}
func sendJSON(w io.Writer, v interface{}) {
if glog.V(logger.Detail) {
if payload, err := json.MarshalIndent(v, "", "\t"); err == nil {
glog.Infof("Sending payload: %s", payload)
}
}
if err := json.NewEncoder(w).Encode(v); err != nil {
glog.V(logger.Error).Infoln("Error sending JSON:", err)
}
}
// Stop closes all active HTTP connections and shuts down the server.
func StopHttp() {
httpServerMu.Lock()
defer httpServerMu.Unlock()
if httpServer != nil {
httpServer.Close()
httpServer = nil
}
}
func listenHTTP(addr string, h http.Handler) (*stopServer, error) {
l, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
l = fdtrack.WrapListener("rpc", l)
s := &stopServer{l: l, idle: make(map[net.Conn]struct{})}
s.Server = &http.Server{
Addr: addr,
Handler: h,
ReadTimeout: serverReadTimeout,
WriteTimeout: serverWriteTimeout,
ConnState: s.connState,
}
go s.Serve(l)
return s, nil
}
func (s *stopServer) connState(c net.Conn, state http.ConnState) {
s.mu.Lock()
defer s.mu.Unlock()
// Close c immediately if we're past shutdown.
if s.shutdown {
if state != http.StateClosed {
c.Close()
}
return
}
if state == http.StateIdle {
s.idle[c] = struct{}{}
} else {
delete(s.idle, c)
}
}
func (s *stopServer) Close() {
s.mu.Lock()
defer s.mu.Unlock()
// Shut down the acceptor. No new connections can be created.
s.l.Close()
// Drop all idle connections. Non-idle connections will be
// closed by connState as soon as they become idle.
s.shutdown = true
for c := range s.idle {
glog.V(logger.Detail).Infof("closing idle connection %v", c.RemoteAddr())
c.Close()
delete(s.idle, c)
if httpListener != nil {
httpListener.Stop()
httpListener = nil
}
}

182
rpc/comms/http_net.go Normal file
View File

@ -0,0 +1,182 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package comms
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"time"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/shared"
)
// When https://github.com/golang/go/issues/4674 is implemented this could be replaced
type stoppableTCPListener struct {
*net.TCPListener
stop chan struct{} // closed when the listener must stop
}
func newStoppableTCPListener(addr string) (*stoppableTCPListener, error) {
wl, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
if tcpl, ok := wl.(*net.TCPListener); ok {
stop := make(chan struct{})
return &stoppableTCPListener{tcpl, stop}, nil
}
return nil, fmt.Errorf("Unable to create TCP listener for RPC service")
}
// Stop the listener and all accepted and still active connections.
func (self *stoppableTCPListener) Stop() {
close(self.stop)
}
func (self *stoppableTCPListener) Accept() (net.Conn, error) {
for {
self.SetDeadline(time.Now().Add(time.Duration(1 * time.Second)))
c, err := self.TCPListener.AcceptTCP()
select {
case <-self.stop:
if c != nil { // accept timeout
c.Close()
}
self.TCPListener.Close()
return nil, listenerStoppedError
default:
}
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Timeout() && netErr.Temporary() {
continue // regular timeout
}
}
return &closableConnection{c, self.stop}, err
}
}
type closableConnection struct {
*net.TCPConn
closed chan struct{}
}
func (self *closableConnection) Read(b []byte) (n int, err error) {
select {
case <-self.closed:
self.TCPConn.Close()
return 0, io.EOF
default:
return self.TCPConn.Read(b)
}
}
// Wraps the default handler and checks if the RPC service was stopped. In that case it returns an
// error indicating that the service was stopped. This will only happen for connections which are
// kept open (HTTP keep-alive) when the RPC service was shutdown.
func newStoppableHandler(h http.Handler, stop chan struct{}) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
select {
case <-stop:
w.Header().Set("Content-Type", "application/json")
err := fmt.Errorf("RPC service stopped")
response := shared.NewRpcResponse(-1, shared.JsonRpcVersion, nil, err)
httpSend(w, response)
default:
h.ServeHTTP(w, r)
}
})
}
func httpSend(writer io.Writer, v interface{}) (n int, err error) {
var payload []byte
payload, err = json.MarshalIndent(v, "", "\t")
if err != nil {
glog.V(logger.Error).Infoln("Error marshalling JSON", err)
return 0, err
}
glog.V(logger.Detail).Infof("Sending payload: %s", payload)
return writer.Write(payload)
}
func gethHttpHandler(codec codec.Codec, a shared.EthereumApi) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
// Limit request size to resist DoS
if req.ContentLength > maxHttpSizeReqLength {
err := fmt.Errorf("Request too large")
response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err)
httpSend(w, &response)
return
}
defer req.Body.Close()
payload, err := ioutil.ReadAll(req.Body)
if err != nil {
err := fmt.Errorf("Could not read request body")
response := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32700, err)
httpSend(w, &response)
return
}
c := codec.New(nil)
var rpcReq shared.Request
if err = c.Decode(payload, &rpcReq); err == nil {
reply, err := a.Execute(&rpcReq)
res := shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err)
httpSend(w, &res)
return
}
var reqBatch []shared.Request
if err = c.Decode(payload, &reqBatch); err == nil {
resBatch := make([]*interface{}, len(reqBatch))
resCount := 0
for i, rpcReq := range reqBatch {
reply, err := a.Execute(&rpcReq)
if rpcReq.Id != nil { // this leaves nil entries in the response batch for later removal
resBatch[i] = shared.NewRpcResponse(rpcReq.Id, rpcReq.Jsonrpc, reply, err)
resCount += 1
}
}
// make response omitting nil entries
resBatch = resBatch[:resCount]
httpSend(w, resBatch)
return
}
// invalid request
err = fmt.Errorf("Could not decode request")
res := shared.NewRpcErrorResponse(-1, shared.JsonRpcVersion, -32600, err)
httpSend(w, res)
})
}

View File

@ -22,7 +22,6 @@ import (
"net"
"os"
"github.com/ethereum/go-ethereum/fdtrack"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/rpc/codec"
@ -51,16 +50,15 @@ func (self *ipcClient) reconnect() error {
func startIpc(cfg IpcConfig, codec codec.Codec, api shared.EthereumApi) error {
os.Remove(cfg.Endpoint) // in case it still exists from a previous run
l, err := net.Listen("unix", cfg.Endpoint)
l, err := net.ListenUnix("unix", &net.UnixAddr{Name: cfg.Endpoint, Net: "unix"})
if err != nil {
return err
}
l = fdtrack.WrapListener("ipc", l)
os.Chmod(cfg.Endpoint, 0600)
go func() {
for {
conn, err := l.Accept()
conn, err := l.AcceptUnix()
if err != nil {
glog.V(logger.Error).Infof("Error accepting ipc connection - %v\n", err)
continue

View File

@ -35,13 +35,6 @@ func TestBcUncleHeaderValidityTests(t *testing.T) {
}
}
func TestBcUncleTests(t *testing.T) {
err := RunBlockTest(filepath.Join(blockTestDir, "bcUncleTest.json"), BlockSkipTests)
if err != nil {
t.Fatal(err)
}
}
func TestBcInvalidHeaderTests(t *testing.T) {
err := RunBlockTest(filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), BlockSkipTests)
if err != nil {

View File

@ -150,7 +150,7 @@ func runBlockTests(bt map[string]*BlockTest, skipTests []string) error {
// test the block
if err := runBlockTest(test); err != nil {
return fmt.Errorf("%s: %v", name, err)
return err
}
glog.Infoln("Block test passed: ", name)
@ -365,8 +365,8 @@ func (s *BlockTest) validateBlockHeader(h *btHeader, h2 *types.Header) error {
return fmt.Errorf("GasUsed: expected: %v, decoded: %v", expectedGasUsed, h2.GasUsed)
}
expectedTimestamp := mustConvertBigInt(h.Timestamp, 16)
if expectedTimestamp.Cmp(h2.Time) != 0 {
expectedTimestamp := mustConvertUint(h.Timestamp, 16)
if expectedTimestamp != h2.Time {
return fmt.Errorf("Timestamp: expected: %v, decoded: %v", expectedTimestamp, h2.Time)
}
@ -461,7 +461,7 @@ func mustConvertHeader(in btHeader) *types.Header {
GasUsed: mustConvertBigInt(in.GasUsed, 16),
GasLimit: mustConvertBigInt(in.GasLimit, 16),
Difficulty: mustConvertBigInt(in.Difficulty, 16),
Time: mustConvertBigInt(in.Timestamp, 16),
Time: mustConvertUint(in.Timestamp, 16),
Nonce: types.EncodeNonce(mustConvertUint(in.Nonce, 16)),
}
return header

View File

@ -1,100 +0,0 @@
{
"preExpDiffIncrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "42",
"currentDifficulty" : "1000488"
},
"preExpDiffDecrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "42",
"currentDifficulty" : "999512"
},
"ExpDiffAtBlock200000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "200000",
"currentDifficulty" : "1000489"
},
"ExpDiffAtBlock200000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "200000",
"currentDifficulty" : "999513"
},
"ExpDiffPostBlock200000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "200001",
"currentDifficulty" : "1000489"
},
"ExpDiffPostBlock200000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "200001",
"currentDifficulty" : "999513"
},
"ExpDiffPreBlock300000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "299999",
"currentDifficulty" : "1000489"
},
"ExpDiffPreBlock300000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "299999",
"currentDifficulty" : "999513"
},
"ExpDiffAtBlock300000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "300000",
"currentDifficulty" : "1000490"
},
"ExpDiffAtBlock300000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "300000",
"currentDifficulty" : "999514"
},
"ExpDiffPostBlock300000Increase" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "300001",
"currentDifficulty" : "1000490"
},
"ExpDiffPostBlock300000Decrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "300001",
"currentDifficulty" : "999514"
},
"ExpDiffInAYearIncrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "43",
"currentBlockNumber" : "2302400",
"currentDifficulty" : "3097640"
},
"ExpDiffInAYearDecrease" : {
"parentTimestamp" : "42",
"parentDifficulty" : "1000000",
"currentTimestamp" : "60",
"currentBlockNumber" : "2302400",
"currentDifficulty" : "3096664"
}
}

View File

@ -4543,318 +4543,5 @@
}
}
}
},
"uncleTimestampTooBig" : {
"blocks" : [
{
"blockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020000",
"extraData" : "0x",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x5208",
"hash" : "6bd328a10bb674cc758bd1bccb8afb584808766434c28b85580b422c75d4130e",
"mixHash" : "fefce638471ab6b66b1f1423ae574a99a6b2137229fe1846c508554d718d2bc1",
"nonce" : "f8cf2912afdd244d",
"number" : "0x01",
"parentHash" : "b964d0b68e5a3c7265e4087dc2a8aaf599f06b6d6c1316a1b1b6475587f569e2",
"receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313",
"stateRoot" : "cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878",
"timestamp" : "0x55d9d69f",
"transactionsTrie" : "5c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"rlp" : "0xf90261f901f9a0b964d0b68e5a3c7265e4087dc2a8aaf599f06b6d6c1316a1b1b6475587f569e2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a05c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd88252088455d9d69f80a0fefce638471ab6b66b1f1423ae574a99a6b2137229fe1846c508554d718d2bc188f8cf2912afdd244df862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba077c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8a03f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288dc0",
"transactions" : [
{
"data" : "0x",
"gasLimit" : "0x04cb2f",
"gasPrice" : "0x01",
"nonce" : "0x00",
"r" : "0x77c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8",
"s" : "0x3f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288d",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"v" : "0x1b",
"value" : "0x0a"
}
],
"uncleHeaders" : [
]
},
{
"blockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020040",
"extraData" : "0x",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x5208",
"hash" : "4c179927c9b9897464c7133033b412c9b66ee2bb1fa4a4b2595a6006d4081e3f",
"mixHash" : "3449cf46635bab4ae7121dcd145e6ca12ac4337f79e88354c41bff1c48335b48",
"nonce" : "4376da5cd48ffb68",
"number" : "0x02",
"parentHash" : "6bd328a10bb674cc758bd1bccb8afb584808766434c28b85580b422c75d4130e",
"receiptTrie" : "5ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6b",
"stateRoot" : "e7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70e",
"timestamp" : "0x55d9d6a1",
"transactionsTrie" : "c673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"rlp" : "0xf90260f901f9a06bd328a10bb674cc758bd1bccb8afb584808766434c28b85580b422c75d4130ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0e7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70ea0c673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5a05ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6bb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd88252088455d9d6a180a03449cf46635bab4ae7121dcd145e6ca12ac4337f79e88354c41bff1c48335b48884376da5cd48ffb68f861f85f01018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba033c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f239f1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cfc0",
"transactions" : [
{
"data" : "0x",
"gasLimit" : "0x04cb2f",
"gasPrice" : "0x01",
"nonce" : "0x01",
"r" : "0x33c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f23",
"s" : "0x1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cf",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"v" : "0x1b",
"value" : "0x0a"
}
],
"uncleHeaders" : [
]
},
{
"rlp" : "0xf90459f901f9a04c179927c9b9897464c7133033b412c9b66ee2bb1fa4a4b2595a6006d4081e3fa0f4fd3b99eb9b343e87bc472fdcd6b18e5cbcb231b1e70f8948e97b02c008ac26948888f1f195afa192cfee860698584c030f4c9db1a0e9940294a09308406a3d2e09203aed11db40259fac0a25e639ad2b30b82d07dea01722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1aa04ede0225773c7a517b91994aca65ade45124e7ef4b8be1e6097c9773a11920afb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd88252088455d9d6a680a0caf6f553d8c1394d291caaeabc61bc25f9126f4c313c829b2a51134cbd23d27188e6999e52421f5a38f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca015eb1cc916728b9799e55c489857727669afb2986433d5f54cde11faaed9f0eea05d36f6d06c34aae8d0a2a5895c8ba4a17ad46a5fa59f361cb3e7e01a23030e38f901f6f901f3a06bd328a10bb674cc758bd1bccb8afb584808766434c28b85580b422c75d4130ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794bcde5374fce5edbc8e2a8697c15331677e6ebf0ba0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000002832fefd8808080a077355633b05269548d6b3bd8e80d334fcb1a31c566b980dfc56eb57d5c16acc388846c622f81a727e7"
}
],
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020000",
"extraData" : "0x42",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x00",
"hash" : "b964d0b68e5a3c7265e4087dc2a8aaf599f06b6d6c1316a1b1b6475587f569e2",
"mixHash" : "b65f3c17c458ce015c087c3e4c0ffeeb010bf648a1faa2585c674d81ea7dcdfd",
"nonce" : "0b2ec3394d2421e3",
"number" : "0x00",
"parentHash" : "0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "7dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1",
"timestamp" : "0x54c98c81",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0b65f3c17c458ce015c087c3e4c0ffeeb010bf648a1faa2585c674d81ea7dcdfd880b2ec3394d2421e3c0c0",
"lastblockhash" : "4c179927c9b9897464c7133033b412c9b66ee2bb1fa4a4b2595a6006d4081e3f",
"postState" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x14",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
},
"8888f1f195afa192cfee860698584c030f4c9db1" : {
"balance" : "0x8ac7230489e8a410",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x09184e71fbdc",
"code" : "0x",
"nonce" : "0x02",
"storage" : {
}
}
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x09184e72a000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
}
},
"uncleTimestampMaxUint256" : {
"blocks" : [
{
"blockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020000",
"extraData" : "0x",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x5208",
"hash" : "19c900975f94fd78dc12ad13740200fbe0a2eba43fd070bedc65588b0c95438a",
"mixHash" : "4296af28ea723598c959f1cabc6f01fa0c75d126cfde89f13ccd9debcf3079c3",
"nonce" : "3213b3fd7789f5d5",
"number" : "0x01",
"parentHash" : "e688d736f1307c6f97b6777381b30556137b9d4ca5c43fbd5b30d6b5df315264",
"receiptTrie" : "e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313",
"stateRoot" : "cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878",
"timestamp" : "0x55d9c571",
"transactionsTrie" : "5c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"rlp" : "0xf90261f901f9a0e688d736f1307c6f97b6777381b30556137b9d4ca5c43fbd5b30d6b5df315264a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a05c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd88252088455d9c57180a04296af28ea723598c959f1cabc6f01fa0c75d126cfde89f13ccd9debcf3079c3883213b3fd7789f5d5f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba077c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8a03f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288dc0",
"transactions" : [
{
"data" : "0x",
"gasLimit" : "0x04cb2f",
"gasPrice" : "0x01",
"nonce" : "0x00",
"r" : "0x77c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8",
"s" : "0x3f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288d",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"v" : "0x1b",
"value" : "0x0a"
}
],
"uncleHeaders" : [
]
},
{
"blockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020040",
"extraData" : "0x",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x5208",
"hash" : "04e0807bea4d9766809afba8f4dbf2e5ab4e522aa4570bb915381c6593530e89",
"mixHash" : "782e9bf4a3427dee8cf2494f966830dd04a217eb5cf8769dba0ed6400212264f",
"nonce" : "e83b4878a0b9a46f",
"number" : "0x02",
"parentHash" : "19c900975f94fd78dc12ad13740200fbe0a2eba43fd070bedc65588b0c95438a",
"receiptTrie" : "5ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6b",
"stateRoot" : "e7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70e",
"timestamp" : "0x55d9c573",
"transactionsTrie" : "c673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"rlp" : "0xf90260f901f9a019c900975f94fd78dc12ad13740200fbe0a2eba43fd070bedc65588b0c95438aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0e7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70ea0c673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5a05ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6bb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd88252088455d9c57380a0782e9bf4a3427dee8cf2494f966830dd04a217eb5cf8769dba0ed6400212264f88e83b4878a0b9a46ff861f85f01018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba033c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f239f1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cfc0",
"transactions" : [
{
"data" : "0x",
"gasLimit" : "0x04cb2f",
"gasPrice" : "0x01",
"nonce" : "0x01",
"r" : "0x33c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f23",
"s" : "0x1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cf",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"v" : "0x1b",
"value" : "0x0a"
}
],
"uncleHeaders" : [
]
},
{
"blockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020080",
"extraData" : "0x",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x5208",
"hash" : "eed1b4da708283370856fc76352d68f36d9766b7f366da372e2992ced9a1f663",
"mixHash" : "c250fe02a675a64e068023f48df2662ff2269d970f7689bde287228e200d5401",
"nonce" : "105781dacf8bcf41",
"number" : "0x03",
"parentHash" : "04e0807bea4d9766809afba8f4dbf2e5ab4e522aa4570bb915381c6593530e89",
"receiptTrie" : "4ede0225773c7a517b91994aca65ade45124e7ef4b8be1e6097c9773a11920af",
"stateRoot" : "e9940294a09308406a3d2e09203aed11db40259fac0a25e639ad2b30b82d07de",
"timestamp" : "0x55d9c577",
"transactionsTrie" : "1722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1a",
"uncleHash" : "1e8797b712282d23d059df15e9082411499795fe2644bdfb35f310c10c78169b"
},
"rlp" : "0xf90479f901f9a004e0807bea4d9766809afba8f4dbf2e5ab4e522aa4570bb915381c6593530e89a01e8797b712282d23d059df15e9082411499795fe2644bdfb35f310c10c78169b948888f1f195afa192cfee860698584c030f4c9db1a0e9940294a09308406a3d2e09203aed11db40259fac0a25e639ad2b30b82d07dea01722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1aa04ede0225773c7a517b91994aca65ade45124e7ef4b8be1e6097c9773a11920afb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd88252088455d9c57780a0c250fe02a675a64e068023f48df2662ff2269d970f7689bde287228e200d540188105781dacf8bcf41f862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca015eb1cc916728b9799e55c489857727669afb2986433d5f54cde11faaed9f0eea05d36f6d06c34aae8d0a2a5895c8ba4a17ad46a5fa59f361cb3e7e01a23030e38f90216f90213a019c900975f94fd78dc12ad13740200fbe0a2eba43fd070bedc65588b0c95438aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794bcde5374fce5edbc8e2a8697c15331677e6ebf0ba0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000002832fefd880a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80a06868c784ca472bb16eb9b23029965a737713003d0da6c006e4923e400cd783fc88d99c24fcd2648302",
"transactions" : [
{
"data" : "0x",
"gasLimit" : "0x04cb2f",
"gasPrice" : "0x01",
"nonce" : "0x02",
"r" : "0x15eb1cc916728b9799e55c489857727669afb2986433d5f54cde11faaed9f0ee",
"s" : "0x5d36f6d06c34aae8d0a2a5895c8ba4a17ad46a5fa59f361cb3e7e01a23030e38",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"v" : "0x1c",
"value" : "0x0a"
}
],
"uncleHeaders" : [
{
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b",
"difficulty" : "0x020000",
"extraData" : "0x",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x00",
"hash" : "5264110fedc6f468e9b3c1fead10ee4bdd4957bcb6d193503f8ede6a0d478b95",
"mixHash" : "6868c784ca472bb16eb9b23029965a737713003d0da6c006e4923e400cd783fc",
"nonce" : "d99c24fcd2648302",
"number" : "0x02",
"parentHash" : "19c900975f94fd78dc12ad13740200fbe0a2eba43fd070bedc65588b0c95438a",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878",
"timestamp" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
}
],
"genesisBlockHeader" : {
"bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty" : "0x020000",
"extraData" : "0x42",
"gasLimit" : "0x2fefd8",
"gasUsed" : "0x00",
"hash" : "e688d736f1307c6f97b6777381b30556137b9d4ca5c43fbd5b30d6b5df315264",
"mixHash" : "f35b4695bdfef02db19d255636bec7911667c7056df2b2f475053ea78dd1b0ff",
"nonce" : "5333c47f947590d8",
"number" : "0x00",
"parentHash" : "0000000000000000000000000000000000000000000000000000000000000000",
"receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"stateRoot" : "7dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1",
"timestamp" : "0x54c98c81",
"transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
"genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0f35b4695bdfef02db19d255636bec7911667c7056df2b2f475053ea78dd1b0ff885333c47f947590d8c0c0",
"lastblockhash" : "eed1b4da708283370856fc76352d68f36d9766b7f366da372e2992ced9a1f663",
"postState" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x14",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
},
"8888f1f195afa192cfee860698584c030f4c9db1" : {
"balance" : "0x8ac7230489e8a410",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x09184e71fbdc",
"code" : "0x",
"nonce" : "0x02",
"storage" : {
}
}
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x09184e72a000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -131,12 +131,12 @@ type Env struct {
initial bool
Gas *big.Int
origin common.Address
parent common.Hash
origin common.Address
//parent common.Hash
coinbase common.Address
number *big.Int
time *big.Int
time uint64
difficulty *big.Int
gasLimit *big.Int
@ -163,10 +163,10 @@ func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues
env := NewEnv(state)
env.origin = common.HexToAddress(exeValues["caller"])
env.parent = common.HexToHash(envValues["previousHash"])
//env.parent = common.Hex2Bytes(envValues["previousHash"])
env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
env.number = common.Big(envValues["currentNumber"])
env.time = common.Big(envValues["currentTimestamp"])
env.time = common.Big(envValues["currentTimestamp"]).Uint64()
env.difficulty = common.Big(envValues["currentDifficulty"])
env.gasLimit = common.Big(envValues["currentGasLimit"])
env.Gas = new(big.Int)
@ -174,10 +174,12 @@ func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues
return env
}
func (self *Env) Origin() common.Address { return self.origin }
func (self *Env) BlockNumber() *big.Int { return self.number }
func (self *Env) Origin() common.Address { return self.origin }
func (self *Env) BlockNumber() *big.Int { return self.number }
//func (self *Env) PrevHash() []byte { return self.parent }
func (self *Env) Coinbase() common.Address { return self.coinbase }
func (self *Env) Time() *big.Int { return self.time }
func (self *Env) Time() uint64 { return self.time }
func (self *Env) Difficulty() *big.Int { return self.difficulty }
func (self *Env) State() *state.StateDB { return self.state }
func (self *Env) GasLimit() *big.Int { return self.gasLimit }

View File

@ -19,7 +19,6 @@ package xeth
import (
"bytes"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/common"
@ -77,7 +76,7 @@ type Block struct {
Hash string `json:"hash"`
Transactions *common.List `json:"transactions"`
Uncles *common.List `json:"uncles"`
Time *big.Int `json:"time"`
Time uint64 `json:"time"`
Coinbase string `json:"coinbase"`
Name string `json:"name"`
GasLimit string `json:"gasLimit"`

View File

@ -20,10 +20,8 @@ package xeth
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"math/big"
"regexp"
"sync"
"time"
@ -47,7 +45,6 @@ var (
defaultGasPrice = big.NewInt(10000000000000) //150000000000
defaultGas = big.NewInt(90000) //500000
dappStorePre = []byte("dapp-")
addrReg = regexp.MustCompile(`^(0x)?[a-fA-F0-9]{40}$`)
)
// byte will be inferred
@ -126,7 +123,7 @@ func New(ethereum *eth.Ethereum, frontend Frontend) *XEth {
if frontend == nil {
xeth.frontend = dummyFrontend{}
}
xeth.state = NewState(xeth, xeth.backend.ChainManager().State())
xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState())
go xeth.start()
go xeth.filterManager.Start()
@ -313,12 +310,7 @@ func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blha
// some chain, this probably needs to be refactored for more expressiveness
data, _ := self.backend.ExtraDb().Get(common.FromHex(hash))
if len(data) != 0 {
dtx := new(types.Transaction)
if err := rlp.DecodeBytes(data, dtx); err != nil {
glog.V(logger.Error).Infoln(err)
return
}
tx = dtx
tx = types.NewTransactionFromBytes(data)
} else { // check pending transactions
tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
}
@ -781,14 +773,8 @@ func (self *XEth) FromNumber(str string) string {
}
func (self *XEth) PushTx(encodedTx string) (string, error) {
tx := new(types.Transaction)
err := rlp.DecodeBytes(common.FromHex(encodedTx), tx)
if err != nil {
glog.V(logger.Error).Infoln(err)
return "", err
}
err = self.backend.TxPool().Add(tx)
tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
err := self.backend.TxPool().Add(tx)
if err != nil {
return "", err
}
@ -881,10 +867,6 @@ func (self *XEth) Sign(fromStr, hashStr string, didUnlock bool) (string, error)
return common.ToHex(sig), nil
}
func isAddress(addr string) bool {
return addrReg.MatchString(addr)
}
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
// this minimalistic recoding is enough (works for natspec.js)
@ -894,10 +876,6 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS
return "", err
}
if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) {
return "", errors.New("Invalid address")
}
var (
from = common.HexToAddress(fromStr)
to = common.HexToAddress(toStr)

View File

@ -1,26 +0,0 @@
package xeth
import "testing"
func TestIsAddress(t *testing.T) {
for _, invalid := range []string{
"0x00",
"0xNN",
"0x00000000000000000000000000000000000000NN",
"0xAAar000000000000000000000000000000000000",
} {
if isAddress(invalid) {
t.Error("Expected", invalid, "to be invalid")
}
}
for _, valid := range []string{
"0x0000000000000000000000000000000000000000",
"0xAABBbbCCccff9900000000000000000000000000",
"AABBbbCCccff9900000000000000000000000000",
} {
if !isAddress(valid) {
t.Error("Expected", valid, "to be valid")
}
}
}