diff options
114 files changed, 14903 insertions, 4365 deletions
diff --git a/.gitignore b/.gitignore index e8e10db2f..21dbd28c5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,17 +23,11 @@ Godeps/_workspace/bin .project .settings -deploy/osx/Mist.app -deploy/osx/Mist\ Installer.dmg -cmd/mist/assets/ext/ethereum.js/ - # used by the Makefile /build/_workspace/ /build/bin/ +/geth*.zip # travis profile.tmp profile.cov - -# vagrant -.vagrant diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 219564eb7..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "cmd/mist/assets/ext/ethereum.js"] - path = cmd/mist/assets/ext/ethereum.js - url = https://github.com/ethereum/web3.js diff --git a/.travis.yml b/.travis.yml index 24486d4a0..d0fd4b775 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,45 @@ language: go -go: - - 1.4.2 - - 1.5.4 - - 1.6.2 +go_import_path: github.com/ethereum/go-ethereum +sudo: false +matrix: + include: + - os: linux + dist: trusty + go: 1.4.2 + - os: linux + dist: trusty + go: 1.5.4 + - os: linux + dist: trusty + go: 1.6.2 + - os: osx + go: 1.6.2 + + # This builder does the PPA upload (and nothing else). + - os: linux + dist: trusty + go: 1.6.2 + env: PPA + addons: + apt: + packages: + - devscripts + - debhelper + - dput + script: + - go run build/ci.go travis-debsrc + install: - # - go get code.google.com/p/go.tools/cmd/goimports - # - go get github.com/golang/lint/golint - # - go get golang.org/x/tools/cmd/vet - go get golang.org/x/tools/cmd/cover -before_script: - # - gofmt -l -w . - # - goimports -l -w . - # - golint . - # - go vet ./... - # - go test -race ./... script: - - make travis-test-with-coverage + - go run build/ci.go install + - go run build/ci.go test -coverage -vet after_success: - - bash <(curl -s https://codecov.io/bash) -env: - global: - - secure: "U2U1AmkU4NJBgKR/uUAebQY87cNL0+1JHjnLOmmXwxYYyj5ralWb1aSuSH3qSXiT93qLBmtaUkuv9fberHVqrbAeVlztVdUsKAq7JMQH+M99iFkC9UiRMqHmtjWJ0ok4COD1sRYixxi21wb/JrMe3M1iL4QJVS61iltjHhVdM64=" -sudo: false + # - go run build/ci.go archive -type tar + notifications: webhooks: urls: - https://webhooks.gitter.im/e/e09ccdce1048c5e03445 on_success: change on_failure: always - on_start: false diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 9b5b9a44f..fc9523e53 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -94,11 +94,6 @@ "Rev": "e882a96ec18dd43fa283187b66af74497c9101c0" }, { - "ImportPath": "github.com/microsoft/go-winio", - "Comment": "v0.2.0", - "Rev": "9e2895e5f6c3f16473b91d37fae6e89990a4520c" - }, - { "ImportPath": "github.com/nsf/termbox-go", "Rev": "362329b0aa6447eadd52edd8d660ec1dff470295" }, @@ -217,23 +212,23 @@ }, { "ImportPath": "golang.org/x/net/context", - "Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634" + "Rev": "a728288923b47049b2ce791836767ffbe964a5bd" }, { "ImportPath": "golang.org/x/net/html", - "Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634" + "Rev": "a728288923b47049b2ce791836767ffbe964a5bd" }, { "ImportPath": "golang.org/x/net/html/atom", - "Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634" + "Rev": "a728288923b47049b2ce791836767ffbe964a5bd" }, { "ImportPath": "golang.org/x/net/html/charset", - "Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634" + "Rev": "a728288923b47049b2ce791836767ffbe964a5bd" }, { "ImportPath": "golang.org/x/net/websocket", - "Rev": "8968c61983e8f51a91b8c0ef25bf739278c89634" + "Rev": "a728288923b47049b2ce791836767ffbe964a5bd" }, { "ImportPath": "golang.org/x/sys/unix", @@ -321,6 +316,10 @@ "Rev": "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57" }, { + "ImportPath": "gopkg.in/natefinch/npipe.v2", + "Rev": "c1b8fa8bdccecb0b8db834ee0b92fdbcfa606dd6" + }, + { "ImportPath": "gopkg.in/urfave/cli.v1", "Comment": "v1.17.0", "Rev": "01857ac33766ce0c93856370626f9799281c14f4" diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/LICENSE b/Godeps/_workspace/src/github.com/microsoft/go-winio/LICENSE deleted file mode 100644 index b8b569d77..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Microsoft - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/README.md b/Godeps/_workspace/src/github.com/microsoft/go-winio/README.md deleted file mode 100644 index 478862a8b..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# go-winio - -This repository contains utilities for efficiently performing Win32 IO operations in -Go. Currently, this is focused on accessing named pipes and other file handles, and -for using named pipes as a net transport. - -This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go -to reuse the thread to schedule another goroutine. This limits support to Windows Vista and -newer operating systems. This is similar to the implementation of network sockets in Go's net -package. - -Please see the LICENSE file for licensing information. - -Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe -for another named pipe implementation. diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go deleted file mode 100644 index 864935175..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/backup.go +++ /dev/null @@ -1,266 +0,0 @@ -package winio - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "runtime" - "syscall" - "unicode/utf16" -) - -//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead -//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite - -const ( - BackupData = uint32(iota + 1) - BackupEaData - BackupSecurity - BackupAlternateData - BackupLink - BackupPropertyData - BackupObjectId - BackupReparseData - BackupSparseBlock - BackupTxfsData -) - -const ( - StreamSparseAttributes = uint32(8) -) - -const ( - WRITE_DAC = 0x40000 - WRITE_OWNER = 0x80000 - ACCESS_SYSTEM_SECURITY = 0x1000000 -) - -// BackupHeader represents a backup stream of a file. -type BackupHeader struct { - Id uint32 // The backup stream ID - Attributes uint32 // Stream attributes - Size int64 // The size of the stream in bytes - Name string // The name of the stream (for BackupAlternateData only). - Offset int64 // The offset of the stream in the file (for BackupSparseBlock only). -} - -type win32StreamId struct { - StreamId uint32 - Attributes uint32 - Size uint64 - NameSize uint32 -} - -// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series -// of BackupHeader values. -type BackupStreamReader struct { - r io.Reader - bytesLeft int64 -} - -// NewBackupStreamReader produces a BackupStreamReader from any io.Reader. -func NewBackupStreamReader(r io.Reader) *BackupStreamReader { - return &BackupStreamReader{r, 0} -} - -// Next returns the next backup stream and prepares for calls to Write(). It skips the remainder of the current stream if -// it was not completely read. -func (r *BackupStreamReader) Next() (*BackupHeader, error) { - if r.bytesLeft > 0 { - if _, err := io.Copy(ioutil.Discard, r); err != nil { - return nil, err - } - } - var wsi win32StreamId - if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil { - return nil, err - } - hdr := &BackupHeader{ - Id: wsi.StreamId, - Attributes: wsi.Attributes, - Size: int64(wsi.Size), - } - if wsi.NameSize != 0 { - name := make([]uint16, int(wsi.NameSize/2)) - if err := binary.Read(r.r, binary.LittleEndian, name); err != nil { - return nil, err - } - hdr.Name = syscall.UTF16ToString(name) - } - if wsi.StreamId == BackupSparseBlock { - if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil { - return nil, err - } - hdr.Size -= 8 - } - r.bytesLeft = hdr.Size - return hdr, nil -} - -// Read reads from the current backup stream. -func (r *BackupStreamReader) Read(b []byte) (int, error) { - if r.bytesLeft == 0 { - return 0, io.EOF - } - if int64(len(b)) > r.bytesLeft { - b = b[:r.bytesLeft] - } - n, err := r.r.Read(b) - r.bytesLeft -= int64(n) - if err == io.EOF { - err = io.ErrUnexpectedEOF - } else if r.bytesLeft == 0 && err == nil { - err = io.EOF - } - return n, err -} - -// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API. -type BackupStreamWriter struct { - w io.Writer - bytesLeft int64 -} - -// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer. -func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter { - return &BackupStreamWriter{w, 0} -} - -// WriteHeader writes the next backup stream header and prepares for calls to Write(). -func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error { - if w.bytesLeft != 0 { - return fmt.Errorf("missing %d bytes", w.bytesLeft) - } - name := utf16.Encode([]rune(hdr.Name)) - wsi := win32StreamId{ - StreamId: hdr.Id, - Attributes: hdr.Attributes, - Size: uint64(hdr.Size), - NameSize: uint32(len(name) * 2), - } - if hdr.Id == BackupSparseBlock { - // Include space for the int64 block offset - wsi.Size += 8 - } - if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil { - return err - } - if len(name) != 0 { - if err := binary.Write(w.w, binary.LittleEndian, name); err != nil { - return err - } - } - if hdr.Id == BackupSparseBlock { - if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil { - return err - } - } - w.bytesLeft = hdr.Size - return nil -} - -// Write writes to the current backup stream. -func (w *BackupStreamWriter) Write(b []byte) (int, error) { - if w.bytesLeft < int64(len(b)) { - return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft) - } - n, err := w.w.Write(b) - w.bytesLeft -= int64(n) - return n, err -} - -// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API. -type BackupFileReader struct { - f *os.File - includeSecurity bool - ctx uintptr -} - -// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true, -// Read will attempt to read the security descriptor of the file. -func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader { - r := &BackupFileReader{f, includeSecurity, 0} - runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() }) - return r -} - -// Read reads a backup stream from the file by calling the Win32 API BackupRead(). -func (r *BackupFileReader) Read(b []byte) (int, error) { - var bytesRead uint32 - err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx) - if err != nil { - return 0, &os.PathError{"BackupRead", r.f.Name(), err} - } - if bytesRead == 0 { - return 0, io.EOF - } - return int(bytesRead), nil -} - -// Close frees Win32 resources associated with the BackupFileReader. It does not close -// the underlying file. -func (r *BackupFileReader) Close() error { - if r.ctx != 0 { - backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx) - r.ctx = 0 - } - return nil -} - -// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API. -type BackupFileWriter struct { - f *os.File - includeSecurity bool - ctx uintptr -} - -// NewBackupFileWrtier returns a new BackupFileWriter from a file handle. If includeSecurity is true, -// Write() will attempt to restore the security descriptor from the stream. -func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter { - w := &BackupFileWriter{f, includeSecurity, 0} - runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() }) - return w -} - -// Write restores a portion of the file using the provided backup stream. -func (w *BackupFileWriter) Write(b []byte) (int, error) { - var bytesWritten uint32 - err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx) - if err != nil { - return 0, &os.PathError{"BackupWrite", w.f.Name(), err} - } - if int(bytesWritten) != len(b) { - return int(bytesWritten), errors.New("not all bytes could be written") - } - return len(b), nil -} - -// Close frees Win32 resources associated with the BackupFileWriter. It does not -// close the underlying file. -func (w *BackupFileWriter) Close() error { - if w.ctx != 0 { - backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx) - w.ctx = 0 - } - return nil -} - -// OpenForBackup opens a file or directory, potentially skipping access checks if the backup -// or restore privileges have been acquired. -// -// If the file opened was a directory, it cannot be used with Readdir(). -func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) { - winPath, err := syscall.UTF16FromString(path) - if err != nil { - return nil, err - } - h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) - if err != nil { - err = &os.PathError{Op: "open", Path: path, Err: err} - return nil, err - } - return os.NewFile(uintptr(h), path), nil -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/file.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/file.go deleted file mode 100644 index fd16f0075..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/file.go +++ /dev/null @@ -1,219 +0,0 @@ -package winio - -import ( - "errors" - "io" - "runtime" - "sync" - "syscall" - "time" -) - -//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx -//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort -//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus -//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes -//sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod - -const ( - cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 - cFILE_SKIP_SET_EVENT_ON_HANDLE = 2 -) - -var ( - ErrFileClosed = errors.New("file has already been closed") - ErrTimeout = &timeoutError{} -) - -type timeoutError struct{} - -func (e *timeoutError) Error() string { return "i/o timeout" } -func (e *timeoutError) Timeout() bool { return true } -func (e *timeoutError) Temporary() bool { return true } - -var ioInitOnce sync.Once -var ioCompletionPort syscall.Handle - -// ioResult contains the result of an asynchronous IO operation -type ioResult struct { - bytes uint32 - err error -} - -// ioOperation represents an outstanding asynchronous Win32 IO -type ioOperation struct { - o syscall.Overlapped - ch chan ioResult -} - -func initIo() { - h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff) - if err != nil { - panic(err) - } - ioCompletionPort = h - go ioCompletionProcessor(h) -} - -// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall. -// It takes ownership of this handle and will close it if it is garbage collected. -type win32File struct { - handle syscall.Handle - wg sync.WaitGroup - closing bool - readDeadline time.Time - writeDeadline time.Time -} - -// makeWin32File makes a new win32File from an existing file handle -func makeWin32File(h syscall.Handle) (*win32File, error) { - f := &win32File{handle: h} - ioInitOnce.Do(initIo) - _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff) - if err != nil { - return nil, err - } - err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE) - if err != nil { - return nil, err - } - runtime.SetFinalizer(f, (*win32File).closeHandle) - return f, nil -} - -func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) { - return makeWin32File(h) -} - -// closeHandle closes the resources associated with a Win32 handle -func (f *win32File) closeHandle() { - if !f.closing { - // cancel all IO and wait for it to complete - f.closing = true - cancelIoEx(f.handle, nil) - f.wg.Wait() - // at this point, no new IO can start - syscall.Close(f.handle) - f.handle = 0 - } -} - -// Close closes a win32File. -func (f *win32File) Close() error { - f.closeHandle() - runtime.SetFinalizer(f, nil) - return nil -} - -// prepareIo prepares for a new IO operation -func (f *win32File) prepareIo() (*ioOperation, error) { - f.wg.Add(1) - if f.closing { - return nil, ErrFileClosed - } - c := &ioOperation{} - c.ch = make(chan ioResult) - return c, nil -} - -// ioCompletionProcessor processes completed async IOs forever -func ioCompletionProcessor(h syscall.Handle) { - // Set the timer resolution to 1. This fixes a performance regression in golang 1.6. - timeBeginPeriod(1) - for { - var bytes uint32 - var key uintptr - var op *ioOperation - err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE) - if op == nil { - panic(err) - } - op.ch <- ioResult{bytes, err} - } -} - -// asyncIo processes the return value from ReadFile or WriteFile, blocking until -// the operation has actually completed. -func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) { - if err != syscall.ERROR_IO_PENDING { - f.wg.Done() - return int(bytes), err - } else { - var r ioResult - wait := true - timedout := false - if f.closing { - cancelIoEx(f.handle, &c.o) - } else if !deadline.IsZero() { - now := time.Now() - if !deadline.After(now) { - timedout = true - } else { - timeout := time.After(deadline.Sub(now)) - select { - case r = <-c.ch: - wait = false - case <-timeout: - timedout = true - } - } - } - if timedout { - cancelIoEx(f.handle, &c.o) - } - if wait { - r = <-c.ch - } - err = r.err - if err == syscall.ERROR_OPERATION_ABORTED { - if f.closing { - err = ErrFileClosed - } else if timedout { - err = ErrTimeout - } - } - f.wg.Done() - return int(r.bytes), err - } -} - -// Read reads from a file handle. -func (f *win32File) Read(b []byte) (int, error) { - c, err := f.prepareIo() - if err != nil { - return 0, err - } - var bytes uint32 - err = syscall.ReadFile(f.handle, b, &bytes, &c.o) - n, err := f.asyncIo(c, f.readDeadline, bytes, err) - - // Handle EOF conditions. - if err == nil && n == 0 && len(b) != 0 { - return 0, io.EOF - } else if err == syscall.ERROR_BROKEN_PIPE { - return 0, io.EOF - } else { - return n, err - } -} - -// Write writes to a file handle. -func (f *win32File) Write(b []byte) (int, error) { - c, err := f.prepareIo() - if err != nil { - return 0, err - } - var bytes uint32 - err = syscall.WriteFile(f.handle, b, &bytes, &c.o) - return f.asyncIo(c, f.writeDeadline, bytes, err) -} - -func (f *win32File) SetReadDeadline(t time.Time) error { - f.readDeadline = t - return nil -} - -func (f *win32File) SetWriteDeadline(t time.Time) error { - f.writeDeadline = t - return nil -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go deleted file mode 100644 index d5acb72d5..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/fileinfo.go +++ /dev/null @@ -1,54 +0,0 @@ -package winio - -import ( - "os" - "syscall" - "unsafe" -) - -//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx -//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle - -const ( - fileBasicInfo = 0 - fileIDInfo = 0x12 -) - -// FileBasicInfo contains file access time and file attributes information. -type FileBasicInfo struct { - CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime - FileAttributes uintptr // includes padding -} - -// GetFileBasicInfo retrieves times and attributes for a file. -func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { - bi := &FileBasicInfo{} - if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { - return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} - } - return bi, nil -} - -// SetFileBasicInfo sets times and attributes for a file. -func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error { - if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { - return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} - } - return nil -} - -// FileIDInfo contains the volume serial number and file ID for a file. This pair should be -// unique on a system. -type FileIDInfo struct { - VolumeSerialNumber uint64 - FileID [16]byte -} - -// GetFileID retrieves the unique (volume, file ID) pair for a file. -func GetFileID(f *os.File) (*FileIDInfo, error) { - fileID := &FileIDInfo{} - if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil { - return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} - } - return fileID, nil -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go deleted file mode 100644 index 82db28306..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/pipe.go +++ /dev/null @@ -1,398 +0,0 @@ -package winio - -import ( - "errors" - "io" - "net" - "os" - "syscall" - "time" - "unsafe" -) - -//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe -//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW -//sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW -//sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW -//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo -//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW - -type securityAttributes struct { - Length uint32 - SecurityDescriptor *byte - InheritHandle uint32 -} - -const ( - cERROR_PIPE_BUSY = syscall.Errno(231) - cERROR_PIPE_CONNECTED = syscall.Errno(535) - cERROR_SEM_TIMEOUT = syscall.Errno(121) - - cPIPE_ACCESS_DUPLEX = 0x3 - cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000 - cSECURITY_SQOS_PRESENT = 0x100000 - cSECURITY_ANONYMOUS = 0 - - cPIPE_REJECT_REMOTE_CLIENTS = 0x8 - - cPIPE_UNLIMITED_INSTANCES = 255 - - cNMPWAIT_USE_DEFAULT_WAIT = 0 - cNMPWAIT_NOWAIT = 1 - - cPIPE_TYPE_MESSAGE = 4 - - cPIPE_READMODE_MESSAGE = 2 -) - -var ( - // ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed. - // This error should match net.errClosing since docker takes a dependency on its text. - ErrPipeListenerClosed = errors.New("use of closed network connection") - - errPipeWriteClosed = errors.New("pipe has been closed for write") -) - -type win32Pipe struct { - *win32File - path string -} - -type win32MessageBytePipe struct { - win32Pipe - writeClosed bool - readEOF bool -} - -type pipeAddress string - -func (f *win32Pipe) LocalAddr() net.Addr { - return pipeAddress(f.path) -} - -func (f *win32Pipe) RemoteAddr() net.Addr { - return pipeAddress(f.path) -} - -func (f *win32Pipe) SetDeadline(t time.Time) error { - f.SetReadDeadline(t) - f.SetWriteDeadline(t) - return nil -} - -// CloseWrite closes the write side of a message pipe in byte mode. -func (f *win32MessageBytePipe) CloseWrite() error { - if f.writeClosed { - return errPipeWriteClosed - } - _, err := f.win32File.Write(nil) - if err != nil { - return err - } - f.writeClosed = true - return nil -} - -// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since -// they are used to implement CloseWrite(). -func (f *win32MessageBytePipe) Write(b []byte) (int, error) { - if f.writeClosed { - return 0, errPipeWriteClosed - } - if len(b) == 0 { - return 0, nil - } - return f.win32File.Write(b) -} - -// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message -// mode pipe will return io.EOF, as will all subsequent reads. -func (f *win32MessageBytePipe) Read(b []byte) (int, error) { - if f.readEOF { - return 0, io.EOF - } - n, err := f.win32File.Read(b) - if err == io.EOF { - // If this was the result of a zero-byte read, then - // it is possible that the read was due to a zero-size - // message. Since we are simulating CloseWrite with a - // zero-byte message, ensure that all future Read() calls - // also return EOF. - f.readEOF = true - } - return n, err -} - -func (s pipeAddress) Network() string { - return "pipe" -} - -func (s pipeAddress) String() string { - return string(s) -} - -// DialPipe connects to a named pipe by path, timing out if the connection -// takes longer than the specified duration. If timeout is nil, then the timeout -// is the default timeout established by the pipe server. -func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { - var absTimeout time.Time - if timeout != nil { - absTimeout = time.Now().Add(*timeout) - } - var err error - var h syscall.Handle - for { - h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0) - if err != cERROR_PIPE_BUSY { - break - } - now := time.Now() - var ms uint32 - if absTimeout.IsZero() { - ms = cNMPWAIT_USE_DEFAULT_WAIT - } else if now.After(absTimeout) { - ms = cNMPWAIT_NOWAIT - } else { - ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000) - } - err = waitNamedPipe(path, ms) - if err != nil { - if err == cERROR_SEM_TIMEOUT { - return nil, ErrTimeout - } - break - } - } - if err != nil { - return nil, &os.PathError{Op: "open", Path: path, Err: err} - } - - var flags uint32 - err = getNamedPipeInfo(h, &flags, nil, nil, nil) - if err != nil { - return nil, err - } - - var state uint32 - err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0) - if err != nil { - return nil, err - } - - if state&cPIPE_READMODE_MESSAGE != 0 { - return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")} - } - - f, err := makeWin32File(h) - if err != nil { - syscall.Close(h) - return nil, err - } - - // If the pipe is in message mode, return a message byte pipe, which - // supports CloseWrite(). - if flags&cPIPE_TYPE_MESSAGE != 0 { - return &win32MessageBytePipe{ - win32Pipe: win32Pipe{win32File: f, path: path}, - }, nil - } - return &win32Pipe{win32File: f, path: path}, nil -} - -type acceptResponse struct { - f *win32File - err error -} - -type win32PipeListener struct { - firstHandle syscall.Handle - path string - securityDescriptor []byte - config PipeConfig - acceptCh chan (chan acceptResponse) - closeCh chan int - doneCh chan int -} - -func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) { - var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED - if first { - flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE - } - - var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS - if c.MessageMode { - mode |= cPIPE_TYPE_MESSAGE - } - - var sa securityAttributes - sa.Length = uint32(unsafe.Sizeof(sa)) - if securityDescriptor != nil { - sa.SecurityDescriptor = &securityDescriptor[0] - } - h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa) - if err != nil { - return 0, &os.PathError{Op: "open", Path: path, Err: err} - } - return h, nil -} - -func (l *win32PipeListener) makeServerPipe() (*win32File, error) { - h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false) - if err != nil { - return nil, err - } - f, err := makeWin32File(h) - if err != nil { - syscall.Close(h) - return nil, err - } - return f, nil -} - -func (l *win32PipeListener) listenerRoutine() { - closed := false - for !closed { - select { - case <-l.closeCh: - closed = true - case responseCh := <-l.acceptCh: - p, err := l.makeServerPipe() - if err == nil { - // Wait for the client to connect. - ch := make(chan error) - go func() { - ch <- connectPipe(p) - }() - select { - case err = <-ch: - if err != nil { - p.Close() - p = nil - } - case <-l.closeCh: - // Abort the connect request by closing the handle. - p.Close() - p = nil - err = <-ch - if err == nil || err == ErrFileClosed { - err = ErrPipeListenerClosed - } - closed = true - } - } - responseCh <- acceptResponse{p, err} - } - } - syscall.Close(l.firstHandle) - l.firstHandle = 0 - // Notify Close() and Accept() callers that the handle has been closed. - close(l.doneCh) -} - -// PipeConfig contain configuration for the pipe listener. -type PipeConfig struct { - // SecurityDescriptor contains a Windows security descriptor in SDDL format. - SecurityDescriptor string - - // MessageMode determines whether the pipe is in byte or message mode. In either - // case the pipe is read in byte mode by default. The only practical difference in - // this implementation is that CloseWrite() is only supported for message mode pipes; - // CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only - // transferred to the reader (and returned as io.EOF in this implementation) - // when the pipe is in message mode. - MessageMode bool - - // InputBufferSize specifies the size the input buffer, in bytes. - InputBufferSize int32 - - // OutputBufferSize specifies the size the input buffer, in bytes. - OutputBufferSize int32 -} - -// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe. -// The pipe must not already exist. -func ListenPipe(path string, c *PipeConfig) (net.Listener, error) { - var ( - sd []byte - err error - ) - if c == nil { - c = &PipeConfig{} - } - if c.SecurityDescriptor != "" { - sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor) - if err != nil { - return nil, err - } - } - h, err := makeServerPipeHandle(path, sd, c, true) - if err != nil { - return nil, err - } - // Immediately open and then close a client handle so that the named pipe is - // created but not currently accepting connections. - h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0) - if err != nil { - syscall.Close(h) - return nil, err - } - syscall.Close(h2) - l := &win32PipeListener{ - firstHandle: h, - path: path, - securityDescriptor: sd, - config: *c, - acceptCh: make(chan (chan acceptResponse)), - closeCh: make(chan int), - doneCh: make(chan int), - } - go l.listenerRoutine() - return l, nil -} - -func connectPipe(p *win32File) error { - c, err := p.prepareIo() - if err != nil { - return err - } - err = connectNamedPipe(p.handle, &c.o) - _, err = p.asyncIo(c, time.Time{}, 0, err) - if err != nil && err != cERROR_PIPE_CONNECTED { - return err - } - return nil -} - -func (l *win32PipeListener) Accept() (net.Conn, error) { - ch := make(chan acceptResponse) - select { - case l.acceptCh <- ch: - response := <-ch - err := response.err - if err != nil { - return nil, err - } - if l.config.MessageMode { - return &win32MessageBytePipe{ - win32Pipe: win32Pipe{win32File: response.f, path: l.path}, - }, nil - } - return &win32Pipe{win32File: response.f, path: l.path}, nil - case <-l.doneCh: - return nil, ErrPipeListenerClosed - } -} - -func (l *win32PipeListener) Close() error { - select { - case l.closeCh <- 1: - <-l.doneCh - case <-l.doneCh: - } - return nil -} - -func (l *win32PipeListener) Addr() net.Addr { - return pipeAddress(l.path) -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go deleted file mode 100644 index 81f9af7b7..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/privilege.go +++ /dev/null @@ -1,150 +0,0 @@ -package winio - -import ( - "bytes" - "encoding/binary" - "fmt" - "runtime" - "syscall" - "unicode/utf16" -) - -//sys adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges -//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf -//sys revertToSelf() (err error) = advapi32.RevertToSelf -//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) = advapi32.OpenThreadToken -//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread -//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW -//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW -//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW - -const ( - SE_PRIVILEGE_ENABLED = 2 - - ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 - - SeBackupPrivilege = "SeBackupPrivilege" - SeRestorePrivilege = "SeRestorePrivilege" -) - -const ( - securityAnonymous = iota - securityIdentification - securityImpersonation - securityDelegation -) - -type PrivilegeError struct { - privileges []uint64 -} - -func (e *PrivilegeError) Error() string { - s := "" - if len(e.privileges) > 1 { - s = "Could not enable privileges " - } else { - s = "Could not enable privilege " - } - for i, p := range e.privileges { - if i != 0 { - s += ", " - } - s += `"` - s += getPrivilegeName(p) - s += `"` - } - return s -} - -func RunWithPrivilege(name string, fn func() error) error { - return RunWithPrivileges([]string{name}, fn) -} - -func RunWithPrivileges(names []string, fn func() error) error { - var privileges []uint64 - for _, name := range names { - p := uint64(0) - err := lookupPrivilegeValue("", name, &p) - if err != nil { - return err - } - privileges = append(privileges, p) - } - runtime.LockOSThread() - defer runtime.UnlockOSThread() - token, err := newThreadToken() - if err != nil { - return err - } - defer releaseThreadToken(token) - err = adjustPrivileges(token, privileges) - if err != nil { - return err - } - return fn() -} - -func adjustPrivileges(token syscall.Handle, privileges []uint64) error { - var b bytes.Buffer - binary.Write(&b, binary.LittleEndian, uint32(len(privileges))) - for _, p := range privileges { - binary.Write(&b, binary.LittleEndian, p) - binary.Write(&b, binary.LittleEndian, uint32(SE_PRIVILEGE_ENABLED)) - } - prevState := make([]byte, b.Len()) - reqSize := uint32(0) - success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize) - if !success { - return err - } - if err == ERROR_NOT_ALL_ASSIGNED { - return &PrivilegeError{privileges} - } - return nil -} - -func getPrivilegeName(luid uint64) string { - var nameBuffer [256]uint16 - bufSize := uint32(len(nameBuffer)) - err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize) - if err != nil { - return fmt.Sprintf("<unknown privilege %d>", luid) - } - - var displayNameBuffer [256]uint16 - displayBufSize := uint32(len(displayNameBuffer)) - var langId uint32 - err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langId) - if err != nil { - return fmt.Sprintf("<unknown privilege %s>", utf16.Decode(nameBuffer[:bufSize])) - } - - return string(utf16.Decode(displayNameBuffer[:displayBufSize])) -} - -func newThreadToken() (syscall.Handle, error) { - err := impersonateSelf(securityImpersonation) - if err != nil { - panic(err) - return 0, err - } - - var token syscall.Handle - err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token) - if err != nil { - rerr := revertToSelf() - if rerr != nil { - panic(rerr) - } - return 0, err - } - return token, nil -} - -func releaseThreadToken(h syscall.Handle) { - err := revertToSelf() - if err != nil { - panic(err) - } - syscall.Close(h) -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go deleted file mode 100644 index 96d7b9a87..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/reparse.go +++ /dev/null @@ -1,124 +0,0 @@ -package winio - -import ( - "bytes" - "encoding/binary" - "fmt" - "strings" - "unicode/utf16" - "unsafe" -) - -const ( - reparseTagMountPoint = 0xA0000003 - reparseTagSymlink = 0xA000000C -) - -type reparseDataBuffer struct { - ReparseTag uint32 - ReparseDataLength uint16 - Reserved uint16 - SubstituteNameOffset uint16 - SubstituteNameLength uint16 - PrintNameOffset uint16 - PrintNameLength uint16 -} - -// ReparsePoint describes a Win32 symlink or mount point. -type ReparsePoint struct { - Target string - IsMountPoint bool -} - -// UnsupportedReparsePointError is returned when trying to decode a non-symlink or -// mount point reparse point. -type UnsupportedReparsePointError struct { - Tag uint32 -} - -func (e *UnsupportedReparsePointError) Error() string { - return fmt.Sprintf("unsupported reparse point %x", e.Tag) -} - -// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink -// or a mount point. -func DecodeReparsePoint(b []byte) (*ReparsePoint, error) { - isMountPoint := false - tag := binary.LittleEndian.Uint32(b[0:4]) - switch tag { - case reparseTagMountPoint: - isMountPoint = true - case reparseTagSymlink: - default: - return nil, &UnsupportedReparsePointError{tag} - } - nameOffset := 16 + binary.LittleEndian.Uint16(b[12:14]) - if !isMountPoint { - nameOffset += 4 - } - nameLength := binary.LittleEndian.Uint16(b[14:16]) - name := make([]uint16, nameLength/2) - err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name) - if err != nil { - return nil, err - } - return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil -} - -func isDriveLetter(c byte) bool { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') -} - -// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or -// mount point. -func EncodeReparsePoint(rp *ReparsePoint) []byte { - // Generate an NT path and determine if this is a relative path. - var ntTarget string - relative := false - if strings.HasPrefix(rp.Target, `\\?\`) { - ntTarget = rp.Target - } else if strings.HasPrefix(rp.Target, `\\`) { - ntTarget = `\??\UNC\` + rp.Target[2:] - } else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' { - ntTarget = `\??\` + rp.Target - } else { - ntTarget = rp.Target - relative = true - } - - // The paths must be NUL-terminated even though they are counted strings. - target16 := utf16.Encode([]rune(rp.Target + "\x00")) - ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00")) - - size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8 - size += len(ntTarget16)*2 + len(target16)*2 - - tag := uint32(reparseTagMountPoint) - if !rp.IsMountPoint { - tag = reparseTagSymlink - size += 4 // Add room for symlink flags - } - - data := reparseDataBuffer{ - ReparseTag: tag, - ReparseDataLength: uint16(size), - SubstituteNameOffset: 0, - SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2), - PrintNameOffset: uint16(len(ntTarget16) * 2), - PrintNameLength: uint16((len(target16) - 1) * 2), - } - - var b bytes.Buffer - binary.Write(&b, binary.LittleEndian, &data) - if !rp.IsMountPoint { - flags := uint32(0) - if relative { - flags |= 1 - } - binary.Write(&b, binary.LittleEndian, flags) - } - - binary.Write(&b, binary.LittleEndian, ntTarget16) - binary.Write(&b, binary.LittleEndian, target16) - return b.Bytes() -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go deleted file mode 100644 index 60ab56ce7..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/sd.go +++ /dev/null @@ -1,96 +0,0 @@ -package winio - -import ( - "syscall" - "unsafe" -) - -//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW -//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW -//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW -//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW -//sys localFree(mem uintptr) = LocalFree -//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength - -const ( - cERROR_NONE_MAPPED = syscall.Errno(1332) -) - -type AccountLookupError struct { - Name string - Err error -} - -func (e *AccountLookupError) Error() string { - if e.Name == "" { - return "lookup account: empty account name specified" - } - var s string - switch e.Err { - case cERROR_NONE_MAPPED: - s = "not found" - default: - s = e.Err.Error() - } - return "lookup account " + e.Name + ": " + s -} - -type SddlConversionError struct { - Sddl string - Err error -} - -func (e *SddlConversionError) Error() string { - return "convert " + e.Sddl + ": " + e.Err.Error() -} - -// LookupSidByName looks up the SID of an account by name -func LookupSidByName(name string) (sid string, err error) { - if name == "" { - return "", &AccountLookupError{name, cERROR_NONE_MAPPED} - } - - var sidSize, sidNameUse, refDomainSize uint32 - err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse) - if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { - return "", &AccountLookupError{name, err} - } - sidBuffer := make([]byte, sidSize) - refDomainBuffer := make([]uint16, refDomainSize) - err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse) - if err != nil { - return "", &AccountLookupError{name, err} - } - var strBuffer *uint16 - err = convertSidToStringSid(&sidBuffer[0], &strBuffer) - if err != nil { - return "", &AccountLookupError{name, err} - } - sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:]) - localFree(uintptr(unsafe.Pointer(strBuffer))) - return sid, nil -} - -func SddlToSecurityDescriptor(sddl string) ([]byte, error) { - var sdBuffer uintptr - err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil) - if err != nil { - return nil, &SddlConversionError{sddl, err} - } - defer localFree(sdBuffer) - sd := make([]byte, getSecurityDescriptorLength(sdBuffer)) - copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)]) - return sd, nil -} - -func SecurityDescriptorToSddl(sd []byte) (string, error) { - var sddl *uint16 - // The returned string length seems to including an aribtrary number of terminating NULs. - // Don't use it. - err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil) - if err != nil { - return "", err - } - defer localFree(uintptr(unsafe.Pointer(sddl))) - return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil -} diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go deleted file mode 100644 index 96fdff7b4..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/syscall.go +++ /dev/null @@ -1,3 +0,0 @@ -package winio - -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go diff --git a/Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go b/Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go deleted file mode 100644 index 74b6e97a6..000000000 --- a/Godeps/_workspace/src/github.com/microsoft/go-winio/zsyscall.go +++ /dev/null @@ -1,492 +0,0 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT - -package winio - -import "unsafe" -import "syscall" - -var _ unsafe.Pointer - -var ( - modkernel32 = syscall.NewLazyDLL("kernel32.dll") - modwinmm = syscall.NewLazyDLL("winmm.dll") - modadvapi32 = syscall.NewLazyDLL("advapi32.dll") - - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod") - procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") - procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") - procCreateFileW = modkernel32.NewProc("CreateFileW") - procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW") - procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") - procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") - procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") - procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") - procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") - procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") - procLocalFree = modkernel32.NewProc("LocalFree") - procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") - procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") - procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") - procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") - procRevertToSelf = modadvapi32.NewProc("RevertToSelf") - procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") - procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") - procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") - procBackupRead = modkernel32.NewProc("BackupRead") - procBackupWrite = modkernel32.NewProc("BackupWrite") -) - -func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) - newport = syscall.Handle(r0) - if newport == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func timeBeginPeriod(period uint32) (n int32) { - r0, _, _ := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) - n = int32(r0) - return -} - -func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) -} - -func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) - handle = syscall.Handle(r0) - if handle == syscall.InvalidHandle { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile) -} - -func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) - handle = syscall.Handle(r0) - if handle == syscall.InvalidHandle { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func waitNamedPipe(name string, timeout uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _waitNamedPipe(_p0, timeout) -} - -func _waitNamedPipe(name *uint16, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(accountName) - if err != nil { - return - } - return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse) -} - -func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func convertSidToStringSid(sid *byte, str **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(str) - if err != nil { - return - } - return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) -} - -func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func localFree(mem uintptr) { - syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0) - return -} - -func getSecurityDescriptorLength(sd uintptr) (len uint32) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0) - len = uint32(r0) - return -} - -func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { - var _p0 uint32 - if releaseAll { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) - success = r0 != 0 - if true { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func impersonateSelf(level uint32) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func revertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) { - var _p0 uint32 - if openAsSelf { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getCurrentThread() (h syscall.Handle) { - r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) - h = syscall.Handle(r0) - return -} - -func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - var _p1 *uint16 - _p1, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _lookupPrivilegeValue(_p0, _p1, luid) -} - -func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - return _lookupPrivilegeName(_p0, luid, buffer, size) -} - -func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId) -} - -func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - var _p1 uint32 - if abort { - _p1 = 1 - } else { - _p1 = 0 - } - var _p2 uint32 - if processSecurity { - _p2 = 1 - } else { - _p2 = 0 - } - r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - var _p1 uint32 - if abort { - _p1 = 1 - } else { - _p1 = 0 - } - var _p2 uint32 - if processSecurity { - _p2 = 1 - } else { - _p2 = 0 - } - r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/context.go b/Godeps/_workspace/src/golang.org/x/net/context/context.go index 11bd8d34e..ea1a7cd53 100644 --- a/Godeps/_workspace/src/golang.org/x/net/context/context.go +++ b/Godeps/_workspace/src/golang.org/x/net/context/context.go @@ -36,12 +36,7 @@ // Contexts. package context -import ( - "errors" - "fmt" - "sync" - "time" -) +import "time" // A Context carries a deadline, a cancelation signal, and other values across // API boundaries. @@ -66,7 +61,7 @@ type Context interface { // // // Stream generates values with DoSomething and sends them to out // // until DoSomething returns an error or ctx.Done is closed. - // func Stream(ctx context.Context, out <-chan Value) error { + // func Stream(ctx context.Context, out chan<- Value) error { // for { // v, err := DoSomething(ctx) // if err != nil { @@ -138,48 +133,6 @@ type Context interface { Value(key interface{}) interface{} } -// Canceled is the error returned by Context.Err when the context is canceled. -var Canceled = errors.New("context canceled") - -// DeadlineExceeded is the error returned by Context.Err when the context's -// deadline passes. -var DeadlineExceeded = errors.New("context deadline exceeded") - -// An emptyCtx is never canceled, has no values, and has no deadline. It is not -// struct{}, since vars of this type must have distinct addresses. -type emptyCtx int - -func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { - return -} - -func (*emptyCtx) Done() <-chan struct{} { - return nil -} - -func (*emptyCtx) Err() error { - return nil -} - -func (*emptyCtx) Value(key interface{}) interface{} { - return nil -} - -func (e *emptyCtx) String() string { - switch e { - case background: - return "context.Background" - case todo: - return "context.TODO" - } - return "unknown empty Context" -} - -var ( - background = new(emptyCtx) - todo = new(emptyCtx) -) - // Background returns a non-nil, empty Context. It is never canceled, has no // values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming @@ -201,247 +154,3 @@ func TODO() Context { // A CancelFunc does not wait for the work to stop. // After the first call, subsequent calls to a CancelFunc do nothing. type CancelFunc func() - -// WithCancel returns a copy of parent with a new Done channel. The returned -// context's Done channel is closed when the returned cancel function is called -// or when the parent context's Done channel is closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { - c := newCancelCtx(parent) - propagateCancel(parent, &c) - return &c, func() { c.cancel(true, Canceled) } -} - -// newCancelCtx returns an initialized cancelCtx. -func newCancelCtx(parent Context) cancelCtx { - return cancelCtx{ - Context: parent, - done: make(chan struct{}), - } -} - -// propagateCancel arranges for child to be canceled when parent is. -func propagateCancel(parent Context, child canceler) { - if parent.Done() == nil { - return // parent is never canceled - } - if p, ok := parentCancelCtx(parent); ok { - p.mu.Lock() - if p.err != nil { - // parent has already been canceled - child.cancel(false, p.err) - } else { - if p.children == nil { - p.children = make(map[canceler]bool) - } - p.children[child] = true - } - p.mu.Unlock() - } else { - go func() { - select { - case <-parent.Done(): - child.cancel(false, parent.Err()) - case <-child.Done(): - } - }() - } -} - -// parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this -// package represents its parent. -func parentCancelCtx(parent Context) (*cancelCtx, bool) { - for { - switch c := parent.(type) { - case *cancelCtx: - return c, true - case *timerCtx: - return &c.cancelCtx, true - case *valueCtx: - parent = c.Context - default: - return nil, false - } - } -} - -// removeChild removes a context from its parent. -func removeChild(parent Context, child canceler) { - p, ok := parentCancelCtx(parent) - if !ok { - return - } - p.mu.Lock() - if p.children != nil { - delete(p.children, child) - } - p.mu.Unlock() -} - -// A canceler is a context type that can be canceled directly. The -// implementations are *cancelCtx and *timerCtx. -type canceler interface { - cancel(removeFromParent bool, err error) - Done() <-chan struct{} -} - -// A cancelCtx can be canceled. When canceled, it also cancels any children -// that implement canceler. -type cancelCtx struct { - Context - - done chan struct{} // closed by the first cancel call. - - mu sync.Mutex - children map[canceler]bool // set to nil by the first cancel call - err error // set to non-nil by the first cancel call -} - -func (c *cancelCtx) Done() <-chan struct{} { - return c.done -} - -func (c *cancelCtx) Err() error { - c.mu.Lock() - defer c.mu.Unlock() - return c.err -} - -func (c *cancelCtx) String() string { - return fmt.Sprintf("%v.WithCancel", c.Context) -} - -// cancel closes c.done, cancels each of c's children, and, if -// removeFromParent is true, removes c from its parent's children. -func (c *cancelCtx) cancel(removeFromParent bool, err error) { - if err == nil { - panic("context: internal error: missing cancel error") - } - c.mu.Lock() - if c.err != nil { - c.mu.Unlock() - return // already canceled - } - c.err = err - close(c.done) - for child := range c.children { - // NOTE: acquiring the child's lock while holding parent's lock. - child.cancel(false, err) - } - c.children = nil - c.mu.Unlock() - - if removeFromParent { - removeChild(c.Context, c) - } -} - -// WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned -// context's Done channel is closed when the deadline expires, when the returned -// cancel function is called, or when the parent context's Done channel is -// closed, whichever happens first. -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete. -func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { - if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { - // The current deadline is already sooner than the new one. - return WithCancel(parent) - } - c := &timerCtx{ - cancelCtx: newCancelCtx(parent), - deadline: deadline, - } - propagateCancel(parent, c) - d := deadline.Sub(time.Now()) - if d <= 0 { - c.cancel(true, DeadlineExceeded) // deadline has already passed - return c, func() { c.cancel(true, Canceled) } - } - c.mu.Lock() - defer c.mu.Unlock() - if c.err == nil { - c.timer = time.AfterFunc(d, func() { - c.cancel(true, DeadlineExceeded) - }) - } - return c, func() { c.cancel(true, Canceled) } -} - -// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to -// implement Done and Err. It implements cancel by stopping its timer then -// delegating to cancelCtx.cancel. -type timerCtx struct { - cancelCtx - timer *time.Timer // Under cancelCtx.mu. - - deadline time.Time -} - -func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { - return c.deadline, true -} - -func (c *timerCtx) String() string { - return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) -} - -func (c *timerCtx) cancel(removeFromParent bool, err error) { - c.cancelCtx.cancel(false, err) - if removeFromParent { - // Remove this timerCtx from its parent cancelCtx's children. - removeChild(c.cancelCtx.Context, c) - } - c.mu.Lock() - if c.timer != nil { - c.timer.Stop() - c.timer = nil - } - c.mu.Unlock() -} - -// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). -// -// Canceling this context releases resources associated with it, so code should -// call cancel as soon as the operations running in this Context complete: -// -// func slowOperationWithTimeout(ctx context.Context) (Result, error) { -// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) -// defer cancel() // releases resources if slowOperation completes before timeout elapses -// return slowOperation(ctx) -// } -func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { - return WithDeadline(parent, time.Now().Add(timeout)) -} - -// WithValue returns a copy of parent in which the value associated with key is -// val. -// -// Use context Values only for request-scoped data that transits processes and -// APIs, not for passing optional parameters to functions. -func WithValue(parent Context, key interface{}, val interface{}) Context { - return &valueCtx{parent, key, val} -} - -// A valueCtx carries a key-value pair. It implements Value for that key and -// delegates all other calls to the embedded Context. -type valueCtx struct { - Context - key, val interface{} -} - -func (c *valueCtx) String() string { - return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) -} - -func (c *valueCtx) Value(key interface{}) interface{} { - if c.key == key { - return c.val - } - return c.Context.Value(key) -} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go deleted file mode 100644 index e3170e333..000000000 --- a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.5 - -package ctxhttp - -import "net/http" - -func canceler(client *http.Client, req *http.Request) func() { - // TODO(djd): Respect any existing value of req.Cancel. - ch := make(chan struct{}) - req.Cancel = ch - - return func() { - close(ch) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go deleted file mode 100644 index 56bcbadb8..000000000 --- a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.5 - -package ctxhttp - -import "net/http" - -type requestCanceler interface { - CancelRequest(*http.Request) -} - -func canceler(client *http.Client, req *http.Request) func() { - rc, ok := client.Transport.(requestCanceler) - if !ok { - return func() {} - } - return func() { - rc.CancelRequest(req) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go deleted file mode 100644 index 26a5e19ac..000000000 --- a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ctxhttp provides helper functions for performing context-aware HTTP requests. -package ctxhttp - -import ( - "io" - "net/http" - "net/url" - "strings" - - "golang.org/x/net/context" -) - -func nop() {} - -var ( - testHookContextDoneBeforeHeaders = nop - testHookDoReturned = nop - testHookDidBodyClose = nop -) - -// Do sends an HTTP request with the provided http.Client and returns an HTTP response. -// If the client is nil, http.DefaultClient is used. -// If the context is canceled or times out, ctx.Err() will be returned. -func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { - if client == nil { - client = http.DefaultClient - } - - // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. - cancel := canceler(client, req) - - type responseAndError struct { - resp *http.Response - err error - } - result := make(chan responseAndError, 1) - - go func() { - resp, err := client.Do(req) - testHookDoReturned() - result <- responseAndError{resp, err} - }() - - var resp *http.Response - - select { - case <-ctx.Done(): - testHookContextDoneBeforeHeaders() - cancel() - // Clean up after the goroutine calling client.Do: - go func() { - if r := <-result; r.resp != nil { - testHookDidBodyClose() - r.resp.Body.Close() - } - }() - return nil, ctx.Err() - case r := <-result: - var err error - resp, err = r.resp, r.err - if err != nil { - return resp, err - } - } - - c := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - cancel() - case <-c: - // The response's Body is closed. - } - }() - resp.Body = ¬ifyingReader{resp.Body, c} - - return resp, nil -} - -// Get issues a GET request via the Do function. -func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Head issues a HEAD request via the Do function. -func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { - req, err := http.NewRequest("HEAD", url, nil) - if err != nil { - return nil, err - } - return Do(ctx, client, req) -} - -// Post issues a POST request via the Do function. -func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { - req, err := http.NewRequest("POST", url, body) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", bodyType) - return Do(ctx, client, req) -} - -// PostForm issues a POST request via the Do function. -func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { - return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) -} - -// notifyingReader is an io.ReadCloser that closes the notify channel after -// Close is called or a Read fails on the underlying ReadCloser. -type notifyingReader struct { - io.ReadCloser - notify chan<- struct{} -} - -func (r *notifyingReader) Read(p []byte) (int, error) { - n, err := r.ReadCloser.Read(p) - if err != nil && r.notify != nil { - close(r.notify) - r.notify = nil - } - return n, err -} - -func (r *notifyingReader) Close() error { - err := r.ReadCloser.Close() - if r.notify != nil { - close(r.notify) - r.notify = nil - } - return err -} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/go17.go b/Godeps/_workspace/src/golang.org/x/net/context/go17.go new file mode 100644 index 000000000..f8cda19ad --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/context/go17.go @@ -0,0 +1,72 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package context + +import ( + "context" // standard library's context, as of Go 1.7 + "time" +) + +var ( + todo = context.TODO() + background = context.Background() +) + +// Canceled is the error returned by Context.Err when the context is canceled. +var Canceled = context.Canceled + +// DeadlineExceeded is the error returned by Context.Err when the context's +// deadline passes. +var DeadlineExceeded = context.DeadlineExceeded + +// WithCancel returns a copy of parent with a new Done channel. The returned +// context's Done channel is closed when the returned cancel function is called +// or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + ctx, f := context.WithCancel(parent) + return ctx, CancelFunc(f) +} + +// WithDeadline returns a copy of the parent context with the deadline adjusted +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// context's Done channel is closed when the deadline expires, when the returned +// cancel function is called, or when the parent context's Done channel is +// closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { + ctx, f := context.WithDeadline(parent, deadline) + return ctx, CancelFunc(f) +} + +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: +// +// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +// defer cancel() // releases resources if slowOperation completes before timeout elapses +// return slowOperation(ctx) +// } +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { + return WithDeadline(parent, time.Now().Add(timeout)) +} + +// WithValue returns a copy of parent in which the value associated with key is +// val. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +func WithValue(parent Context, key interface{}, val interface{}) Context { + return context.WithValue(parent, key, val) +} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/pre_go17.go b/Godeps/_workspace/src/golang.org/x/net/context/pre_go17.go new file mode 100644 index 000000000..5a30acabd --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/context/pre_go17.go @@ -0,0 +1,300 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.7 + +package context + +import ( + "errors" + "fmt" + "sync" + "time" +) + +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case background: + return "context.Background" + case todo: + return "context.TODO" + } + return "unknown empty Context" +} + +var ( + background = new(emptyCtx) + todo = new(emptyCtx) +) + +// Canceled is the error returned by Context.Err when the context is canceled. +var Canceled = errors.New("context canceled") + +// DeadlineExceeded is the error returned by Context.Err when the context's +// deadline passes. +var DeadlineExceeded = errors.New("context deadline exceeded") + +// WithCancel returns a copy of parent with a new Done channel. The returned +// context's Done channel is closed when the returned cancel function is called +// or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + c := newCancelCtx(parent) + propagateCancel(parent, c) + return c, func() { c.cancel(true, Canceled) } +} + +// newCancelCtx returns an initialized cancelCtx. +func newCancelCtx(parent Context) *cancelCtx { + return &cancelCtx{ + Context: parent, + done: make(chan struct{}), + } +} + +// propagateCancel arranges for child to be canceled when parent is. +func propagateCancel(parent Context, child canceler) { + if parent.Done() == nil { + return // parent is never canceled + } + if p, ok := parentCancelCtx(parent); ok { + p.mu.Lock() + if p.err != nil { + // parent has already been canceled + child.cancel(false, p.err) + } else { + if p.children == nil { + p.children = make(map[canceler]bool) + } + p.children[child] = true + } + p.mu.Unlock() + } else { + go func() { + select { + case <-parent.Done(): + child.cancel(false, parent.Err()) + case <-child.Done(): + } + }() + } +} + +// parentCancelCtx follows a chain of parent references until it finds a +// *cancelCtx. This function understands how each of the concrete types in this +// package represents its parent. +func parentCancelCtx(parent Context) (*cancelCtx, bool) { + for { + switch c := parent.(type) { + case *cancelCtx: + return c, true + case *timerCtx: + return c.cancelCtx, true + case *valueCtx: + parent = c.Context + default: + return nil, false + } + } +} + +// removeChild removes a context from its parent. +func removeChild(parent Context, child canceler) { + p, ok := parentCancelCtx(parent) + if !ok { + return + } + p.mu.Lock() + if p.children != nil { + delete(p.children, child) + } + p.mu.Unlock() +} + +// A canceler is a context type that can be canceled directly. The +// implementations are *cancelCtx and *timerCtx. +type canceler interface { + cancel(removeFromParent bool, err error) + Done() <-chan struct{} +} + +// A cancelCtx can be canceled. When canceled, it also cancels any children +// that implement canceler. +type cancelCtx struct { + Context + + done chan struct{} // closed by the first cancel call. + + mu sync.Mutex + children map[canceler]bool // set to nil by the first cancel call + err error // set to non-nil by the first cancel call +} + +func (c *cancelCtx) Done() <-chan struct{} { + return c.done +} + +func (c *cancelCtx) Err() error { + c.mu.Lock() + defer c.mu.Unlock() + return c.err +} + +func (c *cancelCtx) String() string { + return fmt.Sprintf("%v.WithCancel", c.Context) +} + +// cancel closes c.done, cancels each of c's children, and, if +// removeFromParent is true, removes c from its parent's children. +func (c *cancelCtx) cancel(removeFromParent bool, err error) { + if err == nil { + panic("context: internal error: missing cancel error") + } + c.mu.Lock() + if c.err != nil { + c.mu.Unlock() + return // already canceled + } + c.err = err + close(c.done) + for child := range c.children { + // NOTE: acquiring the child's lock while holding parent's lock. + child.cancel(false, err) + } + c.children = nil + c.mu.Unlock() + + if removeFromParent { + removeChild(c.Context, c) + } +} + +// WithDeadline returns a copy of the parent context with the deadline adjusted +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// context's Done channel is closed when the deadline expires, when the returned +// cancel function is called, or when the parent context's Done channel is +// closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { + if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { + // The current deadline is already sooner than the new one. + return WithCancel(parent) + } + c := &timerCtx{ + cancelCtx: newCancelCtx(parent), + deadline: deadline, + } + propagateCancel(parent, c) + d := deadline.Sub(time.Now()) + if d <= 0 { + c.cancel(true, DeadlineExceeded) // deadline has already passed + return c, func() { c.cancel(true, Canceled) } + } + c.mu.Lock() + defer c.mu.Unlock() + if c.err == nil { + c.timer = time.AfterFunc(d, func() { + c.cancel(true, DeadlineExceeded) + }) + } + return c, func() { c.cancel(true, Canceled) } +} + +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +// implement Done and Err. It implements cancel by stopping its timer then +// delegating to cancelCtx.cancel. +type timerCtx struct { + *cancelCtx + timer *time.Timer // Under cancelCtx.mu. + + deadline time.Time +} + +func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { + return c.deadline, true +} + +func (c *timerCtx) String() string { + return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) +} + +func (c *timerCtx) cancel(removeFromParent bool, err error) { + c.cancelCtx.cancel(false, err) + if removeFromParent { + // Remove this timerCtx from its parent cancelCtx's children. + removeChild(c.cancelCtx.Context, c) + } + c.mu.Lock() + if c.timer != nil { + c.timer.Stop() + c.timer = nil + } + c.mu.Unlock() +} + +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: +// +// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +// defer cancel() // releases resources if slowOperation completes before timeout elapses +// return slowOperation(ctx) +// } +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { + return WithDeadline(parent, time.Now().Add(timeout)) +} + +// WithValue returns a copy of parent in which the value associated with key is +// val. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +func WithValue(parent Context, key interface{}, val interface{}) Context { + return &valueCtx{parent, key, val} +} + +// A valueCtx carries a key-value pair. It implements Value for that key and +// delegates all other calls to the embedded Context. +type valueCtx struct { + Context + key, val interface{} +} + +func (c *valueCtx) String() string { + return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) +} + +func (c *valueCtx) Value(key interface{}) interface{} { + if c.key == key { + return c.val + } + return c.Context.Value(key) +} diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go index 60bbc8418..8cffdd16c 100644 --- a/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/hybi.go @@ -81,9 +81,6 @@ type hybiFrameReader struct { func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) { n, err = frame.reader.Read(msg) - if err != nil { - return 0, err - } if frame.header.MaskingKey != nil { for i := 0; i < n; i++ { msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4] diff --git a/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go index da0dd964c..9f9b9a52d 100644 --- a/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go +++ b/Godeps/_workspace/src/golang.org/x/net/websocket/websocket.go @@ -144,6 +144,8 @@ type frameHandler interface { } // Conn represents a WebSocket connection. +// +// Multiple goroutines may invoke methods on a Conn simultaneously. type Conn struct { config *Config request *http.Request @@ -207,9 +209,6 @@ func (ws *Conn) Write(msg []byte) (n int, err error) { } n, err = w.Write(msg) w.Close() - if err != nil { - return n, err - } return n, err } diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/.gitignore b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/.gitignore new file mode 100644 index 000000000..00268614f --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/LICENSE.txt b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/LICENSE.txt new file mode 100644 index 000000000..a4a11046c --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/LICENSE.txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright (c) 2013 npipe authors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/README.md b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/README.md new file mode 100644 index 000000000..420a4d16c --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/README.md @@ -0,0 +1,308 @@ +npipe [![Build status](https://ci.appveyor.com/api/projects/status/00vuepirsot29qwi)](https://ci.appveyor.com/project/natefinch/npipe) [![GoDoc](https://godoc.org/gopkg.in/natefinch/npipe.v2?status.svg)](https://godoc.org/gopkg.in/natefinch/npipe.v2) +===== +Package npipe provides a pure Go wrapper around Windows named pipes. + +Windows named pipe documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365780 + +Note that the code lives at https://github.com/natefinch/npipe (v2 branch) +but should be imported as gopkg.in/natefinch/npipe.v2 (the package name is +still npipe). + +npipe provides an interface based on stdlib's net package, with Dial, Listen, +and Accept functions, as well as associated implementations of net.Conn and +net.Listener. It supports rpc over the connection. + +### Notes +* Deadlines for reading/writing to the connection are only functional in Windows Vista/Server 2008 and above, due to limitations with the Windows API. + +* The pipes support byte mode only (no support for message mode) + +### Examples +The Dial function connects a client to a named pipe: + + + conn, err := npipe.Dial(`\\.\pipe\mypipename`) + if err != nil { + <handle error> + } + fmt.Fprintf(conn, "Hi server!\n") + msg, err := bufio.NewReader(conn).ReadString('\n') + ... + +The Listen function creates servers: + + + ln, err := npipe.Listen(`\\.\pipe\mypipename`) + if err != nil { + // handle error + } + for { + conn, err := ln.Accept() + if err != nil { + // handle error + continue + } + go handleConnection(conn) + } + + + + + +## Variables +``` go +var ErrClosed = PipeError{"Pipe has been closed.", false} +``` +ErrClosed is the error returned by PipeListener.Accept when Close is called +on the PipeListener. + + + +## type PipeAddr +``` go +type PipeAddr string +``` +PipeAddr represents the address of a named pipe. + + + + + + + + + + + +### func (PipeAddr) Network +``` go +func (a PipeAddr) Network() string +``` +Network returns the address's network name, "pipe". + + + +### func (PipeAddr) String +``` go +func (a PipeAddr) String() string +``` +String returns the address of the pipe + + + +## type PipeConn +``` go +type PipeConn struct { + // contains filtered or unexported fields +} +``` +PipeConn is the implementation of the net.Conn interface for named pipe connections. + + + + + + + + + +### func Dial +``` go +func Dial(address string) (*PipeConn, error) +``` +Dial connects to a named pipe with the given address. If the specified pipe is not available, +it will wait indefinitely for the pipe to become available. + +The address must be of the form \\.\\pipe\<name> for local pipes and \\<computer>\pipe\<name> +for remote pipes. + +Dial will return a PipeError if you pass in a badly formatted pipe name. + +Examples: + + + // local pipe + conn, err := Dial(`\\.\pipe\mypipename`) + + // remote pipe + conn, err := Dial(`\\othercomp\pipe\mypipename`) + + +### func DialTimeout +``` go +func DialTimeout(address string, timeout time.Duration) (*PipeConn, error) +``` +DialTimeout acts like Dial, but will time out after the duration of timeout + + + + +### func (\*PipeConn) Close +``` go +func (c *PipeConn) Close() error +``` +Close closes the connection. + + + +### func (\*PipeConn) LocalAddr +``` go +func (c *PipeConn) LocalAddr() net.Addr +``` +LocalAddr returns the local network address. + + + +### func (\*PipeConn) Read +``` go +func (c *PipeConn) Read(b []byte) (int, error) +``` +Read implements the net.Conn Read method. + + + +### func (\*PipeConn) RemoteAddr +``` go +func (c *PipeConn) RemoteAddr() net.Addr +``` +RemoteAddr returns the remote network address. + + + +### func (\*PipeConn) SetDeadline +``` go +func (c *PipeConn) SetDeadline(t time.Time) error +``` +SetDeadline implements the net.Conn SetDeadline method. +Note that timeouts are only supported on Windows Vista/Server 2008 and above + + + +### func (\*PipeConn) SetReadDeadline +``` go +func (c *PipeConn) SetReadDeadline(t time.Time) error +``` +SetReadDeadline implements the net.Conn SetReadDeadline method. +Note that timeouts are only supported on Windows Vista/Server 2008 and above + + + +### func (\*PipeConn) SetWriteDeadline +``` go +func (c *PipeConn) SetWriteDeadline(t time.Time) error +``` +SetWriteDeadline implements the net.Conn SetWriteDeadline method. +Note that timeouts are only supported on Windows Vista/Server 2008 and above + + + +### func (\*PipeConn) Write +``` go +func (c *PipeConn) Write(b []byte) (int, error) +``` +Write implements the net.Conn Write method. + + + +## type PipeError +``` go +type PipeError struct { + // contains filtered or unexported fields +} +``` +PipeError is an error related to a call to a pipe + + + + + + + + + + + +### func (PipeError) Error +``` go +func (e PipeError) Error() string +``` +Error implements the error interface + + + +### func (PipeError) Temporary +``` go +func (e PipeError) Temporary() bool +``` +Temporary implements net.AddrError.Temporary() + + + +### func (PipeError) Timeout +``` go +func (e PipeError) Timeout() bool +``` +Timeout implements net.AddrError.Timeout() + + + +## type PipeListener +``` go +type PipeListener struct { + // contains filtered or unexported fields +} +``` +PipeListener is a named pipe listener. Clients should typically +use variables of type net.Listener instead of assuming named pipe. + + + + + + + + + +### func Listen +``` go +func Listen(address string) (*PipeListener, error) +``` +Listen returns a new PipeListener that will listen on a pipe with the given +address. The address must be of the form \\.\pipe\<name> + +Listen will return a PipeError for an incorrectly formatted pipe name. + + + + +### func (\*PipeListener) Accept +``` go +func (l *PipeListener) Accept() (net.Conn, error) +``` +Accept implements the Accept method in the net.Listener interface; it +waits for the next call and returns a generic net.Conn. + + + +### func (\*PipeListener) AcceptPipe +``` go +func (l *PipeListener) AcceptPipe() (*PipeConn, error) +``` +AcceptPipe accepts the next incoming call and returns the new connection. + + + +### func (\*PipeListener) Addr +``` go +func (l *PipeListener) Addr() net.Addr +``` +Addr returns the listener's network address, a PipeAddr. + + + +### func (\*PipeListener) Close +``` go +func (l *PipeListener) Close() error +``` +Close stops listening on the address. +Already Accepted connections are not closed. diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/doc.go b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/doc.go new file mode 100644 index 000000000..3445773b4 --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/doc.go @@ -0,0 +1,50 @@ +// Copyright 2013 Nate Finch. All rights reserved. +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file. + +// Package npipe provides a pure Go wrapper around Windows named pipes. +// +// !! Note, this package is Windows-only. There is no code to compile on linux. +// +// Windows named pipe documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365780 +// +// Note that the code lives at https://github.com/natefinch/npipe (v2 branch) +// but should be imported as gopkg.in/natefinch/npipe.v2 (the package name is +// still npipe). +// +// npipe provides an interface based on stdlib's net package, with Dial, Listen, +// and Accept functions, as well as associated implementations of net.Conn and +// net.Listener. It supports rpc over the connection. +// +// Notes +// +// * Deadlines for reading/writing to the connection are only functional in Windows Vista/Server 2008 and above, due to limitations with the Windows API. +// +// * The pipes support byte mode only (no support for message mode) +// +// Examples +// +// The Dial function connects a client to a named pipe: +// conn, err := npipe.Dial(`\\.\pipe\mypipename`) +// if err != nil { +// <handle error> +// } +// fmt.Fprintf(conn, "Hi server!\n") +// msg, err := bufio.NewReader(conn).ReadString('\n') +// ... +// +// The Listen function creates servers: +// +// ln, err := npipe.Listen(`\\.\pipe\mypipename`) +// if err != nil { +// // handle error +// } +// for { +// conn, err := ln.Accept() +// if err != nil { +// // handle error +// continue +// } +// go handleConnection(conn) +// } +package npipe diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/npipe_windows.go b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/npipe_windows.go new file mode 100755 index 000000000..5e7cf13ee --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/npipe_windows.go @@ -0,0 +1,531 @@ +package npipe + +//sys createNamedPipe(name *uint16, openMode uint32, pipeMode uint32, maxInstances uint32, outBufSize uint32, inBufSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW +//sys connectNamedPipe(handle syscall.Handle, overlapped *syscall.Overlapped) (err error) = ConnectNamedPipe +//sys disconnectNamedPipe(handle syscall.Handle) (err error) = DisconnectNamedPipe +//sys waitNamedPipe(name *uint16, timeout uint32) (err error) = WaitNamedPipeW +//sys createEvent(sa *syscall.SecurityAttributes, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateEventW +//sys getOverlappedResult(handle syscall.Handle, overlapped *syscall.Overlapped, transferred *uint32, wait bool) (err error) = GetOverlappedResult +//sys cancelIoEx(handle syscall.Handle, overlapped *syscall.Overlapped) (err error) = CancelIoEx + +import ( + "fmt" + "io" + "net" + "sync" + "syscall" + "time" +) + +const ( + // openMode + pipe_access_duplex = 0x3 + pipe_access_inbound = 0x1 + pipe_access_outbound = 0x2 + + // openMode write flags + file_flag_first_pipe_instance = 0x00080000 + file_flag_write_through = 0x80000000 + file_flag_overlapped = 0x40000000 + + // openMode ACL flags + write_dac = 0x00040000 + write_owner = 0x00080000 + access_system_security = 0x01000000 + + // pipeMode + pipe_type_byte = 0x0 + pipe_type_message = 0x4 + + // pipeMode read mode flags + pipe_readmode_byte = 0x0 + pipe_readmode_message = 0x2 + + // pipeMode wait mode flags + pipe_wait = 0x0 + pipe_nowait = 0x1 + + // pipeMode remote-client mode flags + pipe_accept_remote_clients = 0x0 + pipe_reject_remote_clients = 0x8 + + pipe_unlimited_instances = 255 + + nmpwait_wait_forever = 0xFFFFFFFF + + // the two not-an-errors below occur if a client connects to the pipe between + // the server's CreateNamedPipe and ConnectNamedPipe calls. + error_no_data syscall.Errno = 0xE8 + error_pipe_connected syscall.Errno = 0x217 + error_pipe_busy syscall.Errno = 0xE7 + error_sem_timeout syscall.Errno = 0x79 + + error_bad_pathname syscall.Errno = 0xA1 + error_invalid_name syscall.Errno = 0x7B + + error_io_incomplete syscall.Errno = 0x3e4 +) + +var _ net.Conn = (*PipeConn)(nil) +var _ net.Listener = (*PipeListener)(nil) + +// ErrClosed is the error returned by PipeListener.Accept when Close is called +// on the PipeListener. +var ErrClosed = PipeError{"Pipe has been closed.", false} + +// PipeError is an error related to a call to a pipe +type PipeError struct { + msg string + timeout bool +} + +// Error implements the error interface +func (e PipeError) Error() string { + return e.msg +} + +// Timeout implements net.AddrError.Timeout() +func (e PipeError) Timeout() bool { + return e.timeout +} + +// Temporary implements net.AddrError.Temporary() +func (e PipeError) Temporary() bool { + return false +} + +// Dial connects to a named pipe with the given address. If the specified pipe is not available, +// it will wait indefinitely for the pipe to become available. +// +// The address must be of the form \\.\\pipe\<name> for local pipes and \\<computer>\pipe\<name> +// for remote pipes. +// +// Dial will return a PipeError if you pass in a badly formatted pipe name. +// +// Examples: +// // local pipe +// conn, err := Dial(`\\.\pipe\mypipename`) +// +// // remote pipe +// conn, err := Dial(`\\othercomp\pipe\mypipename`) +func Dial(address string) (*PipeConn, error) { + for { + conn, err := dial(address, nmpwait_wait_forever) + if err == nil { + return conn, nil + } + if isPipeNotReady(err) { + <-time.After(100 * time.Millisecond) + continue + } + return nil, err + } +} + +// DialTimeout acts like Dial, but will time out after the duration of timeout +func DialTimeout(address string, timeout time.Duration) (*PipeConn, error) { + deadline := time.Now().Add(timeout) + + now := time.Now() + for now.Before(deadline) { + millis := uint32(deadline.Sub(now) / time.Millisecond) + conn, err := dial(address, millis) + if err == nil { + return conn, nil + } + if err == error_sem_timeout { + // This is WaitNamedPipe's timeout error, so we know we're done + return nil, PipeError{fmt.Sprintf( + "Timed out waiting for pipe '%s' to come available", address), true} + } + if isPipeNotReady(err) { + left := deadline.Sub(time.Now()) + retry := 100 * time.Millisecond + if left > retry { + <-time.After(retry) + } else { + <-time.After(left - time.Millisecond) + } + now = time.Now() + continue + } + return nil, err + } + return nil, PipeError{fmt.Sprintf( + "Timed out waiting for pipe '%s' to come available", address), true} +} + +// isPipeNotReady checks the error to see if it indicates the pipe is not ready +func isPipeNotReady(err error) bool { + // Pipe Busy means another client just grabbed the open pipe end, + // and the server hasn't made a new one yet. + // File Not Found means the server hasn't created the pipe yet. + // Neither is a fatal error. + + return err == syscall.ERROR_FILE_NOT_FOUND || err == error_pipe_busy +} + +// newOverlapped creates a structure used to track asynchronous +// I/O requests that have been issued. +func newOverlapped() (*syscall.Overlapped, error) { + event, err := createEvent(nil, true, true, nil) + if err != nil { + return nil, err + } + return &syscall.Overlapped{HEvent: event}, nil +} + +// waitForCompletion waits for an asynchronous I/O request referred to by overlapped to complete. +// This function returns the number of bytes transferred by the operation and an error code if +// applicable (nil otherwise). +func waitForCompletion(handle syscall.Handle, overlapped *syscall.Overlapped) (uint32, error) { + _, err := syscall.WaitForSingleObject(overlapped.HEvent, syscall.INFINITE) + if err != nil { + return 0, err + } + var transferred uint32 + err = getOverlappedResult(handle, overlapped, &transferred, true) + return transferred, err +} + +// dial is a helper to initiate a connection to a named pipe that has been started by a server. +// The timeout is only enforced if the pipe server has already created the pipe, otherwise +// this function will return immediately. +func dial(address string, timeout uint32) (*PipeConn, error) { + name, err := syscall.UTF16PtrFromString(string(address)) + if err != nil { + return nil, err + } + // If at least one instance of the pipe has been created, this function + // will wait timeout milliseconds for it to become available. + // It will return immediately regardless of timeout, if no instances + // of the named pipe have been created yet. + // If this returns with no error, there is a pipe available. + if err := waitNamedPipe(name, timeout); err != nil { + if err == error_bad_pathname { + // badly formatted pipe name + return nil, badAddr(address) + } + return nil, err + } + pathp, err := syscall.UTF16PtrFromString(address) + if err != nil { + return nil, err + } + handle, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, + uint32(syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE), nil, syscall.OPEN_EXISTING, + syscall.FILE_FLAG_OVERLAPPED, 0) + if err != nil { + return nil, err + } + return &PipeConn{handle: handle, addr: PipeAddr(address)}, nil +} + +// Listen returns a new PipeListener that will listen on a pipe with the given +// address. The address must be of the form \\.\pipe\<name> +// +// Listen will return a PipeError for an incorrectly formatted pipe name. +func Listen(address string) (*PipeListener, error) { + handle, err := createPipe(address, true) + if err == error_invalid_name { + return nil, badAddr(address) + } + if err != nil { + return nil, err + } + + return &PipeListener{ + addr: PipeAddr(address), + handle: handle, + }, nil +} + +// PipeListener is a named pipe listener. Clients should typically +// use variables of type net.Listener instead of assuming named pipe. +type PipeListener struct { + mu sync.Mutex + + addr PipeAddr + handle syscall.Handle + closed bool + + // acceptHandle contains the current handle waiting for + // an incoming connection or nil. + acceptHandle syscall.Handle + // acceptOverlapped is set before waiting on a connection. + // If not waiting, it is nil. + acceptOverlapped *syscall.Overlapped +} + +// Accept implements the Accept method in the net.Listener interface; it +// waits for the next call and returns a generic net.Conn. +func (l *PipeListener) Accept() (net.Conn, error) { + c, err := l.AcceptPipe() + for err == error_no_data { + // Ignore clients that connect and immediately disconnect. + c, err = l.AcceptPipe() + } + if err != nil { + return nil, err + } + return c, nil +} + +// AcceptPipe accepts the next incoming call and returns the new connection. +// It might return an error if a client connected and immediately cancelled +// the connection. +func (l *PipeListener) AcceptPipe() (*PipeConn, error) { + if l == nil { + return nil, syscall.EINVAL + } + + l.mu.Lock() + defer l.mu.Unlock() + + if l.addr == "" || l.closed { + return nil, syscall.EINVAL + } + + // the first time we call accept, the handle will have been created by the Listen + // call. This is to prevent race conditions where the client thinks the server + // isn't listening because it hasn't actually called create yet. After the first time, we'll + // have to create a new handle each time + handle := l.handle + if handle == 0 { + var err error + handle, err = createPipe(string(l.addr), false) + if err != nil { + return nil, err + } + } else { + l.handle = 0 + } + + overlapped, err := newOverlapped() + if err != nil { + return nil, err + } + defer syscall.CloseHandle(overlapped.HEvent) + err = connectNamedPipe(handle, overlapped) + if err == nil || err == error_pipe_connected { + return &PipeConn{handle: handle, addr: l.addr}, nil + } + + if err == error_io_incomplete || err == syscall.ERROR_IO_PENDING { + l.acceptOverlapped = overlapped + l.acceptHandle = handle + // unlock here so close can function correctly while we wait (we'll + // get relocked via the defer below, before the original defer + // unlock happens.) + l.mu.Unlock() + defer func() { + l.mu.Lock() + l.acceptOverlapped = nil + l.acceptHandle = 0 + // unlock is via defer above. + }() + _, err = waitForCompletion(handle, overlapped) + } + if err == syscall.ERROR_OPERATION_ABORTED { + // Return error compatible to net.Listener.Accept() in case the + // listener was closed. + return nil, ErrClosed + } + if err != nil { + return nil, err + } + return &PipeConn{handle: handle, addr: l.addr}, nil +} + +// Close stops listening on the address. +// Already Accepted connections are not closed. +func (l *PipeListener) Close() error { + l.mu.Lock() + defer l.mu.Unlock() + + if l.closed { + return nil + } + l.closed = true + if l.handle != 0 { + err := disconnectNamedPipe(l.handle) + if err != nil { + return err + } + err = syscall.CloseHandle(l.handle) + if err != nil { + return err + } + l.handle = 0 + } + if l.acceptOverlapped != nil && l.acceptHandle != 0 { + // Cancel the pending IO. This call does not block, so it is safe + // to hold onto the mutex above. + if err := cancelIoEx(l.acceptHandle, l.acceptOverlapped); err != nil { + return err + } + err := syscall.CloseHandle(l.acceptOverlapped.HEvent) + if err != nil { + return err + } + l.acceptOverlapped.HEvent = 0 + err = syscall.CloseHandle(l.acceptHandle) + if err != nil { + return err + } + l.acceptHandle = 0 + } + return nil +} + +// Addr returns the listener's network address, a PipeAddr. +func (l *PipeListener) Addr() net.Addr { return l.addr } + +// PipeConn is the implementation of the net.Conn interface for named pipe connections. +type PipeConn struct { + handle syscall.Handle + addr PipeAddr + + // these aren't actually used yet + readDeadline *time.Time + writeDeadline *time.Time +} + +type iodata struct { + n uint32 + err error +} + +// completeRequest looks at iodata to see if a request is pending. If so, it waits for it to either complete or to +// abort due to hitting the specified deadline. Deadline may be set to nil to wait forever. If no request is pending, +// the content of iodata is returned. +func (c *PipeConn) completeRequest(data iodata, deadline *time.Time, overlapped *syscall.Overlapped) (int, error) { + if data.err == error_io_incomplete || data.err == syscall.ERROR_IO_PENDING { + var timer <-chan time.Time + if deadline != nil { + if timeDiff := deadline.Sub(time.Now()); timeDiff > 0 { + timer = time.After(timeDiff) + } + } + done := make(chan iodata) + go func() { + n, err := waitForCompletion(c.handle, overlapped) + done <- iodata{n, err} + }() + select { + case data = <-done: + case <-timer: + syscall.CancelIoEx(c.handle, overlapped) + data = iodata{0, timeout(c.addr.String())} + } + } + // Windows will produce ERROR_BROKEN_PIPE upon closing + // a handle on the other end of a connection. Go RPC + // expects an io.EOF error in this case. + if data.err == syscall.ERROR_BROKEN_PIPE { + data.err = io.EOF + } + return int(data.n), data.err +} + +// Read implements the net.Conn Read method. +func (c *PipeConn) Read(b []byte) (int, error) { + // Use ReadFile() rather than Read() because the latter + // contains a workaround that eats ERROR_BROKEN_PIPE. + overlapped, err := newOverlapped() + if err != nil { + return 0, err + } + defer syscall.CloseHandle(overlapped.HEvent) + var n uint32 + err = syscall.ReadFile(c.handle, b, &n, overlapped) + return c.completeRequest(iodata{n, err}, c.readDeadline, overlapped) +} + +// Write implements the net.Conn Write method. +func (c *PipeConn) Write(b []byte) (int, error) { + overlapped, err := newOverlapped() + if err != nil { + return 0, err + } + defer syscall.CloseHandle(overlapped.HEvent) + var n uint32 + err = syscall.WriteFile(c.handle, b, &n, overlapped) + return c.completeRequest(iodata{n, err}, c.writeDeadline, overlapped) +} + +// Close closes the connection. +func (c *PipeConn) Close() error { + return syscall.CloseHandle(c.handle) +} + +// LocalAddr returns the local network address. +func (c *PipeConn) LocalAddr() net.Addr { + return c.addr +} + +// RemoteAddr returns the remote network address. +func (c *PipeConn) RemoteAddr() net.Addr { + // not sure what to do here, we don't have remote addr.... + return c.addr +} + +// SetDeadline implements the net.Conn SetDeadline method. +// Note that timeouts are only supported on Windows Vista/Server 2008 and above +func (c *PipeConn) SetDeadline(t time.Time) error { + c.SetReadDeadline(t) + c.SetWriteDeadline(t) + return nil +} + +// SetReadDeadline implements the net.Conn SetReadDeadline method. +// Note that timeouts are only supported on Windows Vista/Server 2008 and above +func (c *PipeConn) SetReadDeadline(t time.Time) error { + c.readDeadline = &t + return nil +} + +// SetWriteDeadline implements the net.Conn SetWriteDeadline method. +// Note that timeouts are only supported on Windows Vista/Server 2008 and above +func (c *PipeConn) SetWriteDeadline(t time.Time) error { + c.writeDeadline = &t + return nil +} + +// PipeAddr represents the address of a named pipe. +type PipeAddr string + +// Network returns the address's network name, "pipe". +func (a PipeAddr) Network() string { return "pipe" } + +// String returns the address of the pipe +func (a PipeAddr) String() string { + return string(a) +} + +// createPipe is a helper function to make sure we always create pipes +// with the same arguments, since subsequent calls to create pipe need +// to use the same arguments as the first one. If first is set, fail +// if the pipe already exists. +func createPipe(address string, first bool) (syscall.Handle, error) { + n, err := syscall.UTF16PtrFromString(address) + if err != nil { + return 0, err + } + mode := uint32(pipe_access_duplex | syscall.FILE_FLAG_OVERLAPPED) + if first { + mode |= file_flag_first_pipe_instance + } + return createNamedPipe(n, + mode, + pipe_type_byte, + pipe_unlimited_instances, + 512, 512, 0, nil) +} + +func badAddr(addr string) PipeError { + return PipeError{fmt.Sprintf("Invalid pipe address '%s'.", addr), false} +} +func timeout(addr string) PipeError { + return PipeError{fmt.Sprintf("Pipe IO timed out waiting for '%s'", addr), true} +} diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/znpipe_windows_386.go b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/znpipe_windows_386.go new file mode 100644 index 000000000..c283e6cf9 --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/znpipe_windows_386.go @@ -0,0 +1,124 @@ +// +build windows +// go build mksyscall_windows.go && ./mksyscall_windows npipe_windows.go +// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package npipe + +import "unsafe" +import "syscall" + +var ( + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + + procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") + procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") + procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe") + procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") +) + +func createNamedPipe(name *uint16, openMode uint32, pipeMode uint32, maxInstances uint32, outBufSize uint32, inBufSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(openMode), uintptr(pipeMode), uintptr(maxInstances), uintptr(outBufSize), uintptr(inBufSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func cancelIoEx(handle syscall.Handle, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func connectNamedPipe(handle syscall.Handle, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func disconnectNamedPipe(handle syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func waitNamedPipe(name *uint16, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func createEvent(sa *syscall.SecurityAttributes, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) { + var _p0 uint32 + if manualReset { + _p0 = 1 + } else { + _p0 = 0 + } + var _p1 uint32 + if initialState { + _p1 = 1 + } else { + _p1 = 0 + } + r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(sa)), uintptr(_p0), uintptr(_p1), uintptr(unsafe.Pointer(name)), 0, 0) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getOverlappedResult(handle syscall.Handle, overlapped *syscall.Overlapped, transferred *uint32, wait bool) (err error) { + var _p0 uint32 + if wait { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transferred)), uintptr(_p0), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} diff --git a/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/znpipe_windows_amd64.go b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/znpipe_windows_amd64.go new file mode 100644 index 000000000..c283e6cf9 --- /dev/null +++ b/Godeps/_workspace/src/gopkg.in/natefinch/npipe.v2/znpipe_windows_amd64.go @@ -0,0 +1,124 @@ +// +build windows +// go build mksyscall_windows.go && ./mksyscall_windows npipe_windows.go +// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package npipe + +import "unsafe" +import "syscall" + +var ( + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + + procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") + procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") + procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe") + procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") +) + +func createNamedPipe(name *uint16, openMode uint32, pipeMode uint32, maxInstances uint32, outBufSize uint32, inBufSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(openMode), uintptr(pipeMode), uintptr(maxInstances), uintptr(outBufSize), uintptr(inBufSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func cancelIoEx(handle syscall.Handle, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func connectNamedPipe(handle syscall.Handle, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func disconnectNamedPipe(handle syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func waitNamedPipe(name *uint16, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func createEvent(sa *syscall.SecurityAttributes, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) { + var _p0 uint32 + if manualReset { + _p0 = 1 + } else { + _p0 = 0 + } + var _p1 uint32 + if initialState { + _p1 = 1 + } else { + _p1 = 0 + } + r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(sa)), uintptr(_p0), uintptr(_p1), uintptr(unsafe.Pointer(name)), 0, 0) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getOverlappedResult(handle syscall.Handle, overlapped *syscall.Overlapped, transferred *uint32, wait bool) (err error) { + var _p0 uint32 + if wait { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transferred)), uintptr(_p0), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} @@ -2,7 +2,7 @@ # with Go source code. If you know what GOPATH is then you probably # don't need to bother with make. -.PHONY: geth geth-cross evm all test travis-test-with-coverage xgo clean +.PHONY: geth geth-cross evm all test xgo clean .PHONY: geth-linux geth-linux-386 geth-linux-amd64 .PHONY: geth-linux-arm geth-linux-arm-5 geth-linux-arm-6 geth-linux-arm-7 geth-linux-arm64 .PHONY: geth-darwin geth-darwin-386 geth-darwin-amd64 @@ -13,10 +13,29 @@ GOBIN = build/bin GO ?= latest geth: - build/env.sh go build -i -v $(shell build/flags.sh) -o $(GOBIN)/geth ./cmd/geth + build/env.sh go run build/ci.go install ./cmd/geth @echo "Done building." @echo "Run \"$(GOBIN)/geth\" to launch geth." +evm: + build/env.sh go run build/ci.go install ./cmd/evm + @echo "Done building." + @echo "Run \"$(GOBIN)/evm to start the evm." + +all: + build/env.sh go run build/ci.go install + +test: all + build/env.sh go run build/ci.go test + +clean: + rm -fr build/_workspace/pkg/ Godeps/_workspace/pkg $(GOBIN)/* + +# Cross Compilation Targets (xgo) + +xgo: + build/env.sh go get github.com/karalabe/xgo + geth-cross: geth-linux geth-darwin geth-windows geth-android geth-ios @echo "Full cross compilation done:" @ls -ld $(GOBIN)/geth-* @@ -96,26 +115,3 @@ geth-ios: xgo build/env.sh $(GOBIN)/xgo --go=$(GO) --dest=$(GOBIN) --targets=ios-7.0/framework -v $(shell build/flags.sh) ./cmd/geth @echo "iOS framework cross compilation done:" @ls -ld $(GOBIN)/geth-ios-* - -evm: - build/env.sh $(GOROOT)/bin/go install -v $(shell build/flags.sh) ./cmd/evm - @echo "Done building." - @echo "Run \"$(GOBIN)/evm to start the evm." - -all: - for cmd in `ls ./cmd/`; do \ - build/env.sh go build -i -v $(shell build/flags.sh) -o $(GOBIN)/$$cmd ./cmd/$$cmd; \ - done - -test: all - build/env.sh go test ./... - -travis-test-with-coverage: all - build/env.sh go vet ./... - build/env.sh build/test-global-coverage.sh - -xgo: - build/env.sh go get github.com/karalabe/xgo - -clean: - rm -fr build/_workspace/pkg/ Godeps/_workspace/pkg $(GOBIN)/* @@ -14,7 +14,7 @@ https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/6874 ## Automated development builds -The following builds are build automatically by our build servers after each push to the [develop](https://github.com/ethereum/go-ethereum/tree/develop) branch. +The following builds are built automatically by our build servers after each push to the [develop](https://github.com/ethereum/go-ethereum/tree/develop) branch. * [Docker](https://registry.hub.docker.com/u/ethereum/client-go/) * [OS X](http://build.ethdev.com/builds/OSX%20Go%20develop%20branch/Mist-OSX-latest.dmg) @@ -46,7 +46,7 @@ The go-ethereum project comes with several wrappers/executables found in the `cm | Command | Description | |:----------:|-------------| -| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default) archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as an gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. Please see our [Command Line Options](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) wiki page for details. | +| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default) archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. Please see our [Command Line Options](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) wiki page for details. | | `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. | | `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. | | `disasm` | Bytecode disassembler to convert EVM (Ethereum Virtual Machine) bytecode into more user friendly assembly-like opcodes (e.g. `echo "6001" | disasm`). For details on the individual opcodes, please see pages 22-30 of the [Ethereum Yellow Paper](http://gavwood.com/paper.pdf). | @@ -54,6 +54,197 @@ The go-ethereum project comes with several wrappers/executables found in the `cm | `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. | | `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). | +## Running geth + +Going through all the possible command line flags is out of scope here (please consult our +[CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)), but we've +enumerated a few common parameter combos to get you up to speed quickly on how you can run your +own Geth instance. + +### Full node on the main Ethereum network + +By far the most common scenario is people wanting to simply interact with the Ethereum network: +create accounts; transfer funds; deploy and interact with contracts. For this particular use-case +the user doesn't care about years-old historical data, so we can fast-sync quickly to the current +state of the network. To do so: + +``` +$ geth --fast --cache=512 console +``` + +This command will: + + * Start geth in fast sync mode (`--fast`), causing it to download more data in exchange for avoiding + processing the entire history of the Ethereum network, which is very CPU intensive. + * Bump the memory allowance of the database to 512MB (`--cache=512`), which can help significantly in + sync times especially for HDD users. This flag is optional and you can set it as high or as low as + you'd like, though we'd recommend the 512MB - 2GB range. + * Start up Geth's built-in interactive [JavaScript console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console), + (via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/ethereum/wiki/wiki/JavaScript-API) + as well as Geth's own [management APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs). + This too is optional and if you leave it out you can always attach to an already running Geth instance + with `geth --attach`. + +### Full node on the Ethereum test network + +Transitioning towards developers, if you'd like to play around with creating Ethereum contracts, you +almost certainly would like to do that without any real money involved until you get the hang of the +entire system. In other words, instead of attaching to the main network, you want to join the **test** +network with your node, which is fully equivalent to the main network, but with play-Ether only. + +``` +$ geth --testnet --fast --cache=512 console +``` + +The `--fast`, `--cache` flags and `console` subcommand have the exact same meaning as above and they +are equially useful on the testnet too. Please see above for their explanations if you've skipped to +here. + +Specifying the `--testnet` flag however will reconfigure your Geth instance a bit: + + * Instead of using the default data directory (`~/.ethereum` on Linux for example), Geth will nest + itself one level deeper into a `testnet` subfolder (`~/.ethereum/testnet` on Linux). + * Instead of connecting the main Ethereum network, the client will connect to the test network, + which uses different P2P bootnodes, different network IDs and genesis states. + +*Note: Although there are some internal protective measures to prevent transactions from crossing +over between the main network and test network (different starting nonces), you should make sure to +always use separate accounts for play-money and real-money. Unless you manually move accounts, Geth +will by default correctly separate the two networks and will not make any accounts available between +them.* + +### Programatically interfacing Geth nodes + +As a developer, sooner rather than later you'll want to start interacting with Geth and the Ethereum +network via your own programs and not manually through the console. To aid this, Geth has built in +support for a JSON-RPC based APIs ([standard APIs](https://github.com/ethereum/wiki/wiki/JSON-RPC) and +[Geth specific APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs)). These can be +exposed via HTTP, WebSockets and IPC (unix sockets on unix based platroms, and named pipes on Windows). + +The IPC interface is enabled by default and exposes all the APIs supported by Geth, whereas the HTTP +and WS interfaces need to manually be enabled and only expose a subset of APIs due to security reasons. +These can be turned on/off and configured as you'd expect. + +HTTP based JSON-RPC API options: + + * `--rpc` Enable the HTTP-RPC server + * `--rpcaddr` HTTP-RPC server listening interface (default: "localhost") + * `--rpcport` HTTP-RPC server listening port (default: 8545) + * `--rpcapi` API's offered over the HTTP-RPC interface (default: "eth,net,web3") + * `--rpccorsdomain` Comma separated list of domains from which to accept cross origin requests (browser enforced) + * `--ws` Enable the WS-RPC server + * `--wsaddr` WS-RPC server listening interface (default: "localhost") + * `--wsport` WS-RPC server listening port (default: 8546) + * `--wsapi` API's offered over the WS-RPC interface (default: "eth,net,web3") + * `--wsorigins` Origins from which to accept websockets requests + * `--ipcdisable` Disable the IPC-RPC server + * `--ipcapi` API's offered over the IPC-RPC interface (default: "admin,debug,eth,miner,net,personal,shh,txpool,web3") + * `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it) + +You'll need to use your own programming environments' capabilities (libraries, tools, etc) to connect +via HTTP, WS or IPC to a Geth node configured with the above flags and you'll need to speak [JSON-RPC](http://www.jsonrpc.org/specification) +on all transports. You can reuse the same connection for multiple requests! + +**Note: Please understand the security implications of opening up an HTTP/WS based transport before +doing so! Hackers on the internet are actively trying to subvert Ethereum nodes with exposed APIs! +Further, all browser tabs can access locally running webservers, so malicious webpages could try to +subvert locally available APIs!** + +### Operating a private network + +Maintaining your own private network is more involved as a lot of configurations taken for granted in +the official networks need to be manually set up. + +#### Defining the private genesis state + +First, you'll need to create the genesis state of your networks, which all nodes need to be aware of +and agree upon. This consists of a small JSON file (e.g. call it `genesis.json`): + +```json +{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00" +} +``` + +The above fields should be fine for most purposes, although we'd recommend changing the `nonce` to +some random value so you prevent unknown remote nodes from being able to connect to you. If you'd +like to pre-fund some accounts for easier testing, you can populate the `alloc` field with account +configs: + +```json +"alloc": { + "0x0000000000000000000000000000000000000001": {"balance": "111111111"}, + "0x0000000000000000000000000000000000000002": {"balance": "222222222"} +} +``` + +With the genesis state defined in the above JSON file, you'll need to initialize **every** Geth node +with it prior to starting it up to ensure all blockchain parameters are correctly set: + +``` +$ geth init path/to/genesis.json +``` + +#### Creating the rendezvous point + +With all nodes that you want to run initialized to the desired genesis state, you'll need to start a +bootstrap node that others can use to find each other in your network and/or over the internet. The +clean way is to configure and run a dedicated bootnode: + +``` +$ bootnode --genkey=boot.key +$ bootnode --nodekey=boot.key +``` + +With the bootnode online, it will display an [`enode` URL](https://github.com/ethereum/wiki/wiki/enode-url-format) +that other nodes can use to connect to it and exchange peer information. Make sure to replace the +displayed IP address information (most probably `[::]`) with your externally accessible IP to get the +actual `enode` URL. + +*Note: You could also use a full fledged Geth node as a bootnode, but it's the less recommended way.* + +#### Starting up your member nodes + +With the bootnode operational and externally reachable (you can try `telnet <ip> <port>` to ensure +it's indeed reachable), start every subsequent Geth node pointed to the bootnode for peer discovery +via the `--bootnodes` flag. It will probably also be desirable to keep the data directory of your +private network separated, so do also specify a custom `--datadir` flag. + +``` +$ geth --datadir=path/to/custom/data/folder --bootnodes=<bootnode-enode-url-from-above> +``` + +*Note: Since your network will be completely cut off from the main and test networks, you'll also +need to configure a miner to process transactions and create new blocks for you.* + +#### Running a private miner + +Mining on the public Ethereum network is a complex task as it's only feasible using GPUs, requiring +an OpenCL or CUDA enabled `ethminer` instance. For information on such a setup, please consult the +[EtherMining subreddit](https://www.reddit.com/r/EtherMining/) and the [Genoil miner](https://github.com/Genoil/cpp-ethereum) +repository. + +In a private network setting however, a single CPU miner instance is more than enough for practical +purposes as it can produce a stable stream of blocks at the correct intervals without needing heavy +resources (consider running on a single thread, no need for multiple ones either). To start a Geth +instance for mining, run it with all your usual flags, extended by: + +``` +$ geth <usual-flags> --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000 +``` + +Which will start mining bocks and transactions on a single CPU thread, crediting all proceedings to +the account specified by `--etherbase`. You can further tune the mining by changing the default gas +limit blocks converge to (`--targetgaslimit`) and the price transactions are accepted at (`--gasprice`). + ## Contribution Thank you for considering to help out with the source code! We welcome contributions from diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index 65806aef4..bec742c29 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "golang.org/x/net/context" ) // ErrNoCode is returned by call and transact operations for which the requested @@ -35,12 +36,12 @@ type ContractCaller interface { // HasCode checks if the contract at the given address has any code associated // with it or not. This is needed to differentiate between contract internal // errors and the local chain being out of sync. - HasCode(contract common.Address, pending bool) (bool, error) + HasCode(ctx context.Context, contract common.Address, pending bool) (bool, error) // ContractCall executes an Ethereum contract call with the specified data as // the input. The pending flag requests execution against the pending block, not // the stable head of the chain. - ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) + ContractCall(ctx context.Context, contract common.Address, data []byte, pending bool) ([]byte, error) } // ContractTransactor defines the methods needed to allow operating with contract @@ -50,26 +51,26 @@ type ContractCaller interface { type ContractTransactor interface { // PendingAccountNonce retrieves the current pending nonce associated with an // account. - PendingAccountNonce(account common.Address) (uint64, error) + PendingAccountNonce(ctx context.Context, account common.Address) (uint64, error) // SuggestGasPrice retrieves the currently suggested gas price to allow a timely // execution of a transaction. - SuggestGasPrice() (*big.Int, error) + SuggestGasPrice(ctx context.Context) (*big.Int, error) // HasCode checks if the contract at the given address has any code associated // with it or not. This is needed to differentiate between contract internal // errors and the local chain being out of sync. - HasCode(contract common.Address, pending bool) (bool, error) + HasCode(ctx context.Context, contract common.Address, pending bool) (bool, error) // EstimateGasLimit tries to estimate the gas needed to execute a specific // transaction based on the current pending state of the backend blockchain. // There is no guarantee that this is the true gas limit requirement as other // transactions may be added or removed by miners, but it should provide a basis // for setting a reasonable default. - EstimateGasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) + EstimateGasLimit(ctx context.Context, sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) // SendTransaction injects the transaction into the pending pool for execution. - SendTransaction(tx *types.Transaction) error + SendTransaction(ctx context.Context, tx *types.Transaction) error } // ContractBackend defines the methods needed to allow operating with contract @@ -84,28 +85,28 @@ type ContractBackend interface { // HasCode checks if the contract at the given address has any code associated // with it or not. This is needed to differentiate between contract internal // errors and the local chain being out of sync. - HasCode(contract common.Address, pending bool) (bool, error) + HasCode(ctx context.Context, contract common.Address, pending bool) (bool, error) // ContractCall executes an Ethereum contract call with the specified data as // the input. The pending flag requests execution against the pending block, not // the stable head of the chain. - ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) + ContractCall(ctx context.Context, contract common.Address, data []byte, pending bool) ([]byte, error) // PendingAccountNonce retrieves the current pending nonce associated with an // account. - PendingAccountNonce(account common.Address) (uint64, error) + PendingAccountNonce(ctx context.Context, account common.Address) (uint64, error) // SuggestGasPrice retrieves the currently suggested gas price to allow a timely // execution of a transaction. - SuggestGasPrice() (*big.Int, error) + SuggestGasPrice(ctx context.Context) (*big.Int, error) // EstimateGasLimit tries to estimate the gas needed to execute a specific // transaction based on the current pending state of the backend blockchain. // There is no guarantee that this is the true gas limit requirement as other // transactions may be added or removed by miners, but it should provide a basis // for setting a reasonable default. - EstimateGasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) + EstimateGasLimit(ctx context.Context, sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) // SendTransaction injects the transaction into the pending pool for execution. - SendTransaction(tx *types.Transaction) error + SendTransaction(ctx context.Context, tx *types.Transaction) error } diff --git a/accounts/abi/bind/backends/nil.go b/accounts/abi/bind/backends/nil.go index f10bb61ac..54b222f1f 100644 --- a/accounts/abi/bind/backends/nil.go +++ b/accounts/abi/bind/backends/nil.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "golang.org/x/net/context" ) // This nil assignment ensures compile time that nilBackend implements bind.ContractBackend. @@ -32,16 +33,22 @@ var _ bind.ContractBackend = (*nilBackend)(nil) // wrappers without calling any methods on them. type nilBackend struct{} -func (*nilBackend) ContractCall(common.Address, []byte, bool) ([]byte, error) { +func (*nilBackend) ContractCall(context.Context, common.Address, []byte, bool) ([]byte, error) { panic("not implemented") } -func (*nilBackend) EstimateGasLimit(common.Address, *common.Address, *big.Int, []byte) (*big.Int, error) { +func (*nilBackend) EstimateGasLimit(context.Context, common.Address, *common.Address, *big.Int, []byte) (*big.Int, error) { + panic("not implemented") +} +func (*nilBackend) HasCode(context.Context, common.Address, bool) (bool, error) { + panic("not implemented") +} +func (*nilBackend) SuggestGasPrice(context.Context) (*big.Int, error) { panic("not implemented") } +func (*nilBackend) PendingAccountNonce(context.Context, common.Address) (uint64, error) { + panic("not implemented") +} +func (*nilBackend) SendTransaction(context.Context, *types.Transaction) error { panic("not implemented") } -func (*nilBackend) HasCode(common.Address, bool) (bool, error) { panic("not implemented") } -func (*nilBackend) SuggestGasPrice() (*big.Int, error) { panic("not implemented") } -func (*nilBackend) PendingAccountNonce(common.Address) (uint64, error) { panic("not implemented") } -func (*nilBackend) SendTransaction(*types.Transaction) error { panic("not implemented") } // NewNilBackend creates a new binding backend that can be used for instantiation // but will panic on any invocation. Its sole purpose is to help testing. diff --git a/accounts/abi/bind/backends/remote.go b/accounts/abi/bind/backends/remote.go index d903cbc8f..4793143e4 100644 --- a/accounts/abi/bind/backends/remote.go +++ b/accounts/abi/bind/backends/remote.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/context" ) // This nil assignment ensures compile time that rpcBackend implements bind.ContractBackend. @@ -80,18 +81,23 @@ type failure struct { // // This is currently painfully non-concurrent, but it will have to do until we // find the time for niceties like this :P -func (b *rpcBackend) request(method string, params []interface{}) (json.RawMessage, error) { +func (b *rpcBackend) request(ctx context.Context, method string, params []interface{}) (json.RawMessage, error) { b.lock.Lock() defer b.lock.Unlock() + if ctx == nil { + ctx = context.Background() + } + // Ugly hack to serialize an empty list properly if params == nil { params = []interface{}{} } // Assemble the request object + reqID := int(atomic.AddUint32(&b.autoid, 1)) req := &request{ JSONRPC: "2.0", - ID: int(atomic.AddUint32(&b.autoid, 1)), + ID: reqID, Method: method, Params: params, } @@ -99,8 +105,17 @@ func (b *rpcBackend) request(method string, params []interface{}) (json.RawMessa return nil, err } res := new(response) - if err := b.client.Recv(res); err != nil { - return nil, err + errc := make(chan error, 1) + go func() { + errc <- b.client.Recv(res) + }() + select { + case err := <-errc: + if err != nil { + return nil, err + } + case <-ctx.Done(): + return nil, ctx.Err() } if res.Error != nil { if res.Error.Message == bind.ErrNoCode.Error() { @@ -113,13 +128,13 @@ func (b *rpcBackend) request(method string, params []interface{}) (json.RawMessa // HasCode implements ContractVerifier.HasCode by retrieving any code associated // with the contract from the remote node, and checking its size. -func (b *rpcBackend) HasCode(contract common.Address, pending bool) (bool, error) { +func (b *rpcBackend) HasCode(ctx context.Context, contract common.Address, pending bool) (bool, error) { // Execute the RPC code retrieval block := "latest" if pending { block = "pending" } - res, err := b.request("eth_getCode", []interface{}{contract.Hex(), block}) + res, err := b.request(ctx, "eth_getCode", []interface{}{contract.Hex(), block}) if err != nil { return false, err } @@ -133,7 +148,7 @@ func (b *rpcBackend) HasCode(contract common.Address, pending bool) (bool, error // ContractCall implements ContractCaller.ContractCall, delegating the execution of // a contract call to the remote node, returning the reply to for local processing. -func (b *rpcBackend) ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) { +func (b *rpcBackend) ContractCall(ctx context.Context, contract common.Address, data []byte, pending bool) ([]byte, error) { // Pack up the request into an RPC argument args := struct { To common.Address `json:"to"` @@ -147,7 +162,7 @@ func (b *rpcBackend) ContractCall(contract common.Address, data []byte, pending if pending { block = "pending" } - res, err := b.request("eth_call", []interface{}{args, block}) + res, err := b.request(ctx, "eth_call", []interface{}{args, block}) if err != nil { return nil, err } @@ -161,8 +176,8 @@ func (b *rpcBackend) ContractCall(contract common.Address, data []byte, pending // PendingAccountNonce implements ContractTransactor.PendingAccountNonce, delegating // the current account nonce retrieval to the remote node. -func (b *rpcBackend) PendingAccountNonce(account common.Address) (uint64, error) { - res, err := b.request("eth_getTransactionCount", []interface{}{account.Hex(), "pending"}) +func (b *rpcBackend) PendingAccountNonce(ctx context.Context, account common.Address) (uint64, error) { + res, err := b.request(ctx, "eth_getTransactionCount", []interface{}{account.Hex(), "pending"}) if err != nil { return 0, err } @@ -179,8 +194,8 @@ func (b *rpcBackend) PendingAccountNonce(account common.Address) (uint64, error) // SuggestGasPrice implements ContractTransactor.SuggestGasPrice, delegating the // gas price oracle request to the remote node. -func (b *rpcBackend) SuggestGasPrice() (*big.Int, error) { - res, err := b.request("eth_gasPrice", nil) +func (b *rpcBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + res, err := b.request(ctx, "eth_gasPrice", nil) if err != nil { return nil, err } @@ -197,7 +212,7 @@ func (b *rpcBackend) SuggestGasPrice() (*big.Int, error) { // EstimateGasLimit implements ContractTransactor.EstimateGasLimit, delegating // the gas estimation to the remote node. -func (b *rpcBackend) EstimateGasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { +func (b *rpcBackend) EstimateGasLimit(ctx context.Context, sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { // Pack up the request into an RPC argument args := struct { From common.Address `json:"from"` @@ -211,7 +226,7 @@ func (b *rpcBackend) EstimateGasLimit(sender common.Address, contract *common.Ad Value: rpc.NewHexNumber(value), } // Execute the RPC call and retrieve the response - res, err := b.request("eth_estimateGas", []interface{}{args}) + res, err := b.request(ctx, "eth_estimateGas", []interface{}{args}) if err != nil { return nil, err } @@ -228,12 +243,12 @@ func (b *rpcBackend) EstimateGasLimit(sender common.Address, contract *common.Ad // SendTransaction implements ContractTransactor.SendTransaction, delegating the // raw transaction injection to the remote node. -func (b *rpcBackend) SendTransaction(tx *types.Transaction) error { +func (b *rpcBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { data, err := rlp.EncodeToBytes(tx) if err != nil { return err } - res, err := b.request("eth_sendRawTransaction", []interface{}{common.ToHex(data)}) + res, err := b.request(ctx, "eth_sendRawTransaction", []interface{}{common.ToHex(data)}) if err != nil { return err } diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 54b1ce603..687a31bf1 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "golang.org/x/net/context" ) // Default chain configuration which sets homestead phase at block 0 (i.e. no frontier) @@ -72,7 +73,7 @@ func (b *SimulatedBackend) Commit() { // Rollback aborts all pending transactions, reverting to the last committed state. func (b *SimulatedBackend) Rollback() { - blocks, _ := core.GenerateChain(b.blockchain.CurrentBlock(), b.database, 1, func(int, *core.BlockGen) {}) + blocks, _ := core.GenerateChain(nil, b.blockchain.CurrentBlock(), b.database, 1, func(int, *core.BlockGen) {}) b.pendingBlock = blocks[0] b.pendingState, _ = state.New(b.pendingBlock.Root(), b.database) @@ -80,7 +81,7 @@ func (b *SimulatedBackend) Rollback() { // HasCode implements ContractVerifier.HasCode, checking whether there is any // code associated with a certain account in the blockchain. -func (b *SimulatedBackend) HasCode(contract common.Address, pending bool) (bool, error) { +func (b *SimulatedBackend) HasCode(ctx context.Context, contract common.Address, pending bool) (bool, error) { if pending { return len(b.pendingState.GetCode(contract)) > 0, nil } @@ -90,7 +91,7 @@ func (b *SimulatedBackend) HasCode(contract common.Address, pending bool) (bool, // ContractCall implements ContractCaller.ContractCall, executing the specified // contract with the given input data. -func (b *SimulatedBackend) ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) { +func (b *SimulatedBackend) ContractCall(ctx context.Context, contract common.Address, data []byte, pending bool) ([]byte, error) { // Create a copy of the current state db to screw around with var ( block *types.Block @@ -129,20 +130,20 @@ func (b *SimulatedBackend) ContractCall(contract common.Address, data []byte, pe // PendingAccountNonce implements ContractTransactor.PendingAccountNonce, retrieving // the nonce currently pending for the account. -func (b *SimulatedBackend) PendingAccountNonce(account common.Address) (uint64, error) { +func (b *SimulatedBackend) PendingAccountNonce(ctx context.Context, account common.Address) (uint64, error) { return b.pendingState.GetOrNewStateObject(account).Nonce(), nil } // SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated // chain doens't have miners, we just return a gas price of 1 for any call. -func (b *SimulatedBackend) SuggestGasPrice() (*big.Int, error) { +func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { return big.NewInt(1), nil } // EstimateGasLimit implements ContractTransactor.EstimateGasLimit, executing the // requested code against the currently pending block/state and returning the used // gas. -func (b *SimulatedBackend) EstimateGasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { +func (b *SimulatedBackend) EstimateGasLimit(ctx context.Context, sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { // Create a copy of the currently pending state db to screw around with var ( block = b.pendingBlock @@ -177,8 +178,8 @@ func (b *SimulatedBackend) EstimateGasLimit(sender common.Address, contract *com // SendTransaction implements ContractTransactor.SendTransaction, delegating the raw // transaction injection to the remote node. -func (b *SimulatedBackend) SendTransaction(tx *types.Transaction) error { - blocks, _ := core.GenerateChain(b.blockchain.CurrentBlock(), b.database, 1, func(number int, block *core.BlockGen) { +func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { + blocks, _ := core.GenerateChain(nil, b.blockchain.CurrentBlock(), b.database, 1, func(number int, block *core.BlockGen) { for _, tx := range b.pendingBlock.Transactions() { block.AddTx(tx) } @@ -202,7 +203,8 @@ type callmsg struct { func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } func (m callmsg) FromFrontier() (common.Address, error) { return m.from.Address(), nil } -func (m callmsg) Nonce() uint64 { return m.from.Nonce() } +func (m callmsg) Nonce() uint64 { return 0 } +func (m callmsg) CheckNonce() bool { return false } func (m callmsg) To() *common.Address { return m.to } func (m callmsg) GasPrice() *big.Int { return m.gasPrice } func (m callmsg) Gas() *big.Int { return m.gasLimit } diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 75e8d5bc8..80948d3f1 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "golang.org/x/net/context" ) // SignerFn is a signer function callback when a contract requires a method to @@ -35,6 +36,8 @@ type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, erro // CallOpts is the collection of options to fine tune a contract call request. type CallOpts struct { Pending bool // Whether to operate on the pending state or the last known one + + Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } // TransactOpts is the collection of authorization data required to create a @@ -47,6 +50,8 @@ type TransactOpts struct { Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds) GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) GasLimit *big.Int // Gas limit to set for the transaction execution (nil = estimate + 10%) + + Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } // BoundContract is the base wrapper object that reflects a contract on the @@ -102,7 +107,7 @@ func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, } // Make sure we have a contract to operate on, and bail out otherwise if (opts.Pending && atomic.LoadUint32(&c.pendingHasCode) == 0) || (!opts.Pending && atomic.LoadUint32(&c.latestHasCode) == 0) { - if code, err := c.caller.HasCode(c.address, opts.Pending); err != nil { + if code, err := c.caller.HasCode(opts.Context, c.address, opts.Pending); err != nil { return err } else if !code { return ErrNoCode @@ -118,7 +123,7 @@ func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, if err != nil { return err } - output, err := c.caller.ContractCall(c.address, input, opts.Pending) + output, err := c.caller.ContractCall(opts.Context, c.address, input, opts.Pending) if err != nil { return err } @@ -153,7 +158,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i } nonce := uint64(0) if opts.Nonce == nil { - nonce, err = c.transactor.PendingAccountNonce(opts.From) + nonce, err = c.transactor.PendingAccountNonce(opts.Context, opts.From) if err != nil { return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) } @@ -163,7 +168,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i // Figure out the gas allowance and gas price values gasPrice := opts.GasPrice if gasPrice == nil { - gasPrice, err = c.transactor.SuggestGasPrice() + gasPrice, err = c.transactor.SuggestGasPrice(opts.Context) if err != nil { return nil, fmt.Errorf("failed to suggest gas price: %v", err) } @@ -172,7 +177,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i if gasLimit == nil { // Gas estimation cannot succeed without code for method invocations if contract != nil && atomic.LoadUint32(&c.pendingHasCode) == 0 { - if code, err := c.transactor.HasCode(c.address, true); err != nil { + if code, err := c.transactor.HasCode(opts.Context, c.address, true); err != nil { return nil, err } else if !code { return nil, ErrNoCode @@ -180,7 +185,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i atomic.StoreUint32(&c.pendingHasCode, 1) } // If the contract surely has code (or code is not needed), estimate the transaction - gasLimit, err = c.transactor.EstimateGasLimit(opts.From, contract, value, input) + gasLimit, err = c.transactor.EstimateGasLimit(opts.Context, opts.From, contract, value, input) if err != nil { return nil, fmt.Errorf("failed to exstimate gas needed: %v", err) } @@ -199,7 +204,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i if err != nil { return nil, err } - if err := c.transactor.SendTransaction(signedTx); err != nil { + if err := c.transactor.SendTransaction(opts.Context, signedTx); err != nil { return nil, err } return signedTx, nil diff --git a/accounts/account_manager.go b/accounts/account_manager.go index bfb7556d6..982a2ca6e 100644 --- a/accounts/account_manager.go +++ b/accounts/account_manager.go @@ -34,6 +34,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" ) var ( @@ -340,3 +342,23 @@ func zeroKey(k *ecdsa.PrivateKey) { b[i] = 0 } } + +// APIs implements node.Service +func (am *Manager) APIs() []rpc.API { + return nil +} + +// Protocols implements node.Service +func (am *Manager) Protocols() []p2p.Protocol { + return nil +} + +// Start implements node.Service +func (am *Manager) Start(srvr *p2p.Server) error { + return nil +} + +// Stop implements node.Service +func (am *Manager) Stop() error { + return nil +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..0b1c919d8 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,33 @@ +os: Visual Studio 2015 + +# Clone directly into GOPATH. +clone_folder: c:\gopath\src\github.com\ethereum\go-ethereum +clone_depth: 5 +version: "{branch}.{build}" +environment: + global: + # Go stuff + GOPATH: c:\gopath + GO: c:\go\bin\go + GOROOT: c:\go + CC: C:\msys64\mingw64\bin\gcc.exe + # MSYS2 stuff + MSYS2_ARCH: x86_64 + MSYSTEM: MINGW64 + PATH: C:\msys64\mingw64\bin\;%PATH% + +install: + - "%GO% version" + - "%CC% --version" + +build_script: + - "%GO% run build\\ci.go install" + +test_script: + - "%GO% run build\\ci.go test -vet -coverage" + +after_build: + - "%GO% run build\\ci.go archive -type zip" + +artifacts: + - path: geth-*.zip diff --git a/build/ci-notes.md b/build/ci-notes.md new file mode 100644 index 000000000..989cba6dd --- /dev/null +++ b/build/ci-notes.md @@ -0,0 +1,26 @@ +Debian Packaging +---------------- + +Tagged releases and develop branch commits are available as installable Debian packages +for Ubuntu. Packages are built for the all Ubuntu versions which are supported by +Canonical: + +- Trusty Tahr (14.04 LTS) +- Wily Werewolf (15.10) +- Xenial Xerus (16.04 LTS) + +Packages of develop branch commits have suffix -unstable and cannot be installed alongside +the stable version. Switching between release streams requires user intervention. + +The packages are built and served by launchpad.net. We generate a Debian source package +for each distribution and upload it. Their builder picks up the source package, builds it +and installs the new version into the PPA repository. Launchpad requires a valid signature +by a team member for source package uploads. The signing key is stored in an environment +variable which Travis CI makes available to certain builds. + +We want to build go-ethereum with the most recent version of Go, irrespective of the Go +version that is available in the main Ubuntu repository. In order to make this possible, +our PPA depends on the ~gophers/ubuntu/archive PPA. Our source package build-depends on +golang-1.6, which is co-installable alongside the regular golang package. PPA dependencies +can be edited at https://launchpad.net/%7Elp-fjl/+archive/ubuntu/geth-ci-testing/+edit-dependencies + diff --git a/build/ci.go b/build/ci.go new file mode 100644 index 000000000..33d97c182 --- /dev/null +++ b/build/ci.go @@ -0,0 +1,465 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +// +build none + +/* +The ci command is called from Continuous Integration scripts. + +Usage: go run ci.go <command> <command flags/arguments> + +Available commands are: + + install [ packages... ] -- builds packages and executables + test [ -coverage ] [ -vet ] [ packages... ] -- runs the tests + archive [ -type zip|tar ] -- archives build artefacts + importkeys -- imports signing keys from env + debsrc [ -sign key-id ] [ -upload dest ] -- creates a debian source package + +For all commands, -n prevents execution of external programs (dry run mode). + +*/ +package main + +import ( + "bytes" + "encoding/base64" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "time" + + "../internal/build" +) + +var ( + // Files that end up in the geth*.zip archive. + gethArchiveFiles = []string{ + "COPYING", + executablePath("geth"), + } + + // Files that end up in the geth-alltools*.zip archive. + allToolsArchiveFiles = []string{ + "COPYING", + executablePath("abigen"), + executablePath("evm"), + executablePath("geth"), + executablePath("rlpdump"), + } + + // A debian package is created for all executables listed here. + debExecutables = []debExecutable{ + { + Name: "geth", + Description: "Ethereum CLI client.", + }, + { + Name: "rlpdump", + Description: "Developer utility tool that prints RLP structures.", + }, + { + Name: "evm", + Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", + }, + { + Name: "abigen", + Description: "Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages.", + }, + } + + // Distros for which packages are created. + // Note: vivid is unsupported because there is no golang-1.6 package for it. + debDistros = []string{"trusty", "wily", "xenial", "yakkety"} +) + +var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin")) + +func executablePath(name string) string { + if runtime.GOOS == "windows" { + name += ".exe" + } + return filepath.Join(GOBIN, name) +} + +func main() { + log.SetFlags(log.Lshortfile) + + if _, err := os.Stat(filepath.Join("build", "ci.go")); os.IsNotExist(err) { + log.Fatal("this script must be run from the root of the repository") + } + if len(os.Args) < 2 { + log.Fatal("need subcommand as first argument") + } + switch os.Args[1] { + case "install": + doInstall(os.Args[2:]) + case "test": + doTest(os.Args[2:]) + case "archive": + doArchive(os.Args[2:]) + case "debsrc": + doDebianSource(os.Args[2:]) + case "travis-debsrc": + doTravisDebianSource(os.Args[2:]) + default: + log.Fatal("unknown command ", os.Args[1]) + } +} + +// Compiling + +func doInstall(cmdline []string) { + commitHash := flag.String("gitcommit", "", "Git commit hash embedded into binary.") + flag.CommandLine.Parse(cmdline) + + // Check Go version. People regularly open issues about compilation + // failure with outdated Go. This should save them the trouble. + if runtime.Version() < "go1.4" && !strings.HasPrefix(runtime.Version(), "devel") { + log.Println("You have Go version", runtime.Version()) + log.Println("go-ethereum requires at least Go version 1.4 and cannot") + log.Println("be compiled with an earlier version. Please upgrade your Go installation.") + os.Exit(1) + } + + // Compile packages given as arguments, or everything if there are no arguments. + packages := []string{"./..."} + if flag.NArg() > 0 { + packages = flag.Args() + } + + goinstall := goTool("install", makeBuildFlags(*commitHash)...) + goinstall.Args = append(goinstall.Args, "-v") + goinstall.Args = append(goinstall.Args, packages...) + build.MustRun(goinstall) +} + +func makeBuildFlags(commitHash string) (flags []string) { + // Since Go 1.5, the separator char for link time assignments + // is '=' and using ' ' prints a warning. However, Go < 1.5 does + // not support using '='. + sep := " " + if runtime.Version() > "go1.5" || strings.Contains(runtime.Version(), "devel") { + sep = "=" + } + + if os.Getenv("GO_OPENCL") != "" { + flags = append(flags, "-tags", "opencl") + } + + // Set gitCommit constant via link-time assignment. If this is a git checkout, we can + // just get the current commit hash through git. Otherwise we fall back to the hash + // that was passed as -gitcommit. + // + // -gitcommit is required for Debian package builds. The source package doesn't + // contain .git but we still want to embed the commit hash into the packaged binary. + // The hash is rendered into the debian/rules build script when the source package is + // created. + if _, err := os.Stat(filepath.Join(".git", "HEAD")); !os.IsNotExist(err) { + if c := build.GitCommit(); c != "" { + commitHash = c + } + } + if commitHash != "" { + flags = append(flags, "-ldflags", "-X main.gitCommit"+sep+commitHash) + } + return flags +} + +func goTool(subcmd string, args ...string) *exec.Cmd { + gocmd := filepath.Join(runtime.GOROOT(), "bin", "go") + cmd := exec.Command(gocmd, subcmd) + cmd.Args = append(cmd.Args, args...) + cmd.Env = []string{ + "GOPATH=" + build.GOPATH(), + "GOBIN=" + GOBIN, + } + for _, e := range os.Environ() { + if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") { + continue + } + cmd.Env = append(cmd.Env, e) + } + return cmd +} + +// Running The Tests +// +// "tests" also includes static analysis tools such as vet. + +func doTest(cmdline []string) { + var ( + vet = flag.Bool("vet", false, "Whether to run go vet") + coverage = flag.Bool("coverage", false, "Whether to record code coverage") + ) + flag.CommandLine.Parse(cmdline) + packages := []string{"./..."} + if len(flag.CommandLine.Args()) > 0 { + packages = flag.CommandLine.Args() + } + + // Run analysis tools before the tests. + if *vet { + build.MustRun(goTool("vet", packages...)) + } + + // Run the actual tests. + gotest := goTool("test") + if *coverage { + gotest.Args = append(gotest.Args, "-covermode=atomic", "-cover") + } + gotest.Args = append(gotest.Args, packages...) + build.MustRun(gotest) +} + +// Release Packaging + +func doArchive(cmdline []string) { + var ( + atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") + ext string + ) + flag.CommandLine.Parse(cmdline) + switch *atype { + case "zip": + ext = ".zip" + case "tar": + ext = ".tar.gz" + default: + log.Fatal("unknown archive type: ", atype) + } + base := makeArchiveBasename() + if err := build.WriteArchive("geth-"+base, ext, gethArchiveFiles); err != nil { + log.Fatal(err) + } + if err := build.WriteArchive("geth-alltools-"+base, ext, allToolsArchiveFiles); err != nil { + log.Fatal(err) + } +} + +func makeArchiveBasename() string { + // date := time.Now().UTC().Format("200601021504") + platform := runtime.GOOS + "-" + runtime.GOARCH + archive := platform + "-" + build.VERSION() + if commit := build.GitCommit(); commit != "" { + archive += "-" + commit[:8] + } + return archive +} + +// Debian Packaging + +// CLI entry point for Travis CI. +func doTravisDebianSource(cmdline []string) { + flag.CommandLine.Parse(cmdline) + + // Package only whitelisted branches. + switch { + case os.Getenv("TRAVIS_REPO_SLUG") != "ethereum/go-ethereum": + log.Printf("skipping because this is a fork build") + return + case os.Getenv("TRAVIS_PULL_REQUEST") != "false": + log.Printf("skipping because this is a PR build") + return + case os.Getenv("TRAVIS_BRANCH") != "develop" && !strings.HasPrefix(os.Getenv("TRAVIS_TAG"), "v1."): + log.Printf("skipping because branch %q tag %q is not on the whitelist", + os.Getenv("TRAVIS_BRANCH"), + os.Getenv("TRAVIS_TAG")) + return + } + + // Import the signing key. + if b64key := os.Getenv("PPA_SIGNING_KEY"); b64key != "" { + key, err := base64.StdEncoding.DecodeString(b64key) + if err != nil { + log.Fatal("invalid base64 PPA_SIGNING_KEY") + } + gpg := exec.Command("gpg", "--import") + gpg.Stdin = bytes.NewReader(key) + build.MustRun(gpg) + } + + // Assign unstable status to non-tag builds. + unstable := "true" + if os.Getenv("TRAVIS_BRANCH") != "develop" && os.Getenv("TRAVIS_TAG") != "" { + unstable = "false" + } + + doDebianSource([]string{ + "-signer", "Felix Lange (Geth CI Testing Key) <fjl@twurst.com>", + "-buildnum", os.Getenv("TRAVIS_BUILD_NUMBER"), + "-upload", "ppa:lp-fjl/geth-ci-testing", + "-unstable", unstable, + }) +} + +// CLI entry point for doing packaging locally. +func doDebianSource(cmdline []string) { + var ( + signer = flag.String("signer", "", `Signing key name, also used as package author`) + upload = flag.String("upload", "", `Where to upload the source package (usually "ppa:ethereum/ethereum")`) + buildnum = flag.String("buildnum", "", `Build number (included in version)`) + unstable = flag.Bool("unstable", false, `Use package name suffix "-unstable"`) + now = time.Now() + ) + flag.CommandLine.Parse(cmdline) + + // Create the debian worktree in /tmp. + tmpdir, err := ioutil.TempDir("", "eth-deb-build-") + if err != nil { + log.Fatal(err) + } + + for _, distro := range debDistros { + meta := newDebMetadata(distro, *signer, *buildnum, *unstable, now) + pkgdir := stageDebianSource(tmpdir, meta) + debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc") + debuild.Dir = pkgdir + build.MustRun(debuild) + + changes := fmt.Sprintf("%s_%s_source.changes", meta.Name(), meta.VersionString()) + changes = filepath.Join(tmpdir, changes) + if *signer != "" { + build.MustRunCommand("debsign", changes) + } + if *upload != "" { + build.MustRunCommand("dput", *upload, changes) + } + } +} + +type debExecutable struct { + Name, Description string +} + +type debMetadata struct { + // go-ethereum version being built. Note that this + // is not the debian package version. The package version + // is constructed by VersionString. + Version string + + Author string // "name <email>", also selects signing key + Buildnum string // build number + Distro, Commit, Time string + Executables []debExecutable + Unstable bool +} + +func newDebMetadata(distro, author, buildnum string, unstable bool, t time.Time) debMetadata { + if author == "" { + // No signing key, use default author. + author = "Ethereum Builds <fjl@ethereum.org>" + } + return debMetadata{ + Unstable: unstable, + Author: author, + Distro: distro, + Commit: build.GitCommit(), + Version: build.VERSION(), + Buildnum: buildnum, + Time: t.Format(time.RFC1123Z), + Executables: debExecutables, + } +} + +// Name returns the name of the metapackage that depends +// on all executable packages. +func (meta debMetadata) Name() string { + if meta.Unstable { + return "ethereum-unstable" + } + return "ethereum" +} + +// VersionString returns the debian version of the packages. +func (meta debMetadata) VersionString() string { + vsn := meta.Version + if meta.Buildnum != "" { + vsn += "+build" + meta.Buildnum + } + if meta.Distro != "" { + vsn += "+" + meta.Distro + } + return vsn +} + +// ExeList returns the list of all executable packages. +func (meta debMetadata) ExeList() string { + names := make([]string, len(meta.Executables)) + for i, e := range meta.Executables { + names[i] = meta.ExeName(e) + } + return strings.Join(names, ", ") +} + +// ExeName returns the package name of an executable package. +func (meta debMetadata) ExeName(exe debExecutable) string { + if meta.Unstable { + return exe.Name + "-unstable" + } + return exe.Name +} + +// ExeConflicts returns the content of the Conflicts field +// for executable packages. +func (meta debMetadata) ExeConflicts(exe debExecutable) string { + if meta.Unstable { + // Set up the conflicts list so that the *-unstable packages + // cannot be installed alongside the regular version. + // + // https://www.debian.org/doc/debian-policy/ch-relationships.html + // is very explicit about Conflicts: and says that Breaks: should + // be preferred and the conflicting files should be handled via + // alternates. We might do this eventually but using a conflict is + // easier now. + return "ethereum, " + exe.Name + } + return "" +} + +func stageDebianSource(tmpdir string, meta debMetadata) (pkgdir string) { + pkg := meta.Name() + "-" + meta.VersionString() + pkgdir = filepath.Join(tmpdir, pkg) + if err := os.Mkdir(pkgdir, 0755); err != nil { + log.Fatal(err) + } + + // Copy the source code. + build.MustRunCommand("git", "checkout-index", "-a", "--prefix", pkgdir+string(filepath.Separator)) + + // Put the debian build files in place. + debian := filepath.Join(pkgdir, "debian") + build.Render("build/deb.rules", filepath.Join(debian, "rules"), 0755, meta) + build.Render("build/deb.changelog", filepath.Join(debian, "changelog"), 0644, meta) + build.Render("build/deb.control", filepath.Join(debian, "control"), 0644, meta) + build.Render("build/deb.copyright", filepath.Join(debian, "copyright"), 0644, meta) + build.RenderString("8\n", filepath.Join(debian, "compat"), 0644, meta) + build.RenderString("3.0 (native)\n", filepath.Join(debian, "source/format"), 0644, meta) + for _, exe := range meta.Executables { + install := filepath.Join(debian, exe.Name+".install") + docs := filepath.Join(debian, exe.Name+".docs") + build.Render("build/deb.install", install, 0644, exe) + build.Render("build/deb.docs", docs, 0644, exe) + } + + return pkgdir +} diff --git a/build/deb.changelog b/build/deb.changelog new file mode 100644 index 000000000..a221f5470 --- /dev/null +++ b/build/deb.changelog @@ -0,0 +1,5 @@ +{{.Name}} ({{.VersionString}}) {{.Distro}}; urgency=low + + * git build of {{.Commit}} + + -- {{.Author}} {{.Time}} diff --git a/build/deb.control b/build/deb.control new file mode 100644 index 000000000..4a65c7fac --- /dev/null +++ b/build/deb.control @@ -0,0 +1,25 @@ +Source: {{.Name}} +Section: science +Priority: extra +Maintainer: {{.Author}} +Build-Depends: debhelper (>= 8.0.0), golang-1.6 +Standards-Version: 3.9.5 +Homepage: https://ethereum.org +Vcs-Git: git://github.com/ethereum/go-ethereum.git +Vcs-Browser: https://github.com/ethereum/go-ethereum + +Package: {{.Name}} +Architecture: any +Depends: ${misc:Depends}, {{.ExeList}} +Description: Meta-package to install geth and other tools + Meta-package to install geth and other tools + +{{range .Executables}} +Package: {{$.ExeName .}} +Conflicts: {{$.ExeConflicts .}} +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Built-Using: ${misc:Built-Using} +Description: {{.Description}} + {{.Description}} +{{end}} diff --git a/build/deb.copyright b/build/deb.copyright new file mode 100644 index 000000000..513be45b1 --- /dev/null +++ b/build/deb.copyright @@ -0,0 +1,14 @@ +Copyright 2016 The go-ethereum Authors + +go-ethereum is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +go-ethereum is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. diff --git a/build/deb.docs b/build/deb.docs new file mode 100644 index 000000000..62deb0497 --- /dev/null +++ b/build/deb.docs @@ -0,0 +1 @@ +AUTHORS diff --git a/build/deb.install b/build/deb.install new file mode 100644 index 000000000..7dc76e1f5 --- /dev/null +++ b/build/deb.install @@ -0,0 +1 @@ +build/bin/{{.Name}} usr/bin diff --git a/build/deb.rules b/build/deb.rules new file mode 100644 index 000000000..3dfadb08d --- /dev/null +++ b/build/deb.rules @@ -0,0 +1,13 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +override_dh_auto_build: + build/env.sh /usr/lib/go-1.6/bin/go run build/ci.go install -gitcommit {{.Commit}} + +override_dh_auto_test: + +%: + dh $@ diff --git a/build/env.sh b/build/env.sh index 04401a3e1..c418dae44 100755 --- a/build/env.sh +++ b/build/env.sh @@ -20,9 +20,8 @@ fi # Set up the environment to use the workspace. # Also add Godeps workspace so we build using canned dependencies. -GOPATH="$ethdir/go-ethereum/Godeps/_workspace:$workspace" -GOBIN="$PWD/build/bin" -export GOPATH GOBIN +GOPATH="$workspace" +export GOPATH # Run the command inside the workspace. cd "$ethdir/go-ethereum" diff --git a/build/test-global-coverage.sh b/build/test-global-coverage.sh deleted file mode 100755 index a51b6a9e5..000000000 --- a/build/test-global-coverage.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(find ./* -maxdepth 10 -type d -not -path "./build" -not -path "./Godeps/*" ); do - if ls $d/*.go &> /dev/null; then - go test -coverprofile=profile.out -covermode=atomic $d - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - echo '<<<<<< EOF' >> coverage.txt - rm profile.out - fi - fi -done diff --git a/build/win-ci-compile.bat b/build/win-ci-compile.bat deleted file mode 100644 index 5750990bf..000000000 --- a/build/win-ci-compile.bat +++ /dev/null @@ -1,26 +0,0 @@ -@echo off -if not exist .\build\win-ci-compile.bat ( - echo This script must be run from the root of the repository. - exit /b -) -if not defined GOPATH ( - echo GOPATH is not set. - exit /b -) - -set GOPATH=%GOPATH%;%cd%\Godeps\_workspace -set GOBIN=%cd%\build\bin - -rem set gitCommit when running from a Git checkout. -set goLinkFlags="" -if exist ".git\HEAD" ( - where /q git - if not errorlevel 1 ( - for /f %%h in ('git rev-parse HEAD') do ( - set goLinkFlags="-X main.gitCommit=%%h" - ) - ) -) - -@echo on -go install -v -ldflags %goLinkFlags% ./... diff --git a/build/win-ci-test.bat b/build/win-ci-test.bat deleted file mode 100644 index 5945426db..000000000 --- a/build/win-ci-test.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -if not exist .\build\win-ci-test.bat ( - echo This script must be run from the root of the repository. - exit /b -) -if not defined GOPATH ( - echo GOPATH is not set. - exit /b -) - -set GOPATH=%GOPATH%;%cd%\Godeps\_workspace -set GOBIN=%cd%\build\bin - -@echo on -go test ./... diff --git a/circle.yml b/circle.yml new file mode 100644 index 000000000..39ff5d83c --- /dev/null +++ b/circle.yml @@ -0,0 +1,32 @@ +machine: + services: + - docker + +dependencies: + cache_directories: + - "~/.ethash" # Cache the ethash DAG generated by hive for consecutive builds + - "~/.docker" # Cache all docker images manually to avoid lengthy rebuilds + override: + # Restore all previously cached docker images + - mkdir -p ~/.docker + - for img in `ls ~/.docker`; do docker load -i ~/.docker/$img; done + + # Pull in and hive, restore cached ethash DAGs and do a dry run + - go get -u github.com/karalabe/hive + - (cd ~/.go_workspace/src/github.com/karalabe/hive && mkdir -p workspace/ethash/ ~/.ethash) + - (cd ~/.go_workspace/src/github.com/karalabe/hive && cp -r ~/.ethash/. workspace/ethash/) + - (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=NONE --test=. --sim=. --loglevel=6) + + # Cache all the docker images and the ethash DAGs + - for img in `docker images | grep -v "^<none>" | tail -n +2 | awk '{print $1}'`; do docker save $img > ~/.docker/`echo $img | tr '/' ':'`.tar; done + - cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/ethash/. ~/.ethash + +test: + override: + # Build Geth and move into a known folder + - make geth + - cp ./build/bin/geth $HOME/geth + + # Run hive and move all generated logs into the public artifacts folder + - (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=go-ethereum:local --override=$HOME/geth --test=. --sim=.) + - cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/logs/* $CIRCLE_ARTIFACTS diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index 7d3f9fdb3..40d3cdc17 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -20,6 +20,7 @@ package main import ( "crypto/ecdsa" "flag" + "fmt" "os" "github.com/ethereum/go-ethereum/cmd/utils" @@ -32,7 +33,8 @@ import ( func main() { var ( listenAddr = flag.String("addr", ":30301", "listen address") - genKey = flag.String("genkey", "", "generate a node key and quit") + genKey = flag.String("genkey", "", "generate a node key") + writeAddr = flag.Bool("writeaddress", false, "write out the node's pubkey hash and quit") nodeKeyFile = flag.String("nodekey", "", "private key filename") nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") @@ -45,22 +47,19 @@ func main() { glog.SetToStderr(true) flag.Parse() - if *genKey != "" { - key, err := crypto.GenerateKey() - if err != nil { - utils.Fatalf("could not generate key: %v", err) - } - if err := crypto.SaveECDSA(*genKey, key); err != nil { - utils.Fatalf("%v", err) - } - os.Exit(0) - } - natm, err := nat.Parse(*natdesc) if err != nil { utils.Fatalf("-nat: %v", err) } switch { + case *genKey != "": + nodeKey, err = crypto.GenerateKey() + if err != nil { + utils.Fatalf("could not generate key: %v", err) + } + if err = crypto.SaveECDSA(*genKey, nodeKey); err != nil { + utils.Fatalf("%v", err) + } case *nodeKeyFile == "" && *nodeKeyHex == "": utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key") case *nodeKeyFile != "" && *nodeKeyHex != "": @@ -75,6 +74,11 @@ func main() { } } + if *writeAddr { + fmt.Printf("%v\n", discover.PubkeyID(&nodeKey.PublicKey)) + os.Exit(0) + } + if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, ""); err != nil { utils.Fatalf("%v", err) } diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index e0ad0a7ea..71465fb55 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -74,9 +74,9 @@ func runTestWithReader(test string, r io.Reader) error { var err error switch strings.ToLower(test) { case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests": - err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, r, skipTests) + err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, r, skipTests) case "st", "state", "statetest", "statetests": - rs := tests.RuleSet{HomesteadBlock: params.MainNetHomesteadBlock} + rs := tests.RuleSet{HomesteadBlock: params.MainNetHomesteadBlock, DAOForkBlock: params.MainNetDAOForkBlock, DAOForkSupport: true} err = tests.RunStateTestWithReader(rs, r, skipTests) case "tx", "transactiontest", "transactiontests": err = tests.RunTransactionTestsWithReader(r, skipTests) diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go index 1415240eb..7fea16a25 100644 --- a/cmd/geth/accountcmd.go +++ b/cmd/geth/accountcmd.go @@ -316,7 +316,7 @@ func accountImport(ctx *cli.Context) error { } key, err := crypto.LoadECDSA(keyfile) if err != nil { - utils.Fatalf("keyfile must be given as argument") + utils.Fatalf("Failed to load the private key: %v", err) } accman := utils.MakeAccountManager(ctx) passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go new file mode 100644 index 000000000..7058fb385 --- /dev/null +++ b/cmd/geth/dao_test.go @@ -0,0 +1,232 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. + +package main + +import ( + "io/ioutil" + "math/big" + "os" + "path/filepath" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +// Genesis block for nodes which don't care about the DAO fork (i.e. not configured) +var daoOldGenesis = `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : {} +}` + +// Genesis block for nodes which actively oppose the DAO fork +var daoNoForkGenesis = `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "daoForkBlock" : 314, + "daoForkSupport" : false + } +}` + +// Genesis block for nodes which actively support the DAO fork +var daoProForkGenesis = `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "daoForkBlock" : 314, + "daoForkSupport" : true + } +}` + +var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0") +var daoGenesisForkBlock = big.NewInt(314) + +// Tests that the DAO hard-fork number and the nodes support/opposition is correctly +// set in the database after various initialization procedures and invocations. +func TestDAODefaultMainnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, false}}, params.MainNetDAOForkBlock, true) +} +func TestDAOSupportMainnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, "", [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true) +} +func TestDAOOpposeMainnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false) +} +func TestDAOSwitchToSupportMainnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, "", [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true) +} +func TestDAOSwitchToOpposeMainnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, "", [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false) +} +func TestDAODefaultTestnet(t *testing.T) { + testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, false}}, params.TestNetDAOForkBlock, true) +} +func TestDAOSupportTestnet(t *testing.T) { + testDAOForkBlockNewChain(t, true, "", [][2]bool{{true, false}}, params.TestNetDAOForkBlock, true) +} +func TestDAOOpposeTestnet(t *testing.T) { + testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, true}}, params.TestNetDAOForkBlock, false) +} +func TestDAOSwitchToSupportTestnet(t *testing.T) { + testDAOForkBlockNewChain(t, true, "", [][2]bool{{false, true}, {true, false}}, params.TestNetDAOForkBlock, true) +} +func TestDAOSwitchToOpposeTestnet(t *testing.T) { + testDAOForkBlockNewChain(t, true, "", [][2]bool{{true, false}, {false, true}}, params.TestNetDAOForkBlock, false) +} +func TestDAOInitOldPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{}, nil, false) +} +func TestDAODefaultOldPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, false}}, params.MainNetDAOForkBlock, true) +} +func TestDAOSupportOldPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}}, params.MainNetDAOForkBlock, true) +} +func TestDAOOpposeOldPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}}, params.MainNetDAOForkBlock, false) +} +func TestDAOSwitchToSupportOldPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{false, true}, {true, false}}, params.MainNetDAOForkBlock, true) +} +func TestDAOSwitchToOpposeOldPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoOldGenesis, [][2]bool{{true, false}, {false, true}}, params.MainNetDAOForkBlock, false) +} +func TestDAOInitNoForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{}, daoGenesisForkBlock, false) +} +func TestDAODefaultNoForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, false}}, daoGenesisForkBlock, false) +} +func TestDAOSupportNoForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{true, false}}, daoGenesisForkBlock, true) +} +func TestDAOOpposeNoForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, true}}, daoGenesisForkBlock, false) +} +func TestDAOSwitchToSupportNoForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{false, true}, {true, false}}, daoGenesisForkBlock, true) +} +func TestDAOSwitchToOpposeNoForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoNoForkGenesis, [][2]bool{{true, false}, {false, true}}, daoGenesisForkBlock, false) +} +func TestDAOInitProForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{}, daoGenesisForkBlock, true) +} +func TestDAODefaultProForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, false}}, daoGenesisForkBlock, true) +} +func TestDAOSupportProForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{true, false}}, daoGenesisForkBlock, true) +} +func TestDAOOpposeProForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, true}}, daoGenesisForkBlock, false) +} +func TestDAOSwitchToSupportProForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{false, true}, {true, false}}, daoGenesisForkBlock, true) +} +func TestDAOSwitchToOpposeProForkPrivnet(t *testing.T) { + testDAOForkBlockNewChain(t, false, daoProForkGenesis, [][2]bool{{true, false}, {false, true}}, daoGenesisForkBlock, false) +} + +func testDAOForkBlockNewChain(t *testing.T, testnet bool, genesis string, votes [][2]bool, expectBlock *big.Int, expectVote bool) { + // Create a temporary data directory to use and inspect later + datadir := tmpdir(t) + defer os.RemoveAll(datadir) + + // Start a Geth instance with the requested flags set and immediately terminate + if genesis != "" { + json := filepath.Join(datadir, "genesis.json") + if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil { + t.Fatalf("failed to write genesis file: %v", err) + } + runGeth(t, "--datadir", datadir, "init", json).cmd.Wait() + } + for _, vote := range votes { + args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir} + if testnet { + args = append(args, "--testnet") + } + if vote[0] { + args = append(args, "--support-dao-fork") + } + if vote[1] { + args = append(args, "--oppose-dao-fork") + } + geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...) + geth.cmd.Wait() + } + // Retrieve the DAO config flag from the database + path := filepath.Join(datadir, "chaindata") + if testnet && genesis == "" { + path = filepath.Join(datadir, "testnet", "chaindata") + } + db, err := ethdb.NewLDBDatabase(path, 0, 0) + if err != nil { + t.Fatalf("failed to open test database: %v", err) + } + defer db.Close() + + genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") + if testnet { + genesisHash = common.HexToHash("0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303") + } + if genesis != "" { + genesisHash = daoGenesisHash + } + config, err := core.GetChainConfig(db, genesisHash) + if err != nil { + t.Fatalf("failed to retrieve chain config: %v", err) + } + // Validate the DAO hard-fork block number against the expected value + if config.DAOForkBlock == nil { + if expectBlock != nil { + t.Errorf("dao hard-fork block mismatch: have nil, want %v", expectBlock) + } + } else if expectBlock == nil { + t.Errorf("dao hard-fork block mismatch: have %v, want nil", config.DAOForkBlock) + } else if config.DAOForkBlock.Cmp(expectBlock) != 0 { + t.Errorf("dao hard-fork block mismatch: have %v, want %v", config.DAOForkBlock, expectBlock) + } + if config.DAOForkSupport != expectVote { + t.Errorf("dao hard-fork support mismatch: have %v, want %v", config.DAOForkSupport, expectVote) + } +} diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go new file mode 100644 index 000000000..4f8b1642e --- /dev/null +++ b/cmd/geth/genesis_test.go @@ -0,0 +1,107 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. + +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +var customGenesisTests = []struct { + genesis string + query string + result string +}{ + // Plain genesis file without anything extra + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00" + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000000042", + }, + // Genesis file with an empty chain configuration (ensure missing fields work) + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : {} + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000000042", + }, + // Genesis file with specific chain configurations + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "homesteadBlock" : 314, + "daoForkBlock" : 141, + "daoForkSupport" : true + }, + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000000042", + }, +} + +// Tests that initializing Geth with a custom genesis block and chain definitions +// work properly. +func TestCustomGenesis(t *testing.T) { + for i, tt := range customGenesisTests { + // Create a temporary data directory to use and inspect later + datadir := tmpdir(t) + defer os.RemoveAll(datadir) + + // Initialize the data directory with the custom genesis block + json := filepath.Join(datadir, "genesis.json") + if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil { + t.Fatalf("test %d: failed to write genesis file: %v", i, err) + } + runGeth(t, "--datadir", datadir, "init", json).cmd.Wait() + + // Query the custom genesis block + geth := runGeth(t, "--datadir", datadir, "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--exec", tt.query, "console") + geth.expectRegexp(tt.result) + geth.expectExit() + } +} diff --git a/cmd/geth/main.go b/cmd/geth/main.go index c372430f1..5f1157b90 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -29,6 +29,7 @@ import ( "time" "github.com/ethereum/ethash" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/console" @@ -149,7 +150,6 @@ participating. utils.IdentityFlag, utils.UnlockedAccountFlag, utils.PasswordFileFlag, - utils.GenesisFileFlag, utils.BootnodesFlag, utils.DataDirFlag, utils.KeyStoreDirFlag, @@ -164,6 +164,8 @@ participating. utils.MaxPendingPeersFlag, utils.EtherbaseFlag, utils.GasPriceFlag, + utils.SupportDAOFork, + utils.OpposeDAOFork, utils.MinerThreadsFlag, utils.MiningEnabledFlag, utils.MiningGPUFlag, @@ -224,12 +226,6 @@ participating. eth.EnableBadBlockReporting = true utils.SetupNetwork(ctx) - - // Deprecation warning. - if ctx.GlobalIsSet(utils.GenesisFileFlag.Name) { - common.PrintDepricationWarning("--genesis is deprecated. Switch to use 'geth init /path/to/file'") - } - return nil } @@ -309,15 +305,16 @@ func initGenesis(ctx *cli.Context) error { // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the // miner. func startNode(ctx *cli.Context, stack *node.Node) { + // Report geth version + glog.V(logger.Info).Infof("instance: Geth/%s/%s/%s\n", verString, runtime.Version(), runtime.GOOS) // Start up the node itself utils.StartNode(stack) // Unlock any account specifically requested - var ethereum *eth.Ethereum - if err := stack.Service(ðereum); err != nil { + var accman *accounts.Manager + if err := stack.Service(&accman); err != nil { utils.Fatalf("ethereum service not running: %v", err) } - accman := ethereum.AccountManager() passwords := utils.MakePasswordList(ctx) accounts := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") @@ -328,6 +325,10 @@ func startNode(ctx *cli.Context, stack *node.Node) { } // Start auxiliary services if enabled if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { + var ethereum *eth.Ethereum + if err := stack.Service(ðereum); err != nil { + utils.Fatalf("ethereum service not running: %v", err) + } if err := ethereum.StartMining(ctx.GlobalInt(utils.MinerThreadsFlag.Name), ctx.GlobalString(utils.MiningGPUFlag.Name)); err != nil { utils.Fatalf("Failed to start mining: %v", err) } diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index e7ef9e2c7..eb897d2b5 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -68,7 +68,6 @@ var AppHelpFlagGroups = []flagGroup{ utils.OlympicFlag, utils.TestNetFlag, utils.DevModeFlag, - utils.GenesisFileFlag, utils.IdentityFlag, utils.FastSyncFlag, utils.LightKDFFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 14898b987..de379f84f 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -126,10 +126,6 @@ var ( Name: "dev", Usage: "Developer mode: pre-configured private network with several debugging flags", } - GenesisFileFlag = cli.StringFlag{ - Name: "genesis", - Usage: "Insert/overwrite the genesis block (JSON format)", - } IdentityFlag = cli.StringFlag{ Name: "identity", Usage: "Custom node name", @@ -161,6 +157,15 @@ var ( Name: "lightkdf", Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", } + // Fork settings + SupportDAOFork = cli.BoolFlag{ + Name: "support-dao-fork", + Usage: "Updates the chain rules to support the DAO hard-fork", + } + OpposeDAOFork = cli.BoolFlag{ + Name: "oppose-dao-fork", + Usage: "Updates the chain rules to oppose the DAO hard-fork", + } // Miner settings // TODO: refactor CPU vs GPU mining flags MiningEnabledFlag = cli.BoolFlag{ @@ -534,20 +539,6 @@ func MakeWSRpcHost(ctx *cli.Context) string { return ctx.GlobalString(WSListenAddrFlag.Name) } -// MakeGenesisBlock loads up a genesis block from an input file specified in the -// command line, or returns the empty string if none set. -func MakeGenesisBlock(ctx *cli.Context) string { - genesis := ctx.GlobalString(GenesisFileFlag.Name) - if genesis == "" { - return "" - } - data, err := ioutil.ReadFile(genesis) - if err != nil { - Fatalf("Failed to load custom genesis file: %v", err) - } - return string(data) -} - // MakeDatabaseHandles raises out the number of allowed file handles per process // for Geth and returns half of the allowance to assign to the database. func MakeDatabaseHandles() int { @@ -689,7 +680,6 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, ethConf := ð.Config{ ChainConfig: MustMakeChainConfig(ctx), - Genesis: MakeGenesisBlock(ctx), FastSync: ctx.GlobalBool(FastSyncFlag.Name), BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name), DatabaseCache: ctx.GlobalInt(CacheFlag.Name), @@ -722,17 +712,13 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 1 } - if !ctx.GlobalIsSet(GenesisFileFlag.Name) { - ethConf.Genesis = core.OlympicGenesisBlock() - } + ethConf.Genesis = core.OlympicGenesisBlock() case ctx.GlobalBool(TestNetFlag.Name): if !ctx.GlobalIsSet(NetworkIdFlag.Name) { ethConf.NetworkId = 2 } - if !ctx.GlobalIsSet(GenesisFileFlag.Name) { - ethConf.Genesis = core.TestNetGenesisBlock() - } + ethConf.Genesis = core.TestNetGenesisBlock() state.StartingNonce = 1048576 // (2**20) case ctx.GlobalBool(DevModeFlag.Name): @@ -747,9 +733,7 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, stackConf.ListenAddr = ":0" } // Override the Ethereum protocol configs - if !ctx.GlobalIsSet(GenesisFileFlag.Name) { - ethConf.Genesis = core.OlympicGenesisBlock() - } + ethConf.Genesis = core.OlympicGenesisBlock() if !ctx.GlobalIsSet(GasPriceFlag.Name) { ethConf.GasPrice = new(big.Int) } @@ -763,6 +747,13 @@ func MakeSystemNode(name, version string, relconf release.Config, extra []byte, if err != nil { Fatalf("Failed to create the protocol stack: %v", err) } + + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + return accman, nil + }); err != nil { + Fatalf("Failed to register the account manager service: %v", err) + } + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { return eth.New(ctx, ethConf) }); err != nil { @@ -806,24 +797,62 @@ func MustMakeChainConfig(ctx *cli.Context) *core.ChainConfig { // MustMakeChainConfigFromDb reads the chain configuration from the given database. func MustMakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *core.ChainConfig { - genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0) + // If the chain is already initialized, use any existing chain configs + config := new(core.ChainConfig) + genesis := core.GetBlock(db, core.GetCanonicalHash(db, 0), 0) if genesis != nil { - // Existing genesis block, use stored config if available. storedConfig, err := core.GetChainConfig(db, genesis.Hash()) - if err == nil { - return storedConfig - } else if err != core.ChainConfigNotFoundErr { + switch err { + case nil: + config = storedConfig + case core.ChainConfigNotFoundErr: + // No configs found, use empty, will populate below + default: Fatalf("Could not make chain configuration: %v", err) } } - var homesteadBlockNo *big.Int - if ctx.GlobalBool(TestNetFlag.Name) { - homesteadBlockNo = params.TestNetHomesteadBlock - } else { - homesteadBlockNo = params.MainNetHomesteadBlock + // Set any missing fields due to them being unset or system upgrade + if config.HomesteadBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.HomesteadBlock = params.TestNetHomesteadBlock + } else { + config.HomesteadBlock = params.MainNetHomesteadBlock + } + } + if config.DAOForkBlock == nil { + if ctx.GlobalBool(TestNetFlag.Name) { + config.DAOForkBlock = params.TestNetDAOForkBlock + } else { + config.DAOForkBlock = params.MainNetDAOForkBlock + } + config.DAOForkSupport = true } - return &core.ChainConfig{HomesteadBlock: homesteadBlockNo} + // Force override any existing configs if explicitly requested + switch { + case ctx.GlobalBool(SupportDAOFork.Name): + config.DAOForkSupport = true + case ctx.GlobalBool(OpposeDAOFork.Name): + config.DAOForkSupport = false + } + // Temporarilly display a proper message so the user knows which fork its on + if !ctx.GlobalBool(TestNetFlag.Name) && (genesis == nil || genesis.Hash() == common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")) { + choice := "SUPPORT" + if !config.DAOForkSupport { + choice = "OPPOSE" + } + current := fmt.Sprintf("Geth is currently configured to %s the DAO hard-fork!", choice) + howtoswap := fmt.Sprintf("You can change your choice prior to block #%v with --support-dao-fork or --oppose-dao-fork.", config.DAOForkBlock) + howtosync := fmt.Sprintf("After the hard-fork block #%v passed, changing chains requires a resync from scratch!", config.DAOForkBlock) + separator := strings.Repeat("-", len(howtoswap)) + + glog.V(logger.Warn).Info(separator) + glog.V(logger.Warn).Info(current) + glog.V(logger.Warn).Info(howtoswap) + glog.V(logger.Warn).Info(howtosync) + glog.V(logger.Warn).Info(separator) + } + return config } // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. diff --git a/common/registrar/ethreg/api.go b/common/registrar/ethreg/api.go index 6d77a9385..6dd0ef46f 100644 --- a/common/registrar/ethreg/api.go +++ b/common/registrar/ethreg/api.go @@ -128,7 +128,10 @@ func (m callmsg) FromFrontier() (common.Address, error) { return m.from.Address(), nil } func (m callmsg) Nonce() uint64 { - return m.from.Nonce() + return 0 +} +func (m callmsg) CheckNonce() bool { + return false } func (m callmsg) To() *common.Address { return m.to diff --git a/containers/docker/master-alpine/Dockerfile b/containers/docker/master-alpine/Dockerfile index 11d4159a3..ade4caf6f 100644 --- a/containers/docker/master-alpine/Dockerfile +++ b/containers/docker/master-alpine/Dockerfile @@ -1,11 +1,11 @@ FROM alpine:3.3 RUN \ - apk add --update go git make gcc musl-dev gmp-dev gmp && \ - git clone https://github.com/ethereum/go-ethereum && \ - (cd go-ethereum && make geth) && \ - cp go-ethereum/build/bin/geth /geth && \ - apk del go git make gcc musl-dev gmp-dev && \ + apk add --update go git make gcc musl-dev && \ + git clone https://github.com/ethereum/go-ethereum && \ + (cd go-ethereum && make geth) && \ + cp go-ethereum/build/bin/geth /geth && \ + apk del go git make gcc musl-dev && \ rm -rf /go-ethereum && rm -rf /var/cache/apk/* EXPOSE 8545 diff --git a/core/bench_test.go b/core/bench_test.go index c6029499a..344e7e3c5 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -163,7 +163,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { // Generate a chain of b.N blocks using the supplied block // generator function. genesis := WriteGenesisBlockForTesting(db, GenesisAccount{benchRootAddr, benchRootFunds}) - chain, _ := GenerateChain(genesis, db, b.N, gen) + chain, _ := GenerateChain(nil, genesis, db, b.N, gen) // Time the insertion of the new chain. // State and blocks are stored in the same DB. diff --git a/core/block_validator.go b/core/block_validator.go index f777b9f23..e5bc6178b 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -64,7 +64,7 @@ func NewBlockValidator(config *ChainConfig, blockchain *BlockChain, pow pow.PoW) // // ValidateBlock also validates and makes sure that any previous state (or present) // state that might or might not be present is checked to make sure that fast -// sync has done it's job proper. This prevents the block validator form accepting +// sync has done it's job proper. This prevents the block validator from accepting // false positives where a header is present but the state is not. func (v *BlockValidator) ValidateBlock(block *types.Block) error { if v.bc.HasBlock(block.Hash()) { @@ -139,7 +139,7 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat // error if any of the included uncle headers were invalid. It returns an error // if the validation failed. func (v *BlockValidator) VerifyUncles(block, parent *types.Block) error { - // validate that there at most 2 uncles included in this block + // validate that there are at most 2 uncles included in this block if len(block.Uncles()) > 2 { return ValidationError("Block can only contain maximum 2 uncles (contained %v)", len(block.Uncles())) } @@ -193,7 +193,7 @@ func (v *BlockValidator) ValidateHeader(header, parent *types.Header, checkPow b if parent == nil { return ParentError(header.ParentHash) } - // Short circuit if the header's already known or its parent missing + // Short circuit if the header's already known or its parent is missing if v.bc.HasHeader(header.Hash()) { return nil } @@ -247,7 +247,8 @@ func ValidateHeader(config *ChainConfig, pow pow.PoW, header *types.Header, pare return &BlockNonceErr{header.Number, header.Hash(), header.Nonce.Uint64()} } } - return nil + // If all checks passed, validate the extra-data field for hard forks + return ValidateDAOHeaderExtraData(config, header) } // CalcDifficulty is the difficulty adjustment algorithm. It returns diff --git a/core/blockchain.go b/core/blockchain.go index 95bada5ee..950804d40 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -771,14 +771,13 @@ func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err if ptd == nil { return NonStatTy, ParentError(block.ParentHash()) } - - localTd := self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()) - externTd := new(big.Int).Add(block.Difficulty(), ptd) - // Make sure no inconsistent state is leaked during insertion self.mu.Lock() defer self.mu.Unlock() + localTd := self.GetTd(self.currentBlock.Hash(), self.currentBlock.NumberU64()) + externTd := new(big.Int).Add(block.Difficulty(), ptd) + // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf diff --git a/core/blockchain_test.go b/core/blockchain_test.go index a26fe4a1b..c3e4d352d 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -712,7 +712,7 @@ func TestFastVsFullChains(t *testing.T) { funds = big.NewInt(1000000000) genesis = GenesisBlockForTesting(gendb, address, funds) ) - blocks, receipts := GenerateChain(genesis, gendb, 1024, func(i int, block *BlockGen) { + blocks, receipts := GenerateChain(nil, genesis, gendb, 1024, func(i int, block *BlockGen) { block.SetCoinbase(common.Address{0x00}) // If the block number is multiple of 3, send a few bonus transactions to the miner @@ -795,7 +795,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { genesis = GenesisBlockForTesting(gendb, address, funds) ) height := uint64(1024) - blocks, receipts := GenerateChain(genesis, gendb, int(height), nil) + blocks, receipts := GenerateChain(nil, genesis, gendb, int(height), nil) // Configure a subchain to roll back remove := []common.Hash{} @@ -895,7 +895,7 @@ func TestChainTxReorgs(t *testing.T) { // - futureAdd: transaction added after the reorg has already finished var pastAdd, freshAdd, futureAdd *types.Transaction - chain, _ := GenerateChain(genesis, db, 3, func(i int, gen *BlockGen) { + chain, _ := GenerateChain(nil, genesis, db, 3, func(i int, gen *BlockGen) { switch i { case 0: pastDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(key2) @@ -920,7 +920,7 @@ func TestChainTxReorgs(t *testing.T) { } // overwrite the old chain - chain, _ = GenerateChain(genesis, db, 5, func(i int, gen *BlockGen) { + chain, _ = GenerateChain(nil, genesis, db, 5, func(i int, gen *BlockGen) { switch i { case 0: pastAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil).SignECDSA(key3) @@ -990,7 +990,7 @@ func TestLogReorgs(t *testing.T) { blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) subs := evmux.Subscribe(RemovedLogsEvent{}) - chain, _ := GenerateChain(genesis, db, 2, func(i int, gen *BlockGen) { + chain, _ := GenerateChain(nil, genesis, db, 2, func(i int, gen *BlockGen) { if i == 1 { tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code).SignECDSA(key1) if err != nil { @@ -1003,7 +1003,7 @@ func TestLogReorgs(t *testing.T) { t.Fatalf("failed to insert chain: %v", err) } - chain, _ = GenerateChain(genesis, db, 3, func(i int, gen *BlockGen) {}) + chain, _ = GenerateChain(nil, genesis, db, 3, func(i int, gen *BlockGen) {}) if _, err := blockchain.InsertChain(chain); err != nil { t.Fatalf("failed to insert forked chain: %v", err) } @@ -1025,12 +1025,12 @@ func TestReorgSideEvent(t *testing.T) { evmux := &event.TypeMux{} blockchain, _ := NewBlockChain(db, testChainConfig(), FakePow{}, evmux) - chain, _ := GenerateChain(genesis, db, 3, func(i int, gen *BlockGen) {}) + chain, _ := GenerateChain(nil, genesis, db, 3, func(i int, gen *BlockGen) {}) if _, err := blockchain.InsertChain(chain); err != nil { t.Fatalf("failed to insert chain: %v", err) } - replacementBlocks, _ := GenerateChain(genesis, db, 4, func(i int, gen *BlockGen) { + replacementBlocks, _ := GenerateChain(nil, genesis, db, 4, func(i int, gen *BlockGen) { tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil).SignECDSA(key1) if i == 2 { gen.OffsetTime(-1) diff --git a/core/chain_makers.go b/core/chain_makers.go index ef0ac66d1..0b9a5f75d 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" ) @@ -35,7 +36,11 @@ import ( // MakeChainConfig returns a new ChainConfig with the ethereum default chain settings. func MakeChainConfig() *ChainConfig { - return &ChainConfig{HomesteadBlock: big.NewInt(0)} + return &ChainConfig{ + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + } } // FakePow is a non-validating proof of work implementation. @@ -173,10 +178,27 @@ func (b *BlockGen) OffsetTime(seconds int64) { // Blocks created by GenerateChain do not contain valid proof of work // values. Inserting them into BlockChain requires use of FakePow or // a similar non-validating proof of work implementation. -func GenerateChain(parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { +func GenerateChain(config *ChainConfig, parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) genblock := func(i int, h *types.Header, statedb *state.StateDB) (*types.Block, types.Receipts) { b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb} + + // Mutate the state and block according to any hard-fork specs + if config == nil { + config = MakeChainConfig() + } + if daoBlock := config.DAOForkBlock; daoBlock != nil { + limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) + if h.Number.Cmp(daoBlock) >= 0 && h.Number.Cmp(limit) < 0 { + if config.DAOForkSupport { + h.Extra = common.CopyBytes(params.DAOForkBlockExtra) + } + } + } + if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(h.Number) == 0 { + ApplyDAOHardFork(statedb) + } + // Execute any user modifications to the block and finalize it if gen != nil { gen(i, b) } @@ -261,7 +283,7 @@ func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) [ // makeBlockChain creates a deterministic chain of blocks rooted at parent. func makeBlockChain(parent *types.Block, n int, db ethdb.Database, seed int) []*types.Block { - blocks, _ := GenerateChain(parent, db, n, func(i int, b *BlockGen) { + blocks, _ := GenerateChain(nil, parent, db, n, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) }) return blocks diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 32c3efe8d..f52b09ad9 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -47,7 +47,7 @@ func ExampleGenerateChain() { // This call generates a chain of 5 blocks. The function runs for // each block and adds different features to gen based on the // block index. - chain, _ := GenerateChain(genesis, db, 5, func(i int, gen *BlockGen) { + chain, _ := GenerateChain(nil, genesis, db, 5, func(i int, gen *BlockGen) { switch i { case 0: // In block 1, addr1 sends addr2 some ether. diff --git a/core/chain_pow_test.go b/core/chain_pow_test.go index d2b0bd144..2e26c8211 100644 --- a/core/chain_pow_test.go +++ b/core/chain_pow_test.go @@ -60,7 +60,7 @@ func TestPowVerification(t *testing.T) { var ( testdb, _ = ethdb.NewMemDatabase() genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int)) - blocks, _ = GenerateChain(genesis, testdb, 8, nil) + blocks, _ = GenerateChain(nil, genesis, testdb, 8, nil) ) headers := make([]*types.Header, len(blocks)) for i, block := range blocks { @@ -115,7 +115,7 @@ func testPowConcurrentVerification(t *testing.T, threads int) { var ( testdb, _ = ethdb.NewMemDatabase() genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int)) - blocks, _ = GenerateChain(genesis, testdb, 8, nil) + blocks, _ = GenerateChain(nil, genesis, testdb, 8, nil) ) headers := make([]*types.Header, len(blocks)) for i, block := range blocks { @@ -186,7 +186,7 @@ func testPowConcurrentAbortion(t *testing.T, threads int) { var ( testdb, _ = ethdb.NewMemDatabase() genesis = GenesisBlockForTesting(testdb, common.Address{}, new(big.Int)) - blocks, _ = GenerateChain(genesis, testdb, 1024, nil) + blocks, _ = GenerateChain(nil, genesis, testdb, 1024, nil) ) headers := make([]*types.Header, len(blocks)) for i, block := range blocks { diff --git a/core/config.go b/core/config.go index 81ca76aa3..c0d065a57 100644 --- a/core/config.go +++ b/core/config.go @@ -31,16 +31,17 @@ var ChainConfigNotFoundErr = errors.New("ChainConfig not found") // general conf // that any network, identified by its genesis block, can have its own // set of configuration options. type ChainConfig struct { - HomesteadBlock *big.Int // homestead switch block + HomesteadBlock *big.Int `json:"homesteadBlock"` // Homestead switch block (nil = no fork, 0 = already homestead) + DAOForkBlock *big.Int `json:"daoForkBlock"` // TheDAO hard-fork switch block (nil = no fork) + DAOForkSupport bool `json:"daoForkSupport"` // Whether the nodes supports or opposes the DAO hard-fork VmConfig vm.Config `json:"-"` } // IsHomestead returns whether num is either equal to the homestead block or greater. func (c *ChainConfig) IsHomestead(num *big.Int) bool { - if num == nil { + if c.HomesteadBlock == nil || num == nil { return false } - return num.Cmp(c.HomesteadBlock) >= 0 } diff --git a/core/dao.go b/core/dao.go new file mode 100644 index 000000000..e315c9884 --- /dev/null +++ b/core/dao.go @@ -0,0 +1,74 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package core + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" +) + +// ValidateDAOHeaderExtraData validates the extra-data field of a block header to +// ensure it conforms to DAO hard-fork rules. +// +// DAO hard-fork extension to the header validity: +// a) if the node is no-fork, do not accept blocks in the [fork, fork+10) range +// with the fork specific extra-data set +// b) if the node is pro-fork, require blocks in the specific range to have the +// unique extra-data set. +func ValidateDAOHeaderExtraData(config *ChainConfig, header *types.Header) error { + // Short circuit validation if the node doesn't care about the DAO fork + if config.DAOForkBlock == nil { + return nil + } + // Make sure the block is within the fork's modified extra-data range + limit := new(big.Int).Add(config.DAOForkBlock, params.DAOForkExtraRange) + if header.Number.Cmp(config.DAOForkBlock) < 0 || header.Number.Cmp(limit) >= 0 { + return nil + } + // Depending whether we support or oppose the fork, validate the extra-data contents + if config.DAOForkSupport { + if bytes.Compare(header.Extra, params.DAOForkBlockExtra) != 0 { + return ValidationError("DAO pro-fork bad block extra-data: 0x%x", header.Extra) + } + } else { + if bytes.Compare(header.Extra, params.DAOForkBlockExtra) == 0 { + return ValidationError("DAO no-fork bad block extra-data: 0x%x", header.Extra) + } + } + // All ok, header has the same extra-data we expect + return nil +} + +// ApplyDAOHardFork modifies the state database according to the DAO hard-fork +// rules, transferring all balances of a set of DAO accounts to a single refund +// contract. +func ApplyDAOHardFork(statedb *state.StateDB) { + // Retrieve the contract to refund balances into + refund := statedb.GetOrNewStateObject(params.DAORefundContract) + + // Move every DAO account and extra-balance account funds into the refund contract + for _, addr := range params.DAODrainList { + if account := statedb.GetStateObject(addr); account != nil { + refund.AddBalance(account.Balance()) + account.SetBalance(new(big.Int)) + } + } +} diff --git a/core/dao_test.go b/core/dao_test.go new file mode 100644 index 000000000..0830b1231 --- /dev/null +++ b/core/dao_test.go @@ -0,0 +1,132 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" +) + +// Tests that DAO-fork enabled clients can properly filter out fork-commencing +// blocks based on their extradata fields. +func TestDAOForkRangeExtradata(t *testing.T) { + forkBlock := big.NewInt(32) + + // Generate a common prefix for both pro-forkers and non-forkers + db, _ := ethdb.NewMemDatabase() + genesis := WriteGenesisBlockForTesting(db) + prefix, _ := GenerateChain(nil, genesis, db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {}) + + // Create the concurrent, conflicting two nodes + proDb, _ := ethdb.NewMemDatabase() + WriteGenesisBlockForTesting(proDb) + proConf := &ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: true} + proBc, _ := NewBlockChain(proDb, proConf, new(FakePow), new(event.TypeMux)) + + conDb, _ := ethdb.NewMemDatabase() + WriteGenesisBlockForTesting(conDb) + conConf := &ChainConfig{HomesteadBlock: big.NewInt(0), DAOForkBlock: forkBlock, DAOForkSupport: false} + conBc, _ := NewBlockChain(conDb, conConf, new(FakePow), new(event.TypeMux)) + + if _, err := proBc.InsertChain(prefix); err != nil { + t.Fatalf("pro-fork: failed to import chain prefix: %v", err) + } + if _, err := conBc.InsertChain(prefix); err != nil { + t.Fatalf("con-fork: failed to import chain prefix: %v", err) + } + // Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks + for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ { + // Create a pro-fork block, and try to feed into the no-fork chain + db, _ = ethdb.NewMemDatabase() + WriteGenesisBlockForTesting(db) + bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux)) + + blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1)) + for j := 0; j < len(blocks)/2; j++ { + blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j] + } + if _, err := bc.InsertChain(blocks); err != nil { + t.Fatalf("failed to import contra-fork chain for expansion: %v", err) + } + blocks, _ = GenerateChain(proConf, conBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {}) + if _, err := conBc.InsertChain(blocks); err == nil { + t.Fatalf("contra-fork chain accepted pro-fork block: %v", blocks[0]) + } + // Create a proper no-fork block for the contra-forker + blocks, _ = GenerateChain(conConf, conBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {}) + if _, err := conBc.InsertChain(blocks); err != nil { + t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err) + } + // Create a no-fork block, and try to feed into the pro-fork chain + db, _ = ethdb.NewMemDatabase() + WriteGenesisBlockForTesting(db) + bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux)) + + blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1)) + for j := 0; j < len(blocks)/2; j++ { + blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j] + } + if _, err := bc.InsertChain(blocks); err != nil { + t.Fatalf("failed to import pro-fork chain for expansion: %v", err) + } + blocks, _ = GenerateChain(conConf, proBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {}) + if _, err := proBc.InsertChain(blocks); err == nil { + t.Fatalf("pro-fork chain accepted contra-fork block: %v", blocks[0]) + } + // Create a proper pro-fork block for the pro-forker + blocks, _ = GenerateChain(proConf, proBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {}) + if _, err := proBc.InsertChain(blocks); err != nil { + t.Fatalf("pro-fork chain didn't accepted pro-fork block: %v", err) + } + } + // Verify that contra-forkers accept pro-fork extra-datas after forking finishes + db, _ = ethdb.NewMemDatabase() + WriteGenesisBlockForTesting(db) + bc, _ := NewBlockChain(db, conConf, new(FakePow), new(event.TypeMux)) + + blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().NumberU64()+1)) + for j := 0; j < len(blocks)/2; j++ { + blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j] + } + if _, err := bc.InsertChain(blocks); err != nil { + t.Fatalf("failed to import contra-fork chain for expansion: %v", err) + } + blocks, _ = GenerateChain(proConf, conBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {}) + if _, err := conBc.InsertChain(blocks); err != nil { + t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err) + } + // Verify that pro-forkers accept contra-fork extra-datas after forking finishes + db, _ = ethdb.NewMemDatabase() + WriteGenesisBlockForTesting(db) + bc, _ = NewBlockChain(db, proConf, new(FakePow), new(event.TypeMux)) + + blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().NumberU64()+1)) + for j := 0; j < len(blocks)/2; j++ { + blocks[j], blocks[len(blocks)-1-j] = blocks[len(blocks)-1-j], blocks[j] + } + if _, err := bc.InsertChain(blocks); err != nil { + t.Fatalf("failed to import pro-fork chain for expansion: %v", err) + } + blocks, _ = GenerateChain(conConf, proBc.CurrentBlock(), db, 1, func(i int, gen *BlockGen) {}) + if _, err := proBc.InsertChain(blocks); err != nil { + t.Fatalf("pro-fork chain didn't accept contra-fork block post-fork: %v", err) + } +} diff --git a/core/database_util_test.go b/core/database_util_test.go index 6c19f78c8..280270ac8 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -561,7 +561,7 @@ func TestMipmapChain(t *testing.T) { defer db.Close() genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr, big.NewInt(1000000)}) - chain, receipts := GenerateChain(genesis, db, 1010, func(i int, gen *BlockGen) { + chain, receipts := GenerateChain(nil, genesis, db, 1010, func(i int, gen *BlockGen) { var receipts types.Receipts switch i { case 1: diff --git a/core/state_processor.go b/core/state_processor.go index 95b3057bb..fd8e9762e 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -65,7 +65,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg allLogs vm.Logs gp = new(GasPool).AddGas(block.GasLimit()) ) - + // Mutate the the block and state according to any hard-fork specs + if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { + ApplyDAOHardFork(statedb) + } + // Iterate over and process the individual transactions for i, tx := range block.Transactions() { statedb.StartRecord(tx.Hash(), block.Hash(), i) receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg) diff --git a/core/state_transition.go b/core/state_transition.go index c8160424b..9e6b2f567 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -71,6 +71,7 @@ type Message interface { Value() *big.Int Nonce() uint64 + CheckNonce() bool Data() []byte } @@ -208,8 +209,10 @@ func (self *StateTransition) preCheck() (err error) { } // Make sure this transaction's nonce is correct - if n := self.state.GetNonce(sender.Address()); n != msg.Nonce() { - return NonceError(msg.Nonce(), n) + if msg.CheckNonce() { + if n := self.state.GetNonce(sender.Address()); n != msg.Nonce() { + return NonceError(msg.Nonce(), n) + } } // Pre-pay gas diff --git a/core/types/transaction.go b/core/types/transaction.go index b99d3a716..c71c98aa7 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -113,6 +113,7 @@ func (tx *Transaction) Gas() *big.Int { return new(big.Int).Set(tx.data.Gas func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } +func (tx *Transaction) CheckNonce() bool { return true } func (tx *Transaction) To() *common.Address { if tx.data.Recipient == nil { diff --git a/core/vm/environment.go b/core/vm/environment.go index 747627565..664887454 100644 --- a/core/vm/environment.go +++ b/core/vm/environment.go @@ -73,6 +73,8 @@ type Environment interface { DelegateCall(me ContractRef, addr common.Address, data []byte, gas, price *big.Int) ([]byte, error) // Create a new contract Create(me ContractRef, data []byte, gas, price, value *big.Int) ([]byte, common.Address, error) + + StructLogs() []StructLog } // Vm is the basic interface for an implementation of the EVM. diff --git a/core/vm/jit.go b/core/vm/jit.go index f56d7c1af..e2374df42 100644 --- a/core/vm/jit.go +++ b/core/vm/jit.go @@ -421,7 +421,7 @@ func jitCalculateGasAndSize(env Environment, contract *Contract, instr instructi g = params.SstoreClearGas } else { - g = params.SstoreClearGas + g = params.SstoreResetGas } gas.Set(g) case SUICIDE: diff --git a/core/vm/vm.go b/core/vm/vm.go index 0f93715d6..52e782b23 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -306,7 +306,7 @@ func calculateGasAndSize(env Environment, contract *Contract, caller ContractRef g = params.SstoreClearGas } else { // non 0 => non 0 (or 0 => 0) - g = params.SstoreClearGas + g = params.SstoreResetGas } gas.Set(g) case SUICIDE: diff --git a/eth/api.go b/eth/api.go index 9f5f2e677..3b7abb69a 100644 --- a/eth/api.go +++ b/eth/api.go @@ -18,8 +18,6 @@ package eth import ( "bytes" - "encoding/hex" - "encoding/json" "errors" "fmt" "io" @@ -27,111 +25,30 @@ import ( "math/big" "os" "runtime" - "strings" - "sync" - "time" "github.com/ethereum/ethash" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/compiler" "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/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/miner" - "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - "github.com/syndtr/goleveldb/leveldb" - "golang.org/x/net/context" ) -const defaultGas = uint64(90000) - -// blockByNumber is a commonly used helper function which retrieves and returns -// the block for the given block number, capable of handling two special blocks: -// rpc.LatestBlockNumber and rpc.PendingBlockNumber. It returns nil when no block -// could be found. -func blockByNumber(m *miner.Miner, bc *core.BlockChain, blockNr rpc.BlockNumber) *types.Block { - // Pending block is only known by the miner - if blockNr == rpc.PendingBlockNumber { - block, _ := m.Pending() - return block - } - // Otherwise resolve and return the block - if blockNr == rpc.LatestBlockNumber { - return bc.CurrentBlock() - } - return bc.GetBlockByNumber(uint64(blockNr)) -} - -// stateAndBlockByNumber is a commonly used helper function which retrieves and -// returns the state and containing block for the given block number, capable of -// handling two special states: rpc.LatestBlockNumber and rpc.PendingBlockNumber. -// It returns nil when no block or state could be found. -func stateAndBlockByNumber(m *miner.Miner, bc *core.BlockChain, blockNr rpc.BlockNumber, chainDb ethdb.Database) (*state.StateDB, *types.Block, error) { - // Pending state is only known by the miner - if blockNr == rpc.PendingBlockNumber { - block, state := m.Pending() - return state, block, nil - } - // Otherwise resolve the block number and return its state - block := blockByNumber(m, bc, blockNr) - if block == nil { - return nil, nil, nil - } - stateDb, err := state.New(block.Root(), chainDb) - return stateDb, block, err -} - -// PublicEthereumAPI provides an API to access Ethereum related information. -// It offers only methods that operate on public data that is freely available to anyone. +// PublicEthereumAPI provides an API to access Ethereum full node-related +// information. type PublicEthereumAPI struct { - e *Ethereum - gpo *GasPriceOracle + e *Ethereum } -// NewPublicEthereumAPI creates a new Ethereum protocol API. +// NewPublicEthereumAPI creates a new Etheruem protocol API for full nodes. func NewPublicEthereumAPI(e *Ethereum) *PublicEthereumAPI { - return &PublicEthereumAPI{ - e: e, - gpo: e.gpo, - } -} - -// GasPrice returns a suggestion for a gas price. -func (s *PublicEthereumAPI) GasPrice() *big.Int { - return s.gpo.SuggestPrice() -} - -// GetCompilers returns the collection of available smart contract compilers -func (s *PublicEthereumAPI) GetCompilers() ([]string, error) { - solc, err := s.e.Solc() - if err == nil && solc != nil { - return []string{"Solidity"}, nil - } - - return []string{}, nil -} - -// CompileSolidity compiles the given solidity source -func (s *PublicEthereumAPI) CompileSolidity(source string) (map[string]*compiler.Contract, error) { - solc, err := s.e.Solc() - if err != nil { - return nil, err - } - - if solc == nil { - return nil, errors.New("solc (solidity compiler) not found") - } - - return solc.Compile(source) + return &PublicEthereumAPI{e} } // Etherbase is the address that mining rewards will be send to @@ -144,40 +61,11 @@ func (s *PublicEthereumAPI) Coinbase() (common.Address, error) { return s.Etherbase() } -// ProtocolVersion returns the current Ethereum protocol version this node supports -func (s *PublicEthereumAPI) ProtocolVersion() *rpc.HexNumber { - return rpc.NewHexNumber(s.e.EthVersion()) -} - // Hashrate returns the POW hashrate func (s *PublicEthereumAPI) Hashrate() *rpc.HexNumber { return rpc.NewHexNumber(s.e.Miner().HashRate()) } -// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not -// yet received the latest block headers from its pears. In case it is synchronizing: -// - startingBlock: block number this node started to synchronise from -// - currentBlock: block number this node is currently importing -// - highestBlock: block number of the highest block header this node has received from peers -// - pulledStates: number of state entries processed until now -// - knownStates: number of known state entries that still need to be pulled -func (s *PublicEthereumAPI) Syncing() (interface{}, error) { - origin, current, height, pulled, known := s.e.Downloader().Progress() - - // Return not syncing if the synchronisation already completed - if current >= height { - return false, nil - } - // Otherwise gather the block sync stats - return map[string]interface{}{ - "startingBlock": rpc.NewHexNumber(origin), - "currentBlock": rpc.NewHexNumber(current), - "highestBlock": rpc.NewHexNumber(height), - "pulledStates": rpc.NewHexNumber(pulled), - "knownStates": rpc.NewHexNumber(known), - }, nil -} - // PublicMinerAPI provides an API to control the miner. // It offers only methods that operate on data that pose no security risk when it is publicly accessible. type PublicMinerAPI struct { @@ -303,1197 +191,18 @@ func (s *PrivateMinerAPI) MakeDAG(blockNr rpc.BlockNumber) (bool, error) { return true, nil } -// PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. -type PublicTxPoolAPI struct { - e *Ethereum -} - -// NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. -func NewPublicTxPoolAPI(e *Ethereum) *PublicTxPoolAPI { - return &PublicTxPoolAPI{e} -} - -// Content returns the transactions contained within the transaction pool. -func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string][]*RPCTransaction { - content := map[string]map[string]map[string][]*RPCTransaction{ - "pending": make(map[string]map[string][]*RPCTransaction), - "queued": make(map[string]map[string][]*RPCTransaction), - } - pending, queue := s.e.TxPool().Content() - - // Flatten the pending transactions - for account, batches := range pending { - dump := make(map[string][]*RPCTransaction) - for nonce, txs := range batches { - nonce := fmt.Sprintf("%d", nonce) - for _, tx := range txs { - dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx)) - } - } - content["pending"][account.Hex()] = dump - } - // Flatten the queued transactions - for account, batches := range queue { - dump := make(map[string][]*RPCTransaction) - for nonce, txs := range batches { - nonce := fmt.Sprintf("%d", nonce) - for _, tx := range txs { - dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx)) - } - } - content["queued"][account.Hex()] = dump - } - return content -} - -// Status returns the number of pending and queued transaction in the pool. -func (s *PublicTxPoolAPI) Status() map[string]*rpc.HexNumber { - pending, queue := s.e.TxPool().Stats() - return map[string]*rpc.HexNumber{ - "pending": rpc.NewHexNumber(pending), - "queued": rpc.NewHexNumber(queue), - } -} - -// Inspect retrieves the content of the transaction pool and flattens it into an -// easily inspectable list. -func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string][]string { - content := map[string]map[string]map[string][]string{ - "pending": make(map[string]map[string][]string), - "queued": make(map[string]map[string][]string), - } - pending, queue := s.e.TxPool().Content() - - // Define a formatter to flatten a transaction into a string - var format = func(tx *types.Transaction) string { - if to := tx.To(); to != nil { - return fmt.Sprintf("%s: %v wei + %v × %v gas", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) - } - return fmt.Sprintf("contract creation: %v wei + %v × %v gas", tx.Value(), tx.Gas(), tx.GasPrice()) - } - // Flatten the pending transactions - for account, batches := range pending { - dump := make(map[string][]string) - for nonce, txs := range batches { - nonce := fmt.Sprintf("%d", nonce) - for _, tx := range txs { - dump[nonce] = append(dump[nonce], format(tx)) - } - } - content["pending"][account.Hex()] = dump - } - // Flatten the queued transactions - for account, batches := range queue { - dump := make(map[string][]string) - for nonce, txs := range batches { - nonce := fmt.Sprintf("%d", nonce) - for _, tx := range txs { - dump[nonce] = append(dump[nonce], format(tx)) - } - } - content["queued"][account.Hex()] = dump - } - return content -} - -// PublicAccountAPI provides an API to access accounts managed by this node. -// It offers only methods that can retrieve accounts. -type PublicAccountAPI struct { - am *accounts.Manager -} - -// NewPublicAccountAPI creates a new PublicAccountAPI. -func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { - return &PublicAccountAPI{am: am} -} - -// Accounts returns the collection of accounts this node manages -func (s *PublicAccountAPI) Accounts() []accounts.Account { - return s.am.Accounts() -} - -// PrivateAccountAPI provides an API to access accounts managed by this node. -// It offers methods to create, (un)lock en list accounts. Some methods accept -// passwords and are therefore considered private by default. -type PrivateAccountAPI struct { - am *accounts.Manager - txPool *core.TxPool - txMu *sync.Mutex - gpo *GasPriceOracle -} - -// NewPrivateAccountAPI create a new PrivateAccountAPI. -func NewPrivateAccountAPI(e *Ethereum) *PrivateAccountAPI { - return &PrivateAccountAPI{ - am: e.accountManager, - txPool: e.txPool, - txMu: &e.txMu, - gpo: e.gpo, - } -} - -// ListAccounts will return a list of addresses for accounts this node manages. -func (s *PrivateAccountAPI) ListAccounts() []common.Address { - accounts := s.am.Accounts() - addresses := make([]common.Address, len(accounts)) - for i, acc := range accounts { - addresses[i] = acc.Address - } - return addresses -} - -// NewAccount will create a new account and returns the address for the new account. -func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { - acc, err := s.am.NewAccount(password) - if err == nil { - return acc.Address, nil - } - return common.Address{}, err -} - -// ImportRawKey stores the given hex encoded ECDSA key into the key directory, -// encrypting it with the passphrase. -func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { - hexkey, err := hex.DecodeString(privkey) - if err != nil { - return common.Address{}, err - } - - acc, err := s.am.ImportECDSA(crypto.ToECDSA(hexkey), password) - return acc.Address, err -} - -// UnlockAccount will unlock the account associated with the given address with -// the given password for duration seconds. If duration is nil it will use a -// default of 300 seconds. It returns an indication if the account was unlocked. -func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *rpc.HexNumber) (bool, error) { - if duration == nil { - duration = rpc.NewHexNumber(300) - } - a := accounts.Account{Address: addr} - d := time.Duration(duration.Int64()) * time.Second - if err := s.am.TimedUnlock(a, password, d); err != nil { - return false, err - } - return true, nil -} - -// LockAccount will lock the account associated with the given address when it's unlocked. -func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { - return s.am.Lock(addr) == nil -} - -// SignAndSendTransaction will create a transaction from the given arguments and -// tries to sign it with the key associated with args.To. If the given passwd isn't -// able to decrypt the key it fails. -func (s *PrivateAccountAPI) SignAndSendTransaction(args SendTxArgs, passwd string) (common.Hash, error) { - args = prepareSendTxArgs(args, s.gpo) - - s.txMu.Lock() - defer s.txMu.Unlock() - - if args.Nonce == nil { - args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) - } - - var tx *types.Transaction - if args.To == nil { - tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) - } else { - tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) - } - - signature, err := s.am.SignWithPassphrase(args.From, passwd, tx.SigHash().Bytes()) - if err != nil { - return common.Hash{}, err - } - - return submitTransaction(s.txPool, tx, signature) -} - -// PublicBlockChainAPI provides an API to access the Ethereum blockchain. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicBlockChainAPI struct { - config *core.ChainConfig - bc *core.BlockChain - chainDb ethdb.Database - eventMux *event.TypeMux - muNewBlockSubscriptions sync.Mutex // protects newBlocksSubscriptions - newBlockSubscriptions map[string]func(core.ChainEvent) error // callbacks for new block subscriptions - am *accounts.Manager - miner *miner.Miner - gpo *GasPriceOracle -} - -// NewPublicBlockChainAPI creates a new Etheruem blockchain API. -func NewPublicBlockChainAPI(config *core.ChainConfig, bc *core.BlockChain, m *miner.Miner, chainDb ethdb.Database, gpo *GasPriceOracle, eventMux *event.TypeMux, am *accounts.Manager) *PublicBlockChainAPI { - api := &PublicBlockChainAPI{ - config: config, - bc: bc, - miner: m, - chainDb: chainDb, - eventMux: eventMux, - am: am, - newBlockSubscriptions: make(map[string]func(core.ChainEvent) error), - gpo: gpo, - } - - go api.subscriptionLoop() - - return api -} - -// subscriptionLoop reads events from the global event mux and creates notifications for the matched subscriptions. -func (s *PublicBlockChainAPI) subscriptionLoop() { - sub := s.eventMux.Subscribe(core.ChainEvent{}) - for event := range sub.Chan() { - if chainEvent, ok := event.Data.(core.ChainEvent); ok { - s.muNewBlockSubscriptions.Lock() - for id, notifyOf := range s.newBlockSubscriptions { - if notifyOf(chainEvent) == rpc.ErrNotificationNotFound { - delete(s.newBlockSubscriptions, id) - } - } - s.muNewBlockSubscriptions.Unlock() - } - } -} - -// BlockNumber returns the block number of the chain head. -func (s *PublicBlockChainAPI) BlockNumber() *big.Int { - return s.bc.CurrentHeader().Number -} - -// GetBalance returns the amount of wei for the given address in the state of the -// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta -// block numbers are also allowed. -func (s *PublicBlockChainAPI) GetBalance(address common.Address, blockNr rpc.BlockNumber) (*big.Int, error) { - state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) - if state == nil || err != nil { - return nil, err - } - return state.GetBalance(address), nil -} - -// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all -// transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByNumber(blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { - if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { - response, err := s.rpcOutputBlock(block, true, fullTx) - if err == nil && blockNr == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "logsBloom", "miner"} { - response[field] = nil - } - } - return response, err - } - return nil, nil -} - -// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full -// detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByHash(blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { - if block := s.bc.GetBlockByHash(blockHash); block != nil { - return s.rpcOutputBlock(block, true, fullTx) - } - return nil, nil -} - -// GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true -// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(blockNr rpc.BlockNumber, index rpc.HexNumber) (map[string]interface{}, error) { - if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { - uncles := block.Uncles() - if index.Int() < 0 || index.Int() >= len(uncles) { - glog.V(logger.Debug).Infof("uncle block on index %d not found for block #%d", index.Int(), blockNr) - return nil, nil - } - block = types.NewBlockWithHeader(uncles[index.Int()]) - return s.rpcOutputBlock(block, false, false) - } - return nil, nil -} - -// GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true -// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(blockHash common.Hash, index rpc.HexNumber) (map[string]interface{}, error) { - if block := s.bc.GetBlockByHash(blockHash); block != nil { - uncles := block.Uncles() - if index.Int() < 0 || index.Int() >= len(uncles) { - glog.V(logger.Debug).Infof("uncle block on index %d not found for block %s", index.Int(), blockHash.Hex()) - return nil, nil - } - block = types.NewBlockWithHeader(uncles[index.Int()]) - return s.rpcOutputBlock(block, false, false) - } - return nil, nil -} - -// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number -func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(blockNr rpc.BlockNumber) *rpc.HexNumber { - if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { - return rpc.NewHexNumber(len(block.Uncles())) - } - return nil -} - -// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash -func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(blockHash common.Hash) *rpc.HexNumber { - if block := s.bc.GetBlockByHash(blockHash); block != nil { - return rpc.NewHexNumber(len(block.Uncles())) - } - return nil -} - -// NewBlocksArgs allows the user to specify if the returned block should include transactions and in which format. -type NewBlocksArgs struct { - IncludeTransactions bool `json:"includeTransactions"` - TransactionDetails bool `json:"transactionDetails"` -} - -// NewBlocks triggers a new block event each time a block is appended to the chain. It accepts an argument which allows -// the caller to specify whether the output should contain transactions and in what format. -func (s *PublicBlockChainAPI) NewBlocks(ctx context.Context, args NewBlocksArgs) (rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return nil, rpc.ErrNotificationsUnsupported - } - - // create a subscription that will remove itself when unsubscribed/cancelled - subscription, err := notifier.NewSubscription(func(subId string) { - s.muNewBlockSubscriptions.Lock() - delete(s.newBlockSubscriptions, subId) - s.muNewBlockSubscriptions.Unlock() - }) - - if err != nil { - return nil, err - } - - // add a callback that is called on chain events which will format the block and notify the client - s.muNewBlockSubscriptions.Lock() - s.newBlockSubscriptions[subscription.ID()] = func(e core.ChainEvent) error { - notification, err := s.rpcOutputBlock(e.Block, args.IncludeTransactions, args.TransactionDetails) - if err == nil { - return subscription.Notify(notification) - } - glog.V(logger.Warn).Info("unable to format block %v\n", err) - return nil - } - s.muNewBlockSubscriptions.Unlock() - return subscription, nil -} - -// GetCode returns the code stored at the given address in the state for the given block number. -func (s *PublicBlockChainAPI) GetCode(address common.Address, blockNr rpc.BlockNumber) (string, error) { - state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) - if state == nil || err != nil { - return "", err - } - res := state.GetCode(address) - if len(res) == 0 { // backwards compatibility - return "0x", nil - } - return common.ToHex(res), nil -} - -// GetStorageAt returns the storage from the state at the given address, key and -// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block -// numbers are also allowed. -func (s *PublicBlockChainAPI) GetStorageAt(address common.Address, key string, blockNr rpc.BlockNumber) (string, error) { - state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) - if state == nil || err != nil { - return "0x", err - } - return state.GetState(address, common.HexToHash(key)).Hex(), nil -} - -// callmsg is the message type used for call transactions. -type callmsg struct { - from *state.StateObject - to *common.Address - gas, gasPrice *big.Int - value *big.Int - data []byte -} - -// accessor boilerplate to implement core.Message -func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } -func (m callmsg) FromFrontier() (common.Address, error) { return m.from.Address(), nil } -func (m callmsg) Nonce() uint64 { return m.from.Nonce() } -func (m callmsg) To() *common.Address { return m.to } -func (m callmsg) GasPrice() *big.Int { return m.gasPrice } -func (m callmsg) Gas() *big.Int { return m.gas } -func (m callmsg) Value() *big.Int { return m.value } -func (m callmsg) Data() []byte { return m.data } - -// CallArgs represents the arguments for a call. -type CallArgs struct { - From common.Address `json:"from"` - To *common.Address `json:"to"` - Gas *rpc.HexNumber `json:"gas"` - GasPrice *rpc.HexNumber `json:"gasPrice"` - Value rpc.HexNumber `json:"value"` - Data string `json:"data"` -} - -func (s *PublicBlockChainAPI) doCall(args CallArgs, blockNr rpc.BlockNumber) (string, *big.Int, error) { - // Fetch the state associated with the block number - stateDb, block, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) - if stateDb == nil || err != nil { - return "0x", nil, err - } - stateDb = stateDb.Copy() - - // Retrieve the account state object to interact with - var from *state.StateObject - if args.From == (common.Address{}) { - accounts := s.am.Accounts() - if len(accounts) == 0 { - from = stateDb.GetOrNewStateObject(common.Address{}) - } else { - from = stateDb.GetOrNewStateObject(accounts[0].Address) - } - } else { - from = stateDb.GetOrNewStateObject(args.From) - } - from.SetBalance(common.MaxBig) - - // Assemble the CALL invocation - msg := callmsg{ - from: from, - to: args.To, - gas: args.Gas.BigInt(), - gasPrice: args.GasPrice.BigInt(), - value: args.Value.BigInt(), - data: common.FromHex(args.Data), - } - if msg.gas == nil { - msg.gas = big.NewInt(50000000) - } - if msg.gasPrice == nil { - msg.gasPrice = s.gpo.SuggestPrice() - } - - // Execute the call and return - vmenv := core.NewEnv(stateDb, s.config, s.bc, msg, block.Header(), s.config.VmConfig) - gp := new(core.GasPool).AddGas(common.MaxBig) - - res, requiredGas, _, err := core.NewStateTransition(vmenv, msg, gp).TransitionDb() - if len(res) == 0 { // backwards compatibility - return "0x", requiredGas, err - } - return common.ToHex(res), requiredGas, err -} - -// Call executes the given transaction on the state for the given block number. -// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values. -func (s *PublicBlockChainAPI) Call(args CallArgs, blockNr rpc.BlockNumber) (string, error) { - result, _, err := s.doCall(args, blockNr) - return result, err -} - -// EstimateGas returns an estimate of the amount of gas needed to execute the given transaction. -func (s *PublicBlockChainAPI) EstimateGas(args CallArgs) (*rpc.HexNumber, error) { - _, gas, err := s.doCall(args, rpc.PendingBlockNumber) - return rpc.NewHexNumber(gas), err -} - -// rpcOutputBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are -// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain -// transaction hashes. -func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { - fields := map[string]interface{}{ - "number": rpc.NewHexNumber(b.Number()), - "hash": b.Hash(), - "parentHash": b.ParentHash(), - "nonce": b.Header().Nonce, - "sha3Uncles": b.UncleHash(), - "logsBloom": b.Bloom(), - "stateRoot": b.Root(), - "miner": b.Coinbase(), - "difficulty": rpc.NewHexNumber(b.Difficulty()), - "totalDifficulty": rpc.NewHexNumber(s.bc.GetTd(b.Hash(), b.NumberU64())), - "extraData": fmt.Sprintf("0x%x", b.Extra()), - "size": rpc.NewHexNumber(b.Size().Int64()), - "gasLimit": rpc.NewHexNumber(b.GasLimit()), - "gasUsed": rpc.NewHexNumber(b.GasUsed()), - "timestamp": rpc.NewHexNumber(b.Time()), - "transactionsRoot": b.TxHash(), - "receiptRoot": b.ReceiptHash(), - } - - if inclTx { - formatTx := func(tx *types.Transaction) (interface{}, error) { - return tx.Hash(), nil - } - - if fullTx { - formatTx = func(tx *types.Transaction) (interface{}, error) { - return newRPCTransaction(b, tx.Hash()) - } - } - - txs := b.Transactions() - transactions := make([]interface{}, len(txs)) - var err error - for i, tx := range b.Transactions() { - if transactions[i], err = formatTx(tx); err != nil { - return nil, err - } - } - fields["transactions"] = transactions - } - - uncles := b.Uncles() - uncleHashes := make([]common.Hash, len(uncles)) - for i, uncle := range uncles { - uncleHashes[i] = uncle.Hash() - } - fields["uncles"] = uncleHashes - - return fields, nil -} - -// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction -type RPCTransaction struct { - BlockHash common.Hash `json:"blockHash"` - BlockNumber *rpc.HexNumber `json:"blockNumber"` - From common.Address `json:"from"` - Gas *rpc.HexNumber `json:"gas"` - GasPrice *rpc.HexNumber `json:"gasPrice"` - Hash common.Hash `json:"hash"` - Input string `json:"input"` - Nonce *rpc.HexNumber `json:"nonce"` - To *common.Address `json:"to"` - TransactionIndex *rpc.HexNumber `json:"transactionIndex"` - Value *rpc.HexNumber `json:"value"` -} - -// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation -func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { - from, _ := tx.FromFrontier() - - return &RPCTransaction{ - From: from, - Gas: rpc.NewHexNumber(tx.Gas()), - GasPrice: rpc.NewHexNumber(tx.GasPrice()), - Hash: tx.Hash(), - Input: fmt.Sprintf("0x%x", tx.Data()), - Nonce: rpc.NewHexNumber(tx.Nonce()), - To: tx.To(), - Value: rpc.NewHexNumber(tx.Value()), - } -} - -// newRPCTransaction returns a transaction that will serialize to the RPC representation. -func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransaction, error) { - if txIndex >= 0 && txIndex < len(b.Transactions()) { - tx := b.Transactions()[txIndex] - from, err := tx.FromFrontier() - if err != nil { - return nil, err - } - - return &RPCTransaction{ - BlockHash: b.Hash(), - BlockNumber: rpc.NewHexNumber(b.Number()), - From: from, - Gas: rpc.NewHexNumber(tx.Gas()), - GasPrice: rpc.NewHexNumber(tx.GasPrice()), - Hash: tx.Hash(), - Input: fmt.Sprintf("0x%x", tx.Data()), - Nonce: rpc.NewHexNumber(tx.Nonce()), - To: tx.To(), - TransactionIndex: rpc.NewHexNumber(txIndex), - Value: rpc.NewHexNumber(tx.Value()), - }, nil - } - - return nil, nil -} - -// newRPCTransaction returns a transaction that will serialize to the RPC representation. -func newRPCTransaction(b *types.Block, txHash common.Hash) (*RPCTransaction, error) { - for idx, tx := range b.Transactions() { - if tx.Hash() == txHash { - return newRPCTransactionFromBlockIndex(b, idx) - } - } - - return nil, nil -} - -// PublicTransactionPoolAPI exposes methods for the RPC interface -type PublicTransactionPoolAPI struct { - eventMux *event.TypeMux - chainDb ethdb.Database - gpo *GasPriceOracle - bc *core.BlockChain - miner *miner.Miner - am *accounts.Manager - txPool *core.TxPool - txMu *sync.Mutex - muPendingTxSubs sync.Mutex - pendingTxSubs map[string]rpc.Subscription -} - -// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. -func NewPublicTransactionPoolAPI(e *Ethereum) *PublicTransactionPoolAPI { - api := &PublicTransactionPoolAPI{ - eventMux: e.eventMux, - gpo: e.gpo, - chainDb: e.chainDb, - bc: e.blockchain, - am: e.accountManager, - txPool: e.txPool, - txMu: &e.txMu, - miner: e.miner, - pendingTxSubs: make(map[string]rpc.Subscription), - } - go api.subscriptionLoop() - - return api -} - -// subscriptionLoop listens for events on the global event mux and creates notifications for subscriptions. -func (s *PublicTransactionPoolAPI) subscriptionLoop() { - sub := s.eventMux.Subscribe(core.TxPreEvent{}) - for event := range sub.Chan() { - tx := event.Data.(core.TxPreEvent) - if from, err := tx.Tx.FromFrontier(); err == nil { - if s.am.HasAddress(from) { - s.muPendingTxSubs.Lock() - for id, sub := range s.pendingTxSubs { - if sub.Notify(tx.Tx.Hash()) == rpc.ErrNotificationNotFound { - delete(s.pendingTxSubs, id) - } - } - s.muPendingTxSubs.Unlock() - } - } - } -} - -func getTransaction(chainDb ethdb.Database, txPool *core.TxPool, txHash common.Hash) (*types.Transaction, bool, error) { - txData, err := chainDb.Get(txHash.Bytes()) - isPending := false - tx := new(types.Transaction) - - if err == nil && len(txData) > 0 { - if err := rlp.DecodeBytes(txData, tx); err != nil { - return nil, isPending, err - } - } else { - // pending transaction? - tx = txPool.GetTransaction(txHash) - isPending = true - } - - return tx, isPending, nil -} - -// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. -func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(blockNr rpc.BlockNumber) *rpc.HexNumber { - if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { - return rpc.NewHexNumber(len(block.Transactions())) - } - return nil -} - -// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. -func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(blockHash common.Hash) *rpc.HexNumber { - if block := s.bc.GetBlockByHash(blockHash); block != nil { - return rpc.NewHexNumber(len(block.Transactions())) - } - return nil -} - -// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. -func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(blockNr rpc.BlockNumber, index rpc.HexNumber) (*RPCTransaction, error) { - if block := blockByNumber(s.miner, s.bc, blockNr); block != nil { - return newRPCTransactionFromBlockIndex(block, index.Int()) - } - return nil, nil -} - -// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. -func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(blockHash common.Hash, index rpc.HexNumber) (*RPCTransaction, error) { - if block := s.bc.GetBlockByHash(blockHash); block != nil { - return newRPCTransactionFromBlockIndex(block, index.Int()) - } - return nil, nil -} - -// GetTransactionCount returns the number of transactions the given address has sent for the given block number -func (s *PublicTransactionPoolAPI) GetTransactionCount(address common.Address, blockNr rpc.BlockNumber) (*rpc.HexNumber, error) { - state, _, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) - if state == nil || err != nil { - return nil, err - } - return rpc.NewHexNumber(state.GetNonce(address)), nil -} - -// getTransactionBlockData fetches the meta data for the given transaction from the chain database. This is useful to -// retrieve block information for a hash. It returns the block hash, block index and transaction index. -func getTransactionBlockData(chainDb ethdb.Database, txHash common.Hash) (common.Hash, uint64, uint64, error) { - var txBlock struct { - BlockHash common.Hash - BlockIndex uint64 - Index uint64 - } - - blockData, err := chainDb.Get(append(txHash.Bytes(), 0x0001)) - if err != nil { - return common.Hash{}, uint64(0), uint64(0), err - } - - reader := bytes.NewReader(blockData) - if err = rlp.Decode(reader, &txBlock); err != nil { - return common.Hash{}, uint64(0), uint64(0), err - } - - return txBlock.BlockHash, txBlock.BlockIndex, txBlock.Index, nil -} - -// GetTransactionByHash returns the transaction for the given hash -func (s *PublicTransactionPoolAPI) GetTransactionByHash(txHash common.Hash) (*RPCTransaction, error) { - var tx *types.Transaction - var isPending bool - var err error - - if tx, isPending, err = getTransaction(s.chainDb, s.txPool, txHash); err != nil { - glog.V(logger.Debug).Infof("%v\n", err) - return nil, nil - } else if tx == nil { - return nil, nil - } - - if isPending { - return newRPCPendingTransaction(tx), nil - } - - blockHash, _, _, err := getTransactionBlockData(s.chainDb, txHash) - if err != nil { - glog.V(logger.Debug).Infof("%v\n", err) - return nil, nil - } - - if block := s.bc.GetBlockByHash(blockHash); block != nil { - return newRPCTransaction(block, txHash) - } - - return nil, nil -} - -// GetTransactionReceipt returns the transaction receipt for the given transaction hash. -func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error) { - receipt := core.GetReceipt(s.chainDb, txHash) - if receipt == nil { - glog.V(logger.Debug).Infof("receipt not found for transaction %s", txHash.Hex()) - return nil, nil - } - - tx, _, err := getTransaction(s.chainDb, s.txPool, txHash) - if err != nil { - glog.V(logger.Debug).Infof("%v\n", err) - return nil, nil - } - - txBlock, blockIndex, index, err := getTransactionBlockData(s.chainDb, txHash) - if err != nil { - glog.V(logger.Debug).Infof("%v\n", err) - return nil, nil - } - - from, err := tx.FromFrontier() - if err != nil { - glog.V(logger.Debug).Infof("%v\n", err) - return nil, nil - } - - fields := map[string]interface{}{ - "root": common.Bytes2Hex(receipt.PostState), - "blockHash": txBlock, - "blockNumber": rpc.NewHexNumber(blockIndex), - "transactionHash": txHash, - "transactionIndex": rpc.NewHexNumber(index), - "from": from, - "to": tx.To(), - "gasUsed": rpc.NewHexNumber(receipt.GasUsed), - "cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed), - "contractAddress": nil, - "logs": receipt.Logs, - } - - if receipt.Logs == nil { - fields["logs"] = []vm.Logs{} - } - - // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation - if bytes.Compare(receipt.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 { - fields["contractAddress"] = receipt.ContractAddress - } - - return fields, nil -} - -// sign is a helper function that signs a transaction with the private key of the given address. -func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { - signature, err := s.am.Sign(addr, tx.SigHash().Bytes()) - if err != nil { - return nil, err - } - return tx.WithSignature(signature) -} - -// SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. -type SendTxArgs struct { - From common.Address `json:"from"` - To *common.Address `json:"to"` - Gas *rpc.HexNumber `json:"gas"` - GasPrice *rpc.HexNumber `json:"gasPrice"` - Value *rpc.HexNumber `json:"value"` - Data string `json:"data"` - Nonce *rpc.HexNumber `json:"nonce"` -} - -// prepareSendTxArgs is a helper function that fills in default values for unspecified tx fields. -func prepareSendTxArgs(args SendTxArgs, gpo *GasPriceOracle) SendTxArgs { - if args.Gas == nil { - args.Gas = rpc.NewHexNumber(defaultGas) - } - if args.GasPrice == nil { - args.GasPrice = rpc.NewHexNumber(gpo.SuggestPrice()) - } - if args.Value == nil { - args.Value = rpc.NewHexNumber(0) - } - return args -} - -// submitTransaction is a helper function that submits tx to txPool and creates a log entry. -func submitTransaction(txPool *core.TxPool, tx *types.Transaction, signature []byte) (common.Hash, error) { - signedTx, err := tx.WithSignature(signature) - if err != nil { - return common.Hash{}, err - } - - txPool.SetLocal(signedTx) - if err := txPool.Add(signedTx); err != nil { - return common.Hash{}, err - } - - if signedTx.To() == nil { - from, _ := signedTx.From() - addr := crypto.CreateAddress(from, signedTx.Nonce()) - glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) - } else { - glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) - } - - return signedTx.Hash(), nil -} - -// SendTransaction creates a transaction for the given argument, sign it and submit it to the -// transaction pool. -func (s *PublicTransactionPoolAPI) SendTransaction(args SendTxArgs) (common.Hash, error) { - args = prepareSendTxArgs(args, s.gpo) - - s.txMu.Lock() - defer s.txMu.Unlock() - - if args.Nonce == nil { - args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) - } - - var tx *types.Transaction - if args.To == nil { - tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) - } else { - tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) - } - - signature, err := s.am.Sign(args.From, tx.SigHash().Bytes()) - if err != nil { - return common.Hash{}, err - } - - return submitTransaction(s.txPool, tx, signature) -} - -// SendRawTransaction will add the signed transaction to the transaction pool. -// The sender is responsible for signing the transaction and using the correct nonce. -func (s *PublicTransactionPoolAPI) SendRawTransaction(encodedTx string) (string, error) { - tx := new(types.Transaction) - if err := rlp.DecodeBytes(common.FromHex(encodedTx), tx); err != nil { - return "", err - } - - s.txPool.SetLocal(tx) - if err := s.txPool.Add(tx); err != nil { - return "", err - } - - if tx.To() == nil { - from, err := tx.FromFrontier() - if err != nil { - return "", err - } - addr := crypto.CreateAddress(from, tx.Nonce()) - glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) - } else { - glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) - } - - return tx.Hash().Hex(), nil -} - -// Sign signs the given hash using the key that matches the address. The key must be -// unlocked in order to sign the hash. -func (s *PublicTransactionPoolAPI) Sign(addr common.Address, hash common.Hash) (string, error) { - signature, error := s.am.Sign(addr, hash[:]) - return common.ToHex(signature), error -} - -// SignTransactionArgs represents the arguments to sign a transaction. -type SignTransactionArgs struct { - From common.Address - To *common.Address - Nonce *rpc.HexNumber - Value *rpc.HexNumber - Gas *rpc.HexNumber - GasPrice *rpc.HexNumber - Data string - - BlockNumber int64 -} - -// Tx is a helper object for argument and return values -type Tx struct { - tx *types.Transaction - - To *common.Address `json:"to"` - From common.Address `json:"from"` - Nonce *rpc.HexNumber `json:"nonce"` - Value *rpc.HexNumber `json:"value"` - Data string `json:"data"` - GasLimit *rpc.HexNumber `json:"gas"` - GasPrice *rpc.HexNumber `json:"gasPrice"` - Hash common.Hash `json:"hash"` -} - -// UnmarshalJSON parses JSON data into tx. -func (tx *Tx) UnmarshalJSON(b []byte) (err error) { - req := struct { - To *common.Address `json:"to"` - From common.Address `json:"from"` - Nonce *rpc.HexNumber `json:"nonce"` - Value *rpc.HexNumber `json:"value"` - Data string `json:"data"` - GasLimit *rpc.HexNumber `json:"gas"` - GasPrice *rpc.HexNumber `json:"gasPrice"` - Hash common.Hash `json:"hash"` - }{} - - if err := json.Unmarshal(b, &req); err != nil { - return err - } - - tx.To = req.To - tx.From = req.From - tx.Nonce = req.Nonce - tx.Value = req.Value - tx.Data = req.Data - tx.GasLimit = req.GasLimit - tx.GasPrice = req.GasPrice - tx.Hash = req.Hash - - data := common.Hex2Bytes(tx.Data) - - if tx.Nonce == nil { - return fmt.Errorf("need nonce") - } - if tx.Value == nil { - tx.Value = rpc.NewHexNumber(0) - } - if tx.GasLimit == nil { - tx.GasLimit = rpc.NewHexNumber(0) - } - if tx.GasPrice == nil { - tx.GasPrice = rpc.NewHexNumber(int64(50000000000)) - } - - if req.To == nil { - tx.tx = types.NewContractCreation(tx.Nonce.Uint64(), tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data) - } else { - tx.tx = types.NewTransaction(tx.Nonce.Uint64(), *tx.To, tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data) - } - - return nil -} - -// SignTransactionResult represents a RLP encoded signed transaction. -type SignTransactionResult struct { - Raw string `json:"raw"` - Tx *Tx `json:"tx"` -} - -func newTx(t *types.Transaction) *Tx { - from, _ := t.FromFrontier() - return &Tx{ - tx: t, - To: t.To(), - From: from, - Value: rpc.NewHexNumber(t.Value()), - Nonce: rpc.NewHexNumber(t.Nonce()), - Data: "0x" + common.Bytes2Hex(t.Data()), - GasLimit: rpc.NewHexNumber(t.Gas()), - GasPrice: rpc.NewHexNumber(t.GasPrice()), - Hash: t.Hash(), - } -} - -// SignTransaction will sign the given transaction with the from account. -// The node needs to have the private key of the account corresponding with -// the given from address and it needs to be unlocked. -func (s *PublicTransactionPoolAPI) SignTransaction(args SignTransactionArgs) (*SignTransactionResult, error) { - if args.Gas == nil { - args.Gas = rpc.NewHexNumber(defaultGas) - } - if args.GasPrice == nil { - args.GasPrice = rpc.NewHexNumber(s.gpo.SuggestPrice()) - } - if args.Value == nil { - args.Value = rpc.NewHexNumber(0) - } - - s.txMu.Lock() - defer s.txMu.Unlock() - - if args.Nonce == nil { - args.Nonce = rpc.NewHexNumber(s.txPool.State().GetNonce(args.From)) - } - - var tx *types.Transaction - if args.To == nil { - tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) - } else { - tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) - } - - signedTx, err := s.sign(args.From, tx) - if err != nil { - return nil, err - } - - data, err := rlp.EncodeToBytes(signedTx) - if err != nil { - return nil, err - } - - return &SignTransactionResult{"0x" + common.Bytes2Hex(data), newTx(signedTx)}, nil -} - -// PendingTransactions returns the transactions that are in the transaction pool and have a from address that is one of -// the accounts this node manages. -func (s *PublicTransactionPoolAPI) PendingTransactions() []*RPCTransaction { - pending := s.txPool.GetTransactions() - transactions := make([]*RPCTransaction, 0, len(pending)) - for _, tx := range pending { - from, _ := tx.FromFrontier() - if s.am.HasAddress(from) { - transactions = append(transactions, newRPCPendingTransaction(tx)) - } - } - return transactions -} - -// NewPendingTransactions creates a subscription that is triggered each time a transaction enters the transaction pool -// and is send from one of the transactions this nodes manages. -func (s *PublicTransactionPoolAPI) NewPendingTransactions(ctx context.Context) (rpc.Subscription, error) { - notifier, supported := rpc.NotifierFromContext(ctx) - if !supported { - return nil, rpc.ErrNotificationsUnsupported - } - - subscription, err := notifier.NewSubscription(func(id string) { - s.muPendingTxSubs.Lock() - delete(s.pendingTxSubs, id) - s.muPendingTxSubs.Unlock() - }) - - if err != nil { - return nil, err - } - - s.muPendingTxSubs.Lock() - s.pendingTxSubs[subscription.ID()] = subscription - s.muPendingTxSubs.Unlock() - - return subscription, nil -} - -// Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the -// pool and reinsert it with the new gas price and limit. -func (s *PublicTransactionPoolAPI) Resend(tx Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) { - - pending := s.txPool.GetTransactions() - for _, p := range pending { - if pFrom, err := p.FromFrontier(); err == nil && pFrom == tx.From && p.SigHash() == tx.tx.SigHash() { - if gasPrice == nil { - gasPrice = rpc.NewHexNumber(tx.tx.GasPrice()) - } - if gasLimit == nil { - gasLimit = rpc.NewHexNumber(tx.tx.Gas()) - } - - var newTx *types.Transaction - if tx.tx.To() == nil { - newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) - } else { - newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) - } - - signedTx, err := s.sign(tx.From, newTx) - if err != nil { - return common.Hash{}, err - } - - s.txPool.RemoveTx(tx.Hash) - if err = s.txPool.Add(signedTx); err != nil { - return common.Hash{}, err - } - - return signedTx.Hash(), nil - } - } - - return common.Hash{}, fmt.Errorf("Transaction %#x not found", tx.Hash) -} - -// PrivateAdminAPI is the collection of Etheruem APIs exposed over the private -// admin endpoint. +// PrivateAdminAPI is the collection of Etheruem full node-related APIs +// exposed over the private admin endpoint. type PrivateAdminAPI struct { eth *Ethereum } -// NewPrivateAdminAPI creates a new API definition for the private admin methods -// of the Ethereum service. +// NewPrivateAdminAPI creates a new API definition for the full node private +// admin methods of the Ethereum service. func NewPrivateAdminAPI(eth *Ethereum) *PrivateAdminAPI { return &PrivateAdminAPI{eth: eth} } -// SetSolc sets the Solidity compiler path to be used by the node. -func (api *PrivateAdminAPI) SetSolc(path string) (string, error) { - solc, err := api.eth.SetSolc(path) - if err != nil { - return "", err - } - return solc.Info(), nil -} - // ExportChain exports the current blockchain into a local file. func (api *PrivateAdminAPI) ExportChain(file string) (bool, error) { // Make sure we can create the file to export into @@ -1562,14 +271,14 @@ func (api *PrivateAdminAPI) ImportChain(file string) (bool, error) { return true, nil } -// PublicDebugAPI is the collection of Etheruem APIs exposed over the public -// debugging endpoint. +// PublicDebugAPI is the collection of Etheruem full node APIs exposed +// over the public debugging endpoint. type PublicDebugAPI struct { eth *Ethereum } -// NewPublicDebugAPI creates a new API definition for the public debug methods -// of the Ethereum service. +// NewPublicDebugAPI creates a new API definition for the full node- +// related public debug methods of the Ethereum service. func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { return &PublicDebugAPI{eth: eth} } @@ -1587,76 +296,25 @@ func (api *PublicDebugAPI) DumpBlock(number uint64) (state.World, error) { return stateDb.RawDump(), nil } -// GetBlockRlp retrieves the RLP encoded for of a single block. -func (api *PublicDebugAPI) GetBlockRlp(number uint64) (string, error) { - block := api.eth.BlockChain().GetBlockByNumber(number) - if block == nil { - return "", fmt.Errorf("block #%d not found", number) - } - encoded, err := rlp.EncodeToBytes(block) - if err != nil { - return "", err - } - return fmt.Sprintf("%x", encoded), nil -} - -// PrintBlock retrieves a block and returns its pretty printed form. -func (api *PublicDebugAPI) PrintBlock(number uint64) (string, error) { - block := api.eth.BlockChain().GetBlockByNumber(number) - if block == nil { - return "", fmt.Errorf("block #%d not found", number) - } - return fmt.Sprintf("%s", block), nil -} - -// SeedHash retrieves the seed hash of a block. -func (api *PublicDebugAPI) SeedHash(number uint64) (string, error) { - block := api.eth.BlockChain().GetBlockByNumber(number) - if block == nil { - return "", fmt.Errorf("block #%d not found", number) - } - hash, err := ethash.GetSeedHash(number) - if err != nil { - return "", err - } - return fmt.Sprintf("0x%x", hash), nil -} - -// PrivateDebugAPI is the collection of Etheruem APIs exposed over the private -// debugging endpoint. +// PrivateDebugAPI is the collection of Etheruem full node APIs exposed over +// the private debugging endpoint. type PrivateDebugAPI struct { config *core.ChainConfig eth *Ethereum } -// NewPrivateDebugAPI creates a new API definition for the private debug methods -// of the Ethereum service. +// NewPrivateDebugAPI creates a new API definition for the full node-related +// private debug methods of the Ethereum service. func NewPrivateDebugAPI(config *core.ChainConfig, eth *Ethereum) *PrivateDebugAPI { return &PrivateDebugAPI{config: config, eth: eth} } -// ChaindbProperty returns leveldb properties of the chain database. -func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { - ldb, ok := api.eth.chainDb.(interface { - LDB() *leveldb.DB - }) - if !ok { - return "", fmt.Errorf("chaindbProperty does not work for memory databases") - } - if property == "" { - property = "leveldb.stats" - } else if !strings.HasPrefix(property, "leveldb.") { - property = "leveldb." + property - } - return ldb.LDB().GetProperty(property) -} - // BlockTraceResult is the returned value when replaying a block to check for // consensus results and full VM trace logs for all included transactions. type BlockTraceResult struct { - Validated bool `json:"validated"` - StructLogs []structLogRes `json:"structLogs"` - Error string `json:"error"` + Validated bool `json:"validated"` + StructLogs []ethapi.StructLogRes `json:"structLogs"` + Error string `json:"error"` } // TraceBlock processes the given block's RLP but does not import the block in to @@ -1671,7 +329,7 @@ func (api *PrivateDebugAPI) TraceBlock(blockRlp []byte, config *vm.Config) Block validated, logs, err := api.traceBlock(&block, config) return BlockTraceResult{ Validated: validated, - StructLogs: formatLogs(logs), + StructLogs: ethapi.FormatLogs(logs), Error: formatError(err), } } @@ -1697,7 +355,7 @@ func (api *PrivateDebugAPI) TraceBlockByNumber(number uint64, config *vm.Config) validated, logs, err := api.traceBlock(block, config) return BlockTraceResult{ Validated: validated, - StructLogs: formatLogs(logs), + StructLogs: ethapi.FormatLogs(logs), Error: formatError(err), } } @@ -1713,7 +371,7 @@ func (api *PrivateDebugAPI) TraceBlockByHash(hash common.Hash, config *vm.Config validated, logs, err := api.traceBlock(block, config) return BlockTraceResult{ Validated: validated, - StructLogs: formatLogs(logs), + StructLogs: ethapi.FormatLogs(logs), Error: formatError(err), } } @@ -1763,63 +421,25 @@ func (api *PrivateDebugAPI) traceBlock(block *types.Block, config *vm.Config) (b return true, collector.traces, nil } -// SetHead rewinds the head of the blockchain to a previous block. -func (api *PrivateDebugAPI) SetHead(number uint64) { - api.eth.BlockChain().SetHead(number) -} - -// ExecutionResult groups all structured logs emitted by the EVM -// while replaying a transaction in debug mode as well as the amount of -// gas used and the return value -type ExecutionResult struct { - Gas *big.Int `json:"gas"` - ReturnValue string `json:"returnValue"` - StructLogs []structLogRes `json:"structLogs"` -} - -// structLogRes stores a structured log emitted by the EVM while replaying a -// transaction in debug mode -type structLogRes struct { - Pc uint64 `json:"pc"` - Op string `json:"op"` - Gas *big.Int `json:"gas"` - GasCost *big.Int `json:"gasCost"` - Depth int `json:"depth"` - Error string `json:"error"` - Stack []string `json:"stack"` - Memory []string `json:"memory"` - Storage map[string]string `json:"storage"` +// callmsg is the message type used for call transations. +type callmsg struct { + addr common.Address + to *common.Address + gas, gasPrice *big.Int + value *big.Int + data []byte } -// formatLogs formats EVM returned structured logs for json output -func formatLogs(structLogs []vm.StructLog) []structLogRes { - formattedStructLogs := make([]structLogRes, len(structLogs)) - for index, trace := range structLogs { - formattedStructLogs[index] = structLogRes{ - Pc: trace.Pc, - Op: trace.Op.String(), - Gas: trace.Gas, - GasCost: trace.GasCost, - Depth: trace.Depth, - Error: formatError(trace.Err), - Stack: make([]string, len(trace.Stack)), - Storage: make(map[string]string), - } - - for i, stackValue := range trace.Stack { - formattedStructLogs[index].Stack[i] = fmt.Sprintf("%x", common.LeftPadBytes(stackValue.Bytes(), 32)) - } - - for i := 0; i+32 <= len(trace.Memory); i += 32 { - formattedStructLogs[index].Memory = append(formattedStructLogs[index].Memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) - } - - for i, storageValue := range trace.Storage { - formattedStructLogs[index].Storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) - } - } - return formattedStructLogs -} +// accessor boilerplate to implement core.Message +func (m callmsg) From() (common.Address, error) { return m.addr, nil } +func (m callmsg) FromFrontier() (common.Address, error) { return m.addr, nil } +func (m callmsg) Nonce() uint64 { return 0 } +func (m callmsg) CheckNonce() bool { return false } +func (m callmsg) To() *common.Address { return m.to } +func (m callmsg) GasPrice() *big.Int { return m.gasPrice } +func (m callmsg) Gas() *big.Int { return m.gas } +func (m callmsg) Value() *big.Int { return m.value } +func (m callmsg) Data() []byte { return m.data } // formatError formats a Go error into either an empty string or the data content // of the error itself. @@ -1832,7 +452,7 @@ func formatError(err error) string { // TraceTransaction returns the structured logs created during the execution of EVM // and returns them as a JSON object. -func (api *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogConfig) (*ExecutionResult, error) { +func (api *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogConfig) (*ethapi.ExecutionResult, error) { if logger == nil { logger = new(vm.LogConfig) } @@ -1862,7 +482,7 @@ func (api *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogC return nil, fmt.Errorf("sender retrieval failed: %v", err) } msg := callmsg{ - from: stateDb.GetOrNewStateObject(from), + addr: from, to: tx.To(), gas: tx.Gas(), gasPrice: tx.GasPrice(), @@ -1885,90 +505,11 @@ func (api *PrivateDebugAPI) TraceTransaction(txHash common.Hash, logger *vm.LogC if err != nil { return nil, fmt.Errorf("tracing failed: %v", err) } - return &ExecutionResult{ + return ðapi.ExecutionResult{ Gas: gas, ReturnValue: fmt.Sprintf("%x", ret), - StructLogs: formatLogs(vmenv.StructLogs()), + StructLogs: ethapi.FormatLogs(vmenv.StructLogs()), }, nil } return nil, errors.New("database inconsistency") } - -// TraceCall executes a call and returns the amount of gas, created logs and optionally returned values. -func (s *PublicBlockChainAPI) TraceCall(args CallArgs, blockNr rpc.BlockNumber) (*ExecutionResult, error) { - // Fetch the state associated with the block number - stateDb, block, err := stateAndBlockByNumber(s.miner, s.bc, blockNr, s.chainDb) - if stateDb == nil || err != nil { - return nil, err - } - stateDb = stateDb.Copy() - - // Retrieve the account state object to interact with - var from *state.StateObject - if args.From == (common.Address{}) { - accounts := s.am.Accounts() - if len(accounts) == 0 { - from = stateDb.GetOrNewStateObject(common.Address{}) - } else { - from = stateDb.GetOrNewStateObject(accounts[0].Address) - } - } else { - from = stateDb.GetOrNewStateObject(args.From) - } - from.SetBalance(common.MaxBig) - - // Assemble the CALL invocation - msg := callmsg{ - from: from, - to: args.To, - gas: args.Gas.BigInt(), - gasPrice: args.GasPrice.BigInt(), - value: args.Value.BigInt(), - data: common.FromHex(args.Data), - } - if msg.gas.Cmp(common.Big0) == 0 { - msg.gas = big.NewInt(50000000) - } - if msg.gasPrice.Cmp(common.Big0) == 0 { - msg.gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) - } - - // Execute the call and return - vmenv := core.NewEnv(stateDb, s.config, s.bc, msg, block.Header(), vm.Config{ - Debug: true, - }) - gp := new(core.GasPool).AddGas(common.MaxBig) - - ret, gas, err := core.ApplyMessage(vmenv, msg, gp) - return &ExecutionResult{ - Gas: gas, - ReturnValue: fmt.Sprintf("%x", ret), - StructLogs: formatLogs(vmenv.StructLogs()), - }, nil -} - -// PublicNetAPI offers network related RPC methods -type PublicNetAPI struct { - net *p2p.Server - networkVersion int -} - -// NewPublicNetAPI creates a new net API instance. -func NewPublicNetAPI(net *p2p.Server, networkVersion int) *PublicNetAPI { - return &PublicNetAPI{net, networkVersion} -} - -// Listening returns an indication if the node is listening for network connections. -func (s *PublicNetAPI) Listening() bool { - return true // always listening -} - -// PeerCount returns the number of connected peers -func (s *PublicNetAPI) PeerCount() *rpc.HexNumber { - return rpc.NewHexNumber(s.net.PeerCount()) -} - -// Version returns the current ethereum protocol version. -func (s *PublicNetAPI) Version() string { - return fmt.Sprintf("%d", s.networkVersion) -} diff --git a/eth/api_backend.go b/eth/api_backend.go new file mode 100644 index 000000000..efcdb3361 --- /dev/null +++ b/eth/api_backend.go @@ -0,0 +1,201 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. + +package eth + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "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/eth/downloader" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" + rpc "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/context" +) + +// EthApiBackend implements ethapi.Backend for full nodes +type EthApiBackend struct { + eth *Ethereum + gpo *gasprice.GasPriceOracle +} + +func (b *EthApiBackend) SetHead(number uint64) { + b.eth.blockchain.SetHead(number) +} + +func (b *EthApiBackend) HeaderByNumber(blockNr rpc.BlockNumber) *types.Header { + // Pending block is only known by the miner + if blockNr == rpc.PendingBlockNumber { + block, _ := b.eth.miner.Pending() + return block.Header() + } + // Otherwise resolve and return the block + if blockNr == rpc.LatestBlockNumber { + return b.eth.blockchain.CurrentBlock().Header() + } + return b.eth.blockchain.GetHeaderByNumber(uint64(blockNr)) +} + +func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) { + // Pending block is only known by the miner + if blockNr == rpc.PendingBlockNumber { + block, _ := b.eth.miner.Pending() + return block, nil + } + // Otherwise resolve and return the block + if blockNr == rpc.LatestBlockNumber { + return b.eth.blockchain.CurrentBlock(), nil + } + return b.eth.blockchain.GetBlockByNumber(uint64(blockNr)), nil +} + +func (b *EthApiBackend) StateAndHeaderByNumber(blockNr rpc.BlockNumber) (ethapi.State, *types.Header, error) { + // Pending state is only known by the miner + if blockNr == rpc.PendingBlockNumber { + block, state := b.eth.miner.Pending() + return EthApiState{state}, block.Header(), nil + } + // Otherwise resolve the block number and return its state + header := b.HeaderByNumber(blockNr) + if header == nil { + return nil, nil, nil + } + stateDb, err := state.New(header.Root, b.eth.chainDb) + return EthApiState{stateDb}, header, err +} + +func (b *EthApiBackend) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) { + return b.eth.blockchain.GetBlockByHash(blockHash), nil +} + +func (b *EthApiBackend) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) { + return core.GetBlockReceipts(b.eth.chainDb, blockHash, core.GetBlockNumber(b.eth.chainDb, blockHash)), nil +} + +func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int { + return b.eth.blockchain.GetTdByHash(blockHash) +} + +func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (vm.Environment, func() error, error) { + stateDb := state.(EthApiState).state.Copy() + addr, _ := msg.From() + from := stateDb.GetOrNewStateObject(addr) + from.SetBalance(common.MaxBig) + vmError := func() error { return nil } + return core.NewEnv(stateDb, b.eth.chainConfig, b.eth.blockchain, msg, header, b.eth.chainConfig.VmConfig), vmError, nil +} + +func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + b.eth.txPool.SetLocal(signedTx) + return b.eth.txPool.Add(signedTx) +} + +func (b *EthApiBackend) RemoveTx(txHash common.Hash) { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + b.eth.txPool.RemoveTx(txHash) +} + +func (b *EthApiBackend) GetPoolTransactions() types.Transactions { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + return b.eth.txPool.GetTransactions() +} + +func (b *EthApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + return b.eth.txPool.GetTransaction(txHash) +} + +func (b *EthApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + return b.eth.txPool.State().GetNonce(addr), nil +} + +func (b *EthApiBackend) Stats() (pending int, queued int) { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + return b.eth.txPool.Stats() +} + +func (b *EthApiBackend) TxPoolContent() (map[common.Address]map[uint64][]*types.Transaction, map[common.Address]map[uint64][]*types.Transaction) { + b.eth.txMu.Lock() + defer b.eth.txMu.Unlock() + + return b.eth.TxPool().Content() +} + +func (b *EthApiBackend) Downloader() *downloader.Downloader { + return b.eth.Downloader() +} + +func (b *EthApiBackend) ProtocolVersion() int { + return b.eth.EthVersion() +} + +func (b *EthApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) { + return b.gpo.SuggestPrice(), nil +} + +func (b *EthApiBackend) ChainDb() ethdb.Database { + return b.eth.ChainDb() +} + +func (b *EthApiBackend) EventMux() *event.TypeMux { + return b.eth.EventMux() +} + +func (b *EthApiBackend) AccountManager() *accounts.Manager { + return b.eth.AccountManager() +} + +type EthApiState struct { + state *state.StateDB +} + +func (s EthApiState) GetBalance(ctx context.Context, addr common.Address) (*big.Int, error) { + return s.state.GetBalance(addr), nil +} + +func (s EthApiState) GetCode(ctx context.Context, addr common.Address) ([]byte, error) { + return s.state.GetCode(addr), nil +} + +func (s EthApiState) GetState(ctx context.Context, a common.Address, b common.Hash) (common.Hash, error) { + return s.state.GetState(a, b), nil +} + +func (s EthApiState) GetNonce(ctx context.Context, addr common.Address) (uint64, error) { + return s.state.GetNonce(addr), nil +} diff --git a/eth/backend.go b/eth/backend.go index 006523484..c8a9af6ee 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -39,8 +39,10 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/miner" @@ -101,95 +103,86 @@ type Config struct { TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!) } +// Ethereum implements the Ethereum full node service. type Ethereum struct { - chainConfig *core.ChainConfig + chainConfig *core.ChainConfig + // Channel for shutting down the service shutdownChan chan bool // Channel for shutting down the ethereum stopDbUpgrade func() // stop chain db sequential key upgrade - - // DB interfaces - chainDb ethdb.Database // Block chain database - dappDb ethdb.Database // Dapp database - // Handlers txPool *core.TxPool txMu sync.Mutex blockchain *core.BlockChain - accountManager *accounts.Manager - pow *ethash.Ethash protocolManager *ProtocolManager - SolcPath string - solc *compiler.Solidity - gpo *GasPriceOracle + // DB interfaces + chainDb ethdb.Database // Block chain database + dappDb ethdb.Database // Dapp database - GpoMinGasPrice *big.Int - GpoMaxGasPrice *big.Int - GpoFullBlockRatio int - GpobaseStepDown int - GpobaseStepUp int - GpobaseCorrectionFactor int + eventMux *event.TypeMux + pow *ethash.Ethash + httpclient *httpclient.HTTPClient + accountManager *accounts.Manager - httpclient *httpclient.HTTPClient + apiBackend *EthApiBackend - eventMux *event.TypeMux - miner *miner.Miner + miner *miner.Miner + Mining bool + MinerThreads int + AutoDAG bool + autodagquit chan bool + etherbase common.Address + solcPath string + solc *compiler.Solidity - Mining bool - MinerThreads int NatSpec bool - AutoDAG bool PowTest bool - autodagquit chan bool - etherbase common.Address netVersionId int - netRPCService *PublicNetAPI + netRPCService *ethapi.PublicNetAPI } +// New creates a new Ethereum object (including the +// initialisation of the common Ethereum object) func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { - // Open the chain database and perform any upgrades needed - chainDb, err := ctx.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles) + chainDb, dappDb, err := CreateDBs(ctx, config) if err != nil { return nil, err } - if db, ok := chainDb.(*ethdb.LDBDatabase); ok { - db.Meter("eth/db/chaindata/") - } - if err := upgradeChainDatabase(chainDb); err != nil { - return nil, err - } - if err := addMipmapBloomBins(chainDb); err != nil { + stopDbUpgrade := upgradeSequentialKeys(chainDb) + if err := SetupGenesisBlock(&chainDb, config); err != nil { return nil, err } - stopDbUpgrade := upgradeSequentialKeys(chainDb) - - dappDb, err := ctx.OpenDatabase("dapp", config.DatabaseCache, config.DatabaseHandles) + pow, err := CreatePoW(config) if err != nil { return nil, err } - if db, ok := dappDb.(*ethdb.LDBDatabase); ok { - db.Meter("eth/db/dapp/") - } - glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) - // Load up any custom genesis block if requested - if len(config.Genesis) > 0 { - block, err := core.WriteGenesisBlock(chainDb, strings.NewReader(config.Genesis)) - if err != nil { - return nil, err - } - glog.V(logger.Info).Infof("Successfully wrote custom genesis block: %x", block.Hash()) + eth := &Ethereum{ + chainDb: chainDb, + dappDb: dappDb, + eventMux: ctx.EventMux, + accountManager: config.AccountManager, + pow: pow, + shutdownChan: make(chan bool), + stopDbUpgrade: stopDbUpgrade, + httpclient: httpclient.New(config.DocRoot), + netVersionId: config.NetworkId, + NatSpec: config.NatSpec, + PowTest: config.PowTest, + etherbase: config.Etherbase, + MinerThreads: config.MinerThreads, + AutoDAG: config.AutoDAG, + solcPath: config.SolcPath, } - // Load up a test setup if directly injected - if config.TestGenesisState != nil { - chainDb = config.TestGenesisState + if err := upgradeChainDatabase(chainDb); err != nil { + return nil, err } - if config.TestGenesisBlock != nil { - core.WriteTd(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty()) - core.WriteBlock(chainDb, config.TestGenesisBlock) - core.WriteCanonicalHash(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64()) - core.WriteHeadBlockHash(chainDb, config.TestGenesisBlock.Hash()) + if err := addMipmapBloomBins(chainDb); err != nil { + return nil, err } + glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId) + if !config.SkipBcVersionCheck { bcVersion := core.GetBlockChainVersion(chainDb) if bcVersion != config.BlockChainVersion && bcVersion != 0 { @@ -197,44 +190,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } core.WriteBlockChainVersion(chainDb, config.BlockChainVersion) } - glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion) - - eth := &Ethereum{ - shutdownChan: make(chan bool), - stopDbUpgrade: stopDbUpgrade, - chainDb: chainDb, - dappDb: dappDb, - eventMux: ctx.EventMux, - accountManager: config.AccountManager, - etherbase: config.Etherbase, - netVersionId: config.NetworkId, - NatSpec: config.NatSpec, - MinerThreads: config.MinerThreads, - SolcPath: config.SolcPath, - AutoDAG: config.AutoDAG, - PowTest: config.PowTest, - GpoMinGasPrice: config.GpoMinGasPrice, - GpoMaxGasPrice: config.GpoMaxGasPrice, - GpoFullBlockRatio: config.GpoFullBlockRatio, - GpobaseStepDown: config.GpobaseStepDown, - GpobaseStepUp: config.GpobaseStepUp, - GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, - httpclient: httpclient.New(config.DocRoot), - } - switch { - case config.PowTest: - glog.V(logger.Info).Infof("ethash used in test mode") - eth.pow, err = ethash.NewForTesting() - if err != nil { - return nil, err - } - case config.PowShared: - glog.V(logger.Info).Infof("ethash used in shared mode") - eth.pow = ethash.NewShared() - - default: - eth.pow = ethash.New() - } // load the genesis block or write a new one if no genesis // block is prenent in the database. @@ -250,6 +205,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { if config.ChainConfig == nil { return nil, errors.New("missing chain config") } + core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig) + eth.chainConfig = config.ChainConfig eth.chainConfig.VmConfig = vm.Config{ EnableJit: config.EnableJit, @@ -263,8 +220,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } return nil, err } - eth.gpo = NewGasPriceOracle(eth) - newPool := core.NewTxPool(eth.chainConfig, eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit) eth.txPool = newPool @@ -275,13 +230,83 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { eth.miner.SetGasPrice(config.GasPrice) eth.miner.SetExtra(config.ExtraData) + gpoParams := &gasprice.GpoParams{ + GpoMinGasPrice: config.GpoMinGasPrice, + GpoMaxGasPrice: config.GpoMaxGasPrice, + GpoFullBlockRatio: config.GpoFullBlockRatio, + GpobaseStepDown: config.GpobaseStepDown, + GpobaseStepUp: config.GpobaseStepUp, + GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, + } + gpo := gasprice.NewGasPriceOracle(eth.blockchain, chainDb, eth.eventMux, gpoParams) + eth.apiBackend = &EthApiBackend{eth, gpo} + return eth, nil } +// CreateDBs creates the chain and dapp databases for an Ethereum service +func CreateDBs(ctx *node.ServiceContext, config *Config) (chainDb, dappDb ethdb.Database, err error) { + // Open the chain database and perform any upgrades needed + chainDb, err = ctx.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles) + if err != nil { + return nil, nil, err + } + if db, ok := chainDb.(*ethdb.LDBDatabase); ok { + db.Meter("eth/db/chaindata/") + } + + dappDb, err = ctx.OpenDatabase("dapp", config.DatabaseCache, config.DatabaseHandles) + if err != nil { + return nil, nil, err + } + if db, ok := dappDb.(*ethdb.LDBDatabase); ok { + db.Meter("eth/db/dapp/") + } + return +} + +// SetupGenesisBlock initializes the genesis block for an Ethereum service +func SetupGenesisBlock(chainDb *ethdb.Database, config *Config) error { + // Load up any custom genesis block if requested + if len(config.Genesis) > 0 { + block, err := core.WriteGenesisBlock(*chainDb, strings.NewReader(config.Genesis)) + if err != nil { + return err + } + glog.V(logger.Info).Infof("Successfully wrote custom genesis block: %x", block.Hash()) + } + // Load up a test setup if directly injected + if config.TestGenesisState != nil { + *chainDb = config.TestGenesisState + } + if config.TestGenesisBlock != nil { + core.WriteTd(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty()) + core.WriteBlock(*chainDb, config.TestGenesisBlock) + core.WriteCanonicalHash(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64()) + core.WriteHeadBlockHash(*chainDb, config.TestGenesisBlock.Hash()) + } + return nil +} + +// CreatePoW creates the required type of PoW instance for an Ethereum service +func CreatePoW(config *Config) (*ethash.Ethash, error) { + switch { + case config.PowTest: + glog.V(logger.Info).Infof("ethash used in test mode") + return ethash.NewForTesting() + case config.PowShared: + glog.V(logger.Info).Infof("ethash used in shared mode") + return ethash.NewShared(), nil + + default: + return ethash.New(), nil + } +} + // APIs returns the collection of RPC services the ethereum package offers. // NOTE, some of these services probably need to be moved to somewhere else. func (s *Ethereum) APIs() []rpc.API { - return []rpc.API{ + return append(ethapi.GetAPIs(s.apiBackend, &s.solcPath, &s.solc), []rpc.API{ { Namespace: "eth", Version: "1.0", @@ -290,26 +315,6 @@ func (s *Ethereum) APIs() []rpc.API { }, { Namespace: "eth", Version: "1.0", - Service: NewPublicAccountAPI(s.accountManager), - Public: true, - }, { - Namespace: "personal", - Version: "1.0", - Service: NewPrivateAccountAPI(s), - Public: false, - }, { - Namespace: "eth", - Version: "1.0", - Service: NewPublicBlockChainAPI(s.chainConfig, s.blockchain, s.miner, s.chainDb, s.gpo, s.eventMux, s.accountManager), - Public: true, - }, { - Namespace: "eth", - Version: "1.0", - Service: NewPublicTransactionPoolAPI(s), - Public: true, - }, { - Namespace: "eth", - Version: "1.0", Service: NewPublicMinerAPI(s), Public: true, }, { @@ -323,11 +328,6 @@ func (s *Ethereum) APIs() []rpc.API { Service: NewPrivateMinerAPI(s), Public: false, }, { - Namespace: "txpool", - Version: "1.0", - Service: NewPublicTxPoolAPI(s), - Public: true, - }, { Namespace: "eth", Version: "1.0", Service: filters.NewPublicFilterAPI(s.chainDb, s.eventMux), @@ -355,7 +355,7 @@ func (s *Ethereum) APIs() []rpc.API { Version: "1.0", Service: ethreg.NewPrivateRegistarAPI(s.chainConfig, s.blockchain, s.chainDb, s.txPool, s.accountManager), }, - } + }...) } func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { @@ -388,6 +388,7 @@ func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } +func (s *Ethereum) Pow() *ethash.Ethash { return s.pow } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } func (s *Ethereum) DappDb() ethdb.Database { return s.dappDb } func (s *Ethereum) IsListening() bool { return true } // Always listening @@ -404,11 +405,11 @@ func (s *Ethereum) Protocols() []p2p.Protocol { // Start implements node.Service, starting all internal goroutines needed by the // Ethereum protocol implementation. func (s *Ethereum) Start(srvr *p2p.Server) error { + s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.NetVersion()) if s.AutoDAG { s.StartAutoDAG() } s.protocolManager.Start() - s.netRPCService = NewPublicNetAPI(srvr, s.NetVersion()) return nil } @@ -507,21 +508,6 @@ func (self *Ethereum) HTTPClient() *httpclient.HTTPClient { return self.httpclient } -func (self *Ethereum) Solc() (*compiler.Solidity, error) { - var err error - if self.solc == nil { - self.solc, err = compiler.New(self.SolcPath) - } - return self.solc, err -} - -// set in js console via admin interface or wrapper from cli flags -func (self *Ethereum) SetSolc(solcPath string) (*compiler.Solidity, error) { - self.SolcPath = solcPath - self.solc = nil - return self.Solc() -} - // dagFiles(epoch) returns the two alternative DAG filenames (not a path) // 1) <revision>-<hex(seedhash[8])> 2) full-R<revision>-<hex(seedhash[8])> func dagFiles(epoch uint64) (string, string) { diff --git a/eth/backend_test.go b/eth/backend_test.go index cb94adbf0..105d71080 100644 --- a/eth/backend_test.go +++ b/eth/backend_test.go @@ -32,7 +32,7 @@ func TestMipmapUpgrade(t *testing.T) { addr := common.BytesToAddress([]byte("jeff")) genesis := core.WriteGenesisBlockForTesting(db) - chain, receipts := core.GenerateChain(genesis, db, 10, func(i int, gen *core.BlockGen) { + chain, receipts := core.GenerateChain(nil, genesis, db, 10, func(i int, gen *core.BlockGen) { var receipts types.Receipts switch i { case 1: diff --git a/eth/bind.go b/eth/bind.go index fb7f29f60..c1366464f 100644 --- a/eth/bind.go +++ b/eth/bind.go @@ -21,8 +21,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/context" ) // ContractBackend implements bind.ContractBackend with direct calls to Ethereum @@ -33,38 +35,44 @@ import ( // object. These should be rewritten to internal Go method calls when the Go API // is refactored to support a clean library use. type ContractBackend struct { - eapi *PublicEthereumAPI // Wrapper around the Ethereum object to access metadata - bcapi *PublicBlockChainAPI // Wrapper around the blockchain to access chain data - txapi *PublicTransactionPoolAPI // Wrapper around the transaction pool to access transaction data + eapi *ethapi.PublicEthereumAPI // Wrapper around the Ethereum object to access metadata + bcapi *ethapi.PublicBlockChainAPI // Wrapper around the blockchain to access chain data + txapi *ethapi.PublicTransactionPoolAPI // Wrapper around the transaction pool to access transaction data } // NewContractBackend creates a new native contract backend using an existing // Etheruem object. func NewContractBackend(eth *Ethereum) *ContractBackend { return &ContractBackend{ - eapi: NewPublicEthereumAPI(eth), - bcapi: NewPublicBlockChainAPI(eth.chainConfig, eth.blockchain, eth.miner, eth.chainDb, eth.gpo, eth.eventMux, eth.accountManager), - txapi: NewPublicTransactionPoolAPI(eth), + eapi: ethapi.NewPublicEthereumAPI(eth.apiBackend, nil, nil), + bcapi: ethapi.NewPublicBlockChainAPI(eth.apiBackend), + txapi: ethapi.NewPublicTransactionPoolAPI(eth.apiBackend), } } // HasCode implements bind.ContractVerifier.HasCode by retrieving any code associated // with the contract from the local API, and checking its size. -func (b *ContractBackend) HasCode(contract common.Address, pending bool) (bool, error) { +func (b *ContractBackend) HasCode(ctx context.Context, contract common.Address, pending bool) (bool, error) { + if ctx == nil { + ctx = context.Background() + } block := rpc.LatestBlockNumber if pending { block = rpc.PendingBlockNumber } - out, err := b.bcapi.GetCode(contract, block) + out, err := b.bcapi.GetCode(ctx, contract, block) return len(common.FromHex(out)) > 0, err } // ContractCall implements bind.ContractCaller executing an Ethereum contract // call with the specified data as the input. The pending flag requests execution // against the pending block, not the stable head of the chain. -func (b *ContractBackend) ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) { +func (b *ContractBackend) ContractCall(ctx context.Context, contract common.Address, data []byte, pending bool) ([]byte, error) { + if ctx == nil { + ctx = context.Background() + } // Convert the input args to the API spec - args := CallArgs{ + args := ethapi.CallArgs{ To: &contract, Data: common.ToHex(data), } @@ -73,21 +81,27 @@ func (b *ContractBackend) ContractCall(contract common.Address, data []byte, pen block = rpc.PendingBlockNumber } // Execute the call and convert the output back to Go types - out, err := b.bcapi.Call(args, block) + out, err := b.bcapi.Call(ctx, args, block) return common.FromHex(out), err } // PendingAccountNonce implements bind.ContractTransactor retrieving the current // pending nonce associated with an account. -func (b *ContractBackend) PendingAccountNonce(account common.Address) (uint64, error) { - out, err := b.txapi.GetTransactionCount(account, rpc.PendingBlockNumber) +func (b *ContractBackend) PendingAccountNonce(ctx context.Context, account common.Address) (uint64, error) { + if ctx == nil { + ctx = context.Background() + } + out, err := b.txapi.GetTransactionCount(ctx, account, rpc.PendingBlockNumber) return out.Uint64(), err } // SuggestGasPrice implements bind.ContractTransactor retrieving the currently // suggested gas price to allow a timely execution of a transaction. -func (b *ContractBackend) SuggestGasPrice() (*big.Int, error) { - return b.eapi.GasPrice(), nil +func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + if ctx == nil { + ctx = context.Background() + } + return b.eapi.GasPrice(ctx) } // EstimateGasLimit implements bind.ContractTransactor triing to estimate the gas @@ -95,8 +109,11 @@ func (b *ContractBackend) SuggestGasPrice() (*big.Int, error) { // the backend blockchain. There is no guarantee that this is the true gas limit // requirement as other transactions may be added or removed by miners, but it // should provide a basis for setting a reasonable default. -func (b *ContractBackend) EstimateGasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { - out, err := b.bcapi.EstimateGas(CallArgs{ +func (b *ContractBackend) EstimateGasLimit(ctx context.Context, sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { + if ctx == nil { + ctx = context.Background() + } + out, err := b.bcapi.EstimateGas(ctx, ethapi.CallArgs{ From: sender, To: contract, Value: *rpc.NewHexNumber(value), @@ -107,8 +124,11 @@ func (b *ContractBackend) EstimateGasLimit(sender common.Address, contract *comm // SendTransaction implements bind.ContractTransactor injects the transaction // into the pending pool for execution. -func (b *ContractBackend) SendTransaction(tx *types.Transaction) error { +func (b *ContractBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { + if ctx == nil { + ctx = context.Background() + } raw, _ := rlp.EncodeToBytes(tx) - _, err := b.txapi.SendRawTransaction(common.ToHex(raw)) + _, err := b.txapi.SendRawTransaction(ctx, common.ToHex(raw)) return err } diff --git a/eth/db_upgrade.go b/eth/db_upgrade.go index 12de60fe7..172bb0954 100644 --- a/eth/db_upgrade.go +++ b/eth/db_upgrade.go @@ -93,6 +93,9 @@ func upgradeSequentialKeys(db ethdb.Database) (stopFn func()) { func upgradeSequentialCanonicalNumbers(db ethdb.Database, stopFn func() bool) (error, bool) { prefix := []byte("block-num-") it := db.(*ethdb.LDBDatabase).NewIterator() + defer func() { + it.Release() + }() it.Seek(prefix) cnt := 0 for bytes.HasPrefix(it.Key(), prefix) { @@ -100,6 +103,9 @@ func upgradeSequentialCanonicalNumbers(db ethdb.Database, stopFn func() bool) (e if len(keyPtr) < 20 { cnt++ if cnt%100000 == 0 { + it.Release() + it = db.(*ethdb.LDBDatabase).NewIterator() + it.Seek(keyPtr) glog.V(logger.Info).Infof("converting %d canonical numbers...", cnt) } number := big.NewInt(0).SetBytes(keyPtr[10:]).Uint64() @@ -130,6 +136,9 @@ func upgradeSequentialCanonicalNumbers(db ethdb.Database, stopFn func() bool) (e func upgradeSequentialBlocks(db ethdb.Database, stopFn func() bool) (error, bool) { prefix := []byte("block-") it := db.(*ethdb.LDBDatabase).NewIterator() + defer func() { + it.Release() + }() it.Seek(prefix) cnt := 0 for bytes.HasPrefix(it.Key(), prefix) { @@ -137,6 +146,9 @@ func upgradeSequentialBlocks(db ethdb.Database, stopFn func() bool) (error, bool if len(keyPtr) >= 38 { cnt++ if cnt%10000 == 0 { + it.Release() + it = db.(*ethdb.LDBDatabase).NewIterator() + it.Seek(keyPtr) glog.V(logger.Info).Infof("converting %d blocks...", cnt) } // convert header, body, td and block receipts @@ -175,6 +187,7 @@ func upgradeSequentialBlocks(db ethdb.Database, stopFn func() bool) (error, bool func upgradeSequentialOrphanedReceipts(db ethdb.Database, stopFn func() bool) (error, bool) { prefix := []byte("receipts-block-") it := db.(*ethdb.LDBDatabase).NewIterator() + defer it.Release() it.Seek(prefix) cnt := 0 for bytes.HasPrefix(it.Key(), prefix) { diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 92124cfeb..01c0818a0 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -1859,7 +1859,7 @@ func (d *Downloader) processContent() error { } if err != nil { glog.V(logger.Debug).Infof("Result #%d [%x…] processing failed: %v", results[index].Header.Number, results[index].Header.Hash().Bytes()[:4], err) - return err + return errInvalidChain } // Shift the results to the next batch results = results[items:] diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index e9e051ded..fac6ef81c 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -55,7 +55,7 @@ func init() { // reassembly. func makeChain(n int, seed byte, parent *types.Block, parentReceipts types.Receipts, heavy bool) ([]common.Hash, map[common.Hash]*types.Header, map[common.Hash]*types.Block, map[common.Hash]types.Receipts) { // Generate the block chain - blocks, receipts := core.GenerateChain(parent, testdb, n, func(i int, block *core.BlockGen) { + blocks, receipts := core.GenerateChain(nil, parent, testdb, n, func(i int, block *core.BlockGen) { block.SetCoinbase(common.Address{seed}) // If a heavy chain is requested, delay blocks to raise difficulty diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go index 2404c8cfa..6a32be14c 100644 --- a/eth/fetcher/fetcher_test.go +++ b/eth/fetcher/fetcher_test.go @@ -45,7 +45,7 @@ var ( // contains a transaction and every 5th an uncle to allow testing correct block // reassembly. func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block) { - blocks, _ := core.GenerateChain(parent, testdb, n, func(i int, block *core.BlockGen) { + blocks, _ := core.GenerateChain(nil, parent, testdb, n, func(i int, block *core.BlockGen) { block.SetCoinbase(common.Address{seed}) // If the block number is multiple of 3, send a bonus transaction to the miner diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index a95adfce7..7b714f5d5 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -57,7 +57,7 @@ func BenchmarkMipmaps(b *testing.B) { defer db.Close() genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr1, Balance: big.NewInt(1000000)}) - chain, receipts := core.GenerateChain(genesis, db, 100010, func(i int, gen *core.BlockGen) { + chain, receipts := core.GenerateChain(nil, genesis, db, 100010, func(i int, gen *core.BlockGen) { var receipts types.Receipts switch i { case 2403: @@ -133,7 +133,7 @@ func TestFilters(t *testing.T) { defer db.Close() genesis := core.WriteGenesisBlockForTesting(db, core.GenesisAccount{Address: addr, Balance: big.NewInt(1000000)}) - chain, receipts := core.GenerateChain(genesis, db, 1000, func(i int, gen *core.BlockGen) { + chain, receipts := core.GenerateChain(nil, genesis, db, 1000, func(i int, gen *core.BlockGen) { var receipts types.Receipts switch i { case 1: diff --git a/eth/gasprice.go b/eth/gasprice/gasprice.go index ef203f8fe..eb2df4a96 100644 --- a/eth/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -14,7 +14,7 @@ // 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 eth +package gasprice import ( "math/big" @@ -23,6 +23,8 @@ 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/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" ) @@ -39,10 +41,22 @@ type blockPriceInfo struct { baseGasPrice *big.Int } +type GpoParams struct { + GpoMinGasPrice *big.Int + GpoMaxGasPrice *big.Int + GpoFullBlockRatio int + GpobaseStepDown int + GpobaseStepUp int + GpobaseCorrectionFactor int +} + // GasPriceOracle recommends gas prices based on the content of recent // blocks. type GasPriceOracle struct { - eth *Ethereum + chain *core.BlockChain + db ethdb.Database + evmux *event.TypeMux + params *GpoParams initOnce sync.Once minPrice *big.Int lastBaseMutex sync.Mutex @@ -55,17 +69,20 @@ type GasPriceOracle struct { } // NewGasPriceOracle returns a new oracle. -func NewGasPriceOracle(eth *Ethereum) *GasPriceOracle { - minprice := eth.GpoMinGasPrice +func NewGasPriceOracle(chain *core.BlockChain, db ethdb.Database, evmux *event.TypeMux, params *GpoParams) *GasPriceOracle { + minprice := params.GpoMinGasPrice if minprice == nil { minprice = big.NewInt(gpoDefaultMinGasPrice) } minbase := new(big.Int).Mul(minprice, big.NewInt(100)) - if eth.GpobaseCorrectionFactor > 0 { - minbase = minbase.Div(minbase, big.NewInt(int64(eth.GpobaseCorrectionFactor))) + if params.GpobaseCorrectionFactor > 0 { + minbase = minbase.Div(minbase, big.NewInt(int64(params.GpobaseCorrectionFactor))) } return &GasPriceOracle{ - eth: eth, + chain: chain, + db: db, + evmux: evmux, + params: params, blocks: make(map[uint64]*blockPriceInfo), minBase: minbase, minPrice: minprice, @@ -75,14 +92,14 @@ func NewGasPriceOracle(eth *Ethereum) *GasPriceOracle { func (gpo *GasPriceOracle) init() { gpo.initOnce.Do(func() { - gpo.processPastBlocks(gpo.eth.BlockChain()) + gpo.processPastBlocks() go gpo.listenLoop() }) } -func (self *GasPriceOracle) processPastBlocks(chain *core.BlockChain) { +func (self *GasPriceOracle) processPastBlocks() { last := int64(-1) - cblock := chain.CurrentBlock() + cblock := self.chain.CurrentBlock() if cblock != nil { last = int64(cblock.NumberU64()) } @@ -92,7 +109,7 @@ func (self *GasPriceOracle) processPastBlocks(chain *core.BlockChain) { } self.firstProcessed = uint64(first) for i := first; i <= last; i++ { - block := chain.GetBlockByNumber(uint64(i)) + block := self.chain.GetBlockByNumber(uint64(i)) if block != nil { self.processBlock(block) } @@ -101,7 +118,7 @@ func (self *GasPriceOracle) processPastBlocks(chain *core.BlockChain) { } func (self *GasPriceOracle) listenLoop() { - events := self.eth.EventMux().Subscribe(core.ChainEvent{}, core.ChainSplitEvent{}) + events := self.evmux.Subscribe(core.ChainEvent{}, core.ChainSplitEvent{}) defer events.Unsubscribe() for event := range events.Chan() { @@ -136,9 +153,9 @@ func (self *GasPriceOracle) processBlock(block *types.Block) { } if lastBase.Cmp(lp) < 0 { - corr = self.eth.GpobaseStepUp + corr = self.params.GpobaseStepUp } else { - corr = -self.eth.GpobaseStepDown + corr = -self.params.GpobaseStepDown } crand := int64(corr * (900 + rand.Intn(201))) @@ -159,14 +176,14 @@ func (self *GasPriceOracle) processBlock(block *types.Block) { self.lastBase = newBase self.lastBaseMutex.Unlock() - glog.V(logger.Detail).Infof("Processed block #%v, base price is %v\n", block.NumberU64(), newBase.Int64()) + glog.V(logger.Detail).Infof("Processed block #%v, base price is %v\n", i, newBase.Int64()) } // returns the lowers possible price with which a tx was or could have been included func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int { gasUsed := big.NewInt(0) - receipts := core.GetBlockReceipts(self.eth.ChainDb(), block.Hash(), block.NumberU64()) + receipts := core.GetBlockReceipts(self.db, block.Hash(), block.NumberU64()) if len(receipts) > 0 { if cgu := receipts[len(receipts)-1].CumulativeGasUsed; cgu != nil { gasUsed = receipts[len(receipts)-1].CumulativeGasUsed @@ -174,7 +191,7 @@ func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int { } if new(big.Int).Mul(gasUsed, big.NewInt(100)).Cmp(new(big.Int).Mul(block.GasLimit(), - big.NewInt(int64(self.eth.GpoFullBlockRatio)))) < 0 { + big.NewInt(int64(self.params.GpoFullBlockRatio)))) < 0 { // block is not full, could have posted a tx with MinGasPrice return big.NewInt(0) } @@ -201,12 +218,12 @@ func (self *GasPriceOracle) SuggestPrice() *big.Int { price := new(big.Int).Set(self.lastBase) self.lastBaseMutex.Unlock() - price.Mul(price, big.NewInt(int64(self.eth.GpobaseCorrectionFactor))) + price.Mul(price, big.NewInt(int64(self.params.GpobaseCorrectionFactor))) price.Div(price, big.NewInt(100)) if price.Cmp(self.minPrice) < 0 { price.Set(self.minPrice) - } else if self.eth.GpoMaxGasPrice != nil && price.Cmp(self.eth.GpoMaxGasPrice) > 0 { - price.Set(self.eth.GpoMaxGasPrice) + } else if self.params.GpoMaxGasPrice != nil && price.Cmp(self.params.GpoMaxGasPrice) > 0 { + price.Set(self.params.GpoMaxGasPrice) } return price } diff --git a/eth/handler.go b/eth/handler.go index 47a36cc0b..01550e6c2 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -45,6 +45,10 @@ const ( estHeaderRlpSize = 500 // Approximate size of an RLP encoded block header ) +var ( + daoChallengeTimeout = 15 * time.Second // Time allowance for a node to reply to the DAO handshake challenge +) + // errIncompatibleConfig is returned if the requested protocols and configs are // not compatible (low protocol version restrictions and high requirements). var errIncompatibleConfig = errors.New("incompatible configuration") @@ -62,9 +66,10 @@ type ProtocolManager struct { fastSync uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks) synced uint32 // Flag whether we're considered synchronised (enables transaction processing) - txpool txPool - blockchain *core.BlockChain - chaindb ethdb.Database + txpool txPool + blockchain *core.BlockChain + chaindb ethdb.Database + chainconfig *core.ChainConfig downloader *downloader.Downloader fetcher *fetcher.Fetcher @@ -99,6 +104,7 @@ func NewProtocolManager(config *core.ChainConfig, fastSync bool, networkId int, txpool: txpool, blockchain: blockchain, chaindb: chaindb, + chainconfig: config, peers: newPeerSet(), newPeerCh: make(chan *peer), noMorePeers: make(chan struct{}), @@ -278,6 +284,18 @@ func (pm *ProtocolManager) handle(p *peer) error { // after this will be sent via broadcasts. pm.syncTransactions(p) + // If we're DAO hard-fork aware, validate any remote peer with regard to the hard-fork + if daoBlock := pm.chainconfig.DAOForkBlock; daoBlock != nil { + // Request the peer's DAO fork header for extra-data validation + if err := p.RequestHeadersByNumber(daoBlock.Uint64(), 1, 0, false); err != nil { + return err + } + // Start a timer to disconnect if the peer doesn't reply in time + p.forkDrop = time.AfterFunc(daoChallengeTimeout, func() { + glog.V(logger.Warn).Infof("%v: timed out DAO fork-check, dropping", p) + pm.removePeer(p.id) + }) + } // main loop. handle incoming messages. for { if err := pm.handleMsg(p); err != nil { @@ -481,9 +499,43 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { if err := msg.Decode(&headers); err != nil { return errResp(ErrDecode, "msg %v: %v", msg, err) } + // If no headers were received, but we're expending a DAO fork check, maybe it's that + if len(headers) == 0 && p.forkDrop != nil { + // Possibly an empty reply to the fork header checks, sanity check TDs + verifyDAO := true + + // If we already have a DAO header, we can check the peer's TD against it. If + // the peer's ahead of this, it too must have a reply to the DAO check + if daoHeader := pm.blockchain.GetHeaderByNumber(pm.chainconfig.DAOForkBlock.Uint64()); daoHeader != nil { + if p.Td().Cmp(pm.blockchain.GetTd(daoHeader.Hash(), daoHeader.Number.Uint64())) >= 0 { + verifyDAO = false + } + } + // If we're seemingly on the same chain, disable the drop timer + if verifyDAO { + glog.V(logger.Debug).Infof("%v: seems to be on the same side of the DAO fork", p) + p.forkDrop.Stop() + p.forkDrop = nil + return nil + } + } // Filter out any explicitly requested headers, deliver the rest to the downloader filter := len(headers) == 1 if filter { + // If it's a potential DAO fork check, validate against the rules + if p.forkDrop != nil && pm.chainconfig.DAOForkBlock.Cmp(headers[0].Number) == 0 { + // Disable the fork drop timer + p.forkDrop.Stop() + p.forkDrop = nil + + // Validate the header and either drop the peer or continue + if err := core.ValidateDAOHeaderExtraData(pm.chainconfig, headers[0]); err != nil { + glog.V(logger.Debug).Infof("%v: verified to be on the other side of the DAO fork, dropping", p) + return err + } + glog.V(logger.Debug).Infof("%v: verified to be on the same side of the DAO fork", p) + } + // Irrelevant of the fork checks, send the header to the fetcher just in case headers = pm.fetcher.FilterHeaders(headers, time.Now()) } if len(headers) > 0 || !filter { diff --git a/eth/handler_test.go b/eth/handler_test.go index 8418c28b2..66ff26809 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -20,6 +20,7 @@ import ( "math/big" "math/rand" "testing" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -28,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" ) @@ -580,3 +582,75 @@ func testGetReceipt(t *testing.T, protocol int) { t.Errorf("receipts mismatch: %v", err) } } + +// Tests that post eth protocol handshake, DAO fork-enabled clients also execute +// a DAO "challenge" verifying each others' DAO fork headers to ensure they're on +// compatible chains. +func TestDAOChallengeNoVsNo(t *testing.T) { testDAOChallenge(t, false, false, false) } +func TestDAOChallengeNoVsPro(t *testing.T) { testDAOChallenge(t, false, true, false) } +func TestDAOChallengeProVsNo(t *testing.T) { testDAOChallenge(t, true, false, false) } +func TestDAOChallengeProVsPro(t *testing.T) { testDAOChallenge(t, true, true, false) } +func TestDAOChallengeNoVsTimeout(t *testing.T) { testDAOChallenge(t, false, false, true) } +func TestDAOChallengeProVsTimeout(t *testing.T) { testDAOChallenge(t, true, true, true) } + +func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool) { + // Reduce the DAO handshake challenge timeout + if timeout { + defer func(old time.Duration) { daoChallengeTimeout = old }(daoChallengeTimeout) + daoChallengeTimeout = 500 * time.Millisecond + } + // Create a DAO aware protocol manager + var ( + evmux = new(event.TypeMux) + pow = new(core.FakePow) + db, _ = ethdb.NewMemDatabase() + genesis = core.WriteGenesisBlockForTesting(db) + config = &core.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked} + blockchain, _ = core.NewBlockChain(db, config, pow, evmux) + ) + pm, err := NewProtocolManager(config, false, NetworkId, evmux, new(testTxPool), pow, blockchain, db) + if err != nil { + t.Fatalf("failed to start test protocol manager: %v", err) + } + pm.Start() + defer pm.Stop() + + // Connect a new peer and check that we receive the DAO challenge + peer, _ := newTestPeer("peer", eth63, pm, true) + defer peer.close() + + challenge := &getBlockHeadersData{ + Origin: hashOrNumber{Number: config.DAOForkBlock.Uint64()}, + Amount: 1, + Skip: 0, + Reverse: false, + } + if err := p2p.ExpectMsg(peer.app, GetBlockHeadersMsg, challenge); err != nil { + t.Fatalf("challenge mismatch: %v", err) + } + // Create a block to reply to the challenge if no timeout is simualted + if !timeout { + blocks, _ := core.GenerateChain(nil, genesis, db, 1, func(i int, block *core.BlockGen) { + if remoteForked { + block.SetExtra(params.DAOForkBlockExtra) + } + }) + if err := p2p.Send(peer.app, BlockHeadersMsg, []*types.Header{blocks[0].Header()}); err != nil { + t.Fatalf("failed to answer challenge: %v", err) + } + time.Sleep(100 * time.Millisecond) // Sleep to avoid the verification racing with the drops + } else { + // Otherwise wait until the test timeout passes + time.Sleep(daoChallengeTimeout + 500*time.Millisecond) + } + // Verify that depending on fork side, the remote peer is maintained or dropped + if localForked == remoteForked && !timeout { + if peers := pm.peers.Len(); peers != 1 { + t.Fatalf("peer count mismatch: have %d, want %d", peers, 1) + } + } else { + if peers := pm.peers.Len(); peers != 0 { + t.Fatalf("peer count mismatch: have %d, want %d", peers, 0) + } + } +} diff --git a/eth/helper_test.go b/eth/helper_test.go index dacb1593f..28ff69b17 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -56,7 +56,7 @@ func newTestProtocolManager(fastSync bool, blocks int, generator func(int, *core chainConfig = &core.ChainConfig{HomesteadBlock: big.NewInt(0)} // homestead set to 0 because of chain maker blockchain, _ = core.NewBlockChain(db, chainConfig, pow, evmux) ) - chain, _ := core.GenerateChain(genesis, db, blocks, generator) + chain, _ := core.GenerateChain(nil, genesis, db, blocks, generator) if _, err := blockchain.InsertChain(chain); err != nil { panic(err) } diff --git a/eth/peer.go b/eth/peer.go index 8eb41b0f9..b97825c69 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -59,10 +59,12 @@ type peer struct { *p2p.Peer rw p2p.MsgReadWriter - version int // Protocol version negotiated - head common.Hash - td *big.Int - lock sync.RWMutex + version int // Protocol version negotiated + forkDrop *time.Timer // Timed connection dropper if forks aren't validated in time + + head common.Hash + td *big.Int + lock sync.RWMutex knownTxs *set.Set // Set of transaction hashes known to be known by this peer knownBlocks *set.Set // Set of block hashes known to be known by this peer diff --git a/eth/protocol.go b/eth/protocol.go index 808ac0601..7de0cb020 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -37,10 +37,10 @@ const ( var ProtocolName = "eth" // Supported versions of the eth protocol (first is primary). -var ProtocolVersions = []uint{eth63, eth62, eth61} +var ProtocolVersions = []uint{eth63, eth62} // Number of implemented message corresponding to different protocol versions. -var ProtocolLengths = []uint64{17, 8, 9} +var ProtocolLengths = []uint64{17, 8} const ( NetworkId = 1 diff --git a/ethdb/database.go b/ethdb/database.go index dffb42e2b..29da4a197 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -36,14 +36,14 @@ import ( var OpenFileLimit = 64 -// cacheRatio specifies how the total alloted cache is distributed between the +// cacheRatio specifies how the total allotted cache is distributed between the // various system databases. var cacheRatio = map[string]float64{ "dapp": 0.0, "chaindata": 1.0, } -// handleRatio specifies how the total alloted file descriptors is distributed +// handleRatio specifies how the total allotted file descriptors is distributed // between the various system databases. var handleRatio = map[string]float64{ "dapp": 0.0, @@ -79,7 +79,7 @@ func NewLDBDatabase(file string, cache int, handles int) (*LDBDatabase, error) { if handles < 16 { handles = 16 } - glog.V(logger.Info).Infof("Alloted %dMB cache and %d file handles to %s", cache, handles, file) + glog.V(logger.Info).Infof("Allotted %dMB cache and %d file handles to %s", cache, handles, file) // Open the db and recover any potential corruptions db, err := leveldb.OpenFile(file, &opt.Options{ diff --git a/internal/build/archive.go b/internal/build/archive.go new file mode 100644 index 000000000..2a7090c0d --- /dev/null +++ b/internal/build/archive.go @@ -0,0 +1,177 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package build + +import ( + "archive/tar" + "archive/zip" + "compress/gzip" + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +type Archive interface { + // Directory adds a new directory entry to the archive and sets the + // directory for subsequent calls to Header. + Directory(name string) error + + // Header adds a new file to the archive. The file is added to the directory + // set by Directory. The content of the file must be written to the returned + // writer. + Header(os.FileInfo) (io.Writer, error) + + // Close flushes the archive and closes the underlying file. + Close() error +} + +func NewArchive(file *os.File) Archive { + switch { + case strings.HasSuffix(file.Name(), ".zip"): + return NewZipArchive(file) + case strings.HasSuffix(file.Name(), ".tar.gz"): + return NewTarballArchive(file) + default: + return nil + } +} + +// AddFile appends an existing file to an archive. +func AddFile(a Archive, file string) error { + fd, err := os.Open(file) + if err != nil { + return err + } + defer fd.Close() + fi, err := fd.Stat() + if err != nil { + return err + } + w, err := a.Header(fi) + if err != nil { + return err + } + if _, err := io.Copy(w, fd); err != nil { + return err + } + return nil +} + +// WriteArchive creates an archive containing the given files. +func WriteArchive(basename, ext string, files []string) error { + archfd, err := os.Create(basename + ext) + if err != nil { + return err + } + defer archfd.Close() + archive := NewArchive(archfd) + if archive == nil { + return fmt.Errorf("unknown archive extension: %s", ext) + } + fmt.Println(basename + ext) + if err := archive.Directory(basename); err != nil { + return err + } + for _, file := range files { + fmt.Println(" +", filepath.Base(file)) + if err := AddFile(archive, file); err != nil { + return err + } + } + return archive.Close() +} + +type ZipArchive struct { + dir string + zipw *zip.Writer + file io.Closer +} + +func NewZipArchive(w io.WriteCloser) Archive { + return &ZipArchive{"", zip.NewWriter(w), w} +} + +func (a *ZipArchive) Directory(name string) error { + a.dir = name + "/" + return nil +} + +func (a *ZipArchive) Header(fi os.FileInfo) (io.Writer, error) { + head, err := zip.FileInfoHeader(fi) + if err != nil { + return nil, fmt.Errorf("can't make zip header: %v", err) + } + head.Name = a.dir + head.Name + w, err := a.zipw.CreateHeader(head) + if err != nil { + return nil, fmt.Errorf("can't add zip header: %v", err) + } + return w, nil +} + +func (a *ZipArchive) Close() error { + if err := a.zipw.Close(); err != nil { + return err + } + return a.file.Close() +} + +type TarballArchive struct { + dir string + tarw *tar.Writer + gzw *gzip.Writer + file io.Closer +} + +func NewTarballArchive(w io.WriteCloser) Archive { + gzw := gzip.NewWriter(w) + tarw := tar.NewWriter(gzw) + return &TarballArchive{"", tarw, gzw, w} +} + +func (a *TarballArchive) Directory(name string) error { + a.dir = name + "/" + return a.tarw.WriteHeader(&tar.Header{ + Name: a.dir, + Mode: 0755, + Typeflag: tar.TypeDir, + }) +} + +func (a *TarballArchive) Header(fi os.FileInfo) (io.Writer, error) { + head, err := tar.FileInfoHeader(fi, "") + if err != nil { + return nil, fmt.Errorf("can't make tar header: %v", err) + } + head.Name = a.dir + head.Name + if err := a.tarw.WriteHeader(head); err != nil { + return nil, fmt.Errorf("can't add tar header: %v", err) + } + return a.tarw, nil +} + +func (a *TarballArchive) Close() error { + if err := a.tarw.Close(); err != nil { + return err + } + if err := a.gzw.Close(); err != nil { + return err + } + return a.file.Close() +} diff --git a/internal/build/util.go b/internal/build/util.go new file mode 100644 index 000000000..eead824b2 --- /dev/null +++ b/internal/build/util.go @@ -0,0 +1,122 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package build + +import ( + "bytes" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "text/template" +) + +var ( + DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") +) + +// MustRun executes the given command and exits the host process for +// any error. +func MustRun(cmd *exec.Cmd) { + fmt.Println(">>>", strings.Join(cmd.Args, " ")) + if !*DryRunFlag { + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { + log.Fatal(err) + } + } +} + +func MustRunCommand(cmd string, args ...string) { + MustRun(exec.Command(cmd, args...)) +} + +// GOPATH returns the value that the GOPATH environment +// variable should be set to. +func GOPATH() string { + path := filepath.SplitList(os.Getenv("GOPATH")) + if len(path) == 0 { + log.Fatal("GOPATH is not set") + } + // Ensure Godeps workspace is present in the path. + godeps, _ := filepath.Abs(filepath.Join("Godeps", "_workspace")) + for _, dir := range path { + if dir == godeps { + return strings.Join(path, string(filepath.ListSeparator)) + } + } + newpath := append(path[:1], godeps) + newpath = append(newpath, path[1:]...) + return strings.Join(newpath, string(filepath.ListSeparator)) +} + +func VERSION() string { + version, err := ioutil.ReadFile("VERSION") + if err != nil { + log.Fatal(err) + } + return string(bytes.TrimSpace(version)) +} + +func GitCommit() string { + return RunGit("rev-parse", "HEAD") +} + +func RunGit(args ...string) string { + cmd := exec.Command("git", args...) + var stdout, stderr bytes.Buffer + cmd.Stdout, cmd.Stderr = &stdout, &stderr + if err := cmd.Run(); err == exec.ErrNotFound { + log.Println("no git in PATH") + return "" + } else if err != nil { + log.Fatal(strings.Join(cmd.Args, " "), ": ", err, "\n", stderr.String()) + } + return strings.TrimSpace(stdout.String()) +} + +// Render renders the given template file. +func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) { + tpl := template.Must(template.ParseFiles(templateFile)) + render(tpl, outputFile, outputPerm, x) +} + +func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) { + tpl := template.Must(template.New("").Parse(templateContent)) + render(tpl, outputFile, outputPerm, x) +} + +func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x interface{}) { + if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil { + log.Fatal(err) + } + out, err := os.OpenFile(outputFile, os.O_CREATE|os.O_WRONLY|os.O_EXCL, outputPerm) + if err != nil { + log.Fatal(err) + } + if err := tpl.Execute(out, x); err != nil { + log.Fatal(err) + } + if err := out.Close(); err != nil { + log.Fatal(err) + } +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go new file mode 100644 index 000000000..f604a0ef2 --- /dev/null +++ b/internal/ethapi/api.go @@ -0,0 +1,1542 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package ethapi + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "math/big" + "strings" + "sync" + "time" + + "github.com/ethereum/ethash" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/compiler" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/syndtr/goleveldb/leveldb" + "golang.org/x/net/context" +) + +const defaultGas = uint64(90000) + +// PublicEthereumAPI provides an API to access Ethereum related information. +// It offers only methods that operate on public data that is freely available to anyone. +type PublicEthereumAPI struct { + b Backend + solcPath *string + solc **compiler.Solidity +} + +// NewPublicEthereumAPI creates a new Etheruem protocol API. +func NewPublicEthereumAPI(b Backend, solcPath *string, solc **compiler.Solidity) *PublicEthereumAPI { + return &PublicEthereumAPI{b, solcPath, solc} +} + +// GasPrice returns a suggestion for a gas price. +func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*big.Int, error) { + return s.b.SuggestPrice(ctx) +} + +func (s *PublicEthereumAPI) getSolc() (*compiler.Solidity, error) { + var err error + solc := *s.solc + if solc == nil { + solc, err = compiler.New(*s.solcPath) + } + return solc, err +} + +// GetCompilers returns the collection of available smart contract compilers +func (s *PublicEthereumAPI) GetCompilers() ([]string, error) { + solc, err := s.getSolc() + if err == nil && solc != nil { + return []string{"Solidity"}, nil + } + + return []string{}, nil +} + +// CompileSolidity compiles the given solidity source +func (s *PublicEthereumAPI) CompileSolidity(source string) (map[string]*compiler.Contract, error) { + solc, err := s.getSolc() + if err != nil { + return nil, err + } + + if solc == nil { + return nil, errors.New("solc (solidity compiler) not found") + } + + return solc.Compile(source) +} + +// ProtocolVersion returns the current Ethereum protocol version this node supports +func (s *PublicEthereumAPI) ProtocolVersion() *rpc.HexNumber { + return rpc.NewHexNumber(s.b.ProtocolVersion()) +} + +// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not +// yet received the latest block headers from its pears. In case it is synchronizing: +// - startingBlock: block number this node started to synchronise from +// - currentBlock: block number this node is currently importing +// - highestBlock: block number of the highest block header this node has received from peers +// - pulledStates: number of state entries processed until now +// - knownStates: number of known state entries that still need to be pulled +func (s *PublicEthereumAPI) Syncing() (interface{}, error) { + origin, current, height, pulled, known := s.b.Downloader().Progress() + + // Return not syncing if the synchronisation already completed + if current >= height { + return false, nil + } + // Otherwise gather the block sync stats + return map[string]interface{}{ + "startingBlock": rpc.NewHexNumber(origin), + "currentBlock": rpc.NewHexNumber(current), + "highestBlock": rpc.NewHexNumber(height), + "pulledStates": rpc.NewHexNumber(pulled), + "knownStates": rpc.NewHexNumber(known), + }, nil +} + +// PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. +type PublicTxPoolAPI struct { + b Backend +} + +// NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. +func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { + return &PublicTxPoolAPI{b} +} + +// Content returns the transactions contained within the transaction pool. +func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string][]*RPCTransaction { + content := map[string]map[string]map[string][]*RPCTransaction{ + "pending": make(map[string]map[string][]*RPCTransaction), + "queued": make(map[string]map[string][]*RPCTransaction), + } + pending, queue := s.b.TxPoolContent() + + // Flatten the pending transactions + for account, batches := range pending { + dump := make(map[string][]*RPCTransaction) + for nonce, txs := range batches { + nonce := fmt.Sprintf("%d", nonce) + for _, tx := range txs { + dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx)) + } + } + content["pending"][account.Hex()] = dump + } + // Flatten the queued transactions + for account, batches := range queue { + dump := make(map[string][]*RPCTransaction) + for nonce, txs := range batches { + nonce := fmt.Sprintf("%d", nonce) + for _, tx := range txs { + dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx)) + } + } + content["queued"][account.Hex()] = dump + } + return content +} + +// Status returns the number of pending and queued transaction in the pool. +func (s *PublicTxPoolAPI) Status() map[string]*rpc.HexNumber { + pending, queue := s.b.Stats() + return map[string]*rpc.HexNumber{ + "pending": rpc.NewHexNumber(pending), + "queued": rpc.NewHexNumber(queue), + } +} + +// Inspect retrieves the content of the transaction pool and flattens it into an +// easily inspectable list. +func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string][]string { + content := map[string]map[string]map[string][]string{ + "pending": make(map[string]map[string][]string), + "queued": make(map[string]map[string][]string), + } + pending, queue := s.b.TxPoolContent() + + // Define a formatter to flatten a transaction into a string + var format = func(tx *types.Transaction) string { + if to := tx.To(); to != nil { + return fmt.Sprintf("%s: %v wei + %v × %v gas", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) + } + return fmt.Sprintf("contract creation: %v wei + %v × %v gas", tx.Value(), tx.Gas(), tx.GasPrice()) + } + // Flatten the pending transactions + for account, batches := range pending { + dump := make(map[string][]string) + for nonce, txs := range batches { + nonce := fmt.Sprintf("%d", nonce) + for _, tx := range txs { + dump[nonce] = append(dump[nonce], format(tx)) + } + } + content["pending"][account.Hex()] = dump + } + // Flatten the queued transactions + for account, batches := range queue { + dump := make(map[string][]string) + for nonce, txs := range batches { + nonce := fmt.Sprintf("%d", nonce) + for _, tx := range txs { + dump[nonce] = append(dump[nonce], format(tx)) + } + } + content["queued"][account.Hex()] = dump + } + return content +} + +// PublicAccountAPI provides an API to access accounts managed by this node. +// It offers only methods that can retrieve accounts. +type PublicAccountAPI struct { + am *accounts.Manager +} + +// NewPublicAccountAPI creates a new PublicAccountAPI. +func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { + return &PublicAccountAPI{am: am} +} + +// Accounts returns the collection of accounts this node manages +func (s *PublicAccountAPI) Accounts() []accounts.Account { + return s.am.Accounts() +} + +// PrivateAccountAPI provides an API to access accounts managed by this node. +// It offers methods to create, (un)lock en list accounts. Some methods accept +// passwords and are therefore considered private by default. +type PrivateAccountAPI struct { + am *accounts.Manager + b Backend +} + +// NewPrivateAccountAPI create a new PrivateAccountAPI. +func NewPrivateAccountAPI(b Backend) *PrivateAccountAPI { + return &PrivateAccountAPI{ + am: b.AccountManager(), + b: b, + } +} + +// ListAccounts will return a list of addresses for accounts this node manages. +func (s *PrivateAccountAPI) ListAccounts() []common.Address { + accounts := s.am.Accounts() + addresses := make([]common.Address, len(accounts)) + for i, acc := range accounts { + addresses[i] = acc.Address + } + return addresses +} + +// NewAccount will create a new account and returns the address for the new account. +func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { + acc, err := s.am.NewAccount(password) + if err == nil { + return acc.Address, nil + } + return common.Address{}, err +} + +// ImportRawKey stores the given hex encoded ECDSA key into the key directory, +// encrypting it with the passphrase. +func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { + hexkey, err := hex.DecodeString(privkey) + if err != nil { + return common.Address{}, err + } + + acc, err := s.am.ImportECDSA(crypto.ToECDSA(hexkey), password) + return acc.Address, err +} + +// UnlockAccount will unlock the account associated with the given address with +// the given password for duration seconds. If duration is nil it will use a +// default of 300 seconds. It returns an indication if the account was unlocked. +func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *rpc.HexNumber) (bool, error) { + if duration == nil { + duration = rpc.NewHexNumber(300) + } + a := accounts.Account{Address: addr} + d := time.Duration(duration.Int64()) * time.Second + if err := s.am.TimedUnlock(a, password, d); err != nil { + return false, err + } + return true, nil +} + +// LockAccount will lock the account associated with the given address when it's unlocked. +func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { + return s.am.Lock(addr) == nil +} + +// SignAndSendTransaction will create a transaction from the given arguments and +// tries to sign it with the key associated with args.To. If the given passwd isn't +// able to decrypt the key it fails. +func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { + var err error + args, err = prepareSendTxArgs(ctx, args, s.b) + if err != nil { + return common.Hash{}, err + } + + if args.Nonce == nil { + nonce, err := s.b.GetPoolNonce(ctx, args.From) + if err != nil { + return common.Hash{}, err + } + args.Nonce = rpc.NewHexNumber(nonce) + } + + var tx *types.Transaction + if args.To == nil { + tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) + } else { + tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) + } + + signature, err := s.am.SignWithPassphrase(args.From, passwd, tx.SigHash().Bytes()) + if err != nil { + return common.Hash{}, err + } + + return submitTransaction(ctx, s.b, tx, signature) +} + +// PublicBlockChainAPI provides an API to access the Ethereum blockchain. +// It offers only methods that operate on public data that is freely available to anyone. +type PublicBlockChainAPI struct { + b Backend + muNewBlockSubscriptions sync.Mutex // protects newBlocksSubscriptions + newBlockSubscriptions map[string]func(core.ChainEvent) error // callbacks for new block subscriptions +} + +// NewPublicBlockChainAPI creates a new Etheruem blockchain API. +func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { + api := &PublicBlockChainAPI{ + b: b, + newBlockSubscriptions: make(map[string]func(core.ChainEvent) error), + } + + go api.subscriptionLoop() + + return api +} + +// subscriptionLoop reads events from the global event mux and creates notifications for the matched subscriptions. +func (s *PublicBlockChainAPI) subscriptionLoop() { + sub := s.b.EventMux().Subscribe(core.ChainEvent{}) + for event := range sub.Chan() { + if chainEvent, ok := event.Data.(core.ChainEvent); ok { + s.muNewBlockSubscriptions.Lock() + for id, notifyOf := range s.newBlockSubscriptions { + if notifyOf(chainEvent) == rpc.ErrNotificationNotFound { + delete(s.newBlockSubscriptions, id) + } + } + s.muNewBlockSubscriptions.Unlock() + } + } +} + +// BlockNumber returns the block number of the chain head. +func (s *PublicBlockChainAPI) BlockNumber() *big.Int { + return s.b.HeaderByNumber(rpc.LatestBlockNumber).Number +} + +// GetBalance returns the amount of wei for the given address in the state of the +// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta +// block numbers are also allowed. +func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*big.Int, error) { + state, _, err := s.b.StateAndHeaderByNumber(blockNr) + if state == nil || err != nil { + return nil, err + } + + return state.GetBalance(ctx, address) +} + +// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all +// transactions in the block are returned in full detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { + block, err := s.b.BlockByNumber(ctx, blockNr) + if block != nil { + response, err := s.rpcOutputBlock(block, true, fullTx) + if err == nil && blockNr == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "logsBloom", "miner"} { + response[field] = nil + } + } + return response, err + } + return nil, err +} + +// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full +// detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { + block, err := s.b.GetBlock(ctx, blockHash) + if block != nil { + return s.rpcOutputBlock(block, true, fullTx) + } + return nil, err +} + +// GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true +// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index rpc.HexNumber) (map[string]interface{}, error) { + block, err := s.b.BlockByNumber(ctx, blockNr) + if block != nil { + uncles := block.Uncles() + if index.Int() < 0 || index.Int() >= len(uncles) { + glog.V(logger.Debug).Infof("uncle block on index %d not found for block #%d", index.Int(), blockNr) + return nil, nil + } + block = types.NewBlockWithHeader(uncles[index.Int()]) + return s.rpcOutputBlock(block, false, false) + } + return nil, err +} + +// GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true +// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. +func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index rpc.HexNumber) (map[string]interface{}, error) { + block, err := s.b.GetBlock(ctx, blockHash) + if block != nil { + uncles := block.Uncles() + if index.Int() < 0 || index.Int() >= len(uncles) { + glog.V(logger.Debug).Infof("uncle block on index %d not found for block %s", index.Int(), blockHash.Hex()) + return nil, nil + } + block = types.NewBlockWithHeader(uncles[index.Int()]) + return s.rpcOutputBlock(block, false, false) + } + return nil, err +} + +// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number +func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *rpc.HexNumber { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + return rpc.NewHexNumber(len(block.Uncles())) + } + return nil +} + +// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash +func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *rpc.HexNumber { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + return rpc.NewHexNumber(len(block.Uncles())) + } + return nil +} + +// NewBlocksArgs allows the user to specify if the returned block should include transactions and in which format. +type NewBlocksArgs struct { + IncludeTransactions bool `json:"includeTransactions"` + TransactionDetails bool `json:"transactionDetails"` +} + +// NewBlocks triggers a new block event each time a block is appended to the chain. It accepts an argument which allows +// the caller to specify whether the output should contain transactions and in what format. +func (s *PublicBlockChainAPI) NewBlocks(ctx context.Context, args NewBlocksArgs) (rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + // create a subscription that will remove itself when unsubscribed/cancelled + subscription, err := notifier.NewSubscription(func(subId string) { + s.muNewBlockSubscriptions.Lock() + delete(s.newBlockSubscriptions, subId) + s.muNewBlockSubscriptions.Unlock() + }) + + if err != nil { + return nil, err + } + + // add a callback that is called on chain events which will format the block and notify the client + s.muNewBlockSubscriptions.Lock() + s.newBlockSubscriptions[subscription.ID()] = func(e core.ChainEvent) error { + notification, err := s.rpcOutputBlock(e.Block, args.IncludeTransactions, args.TransactionDetails) + if err == nil { + return subscription.Notify(notification) + } + glog.V(logger.Warn).Info("unable to format block %v\n", err) + return nil + } + s.muNewBlockSubscriptions.Unlock() + return subscription, nil +} + +// GetCode returns the code stored at the given address in the state for the given block number. +func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (string, error) { + state, _, err := s.b.StateAndHeaderByNumber(blockNr) + if state == nil || err != nil { + return "", err + } + res, err := state.GetCode(ctx, address) + if len(res) == 0 || err != nil { // backwards compatibility + return "0x", err + } + return common.ToHex(res), nil +} + +// GetStorageAt returns the storage from the state at the given address, key and +// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block +// numbers are also allowed. +func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (string, error) { + state, _, err := s.b.StateAndHeaderByNumber(blockNr) + if state == nil || err != nil { + return "0x", err + } + res, err := state.GetState(ctx, address, common.HexToHash(key)) + if err != nil { + return "0x", err + } + return res.Hex(), nil +} + +// callmsg is the message type used for call transations. +type callmsg struct { + addr common.Address + to *common.Address + gas, gasPrice *big.Int + value *big.Int + data []byte +} + +// accessor boilerplate to implement core.Message +func (m callmsg) From() (common.Address, error) { return m.addr, nil } +func (m callmsg) FromFrontier() (common.Address, error) { return m.addr, nil } +func (m callmsg) Nonce() uint64 { return 0 } +func (m callmsg) CheckNonce() bool { return false } +func (m callmsg) To() *common.Address { return m.to } +func (m callmsg) GasPrice() *big.Int { return m.gasPrice } +func (m callmsg) Gas() *big.Int { return m.gas } +func (m callmsg) Value() *big.Int { return m.value } +func (m callmsg) Data() []byte { return m.data } + +// CallArgs represents the arguments for a call. +type CallArgs struct { + From common.Address `json:"from"` + To *common.Address `json:"to"` + Gas rpc.HexNumber `json:"gas"` + GasPrice rpc.HexNumber `json:"gasPrice"` + Value rpc.HexNumber `json:"value"` + Data string `json:"data"` +} + +func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (string, *big.Int, error) { + state, header, err := s.b.StateAndHeaderByNumber(blockNr) + if state == nil || err != nil { + return "0x", common.Big0, err + } + + // Set the account address to interact with + var addr common.Address + if args.From == (common.Address{}) { + accounts := s.b.AccountManager().Accounts() + if len(accounts) == 0 { + addr = common.Address{} + } else { + addr = accounts[0].Address + } + } else { + addr = args.From + } + + // Assemble the CALL invocation + msg := callmsg{ + addr: addr, + to: args.To, + gas: args.Gas.BigInt(), + gasPrice: args.GasPrice.BigInt(), + value: args.Value.BigInt(), + data: common.FromHex(args.Data), + } + + if msg.gas.Cmp(common.Big0) == 0 { + msg.gas = big.NewInt(50000000) + } + + if msg.gasPrice.Cmp(common.Big0) == 0 { + msg.gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) + } + + // Execute the call and return + vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header) + if err != nil { + return "0x", common.Big0, err + } + gp := new(core.GasPool).AddGas(common.MaxBig) + res, gas, err := core.ApplyMessage(vmenv, msg, gp) + if err := vmError(); err != nil { + return "0x", common.Big0, err + } + if len(res) == 0 { // backwards compatability + return "0x", gas, err + } + return common.ToHex(res), gas, err +} + +// Call executes the given transaction on the state for the given block number. +// It doesn't make and changes in the state/blockchain and is usefull to execute and retrieve values. +func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (string, error) { + result, _, err := s.doCall(ctx, args, blockNr) + return result, err +} + +// EstimateGas returns an estimate of the amount of gas needed to execute the given transaction. +func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*rpc.HexNumber, error) { + _, gas, err := s.doCall(ctx, args, rpc.PendingBlockNumber) + return rpc.NewHexNumber(gas), err +} + +// ExecutionResult groups all structured logs emitted by the EVM +// while replaying a transaction in debug mode as well as the amount of +// gas used and the return value +type ExecutionResult struct { + Gas *big.Int `json:"gas"` + ReturnValue string `json:"returnValue"` + StructLogs []StructLogRes `json:"structLogs"` +} + +// StructLogRes stores a structured log emitted by the EVM while replaying a +// transaction in debug mode +type StructLogRes struct { + Pc uint64 `json:"pc"` + Op string `json:"op"` + Gas *big.Int `json:"gas"` + GasCost *big.Int `json:"gasCost"` + Depth int `json:"depth"` + Error error `json:"error"` + Stack []string `json:"stack"` + Memory []string `json:"memory"` + Storage map[string]string `json:"storage"` +} + +// formatLogs formats EVM returned structured logs for json output +func FormatLogs(structLogs []vm.StructLog) []StructLogRes { + formattedStructLogs := make([]StructLogRes, len(structLogs)) + for index, trace := range structLogs { + formattedStructLogs[index] = StructLogRes{ + Pc: trace.Pc, + Op: trace.Op.String(), + Gas: trace.Gas, + GasCost: trace.GasCost, + Depth: trace.Depth, + Error: trace.Err, + Stack: make([]string, len(trace.Stack)), + Storage: make(map[string]string), + } + + for i, stackValue := range trace.Stack { + formattedStructLogs[index].Stack[i] = fmt.Sprintf("%x", common.LeftPadBytes(stackValue.Bytes(), 32)) + } + + for i := 0; i+32 <= len(trace.Memory); i += 32 { + formattedStructLogs[index].Memory = append(formattedStructLogs[index].Memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) + } + + for i, storageValue := range trace.Storage { + formattedStructLogs[index].Storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) + } + } + return formattedStructLogs +} + +// TraceCall executes a call and returns the amount of gas, created logs and optionally returned values. +func (s *PublicBlockChainAPI) TraceCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (*ExecutionResult, error) { + state, header, err := s.b.StateAndHeaderByNumber(blockNr) + if state == nil || err != nil { + return nil, err + } + + var addr common.Address + if args.From == (common.Address{}) { + accounts := s.b.AccountManager().Accounts() + if len(accounts) == 0 { + addr = common.Address{} + } else { + addr = accounts[0].Address + } + } else { + addr = args.From + } + + // Assemble the CALL invocation + msg := callmsg{ + addr: addr, + to: args.To, + gas: args.Gas.BigInt(), + gasPrice: args.GasPrice.BigInt(), + value: args.Value.BigInt(), + data: common.FromHex(args.Data), + } + + if msg.gas.Cmp(common.Big0) == 0 { + msg.gas = big.NewInt(50000000) + } + + if msg.gasPrice.Cmp(common.Big0) == 0 { + msg.gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) + } + + // Execute the call and return + vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header) + if err != nil { + return nil, err + } + gp := new(core.GasPool).AddGas(common.MaxBig) + ret, gas, err := core.ApplyMessage(vmenv, msg, gp) + if err := vmError(); err != nil { + return nil, err + } + return &ExecutionResult{ + Gas: gas, + ReturnValue: fmt.Sprintf("%x", ret), + StructLogs: FormatLogs(vmenv.StructLogs()), + }, nil +} + +// rpcOutputBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are +// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain +// transaction hashes. +func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { + fields := map[string]interface{}{ + "number": rpc.NewHexNumber(b.Number()), + "hash": b.Hash(), + "parentHash": b.ParentHash(), + "nonce": b.Header().Nonce, + "sha3Uncles": b.UncleHash(), + "logsBloom": b.Bloom(), + "stateRoot": b.Root(), + "miner": b.Coinbase(), + "difficulty": rpc.NewHexNumber(b.Difficulty()), + "totalDifficulty": rpc.NewHexNumber(s.b.GetTd(b.Hash())), + "extraData": fmt.Sprintf("0x%x", b.Extra()), + "size": rpc.NewHexNumber(b.Size().Int64()), + "gasLimit": rpc.NewHexNumber(b.GasLimit()), + "gasUsed": rpc.NewHexNumber(b.GasUsed()), + "timestamp": rpc.NewHexNumber(b.Time()), + "transactionsRoot": b.TxHash(), + "receiptRoot": b.ReceiptHash(), + } + + if inclTx { + formatTx := func(tx *types.Transaction) (interface{}, error) { + return tx.Hash(), nil + } + + if fullTx { + formatTx = func(tx *types.Transaction) (interface{}, error) { + return newRPCTransaction(b, tx.Hash()) + } + } + + txs := b.Transactions() + transactions := make([]interface{}, len(txs)) + var err error + for i, tx := range b.Transactions() { + if transactions[i], err = formatTx(tx); err != nil { + return nil, err + } + } + fields["transactions"] = transactions + } + + uncles := b.Uncles() + uncleHashes := make([]common.Hash, len(uncles)) + for i, uncle := range uncles { + uncleHashes[i] = uncle.Hash() + } + fields["uncles"] = uncleHashes + + return fields, nil +} + +// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction +type RPCTransaction struct { + BlockHash common.Hash `json:"blockHash"` + BlockNumber *rpc.HexNumber `json:"blockNumber"` + From common.Address `json:"from"` + Gas *rpc.HexNumber `json:"gas"` + GasPrice *rpc.HexNumber `json:"gasPrice"` + Hash common.Hash `json:"hash"` + Input string `json:"input"` + Nonce *rpc.HexNumber `json:"nonce"` + To *common.Address `json:"to"` + TransactionIndex *rpc.HexNumber `json:"transactionIndex"` + Value *rpc.HexNumber `json:"value"` +} + +// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation +func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { + from, _ := tx.FromFrontier() + + return &RPCTransaction{ + From: from, + Gas: rpc.NewHexNumber(tx.Gas()), + GasPrice: rpc.NewHexNumber(tx.GasPrice()), + Hash: tx.Hash(), + Input: fmt.Sprintf("0x%x", tx.Data()), + Nonce: rpc.NewHexNumber(tx.Nonce()), + To: tx.To(), + Value: rpc.NewHexNumber(tx.Value()), + } +} + +// newRPCTransaction returns a transaction that will serialize to the RPC representation. +func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransaction, error) { + if txIndex >= 0 && txIndex < len(b.Transactions()) { + tx := b.Transactions()[txIndex] + from, err := tx.FromFrontier() + if err != nil { + return nil, err + } + + return &RPCTransaction{ + BlockHash: b.Hash(), + BlockNumber: rpc.NewHexNumber(b.Number()), + From: from, + Gas: rpc.NewHexNumber(tx.Gas()), + GasPrice: rpc.NewHexNumber(tx.GasPrice()), + Hash: tx.Hash(), + Input: fmt.Sprintf("0x%x", tx.Data()), + Nonce: rpc.NewHexNumber(tx.Nonce()), + To: tx.To(), + TransactionIndex: rpc.NewHexNumber(txIndex), + Value: rpc.NewHexNumber(tx.Value()), + }, nil + } + + return nil, nil +} + +// newRPCTransaction returns a transaction that will serialize to the RPC representation. +func newRPCTransaction(b *types.Block, txHash common.Hash) (*RPCTransaction, error) { + for idx, tx := range b.Transactions() { + if tx.Hash() == txHash { + return newRPCTransactionFromBlockIndex(b, idx) + } + } + + return nil, nil +} + +// PublicTransactionPoolAPI exposes methods for the RPC interface +type PublicTransactionPoolAPI struct { + b Backend + muPendingTxSubs sync.Mutex + pendingTxSubs map[string]rpc.Subscription +} + +// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool. +func NewPublicTransactionPoolAPI(b Backend) *PublicTransactionPoolAPI { + api := &PublicTransactionPoolAPI{ + b: b, + pendingTxSubs: make(map[string]rpc.Subscription), + } + + go api.subscriptionLoop() + + return api +} + +// subscriptionLoop listens for events on the global event mux and creates notifications for subscriptions. +func (s *PublicTransactionPoolAPI) subscriptionLoop() { + sub := s.b.EventMux().Subscribe(core.TxPreEvent{}) + for event := range sub.Chan() { + tx := event.Data.(core.TxPreEvent) + if from, err := tx.Tx.FromFrontier(); err == nil { + if s.b.AccountManager().HasAddress(from) { + s.muPendingTxSubs.Lock() + for id, sub := range s.pendingTxSubs { + if sub.Notify(tx.Tx.Hash()) == rpc.ErrNotificationNotFound { + delete(s.pendingTxSubs, id) + } + } + s.muPendingTxSubs.Unlock() + } + } + } +} + +func getTransaction(chainDb ethdb.Database, b Backend, txHash common.Hash) (*types.Transaction, bool, error) { + txData, err := chainDb.Get(txHash.Bytes()) + isPending := false + tx := new(types.Transaction) + + if err == nil && len(txData) > 0 { + if err := rlp.DecodeBytes(txData, tx); err != nil { + return nil, isPending, err + } + } else { + // pending transaction? + tx = b.GetPoolTransaction(txHash) + isPending = true + } + + return tx, isPending, nil +} + +// GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number. +func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *rpc.HexNumber { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + return rpc.NewHexNumber(len(block.Transactions())) + } + return nil +} + +// GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash. +func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *rpc.HexNumber { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + return rpc.NewHexNumber(len(block.Transactions())) + } + return nil +} + +// GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index. +func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index rpc.HexNumber) (*RPCTransaction, error) { + if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { + return newRPCTransactionFromBlockIndex(block, index.Int()) + } + return nil, nil +} + +// GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index. +func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index rpc.HexNumber) (*RPCTransaction, error) { + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + return newRPCTransactionFromBlockIndex(block, index.Int()) + } + return nil, nil +} + +// GetTransactionCount returns the number of transactions the given address has sent for the given block number +func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*rpc.HexNumber, error) { + state, _, err := s.b.StateAndHeaderByNumber(blockNr) + if state == nil || err != nil { + return nil, err + } + nonce, err := state.GetNonce(ctx, address) + if err != nil { + return nil, err + } + return rpc.NewHexNumber(nonce), nil +} + +// getTransactionBlockData fetches the meta data for the given transaction from the chain database. This is useful to +// retrieve block information for a hash. It returns the block hash, block index and transaction index. +func getTransactionBlockData(chainDb ethdb.Database, txHash common.Hash) (common.Hash, uint64, uint64, error) { + var txBlock struct { + BlockHash common.Hash + BlockIndex uint64 + Index uint64 + } + + blockData, err := chainDb.Get(append(txHash.Bytes(), 0x0001)) + if err != nil { + return common.Hash{}, uint64(0), uint64(0), err + } + + reader := bytes.NewReader(blockData) + if err = rlp.Decode(reader, &txBlock); err != nil { + return common.Hash{}, uint64(0), uint64(0), err + } + + return txBlock.BlockHash, txBlock.BlockIndex, txBlock.Index, nil +} + +// GetTransactionByHash returns the transaction for the given hash +func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, txHash common.Hash) (*RPCTransaction, error) { + var tx *types.Transaction + var isPending bool + var err error + + if tx, isPending, err = getTransaction(s.b.ChainDb(), s.b, txHash); err != nil { + glog.V(logger.Debug).Infof("%v\n", err) + return nil, nil + } else if tx == nil { + return nil, nil + } + + if isPending { + return newRPCPendingTransaction(tx), nil + } + + blockHash, _, _, err := getTransactionBlockData(s.b.ChainDb(), txHash) + if err != nil { + glog.V(logger.Debug).Infof("%v\n", err) + return nil, nil + } + + if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { + return newRPCTransaction(block, txHash) + } + + return nil, nil +} + +// GetTransactionReceipt returns the transaction receipt for the given transaction hash. +func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error) { + receipt := core.GetReceipt(s.b.ChainDb(), txHash) + if receipt == nil { + glog.V(logger.Debug).Infof("receipt not found for transaction %s", txHash.Hex()) + return nil, nil + } + + tx, _, err := getTransaction(s.b.ChainDb(), s.b, txHash) + if err != nil { + glog.V(logger.Debug).Infof("%v\n", err) + return nil, nil + } + + txBlock, blockIndex, index, err := getTransactionBlockData(s.b.ChainDb(), txHash) + if err != nil { + glog.V(logger.Debug).Infof("%v\n", err) + return nil, nil + } + + from, err := tx.FromFrontier() + if err != nil { + glog.V(logger.Debug).Infof("%v\n", err) + return nil, nil + } + + fields := map[string]interface{}{ + "root": common.Bytes2Hex(receipt.PostState), + "blockHash": txBlock, + "blockNumber": rpc.NewHexNumber(blockIndex), + "transactionHash": txHash, + "transactionIndex": rpc.NewHexNumber(index), + "from": from, + "to": tx.To(), + "gasUsed": rpc.NewHexNumber(receipt.GasUsed), + "cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed), + "contractAddress": nil, + "logs": receipt.Logs, + } + + if receipt.Logs == nil { + fields["logs"] = []vm.Logs{} + } + + // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation + if bytes.Compare(receipt.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 { + fields["contractAddress"] = receipt.ContractAddress + } + + return fields, nil +} + +// sign is a helper function that signs a transaction with the private key of the given address. +func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { + signature, err := s.b.AccountManager().Sign(addr, tx.SigHash().Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signature) +} + +// SendTxArgs represents the arguments to sumbit a new transaction into the transaction pool. +type SendTxArgs struct { + From common.Address `json:"from"` + To *common.Address `json:"to"` + Gas *rpc.HexNumber `json:"gas"` + GasPrice *rpc.HexNumber `json:"gasPrice"` + Value *rpc.HexNumber `json:"value"` + Data string `json:"data"` + Nonce *rpc.HexNumber `json:"nonce"` +} + +// prepareSendTxArgs is a helper function that fills in default values for unspecified tx fields. +func prepareSendTxArgs(ctx context.Context, args SendTxArgs, b Backend) (SendTxArgs, error) { + if args.Gas == nil { + args.Gas = rpc.NewHexNumber(defaultGas) + } + if args.GasPrice == nil { + price, err := b.SuggestPrice(ctx) + if err != nil { + return args, err + } + args.GasPrice = rpc.NewHexNumber(price) + } + if args.Value == nil { + args.Value = rpc.NewHexNumber(0) + } + return args, nil +} + +// submitTransaction is a helper function that submits tx to txPool and creates a log entry. +func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, signature []byte) (common.Hash, error) { + signedTx, err := tx.WithSignature(signature) + if err != nil { + return common.Hash{}, err + } + + if err := b.SendTx(ctx, signedTx); err != nil { + return common.Hash{}, err + } + + if signedTx.To() == nil { + from, _ := signedTx.From() + addr := crypto.CreateAddress(from, signedTx.Nonce()) + glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) + } else { + glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) + } + + return signedTx.Hash(), nil +} + +// SendTransaction creates a transaction for the given argument, sign it and submit it to the +// transaction pool. +func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { + var err error + args, err = prepareSendTxArgs(ctx, args, s.b) + if err != nil { + return common.Hash{}, err + } + + if args.Nonce == nil { + nonce, err := s.b.GetPoolNonce(ctx, args.From) + if err != nil { + return common.Hash{}, err + } + args.Nonce = rpc.NewHexNumber(nonce) + } + + var tx *types.Transaction + if args.To == nil { + tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) + } else { + tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) + } + + signature, err := s.b.AccountManager().Sign(args.From, tx.SigHash().Bytes()) + if err != nil { + return common.Hash{}, err + } + + return submitTransaction(ctx, s.b, tx, signature) +} + +// SendRawTransaction will add the signed transaction to the transaction pool. +// The sender is responsible for signing the transaction and using the correct nonce. +func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx string) (string, error) { + tx := new(types.Transaction) + if err := rlp.DecodeBytes(common.FromHex(encodedTx), tx); err != nil { + return "", err + } + + if err := s.b.SendTx(ctx, tx); err != nil { + return "", err + } + + if tx.To() == nil { + from, err := tx.FromFrontier() + if err != nil { + return "", err + } + addr := crypto.CreateAddress(from, tx.Nonce()) + glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) + } else { + glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) + } + + return tx.Hash().Hex(), nil +} + +// Sign signs the given hash using the key that matches the address. The key must be +// unlocked in order to sign the hash. +func (s *PublicTransactionPoolAPI) Sign(addr common.Address, hash common.Hash) (string, error) { + signature, error := s.b.AccountManager().Sign(addr, hash[:]) + return common.ToHex(signature), error +} + +// SignTransactionArgs represents the arguments to sign a transaction. +type SignTransactionArgs struct { + From common.Address + To *common.Address + Nonce *rpc.HexNumber + Value *rpc.HexNumber + Gas *rpc.HexNumber + GasPrice *rpc.HexNumber + Data string + + BlockNumber int64 +} + +// Tx is a helper object for argument and return values +type Tx struct { + tx *types.Transaction + + To *common.Address `json:"to"` + From common.Address `json:"from"` + Nonce *rpc.HexNumber `json:"nonce"` + Value *rpc.HexNumber `json:"value"` + Data string `json:"data"` + GasLimit *rpc.HexNumber `json:"gas"` + GasPrice *rpc.HexNumber `json:"gasPrice"` + Hash common.Hash `json:"hash"` +} + +// UnmarshalJSON parses JSON data into tx. +func (tx *Tx) UnmarshalJSON(b []byte) (err error) { + req := struct { + To *common.Address `json:"to"` + From common.Address `json:"from"` + Nonce *rpc.HexNumber `json:"nonce"` + Value *rpc.HexNumber `json:"value"` + Data string `json:"data"` + GasLimit *rpc.HexNumber `json:"gas"` + GasPrice *rpc.HexNumber `json:"gasPrice"` + Hash common.Hash `json:"hash"` + }{} + + if err := json.Unmarshal(b, &req); err != nil { + return err + } + + tx.To = req.To + tx.From = req.From + tx.Nonce = req.Nonce + tx.Value = req.Value + tx.Data = req.Data + tx.GasLimit = req.GasLimit + tx.GasPrice = req.GasPrice + tx.Hash = req.Hash + + data := common.Hex2Bytes(tx.Data) + + if tx.Nonce == nil { + return fmt.Errorf("need nonce") + } + if tx.Value == nil { + tx.Value = rpc.NewHexNumber(0) + } + if tx.GasLimit == nil { + tx.GasLimit = rpc.NewHexNumber(0) + } + if tx.GasPrice == nil { + tx.GasPrice = rpc.NewHexNumber(int64(50000000000)) + } + + if req.To == nil { + tx.tx = types.NewContractCreation(tx.Nonce.Uint64(), tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data) + } else { + tx.tx = types.NewTransaction(tx.Nonce.Uint64(), *tx.To, tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data) + } + + return nil +} + +// SignTransactionResult represents a RLP encoded signed transaction. +type SignTransactionResult struct { + Raw string `json:"raw"` + Tx *Tx `json:"tx"` +} + +func newTx(t *types.Transaction) *Tx { + from, _ := t.FromFrontier() + return &Tx{ + tx: t, + To: t.To(), + From: from, + Value: rpc.NewHexNumber(t.Value()), + Nonce: rpc.NewHexNumber(t.Nonce()), + Data: "0x" + common.Bytes2Hex(t.Data()), + GasLimit: rpc.NewHexNumber(t.Gas()), + GasPrice: rpc.NewHexNumber(t.GasPrice()), + Hash: t.Hash(), + } +} + +// SignTransaction will sign the given transaction with the from account. +// The node needs to have the private key of the account corresponding with +// the given from address and it needs to be unlocked. +func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SignTransactionArgs) (*SignTransactionResult, error) { + if args.Gas == nil { + args.Gas = rpc.NewHexNumber(defaultGas) + } + if args.GasPrice == nil { + price, err := s.b.SuggestPrice(ctx) + if err != nil { + return nil, err + } + args.GasPrice = rpc.NewHexNumber(price) + } + if args.Value == nil { + args.Value = rpc.NewHexNumber(0) + } + + if args.Nonce == nil { + nonce, err := s.b.GetPoolNonce(ctx, args.From) + if err != nil { + return nil, err + } + args.Nonce = rpc.NewHexNumber(nonce) + } + + var tx *types.Transaction + if args.To == nil { + tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) + } else { + tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data)) + } + + signedTx, err := s.sign(args.From, tx) + if err != nil { + return nil, err + } + + data, err := rlp.EncodeToBytes(signedTx) + if err != nil { + return nil, err + } + + return &SignTransactionResult{"0x" + common.Bytes2Hex(data), newTx(signedTx)}, nil +} + +// PendingTransactions returns the transactions that are in the transaction pool and have a from address that is one of +// the accounts this node manages. +func (s *PublicTransactionPoolAPI) PendingTransactions() []*RPCTransaction { + pending := s.b.GetPoolTransactions() + transactions := make([]*RPCTransaction, 0, len(pending)) + for _, tx := range pending { + from, _ := tx.FromFrontier() + if s.b.AccountManager().HasAddress(from) { + transactions = append(transactions, newRPCPendingTransaction(tx)) + } + } + return transactions +} + +// NewPendingTransactions creates a subscription that is triggered each time a transaction enters the transaction pool +// and is send from one of the transactions this nodes manages. +func (s *PublicTransactionPoolAPI) NewPendingTransactions(ctx context.Context) (rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + subscription, err := notifier.NewSubscription(func(id string) { + s.muPendingTxSubs.Lock() + delete(s.pendingTxSubs, id) + s.muPendingTxSubs.Unlock() + }) + + if err != nil { + return nil, err + } + + s.muPendingTxSubs.Lock() + s.pendingTxSubs[subscription.ID()] = subscription + s.muPendingTxSubs.Unlock() + + return subscription, nil +} + +// Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the +// pool and reinsert it with the new gas price and limit. +func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx *Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) { + + pending := s.b.GetPoolTransactions() + for _, p := range pending { + if pFrom, err := p.FromFrontier(); err == nil && pFrom == tx.From && p.SigHash() == tx.tx.SigHash() { + if gasPrice == nil { + gasPrice = rpc.NewHexNumber(tx.tx.GasPrice()) + } + if gasLimit == nil { + gasLimit = rpc.NewHexNumber(tx.tx.Gas()) + } + + var newTx *types.Transaction + if tx.tx.To() == nil { + newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) + } else { + newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) + } + + signedTx, err := s.sign(tx.From, newTx) + if err != nil { + return common.Hash{}, err + } + + s.b.RemoveTx(tx.Hash) + if err = s.b.SendTx(ctx, signedTx); err != nil { + return common.Hash{}, err + } + + return signedTx.Hash(), nil + } + } + + return common.Hash{}, fmt.Errorf("Transaction %#x not found", tx.Hash) +} + +// PrivateAdminAPI is the collection of Etheruem APIs exposed over the private +// admin endpoint. +type PrivateAdminAPI struct { + b Backend + solcPath *string + solc **compiler.Solidity +} + +// NewPrivateAdminAPI creates a new API definition for the private admin methods +// of the Ethereum service. +func NewPrivateAdminAPI(b Backend, solcPath *string, solc **compiler.Solidity) *PrivateAdminAPI { + return &PrivateAdminAPI{b, solcPath, solc} +} + +// SetSolc sets the Solidity compiler path to be used by the node. +func (api *PrivateAdminAPI) SetSolc(path string) (string, error) { + var err error + *api.solcPath = path + *api.solc, err = compiler.New(path) + if err != nil { + return "", err + } + return (*api.solc).Info(), nil +} + +// PublicDebugAPI is the collection of Etheruem APIs exposed over the public +// debugging endpoint. +type PublicDebugAPI struct { + b Backend +} + +// NewPublicDebugAPI creates a new API definition for the public debug methods +// of the Ethereum service. +func NewPublicDebugAPI(b Backend) *PublicDebugAPI { + return &PublicDebugAPI{b: b} +} + +// GetBlockRlp retrieves the RLP encoded for of a single block. +func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return "", fmt.Errorf("block #%d not found", number) + } + encoded, err := rlp.EncodeToBytes(block) + if err != nil { + return "", err + } + return fmt.Sprintf("%x", encoded), nil +} + +// PrintBlock retrieves a block and returns its pretty printed form. +func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return "", fmt.Errorf("block #%d not found", number) + } + return fmt.Sprintf("%s", block), nil +} + +// SeedHash retrieves the seed hash of a block. +func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { + block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) + if block == nil { + return "", fmt.Errorf("block #%d not found", number) + } + hash, err := ethash.GetSeedHash(number) + if err != nil { + return "", err + } + return fmt.Sprintf("0x%x", hash), nil +} + +// PrivateDebugAPI is the collection of Etheruem APIs exposed over the private +// debugging endpoint. +type PrivateDebugAPI struct { + b Backend +} + +// NewPrivateDebugAPI creates a new API definition for the private debug methods +// of the Ethereum service. +func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { + return &PrivateDebugAPI{b: b} +} + +// ChaindbProperty returns leveldb properties of the chain database. +func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { + ldb, ok := api.b.ChainDb().(interface { + LDB() *leveldb.DB + }) + if !ok { + return "", fmt.Errorf("chaindbProperty does not work for memory databases") + } + if property == "" { + property = "leveldb.stats" + } else if !strings.HasPrefix(property, "leveldb.") { + property = "leveldb." + property + } + return ldb.LDB().GetProperty(property) +} + +// SetHead rewinds the head of the blockchain to a previous block. +func (api *PrivateDebugAPI) SetHead(number uint64) { + api.b.SetHead(number) +} + +// PublicNetAPI offers network related RPC methods +type PublicNetAPI struct { + net *p2p.Server + networkVersion int +} + +// NewPublicNetAPI creates a new net API instance. +func NewPublicNetAPI(net *p2p.Server, networkVersion int) *PublicNetAPI { + return &PublicNetAPI{net, networkVersion} +} + +// Listening returns an indication if the node is listening for network connections. +func (s *PublicNetAPI) Listening() bool { + return true // always listening +} + +// PeerCount returns the number of connected peers +func (s *PublicNetAPI) PeerCount() *rpc.HexNumber { + return rpc.NewHexNumber(s.net.PeerCount()) +} + +// Version returns the current ethereum protocol version. +func (s *PublicNetAPI) Version() string { + return fmt.Sprintf("%d", s.networkVersion) +} diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go new file mode 100644 index 000000000..d112a6aef --- /dev/null +++ b/internal/ethapi/backend.go @@ -0,0 +1,119 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +// Package ethapi implements the general Ethereum API functions. +package ethapi + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/compiler" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/context" +) + +// Backend interface provides the common API services (that are provided by +// both full and light clients) with access to necessary functions. +type Backend interface { + // general Ethereum API + Downloader() *downloader.Downloader + ProtocolVersion() int + SuggestPrice(ctx context.Context) (*big.Int, error) + ChainDb() ethdb.Database + EventMux() *event.TypeMux + AccountManager() *accounts.Manager + // BlockChain API + SetHead(number uint64) + HeaderByNumber(blockNr rpc.BlockNumber) *types.Header + BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) + StateAndHeaderByNumber(blockNr rpc.BlockNumber) (State, *types.Header, error) + GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) + GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) + GetTd(blockHash common.Hash) *big.Int + GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (vm.Environment, func() error, error) + // TxPool API + SendTx(ctx context.Context, signedTx *types.Transaction) error + RemoveTx(txHash common.Hash) + GetPoolTransactions() types.Transactions + GetPoolTransaction(txHash common.Hash) *types.Transaction + GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) + Stats() (pending int, queued int) + TxPoolContent() (map[common.Address]map[uint64][]*types.Transaction, map[common.Address]map[uint64][]*types.Transaction) +} + +type State interface { + GetBalance(ctx context.Context, addr common.Address) (*big.Int, error) + GetCode(ctx context.Context, addr common.Address) ([]byte, error) + GetState(ctx context.Context, a common.Address, b common.Hash) (common.Hash, error) + GetNonce(ctx context.Context, addr common.Address) (uint64, error) +} + +func GetAPIs(apiBackend Backend, solcPath *string, solc **compiler.Solidity) []rpc.API { + return []rpc.API{ + { + Namespace: "eth", + Version: "1.0", + Service: NewPublicEthereumAPI(apiBackend, solcPath, solc), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicBlockChainAPI(apiBackend), + Public: true, + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicTransactionPoolAPI(apiBackend), + Public: true, + }, { + Namespace: "txpool", + Version: "1.0", + Service: NewPublicTxPoolAPI(apiBackend), + Public: true, + }, { + Namespace: "admin", + Version: "1.0", + Service: NewPrivateAdminAPI(apiBackend, solcPath, solc), + }, { + Namespace: "debug", + Version: "1.0", + Service: NewPublicDebugAPI(apiBackend), + Public: true, + }, { + Namespace: "debug", + Version: "1.0", + Service: NewPrivateDebugAPI(apiBackend), + }, { + Namespace: "eth", + Version: "1.0", + Service: NewPublicAccountAPI(apiBackend.AccountManager()), + Public: true, + }, { + Namespace: "personal", + Version: "1.0", + Service: NewPrivateAccountAPI(apiBackend), + Public: false, + }, + } +} diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 8d5d1500f..162cf7096 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -111,21 +111,6 @@ web3._extend({ params: 3 }), new web3._extend.Method({ - name: 'startNatSpec', - call: 'admin_startNatSpec', - params: 0 - }), - new web3._extend.Method({ - name: 'stopNatSpec', - call: 'admin_stopNatSpec', - params: 0 - }), - new web3._extend.Method({ - name: 'getContractInfo', - call: 'admin_getContractInfo', - params: 1 - }), - new web3._extend.Method({ name: 'httpGet', call: 'admin_httpGet', params: 2 diff --git a/miner/worker.go b/miner/worker.go index 09cf6b6aa..dfda6d898 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -17,6 +17,7 @@ package miner import ( + "bytes" "fmt" "math/big" "sync" @@ -33,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" "gopkg.in/fatih/set.v0" ) @@ -468,7 +470,19 @@ func (self *worker) commitNewWork() { Extra: self.extra, Time: big.NewInt(tstamp), } - + // If we are care about TheDAO hard-fork check whether to override the extra-data or not + if daoBlock := self.config.DAOForkBlock; daoBlock != nil { + // Check whether the block is among the fork extra-override range + limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) + if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 { + // Depending whether we support or oppose the fork, override differently + if self.config.DAOForkSupport { + header.Extra = common.CopyBytes(params.DAOForkBlockExtra) + } else if bytes.Compare(header.Extra, params.DAOForkBlockExtra) == 0 { + header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data + } + } + } previous := self.current // Could potentially happen if starting to mine in an odd state. err := self.makeCurrent(parent, header) @@ -476,7 +490,11 @@ func (self *worker) commitNewWork() { glog.V(logger.Info).Infoln("Could not create new env for mining, retrying on next block.") return } + // Create the current work task and check any fork transitions needed work := self.current + if self.config.DAOForkSupport && self.config.DAOForkBlock != nil && self.config.DAOForkBlock.Cmp(header.Number) == 0 { + core.ApplyDAOHardFork(work.state) + } /* //approach 1 transactions := self.eth.TxPool().GetTransactions() diff --git a/p2p/discover/database.go b/p2p/discover/database.go index 6d448515d..d6ea507bb 100644 --- a/p2p/discover/database.go +++ b/p2p/discover/database.go @@ -243,7 +243,7 @@ func (db *nodeDB) expirer() { } // expireNodes iterates over the database and deletes all nodes that have not -// been seen (i.e. received a pong from) for some alloted time. +// been seen (i.e. received a pong from) for some allotted time. func (db *nodeDB) expireNodes() error { threshold := time.Now().Add(-nodeDBNodeExpiration) diff --git a/params/dao.go b/params/dao.go new file mode 100644 index 000000000..3e2a68cc9 --- /dev/null +++ b/params/dao.go @@ -0,0 +1,418 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package params + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + +// TestNetDAOForkBlock is the block number where the DAO hard-fork commences on +// the Ethereum test network. It's enforced nil since it was decided not to do a +// testnet transition. +var TestNetDAOForkBlock *big.Int + +// MainNetDAOForkBlock is the block number where the DAO hard-fork commences on +// the Ethereum main network. +var MainNetDAOForkBlock = big.NewInt(1920000) + +// DAOForkBlockExtra is the block header extra-data field to set for the DAO fork +// point and a number of consecutive blocks to allow fast/light syncers to correctly +// pick the side they want ("dao-hard-fork"). +var DAOForkBlockExtra = common.FromHex("0x64616f2d686172642d666f726b") + +// DAOForkExtraRange is the number of consecutive blocks from the DAO fork point +// to override the extra-data in to prevent no-fork attacks. +var DAOForkExtraRange = big.NewInt(10) + +// DAORefundContract is the address of the refund contract to send DAO balances to. +var DAORefundContract = common.HexToAddress("0xbf4ed7b27f1d666546e30d74d50d173d20bca754") + +// DAODrainList is the list of accounts whose full balances will be moved into a +// refund contract at the beginning of the dao-fork block. +var DAODrainList []common.Address + +func init() { + // Parse the list of DAO accounts to drain + var list []map[string]string + if err := json.Unmarshal([]byte(daoDrainListJSON), &list); err != nil { + panic(fmt.Errorf("Failed to parse DAO drain list: %v", err)) + } + // Collect all the accounts that need draining + for _, dao := range list { + DAODrainList = append(DAODrainList, common.HexToAddress(dao["address"])) + DAODrainList = append(DAODrainList, common.HexToAddress(dao["extraBalanceAccount"])) + } +} + +// daoDrainListJSON is the JSON encoded list of accounts whose full balances will +// be moved into a refund contract at the beginning of the dao-fork block. +const daoDrainListJSON = ` +[ + { + "address":"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728", + "balance":"186cc8bfaefb7be", + "extraBalance":"0", + "extraBalanceAccount":"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425" + }, + { + "address":"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f", + "balance":"b14e8feab1ff435", + "extraBalance":"0", + "extraBalanceAccount":"0xecd135fa4f61a655311e86238c92adcd779555d2" + }, + { + "address":"0x1975bd06d486162d5dc297798dfc41edd5d160a7", + "balance":"359d26614cb5070c77", + "extraBalance":"0", + "extraBalanceAccount":"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6" + }, + { + "address":"0x319f70bab6845585f412ec7724b744fec6095c85", + "balance":"6e075cd846d2cb1d42", + "extraBalance":"13d34fd41b545b81", + "extraBalanceAccount":"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936" + }, + { + "address":"0x5c8536898fbb74fc7445814902fd08422eac56d0", + "balance":"b1e5593558008fd78", + "extraBalance":"0", + "extraBalanceAccount":"0x6966ab0d485353095148a2155858910e0965b6f9" + }, + { + "address":"0x779543a0491a837ca36ce8c635d6154e3c4911a6", + "balance":"392eaa20d1aad59a4c", + "extraBalance":"426938826a96c9", + "extraBalanceAccount":"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c" + }, + { + "address":"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5", + "balance":"2875d22b29793d4ba7", + "extraBalance":"0", + "extraBalanceAccount":"0x9c50426be05db97f5d64fc54bf89eff947f0a321" + }, + { + "address":"0x200450f06520bdd6c527622a273333384d870efb", + "balance":"43c341d9f96954c049", + "extraBalance":"0", + "extraBalanceAccount":"0xbe8539bfe837b67d1282b2b1d61c3f723966f049" + }, + { + "address":"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb", + "balance":"75251057154d70fa816", + "extraBalance":"0", + "extraBalanceAccount":"0xf1385fb24aad0cd7432824085e42aff90886fef5" + }, + { + "address":"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091", + "balance":"392409769296cf67f36", + "extraBalance":"0", + "extraBalanceAccount":"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd" + }, + { + "address":"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6", + "balance":"8ac72eccbf4e8083", + "extraBalance":"0", + "extraBalanceAccount":"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7" + }, + { + "address":"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5", + "balance":"82289c3bb3e8c98799", + "extraBalance":"0", + "extraBalanceAccount":"0x24c4d950dfd4dd1902bbed3508144a54542bba94" + }, + { + "address":"0x9f27daea7aca0aa0446220b98d028715e3bc803d", + "balance":"56bc29049ebed40fd", + "extraBalance":"0", + "extraBalanceAccount":"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" + }, + { + "address":"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b", + "balance":"56bc7d3ff79110524", + "extraBalance":"0", + "extraBalanceAccount":"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf" + }, + { + "address":"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d", + "balance":"23b651bd48cbc70cc", + "extraBalance":"0", + "extraBalanceAccount":"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" + }, + { + "address":"0x492ea3bb0f3315521c31f273e565b868fc090f17", + "balance":"13ea6d4fee651dd7c9", + "extraBalance":"0", + "extraBalanceAccount":"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00" + }, + { + "address":"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416", + "balance":"35ac471a3836ae7de5a", + "extraBalance":"0", + "extraBalanceAccount":"0xceaeb481747ca6c540a000c1f3641f8cef161fa7" + }, + { + "address":"0xcc34673c6c40e791051898567a1222daf90be287", + "balance":"d529c0b76b7aa0", + "extraBalance":"0", + "extraBalanceAccount":"0x579a80d909f346fbfb1189493f521d7f48d52238" + }, + { + "address":"0xe308bd1ac5fda103967359b2712dd89deffb7973", + "balance":"5cd9e7df3a8e5cdd3", + "extraBalance":"0", + "extraBalanceAccount":"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c" + }, + { + "address":"0xac1ecab32727358dba8962a0f3b261731aad9723", + "balance":"2c8442fe35363313b93", + "extraBalance":"0", + "extraBalanceAccount":"0x4fd6ace747f06ece9c49699c7cabc62d02211f75" + }, + { + "address":"0x440c59b325d2997a134c2c7c60a8c61611212bad", + "balance":"e77583a3958130e53", + "extraBalance":"0", + "extraBalanceAccount":"0x4486a3d68fac6967006d7a517b889fd3f98c102b" + }, + { + "address":"0x9c15b54878ba618f494b38f0ae7443db6af648ba", + "balance":"1f0b6ade348ca998", + "extraBalance":"0", + "extraBalanceAccount":"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f" + }, + { + "address":"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241", + "balance":"61725880736659", + "extraBalance":"0", + "extraBalanceAccount":"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50" + }, + { + "address":"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b", + "balance":"42948d8dc7ddbc22d", + "extraBalance":"0", + "extraBalanceAccount":"0xb9637156d330c0d605a791f1c31ba5890582fe1c" + }, + { + "address":"0x6131c42fa982e56929107413a9d526fd99405560", + "balance":"7306683851d1eafbfa", + "extraBalance":"0", + "extraBalanceAccount":"0x1591fc0f688c81fbeb17f5426a162a7024d430c2" + }, + { + "address":"0x542a9515200d14b68e934e9830d91645a980dd7a", + "balance":"2a8457d0d8432e21d0c", + "extraBalance":"0", + "extraBalanceAccount":"0xc4bbd073882dd2add2424cf47d35213405b01324" + }, + { + "address":"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4", + "balance":"d8d7391feaeaa8cdb", + "extraBalance":"0", + "extraBalanceAccount":"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb" + }, + { + "address":"0x3ba4d81db016dc2890c81f3acec2454bff5aada5", + "balance":"1", + "extraBalance":"0", + "extraBalanceAccount":"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab" + }, + { + "address":"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1", + "balance":"456397665fa74041", + "extraBalance":"0", + "extraBalanceAccount":"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" + }, + { + "address":"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53", + "balance":"6324dcb7126ecbef", + "extraBalance":"0", + "extraBalanceAccount":"0x97f43a37f595ab5dd318fb46e7a155eae057317a" + }, + { + "address":"0x52c5317c848ba20c7504cb2c8052abd1fde29d03", + "balance":"6c3419b0705c01cd0d", + "extraBalance":"0", + "extraBalanceAccount":"0x4863226780fe7c0356454236d3b1c8792785748d" + }, + { + "address":"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479", + "balance":"456397665fa74041", + "extraBalance":"0", + "extraBalanceAccount":"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c" + }, + { + "address":"0x057b56736d32b86616a10f619859c6cd6f59092a", + "balance":"232c025bb44b46", + "extraBalance":"0", + "extraBalanceAccount":"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192" + }, + { + "address":"0x304a554a310c7e546dfe434669c62820b7d83490", + "balance":"3034f5ca7d45e17df199b", + "extraBalance":"f7d15162c44e97b6e", + "extraBalanceAccount":"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" + }, + { + "address":"0x4deb0033bb26bc534b197e61d19e0733e5679784", + "balance":"4417e96ed796591e09", + "extraBalance":"0", + "extraBalanceAccount":"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" + }, + { + "address":"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b", + "balance":"d3ff7771412bbcc9", + "extraBalance":"0", + "extraBalanceAccount":"0x4fa802324e929786dbda3b8820dc7834e9134a2a" + }, + { + "address":"0x9da397b9e80755301a3b32173283a91c0ef6c87e", + "balance":"32ae324c233816b4c2", + "extraBalance":"0", + "extraBalanceAccount":"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6" + }, + { + "address":"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9", + "balance":"1e530695b705f037c6", + "extraBalance":"0", + "extraBalanceAccount":"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f" + }, + { + "address":"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76", + "balance":"68013bad5b4b1133fc5", + "extraBalance":"0", + "extraBalanceAccount":"0x12e626b0eebfe86a56d633b9864e389b45dcb260" + }, + { + "address":"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7", + "balance":"456397665fa74041", + "extraBalance":"0", + "extraBalanceAccount":"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" + }, + { + "address":"0xd164b088bd9108b60d0ca3751da4bceb207b0782", + "balance":"3635ce47fabaaa336e", + "extraBalance":"0", + "extraBalanceAccount":"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b" + }, + { + "address":"0x1cba23d343a983e9b5cfd19496b9a9701ada385f", + "balance":"f3abd9906c170a", + "extraBalance":"0", + "extraBalanceAccount":"0xa82f360a8d3455c5c41366975bde739c37bfeb8a" + }, + { + "address":"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339", + "balance":"4c6679d9d9b95a4e08", + "extraBalance":"0", + "extraBalanceAccount":"0x005f5cee7a43331d5a3d3eec71305925a62f34b6" + }, + { + "address":"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d", + "balance":"40f622936475de31849", + "extraBalance":"671e1bbabded39754", + "extraBalanceAccount":"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e" + }, + { + "address":"0xbc07118b9ac290e4622f5e77a0853539789effbe", + "balance":"1316ccfa4a35db5e58f", + "extraBalance":"0", + "extraBalanceAccount":"0x47e7aa56d6bdf3f36be34619660de61275420af8" + }, + { + "address":"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225", + "balance":"b3ad6bb72000bab9f", + "extraBalance":"0", + "extraBalanceAccount":"0xadf80daec7ba8dcf15392f1ac611fff65d94f880" + }, + { + "address":"0x5524c55fb03cf21f549444ccbecb664d0acad706", + "balance":"16f2da372a5c8a70967", + "extraBalance":"0", + "extraBalanceAccount":"0x40b803a9abce16f50f36a77ba41180eb90023925" + }, + { + "address":"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f", + "balance":"ea0b1bdc78f500a43", + "extraBalance":"0", + "extraBalanceAccount":"0x17802f43a0137c506ba92291391a8a8f207f487d" + }, + { + "address":"0x253488078a4edf4d6f42f113d1e62836a942cf1a", + "balance":"3060e3aed135cc80", + "extraBalance":"0", + "extraBalanceAccount":"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915" + }, + { + "address":"0xb136707642a4ea12fb4bae820f03d2562ebff487", + "balance":"6050bdeb3354b5c98adc3", + "extraBalance":"0", + "extraBalanceAccount":"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940" + }, + { + "address":"0xf14c14075d6c4ed84b86798af0956deef67365b5", + "balance":"1d77844e94c25ba2", + "extraBalance":"0", + "extraBalanceAccount":"0xca544e5c4687d109611d0f8f928b53a25af72448" + }, + { + "address":"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c", + "balance":"2e93a72de4fc5ec0ed", + "extraBalance":"0", + "extraBalanceAccount":"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7" + }, + { + "address":"0x6d87578288b6cb5549d5076a207456a1f6a63dc0", + "balance":"1afd340799e48c18", + "extraBalance":"0", + "extraBalanceAccount":"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" + }, + { + "address":"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6", + "balance":"14d0944eb3be947a8", + "extraBalance":"0", + "extraBalanceAccount":"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2" + }, + { + "address":"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a", + "balance":"6202b236a200e365eba", + "extraBalance":"11979be9020f03ec4ec", + "extraBalanceAccount":"0xd343b217de44030afaa275f54d31a9317c7f441e" + }, + { + "address":"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106", + "balance":"7ed634ebbba531901e07", + "extraBalance":"f9c5eff28cb08720c85", + "extraBalanceAccount":"0xda2fef9e4a3230988ff17df2165440f37e8b1708" + }, + { + "address":"0xf4c64518ea10f995918a454158c6b61407ea345c", + "balance":"39152e15508a96ff894a", + "extraBalance":"14041ca908bcc185c8", + "extraBalanceAccount":"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97" + }, + { + "address":"0xbb9bc244d798123fde783fcc1c72d3bb8c189413", + "balance":"1", + "extraBalance":"5553ebc", + "extraBalanceAccount":"0x807640a13483f8ac783c557fcdf27be11ea4ac7a" + } +] +` diff --git a/params/util.go b/params/util.go index b37bc79b2..9d1fa54e6 100644 --- a/params/util.go +++ b/params/util.go @@ -19,6 +19,6 @@ package params import "math/big" var ( - TestNetHomesteadBlock = big.NewInt(494000) // testnet homestead block - MainNetHomesteadBlock = big.NewInt(1150000) // mainnet homestead block + TestNetHomesteadBlock = big.NewInt(494000) // Testnet homestead block + MainNetHomesteadBlock = big.NewInt(1150000) // Mainnet homestead block ) diff --git a/release/release.go b/release/release.go index 05b4885b5..21b5e2ce2 100644 --- a/release/release.go +++ b/release/release.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/context" ) // Interval to check for new releases @@ -110,7 +111,9 @@ func (r *ReleaseService) checker() { timer.Reset(releaseRecheckInterval) // Retrieve the current version, and handle missing contracts gracefully - version, err := r.oracle.CurrentVersion(nil) + ctx, _ := context.WithTimeout(context.Background(), time.Second*5) + opts := &bind.CallOpts{Context: ctx} + version, err := r.oracle.CurrentVersion(opts) if err != nil { if err == bind.ErrNoCode { glog.V(logger.Debug).Infof("Release oracle not found at %x", r.config.Oracle) diff --git a/rpc/doc.go b/rpc/doc.go index 77202634f..14b3780ad 100644 --- a/rpc/doc.go +++ b/rpc/doc.go @@ -49,7 +49,7 @@ arguments. It will pass the mod argument as nil to the RPC method. The server offers the ServeCodec method which accepts a ServerCodec instance. It will read requests from the codec, process the request and sends the response back to the client using the codec. The server can execute requests concurrently. Responses -can be send back to the client out of order. +can be sent back to the client out of order. An example server which uses the JSON codec: type CalculatorService struct {} diff --git a/rpc/ipc_windows.go b/rpc/ipc_windows.go index 8762cdb0d..8342d04d5 100644 --- a/rpc/ipc_windows.go +++ b/rpc/ipc_windows.go @@ -22,16 +22,16 @@ import ( "net" "time" - winio "github.com/microsoft/go-winio" + "gopkg.in/natefinch/npipe.v2" ) // ipcListen will create a named pipe on the given endpoint. func ipcListen(endpoint string) (net.Listener, error) { - return winio.ListenPipe(endpoint, &winio.PipeConfig{}) + return npipe.Listen(endpoint) } // newIPCConnection will connect to a named pipe with the given endpoint as name. func newIPCConnection(endpoint string) (net.Conn, error) { timeout := 5 * time.Second - return winio.DialPipe(endpoint, &timeout) + return npipe.DialTimeout(endpoint, timeout) } diff --git a/rpc/server.go b/rpc/server.go index 69f3271e8..7b7d22063 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -82,7 +82,7 @@ func (s *RPCService) Modules() map[string]string { return modules } -// RegisterName will create an service for the given rcvr type under the given name. When no methods on the given rcvr +// RegisterName will create a service for the given rcvr type under the given name. When no methods on the given rcvr // match the criteria to be either a RPC method or a subscription an error is returned. Otherwise a new service is // created and added to the service collection this server instance serves. func (s *Server) RegisterName(name string, rcvr interface{}) error { @@ -236,7 +236,7 @@ func (s *Server) ServeSingleRequest(codec ServerCodec, options CodecOption) { } // Stop will stop reading new requests, wait for stopPendingRequestTimeout to allow pending requests to finish, -// close all codecs which will cancels pending requests/subscriptions. +// close all codecs which will cancel pending requests/subscriptions. func (s *Server) Stop() { if atomic.CompareAndSwapInt32(&s.run, 1, 0) { glog.V(logger.Debug).Infoln("RPC Server shutdown initiatied") @@ -294,7 +294,7 @@ func (s *Server) handle(ctx context.Context, codec ServerCodec, req *serverReque return codec.CreateErrorResponse(&req.id, &callbackError{err.Error()}), nil } - // active the subscription after the sub id was successful sent to the client + // active the subscription after the sub id was successfully sent to the client activateSub := func() { notifier, _ := NotifierFromContext(ctx) notifier.(*bufferedNotifier).activate(subid) diff --git a/tests/block_test.go b/tests/block_test.go index c258268db..448f2bd76 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -23,63 +23,63 @@ import ( ) func TestBcValidBlockTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcValidBlockTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcValidBlockTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcUncleHeaderValidityTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcUncleHeaderValiditiy.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcUncleTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcUncleTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcUncleTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcForkUncleTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcForkUncle.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcForkUncle.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcInvalidHeaderTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcInvalidHeaderTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcInvalidRLPTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcInvalidRLPTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcRPCAPITests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcRPC_API_Test.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcRPC_API_Test.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcForkBlockTests(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcForkBlockTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcForkBlockTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcForkStress(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcForkStressTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcForkStressTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } @@ -89,21 +89,21 @@ func TestBcTotalDifficulty(t *testing.T) { // skip because these will fail due to selfish mining fix t.Skip() - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcTotalDifficultyTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcWallet(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcWalletTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcWalletTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcGasPricer(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcGasPricerTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcGasPricerTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } @@ -111,7 +111,7 @@ func TestBcGasPricer(t *testing.T) { // TODO: iterate over files once we got more than a few func TestBcRandom(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "RandomTests/bl201507071825GO.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "RandomTests/bl201507071825GO.json"), BlockSkipTests) if err != nil { t.Fatal(err) } @@ -121,14 +121,14 @@ func TestBcMultiChain(t *testing.T) { // skip due to selfish mining t.Skip() - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcMultiChainTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcMultiChainTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestBcState(t *testing.T) { - err := RunBlockTest(big.NewInt(1000000), filepath.Join(blockTestDir, "bcStateTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(1000000), nil, filepath.Join(blockTestDir, "bcStateTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } @@ -136,77 +136,85 @@ func TestBcState(t *testing.T) { // Homestead tests func TestHomesteadBcValidBlockTests(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcValidBlockTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcValidBlockTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcUncleHeaderValidityTests(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcUncleHeaderValiditiy.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcUncleHeaderValiditiy.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcUncleTests(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcUncleTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcUncleTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcInvalidHeaderTests(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcInvalidHeaderTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcInvalidHeaderTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcRPCAPITests(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcRPC_API_Test.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcRPC_API_Test.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcForkStress(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcForkStressTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcForkStressTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcTotalDifficulty(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcTotalDifficultyTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcTotalDifficultyTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcWallet(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcWalletTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcWalletTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcGasPricer(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcGasPricerTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcGasPricerTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcMultiChain(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcMultiChainTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcMultiChainTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } } func TestHomesteadBcState(t *testing.T) { - err := RunBlockTest(big.NewInt(0), filepath.Join(blockTestDir, "Homestead", "bcStateTest.json"), BlockSkipTests) + err := RunBlockTest(big.NewInt(0), nil, filepath.Join(blockTestDir, "Homestead", "bcStateTest.json"), BlockSkipTests) + if err != nil { + t.Fatal(err) + } +} + +// DAO hard-fork tests +func TestDAOBcTheDao(t *testing.T) { + err := RunBlockTest(big.NewInt(5), big.NewInt(8), filepath.Join(blockTestDir, "TestNetwork", "bcTheDaoTest.json"), BlockSkipTests) if err != nil { t.Fatal(err) } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index d9a5eec08..7da15cebe 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -103,7 +103,7 @@ type btTransaction struct { Value string } -func RunBlockTestWithReader(homesteadBlock *big.Int, r io.Reader, skipTests []string) error { +func RunBlockTestWithReader(homesteadBlock, daoForkBlock *big.Int, r io.Reader, skipTests []string) error { btjs := make(map[string]*btJSON) if err := readJson(r, &btjs); err != nil { return err @@ -114,13 +114,13 @@ func RunBlockTestWithReader(homesteadBlock *big.Int, r io.Reader, skipTests []st return err } - if err := runBlockTests(homesteadBlock, bt, skipTests); err != nil { + if err := runBlockTests(homesteadBlock, daoForkBlock, bt, skipTests); err != nil { return err } return nil } -func RunBlockTest(homesteadBlock *big.Int, file string, skipTests []string) error { +func RunBlockTest(homesteadBlock, daoForkBlock *big.Int, file string, skipTests []string) error { btjs := make(map[string]*btJSON) if err := readJsonFile(file, &btjs); err != nil { return err @@ -130,13 +130,13 @@ func RunBlockTest(homesteadBlock *big.Int, file string, skipTests []string) erro if err != nil { return err } - if err := runBlockTests(homesteadBlock, bt, skipTests); err != nil { + if err := runBlockTests(homesteadBlock, daoForkBlock, bt, skipTests); err != nil { return err } return nil } -func runBlockTests(homesteadBlock *big.Int, bt map[string]*BlockTest, skipTests []string) error { +func runBlockTests(homesteadBlock, daoForkBlock *big.Int, bt map[string]*BlockTest, skipTests []string) error { skipTest := make(map[string]bool, len(skipTests)) for _, name := range skipTests { skipTest[name] = true @@ -148,7 +148,7 @@ func runBlockTests(homesteadBlock *big.Int, bt map[string]*BlockTest, skipTests continue } // test the block - if err := runBlockTest(homesteadBlock, test); err != nil { + if err := runBlockTest(homesteadBlock, daoForkBlock, test); err != nil { return fmt.Errorf("%s: %v", name, err) } glog.Infoln("Block test passed: ", name) @@ -157,7 +157,7 @@ func runBlockTests(homesteadBlock *big.Int, bt map[string]*BlockTest, skipTests return nil } -func runBlockTest(homesteadBlock *big.Int, test *BlockTest) error { +func runBlockTest(homesteadBlock, daoForkBlock *big.Int, test *BlockTest) error { // import pre accounts & construct test genesis block & state root db, _ := ethdb.NewMemDatabase() if _, err := test.InsertPreState(db); err != nil { @@ -169,7 +169,7 @@ func runBlockTest(homesteadBlock *big.Int, test *BlockTest) error { core.WriteCanonicalHash(db, test.Genesis.Hash(), test.Genesis.NumberU64()) core.WriteHeadBlockHash(db, test.Genesis.Hash()) evmux := new(event.TypeMux) - config := &core.ChainConfig{HomesteadBlock: homesteadBlock} + config := &core.ChainConfig{HomesteadBlock: homesteadBlock, DAOForkBlock: daoForkBlock, DAOForkSupport: true} chain, err := core.NewBlockChain(db, config, ethash.NewShared(), evmux) if err != nil { return err diff --git a/tests/files/BlockchainTests/TestNetwork/bcTheDaoTest.json b/tests/files/BlockchainTests/TestNetwork/bcTheDaoTest.json new file mode 100644 index 000000000..ad01b82d1 --- /dev/null +++ b/tests/files/BlockchainTests/TestNetwork/bcTheDaoTest.json @@ -0,0 +1,8599 @@ +{ + "DaoTransactions" : { + "blocks" : [ + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "0bf4b15cb25eccec0a0706fc625c525be7da876bd7a8bf60baa8d9e1bce126d3", + "mixHash" : "22ffe16d1d516b8d15428b2347fe62901a12fa4977945b1ae8ced773c27e6755", + "nonce" : "f51d5dc330f2df67", + "number" : "0x01", + "parentHash" : "cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09", + "receiptTrie" : "37aee413d1d4f1335720ed1ee882bac4b2d41c8072453b23445020c951682054", + "stateRoot" : "d3f60d7c23e6d3e8eeaa691dd6d54b653e9d33ce579ed821a1e408c1e89cf01a", + "timestamp" : "0x5788dc1d", + "transactionsTrie" : "ac81275d7a81a720240146377982939179218535bfcfa9469c8bdd3e264ef179", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "1", + "rlp" : "0xf9024cf901f9a0cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0d3f60d7c23e6d3e8eeaa691dd6d54b653e9d33ce579ed821a1e408c1e89cf01aa0ac81275d7a81a720240146377982939179218535bfcfa9469c8bdd3e264ef179a037aee413d1d4f1335720ed1ee882bac4b2d41c8072453b23445020c951682054b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba825208845788dc1d80a022ffe16d1d516b8d15428b2347fe62901a12fa4977945b1ae8ced773c27e675588f51d5dc330f2df67f84df84b8001827530800a801ca057cb46c0b702929c4fd4127b2370f28a7aeeaa65509699e58eedf7692090a0a9a05ba7c83d99be6a9bca0c81947023ba3b5f2162516d82d0757bf8004f3e9bc03ac0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x57cb46c0b702929c4fd4127b2370f28a7aeeaa65509699e58eedf7692090a0a9", + "s" : "0x5ba7c83d99be6a9bca0c81947023ba3b5f2162516d82d0757bf8004f3e9bc03a", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020040", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "ce3ecad2a028ecd1d70c3c4683c1f74d8c521dfdc7cde9bb3857e1740e914402", + "mixHash" : "07d75cbc66143f80cb0b7ed64d88ff9789d1cb72f7701cbc8b5d4a3940610058", + "nonce" : "82a2b2eb85f7ad3c", + "number" : "0x02", + "parentHash" : "0bf4b15cb25eccec0a0706fc625c525be7da876bd7a8bf60baa8d9e1bce126d3", + "receiptTrie" : "9a62bdf5dbcf4d27f17a31d5506d3249c5a6ca549787b1902ba01584bb33cf64", + "stateRoot" : "c97eb33ff96a24bd16aaa76040aff370a690e6e52f0172eba3a436d7c867a988", + "timestamp" : "0x5788dc28", + "transactionsTrie" : "76c7a0ce7644661f276c76fb9a82eaee879d0642cf4ed244fc10afc02c646abf", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "2", + "rlp" : "0xf9024cf901f9a00bf4b15cb25eccec0a0706fc625c525be7da876bd7a8bf60baa8d9e1bce126d3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c97eb33ff96a24bd16aaa76040aff370a690e6e52f0172eba3a436d7c867a988a076c7a0ce7644661f276c76fb9a82eaee879d0642cf4ed244fc10afc02c646abfa09a62bdf5dbcf4d27f17a31d5506d3249c5a6ca549787b1902ba01584bb33cf64b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba825208845788dc2880a007d75cbc66143f80cb0b7ed64d88ff9789d1cb72f7701cbc8b5d4a39406100588882a2b2eb85f7ad3cf84df84b0101827530800a801ca0bb6e3cf3f281af13ef1393d7052b03cab367079a9eb71aa829ec72b231a60e1fa04bcfe1da53f26bb95806d38e9f42fef262aaaf5191e16ec473a695c8978a0b05c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x01", + "r" : "0xbb6e3cf3f281af13ef1393d7052b03cab367079a9eb71aa829ec72b231a60e1f", + "s" : "0x4bcfe1da53f26bb95806d38e9f42fef262aaaf5191e16ec473a695c8978a0b05", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020080", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "3c6ffdf610c30eab3de8cb9ee5ca2218659c998f5996b971016031464dba78c7", + "mixHash" : "3df8b7976e1892e74ef5d6cf859b1436d89454800d7bca1f9d3bbde6cf828d9f", + "nonce" : "159e3b259feea379", + "number" : "0x03", + "parentHash" : "ce3ecad2a028ecd1d70c3c4683c1f74d8c521dfdc7cde9bb3857e1740e914402", + "receiptTrie" : "b9ca869c5641896a8e22fe74b4225c6a43cbc3303b24d13e0af94517180c8097", + "stateRoot" : "9cb74b15edd72a2075b114d9154f4bbdf784054658912024747ea9423e0d2af8", + "timestamp" : "0x5788dc2a", + "transactionsTrie" : "3798aa164b61e27b93484c76a5f319bd93c808dc78ef31cf8b93f4e1b248ca2c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "3", + "rlp" : "0xf9024cf901f9a0ce3ecad2a028ecd1d70c3c4683c1f74d8c521dfdc7cde9bb3857e1740e914402a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a09cb74b15edd72a2075b114d9154f4bbdf784054658912024747ea9423e0d2af8a03798aa164b61e27b93484c76a5f319bd93c808dc78ef31cf8b93f4e1b248ca2ca0b9ca869c5641896a8e22fe74b4225c6a43cbc3303b24d13e0af94517180c8097b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba825208845788dc2a80a03df8b7976e1892e74ef5d6cf859b1436d89454800d7bca1f9d3bbde6cf828d9f88159e3b259feea379f84df84b0201827530800a801ca0f6d884cae1f86bdff1281e95e416089c544a4a5578a75d5e8ad76118e341b055a075b7d88985ed5acd61f30c9f9570c6c33bb92f3ad1a32b86a0747817fbc5ededc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x02", + "r" : "0xf6d884cae1f86bdff1281e95e416089c544a4a5578a75d5e8ad76118e341b055", + "s" : "0x75b7d88985ed5acd61f30c9f9570c6c33bb92f3ad1a32b86a0747817fbc5eded", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0200c0", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "9f33c42c79dd227e07cd7333ec5beabfa4f628abb778f94073e7dcf623c4f6c9", + "mixHash" : "d88ae9006c4143fd0de18950ef90ebe42037502c338eac1154ce21d45375b287", + "nonce" : "8647150d7bfbe0cd", + "number" : "0x04", + "parentHash" : "3c6ffdf610c30eab3de8cb9ee5ca2218659c998f5996b971016031464dba78c7", + "receiptTrie" : "d69ea0fac668bb7ece043f8e6ac833c5d10a7d5bf08ebfe40a8dc1721a3aa4fd", + "stateRoot" : "aeaa38b30cbc02db5cd17a91e9212346cd839fafcb1fc06126cf64b5b782b877", + "timestamp" : "0x5788dc31", + "transactionsTrie" : "4cc1b34b3a9d29bf69842a54e1c48bc97afc433883f66d2c59287f118c9c3c2c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "4", + "rlp" : "0xf9024cf901f9a03c6ffdf610c30eab3de8cb9ee5ca2218659c998f5996b971016031464dba78c7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0aeaa38b30cbc02db5cd17a91e9212346cd839fafcb1fc06126cf64b5b782b877a04cc1b34b3a9d29bf69842a54e1c48bc97afc433883f66d2c59287f118c9c3c2ca0d69ea0fac668bb7ece043f8e6ac833c5d10a7d5bf08ebfe40a8dc1721a3aa4fdb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200c004832fefba825208845788dc3180a0d88ae9006c4143fd0de18950ef90ebe42037502c338eac1154ce21d45375b287888647150d7bfbe0cdf84df84b0301827530800a801ca0753ee5d896db8d87fe850e7935418587277cd9c010dfaaf7dd09b0a2e73785dca066deb3c241d532c7b880ae7a9a311ee7a92ef1c5e4e2bf3307990a2881bc13b0c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x03", + "r" : "0x753ee5d896db8d87fe850e7935418587277cd9c010dfaaf7dd09b0a2e73785dc", + "s" : "0x66deb3c241d532c7b880ae7a9a311ee7a92ef1c5e4e2bf3307990a2881bc13b0", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020100", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xcf08", + "hash" : "341d9eae5bd8696e5e8c4e445cd36ff60a85d9c43ef94df01fbef0ec2ff7125f", + "mixHash" : "ec72429dc3f952b9c7bb2ad9f5b23f8cd23015bdf9cee1258c817a15da6b4a8a", + "nonce" : "a21bef974871f679", + "number" : "0x05", + "parentHash" : "9f33c42c79dd227e07cd7333ec5beabfa4f628abb778f94073e7dcf623c4f6c9", + "receiptTrie" : "d7f28f5ba69ca1893569465903e8d942153c57912f7d1f6b3e33088e8ad17fee", + "stateRoot" : "f54737efdead0a75d49cc6ceaedf75fd4aacf933e8f361a9a9c0a1647bcf6ab5", + "timestamp" : "0x5788dc34", + "transactionsTrie" : "165af780d27795ebc80c27759d3d949a9c4b05d35fcc7e9d3da8be357f5340cd", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "5", + "rlp" : "0xf9024cf901f9a09f33c42c79dd227e07cd7333ec5beabfa4f628abb778f94073e7dcf623c4f6c9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0f54737efdead0a75d49cc6ceaedf75fd4aacf933e8f361a9a9c0a1647bcf6ab5a0165af780d27795ebc80c27759d3d949a9c4b05d35fcc7e9d3da8be357f5340cda0d7f28f5ba69ca1893569465903e8d942153c57912f7d1f6b3e33088e8ad17feeb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302010005832fefba82cf08845788dc3480a0ec72429dc3f952b9c7bb2ad9f5b23f8cd23015bdf9cee1258c817a15da6b4a8a88a21bef974871f679f84df84b040182ea60800a801ba0cb1400f01459519ac3dc0426c6d7f95641dc6a7b8008069c9dfbe4f94b167169a07445362aadae8c25e4f0b494ad553bfc652bf34fb2ed0ccbf9a6b089c2b09f62c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x04", + "r" : "0xcb1400f01459519ac3dc0426c6d7f95641dc6a7b8008069c9dfbe4f94b167169", + "s" : "0x7445362aadae8c25e4f0b494ad553bfc652bf34fb2ed0ccbf9a6b089c2b09f62", + "to" : "", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020140", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xcf08", + "hash" : "bef208f4cf5571b952ab436a84a60934d96a81c4453aa1cd80c79d6fd61242dc", + "mixHash" : "ec1e3b01a1cbae6c8aa72dbefa7711c041a55c8e293a8c70653f604fa892eb3a", + "nonce" : "0580f086c036719d", + "number" : "0x06", + "parentHash" : "341d9eae5bd8696e5e8c4e445cd36ff60a85d9c43ef94df01fbef0ec2ff7125f", + "receiptTrie" : "975eeeb6e46fc2d858080444f0536a1f3a688638fdf0bcbc1958dedc5eda4405", + "stateRoot" : "05ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174", + "timestamp" : "0x5788dc38", + "transactionsTrie" : "ef009c3c274a522a6e2ca98232fffff747bdfab79189be3e2b5e5dc54e2a51be", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "6", + "rlp" : "0xf9024cf901f9a0341d9eae5bd8696e5e8c4e445cd36ff60a85d9c43ef94df01fbef0ec2ff7125fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a005ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174a0ef009c3c274a522a6e2ca98232fffff747bdfab79189be3e2b5e5dc54e2a51bea0975eeeb6e46fc2d858080444f0536a1f3a688638fdf0bcbc1958dedc5eda4405b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014006832fefba82cf08845788dc3880a0ec1e3b01a1cbae6c8aa72dbefa7711c041a55c8e293a8c70653f604fa892eb3a880580f086c036719df84df84b050182ea60800a801ba04d147b172eb81fdb11a21826eabad091084f6e9613d340b5897872843efa6435a023640d906f65fd156b92d518068263d99d94dc88c3e0950fd7633fb0d4d237eec0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x05", + "r" : "0x4d147b172eb81fdb11a21826eabad091084f6e9613d340b5897872843efa6435", + "s" : "0x23640d906f65fd156b92d518068263d99d94dc88c3e0950fd7633fb0d4d237ee", + "to" : "", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xa042", + "hash" : "9c835a5982dbd3e45af50a688075f16b3661a330c87af0f8019ca65329ca7636", + "mixHash" : "3943078bb0754d40ec78d9809de292aa2ec6bf5bad40d85d8da01276752db5ae", + "nonce" : "37f3decdc9a7e0bd", + "number" : "0x07", + "parentHash" : "bef208f4cf5571b952ab436a84a60934d96a81c4453aa1cd80c79d6fd61242dc", + "receiptTrie" : "aec104fc55d9aa0c1767af2dcf73c512f650f24bf89b9b78eb236d70a2de848f", + "stateRoot" : "40d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029", + "timestamp" : "0x5788dc3c", + "transactionsTrie" : "b2d17fa171d19df4e817ffb15f38526d125a42b7879cd712584b130dc8ad341c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "7", + "rlp" : "0xf90260f901f9a0bef208f4cf5571b952ab436a84a60934d96a81c4453aa1cd80c79d6fd61242dca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a0b2d17fa171d19df4e817ffb15f38526d125a42b7879cd712584b130dc8ad341ca0aec104fc55d9aa0c1767af2dcf73c512f650f24bf89b9b78eb236d70a2de848fb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018007832fefba82a042845788dc3c80a03943078bb0754d40ec78d9809de292aa2ec6bf5bad40d85d8da01276752db5ae8837f3decdc9a7e0bdf861f85f060182ea609410000000000000000000000000000000000000070a801ba0bb8523d4c53ed16b355d0a2dba02154d23a5480449dc3894be40ef95511d2fe9a010ad725c2df4979b7a071b3fa9b6b719223f0167d68b98f213e8611f84d4d81bc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x06", + "r" : "0xbb8523d4c53ed16b355d0a2dba02154d23a5480449dc3894be40ef95511d2fe9", + "s" : "0x10ad725c2df4979b7a071b3fa9b6b719223f0167d68b98f213e8611f84d4d81b", + "to" : "1000000000000000000000000000000000000007", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "8", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f070182ea609410000000000000000000000000000000000000080a801ba03bce709627e1c9340795f11cc866742a0b5ced2b7e2da53e0cfe6f5f1df0a77ea02df804cdb52edacc4e01d8632050101cf7de7b235d37c31b504010910ec8f1f6c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x65aa", + "hash" : "37197cab54e89c31d93dfa050c38c916efe2e8a5849b43b245305ecc450eea70", + "mixHash" : "1eb50717ca7b4c633ba350969235157017427af1f807946adcc61098ca98e596", + "nonce" : "81e6b44c39618f34", + "number" : "0x08", + "parentHash" : "9c835a5982dbd3e45af50a688075f16b3661a330c87af0f8019ca65329ca7636", + "receiptTrie" : "2df25a52fb0817ad3948868d59d50cab8f7f780fc5e3939b4c9140936d7bb187", + "stateRoot" : "8565b6c0a57e2566bb768c6c67aaad77794da4e1589966ee51bd0370a9db3d1c", + "timestamp" : "0x5788dc46", + "transactionsTrie" : "2982eb44bedb5b2484b9606fe37f966942a2cce51f0705537f9040ef0614d54e", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "8", + "rlp" : "0xf9026df90206a09c835a5982dbd3e45af50a688075f16b3661a330c87af0f8019ca65329ca7636a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a08565b6c0a57e2566bb768c6c67aaad77794da4e1589966ee51bd0370a9db3d1ca02982eb44bedb5b2484b9606fe37f966942a2cce51f0705537f9040ef0614d54ea02df25a52fb0817ad3948868d59d50cab8f7f780fc5e3939b4c9140936d7bb187b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018008832fefba8265aa845788dc468d64616f2d686172642d666f726ba01eb50717ca7b4c633ba350969235157017427af1f807946adcc61098ca98e5968881e6b44c39618f34f861f85f070182ea609410000000000000000000000000000000000000080a801ba03bce709627e1c9340795f11cc866742a0b5ced2b7e2da53e0cfe6f5f1df0a77ea02df804cdb52edacc4e01d8632050101cf7de7b235d37c31b504010910ec8f1f6c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x07", + "r" : "0x3bce709627e1c9340795f11cc866742a0b5ced2b7e2da53e0cfe6f5f1df0a77e", + "s" : "0x2df804cdb52edacc4e01d8632050101cf7de7b235d37c31b504010910ec8f1f6", + "to" : "1000000000000000000000000000000000000008", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "9", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f080182ea6094100000000000000000000000000000000000000101801ba0af2bb21c6953c5c7bb966a9c09e43c52641e6e317ab738cd409a5fb9ef5e753fa010db71dc8b41e52ce746895f743c1cc1fe7ed32f17ff7935b610fcbccdc75720c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "fcc08674a7d7b521954d2545f7d09c02ebee682ce9a2e408aa094ff254c8b772", + "mixHash" : "188325449fab4b060f142fad86dd35c5b9a5d09e4b3cb0da9855818c832de7ac", + "nonce" : "d4c9a029ed38257b", + "number" : "0x09", + "parentHash" : "37197cab54e89c31d93dfa050c38c916efe2e8a5849b43b245305ecc450eea70", + "receiptTrie" : "06ba5b9bbbcf94865cd9b522c4de701287f0fcb197fc2a19e54aa23d0fb20218", + "stateRoot" : "0eef10cd08a0a4a20df81757eeb4114a0db434c8d41e6cc35e8cf9d8c22d81c7", + "timestamp" : "0x5788dc51", + "transactionsTrie" : "7dac38119a2beeb72d0f67b77bef9a4cbae22ca5c7151f1e737f9db1bf37b135", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "9", + "rlp" : "0xf9026df90206a037197cab54e89c31d93dfa050c38c916efe2e8a5849b43b245305ecc450eea70a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a00eef10cd08a0a4a20df81757eeb4114a0db434c8d41e6cc35e8cf9d8c22d81c7a07dac38119a2beeb72d0f67b77bef9a4cbae22ca5c7151f1e737f9db1bf37b135a006ba5b9bbbcf94865cd9b522c4de701287f0fcb197fc2a19e54aa23d0fb20218b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018009832fefba825208845788dc518d64616f2d686172642d666f726ba0188325449fab4b060f142fad86dd35c5b9a5d09e4b3cb0da9855818c832de7ac88d4c9a029ed38257bf861f85f080182ea6094100000000000000000000000000000000000000101801ba0af2bb21c6953c5c7bb966a9c09e43c52641e6e317ab738cd409a5fb9ef5e753fa010db71dc8b41e52ce746895f743c1cc1fe7ed32f17ff7935b610fcbccdc75720c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x08", + "r" : "0xaf2bb21c6953c5c7bb966a9c09e43c52641e6e317ab738cd409a5fb9ef5e753f", + "s" : "0x10db71dc8b41e52ce746895f743c1cc1fe7ed32f17ff7935b610fcbccdc75720", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1b", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "10", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f090182ea6094100000000000000000000000000000000000000101801ca0c3d783e93561599d86cbf460e153b3cb37d90478a3c47bfc08bd29563c9d849fa0100e466f7a4c6af73a9030988c63ec88ccaba460fd6a1fb1adc30b61dbdd0857c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "5f58b34c4108e44ab7bfbfe9c70b5b86097cdff8b21ae7a990d8ed0c31a04634", + "mixHash" : "fd36229270002f66be02e74dcc3088b324a862e9c2797bf551a064441eb41553", + "nonce" : "0c81358b772e61d1", + "number" : "0x0a", + "parentHash" : "fcc08674a7d7b521954d2545f7d09c02ebee682ce9a2e408aa094ff254c8b772", + "receiptTrie" : "2f00350472bd9d8d635a091a20bac638d9c6bcb1d6b5c81736a0d1ca5fee93be", + "stateRoot" : "96859e95e173eef8004bb592b19cefd71ff683ef0900de4bba7bfe44b96fab3b", + "timestamp" : "0x5788dc5b", + "transactionsTrie" : "771cef5982e1119f26a627bbeeadc21e350838157aad275b2f4a884a57e277da", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "10", + "rlp" : "0xf9026df90206a0fcc08674a7d7b521954d2545f7d09c02ebee682ce9a2e408aa094ff254c8b772a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a096859e95e173eef8004bb592b19cefd71ff683ef0900de4bba7bfe44b96fab3ba0771cef5982e1119f26a627bbeeadc21e350838157aad275b2f4a884a57e277daa02f00350472bd9d8d635a091a20bac638d9c6bcb1d6b5c81736a0d1ca5fee93beb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201800a832fefba825208845788dc5b8d64616f2d686172642d666f726ba0fd36229270002f66be02e74dcc3088b324a862e9c2797bf551a064441eb41553880c81358b772e61d1f861f85f090182ea6094100000000000000000000000000000000000000101801ca0c3d783e93561599d86cbf460e153b3cb37d90478a3c47bfc08bd29563c9d849fa0100e466f7a4c6af73a9030988c63ec88ccaba460fd6a1fb1adc30b61dbdd0857c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x09", + "r" : "0xc3d783e93561599d86cbf460e153b3cb37d90478a3c47bfc08bd29563c9d849f", + "s" : "0x100e466f7a4c6af73a9030988c63ec88ccaba460fd6a1fb1adc30b61dbdd0857", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1c", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "11", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f0a0182ea6094100000000000000000000000000000000000000101801ca076766ba9925c43448e1ac5c05f7583e6d3a3366eb3dc95a3489ff363b449795ca059b8da33b7aea0d60059f5c1eabce26c1e23e32f31930bff3b49eb1e94cc62a0c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0201c0", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "851a805fb871ff549a759409ed3b909ec2e3abbca7c4df259a473489c346ba43", + "mixHash" : "89999ed1fac8370a082cb0a364de948d6cf9db298d40c3632936cbe9efe7d58e", + "nonce" : "8ce8d22f2893653c", + "number" : "0x0b", + "parentHash" : "5f58b34c4108e44ab7bfbfe9c70b5b86097cdff8b21ae7a990d8ed0c31a04634", + "receiptTrie" : "324f8d9eb5892134e0d375c7a4826bbd28ba0f6e73b9b64bbb595e410387ddc3", + "stateRoot" : "56bf73c2776f59118fdb82e8b01dc88c3cbb1e2ded3c1d7ef17c4603c500346d", + "timestamp" : "0x5788dc63", + "transactionsTrie" : "10a81573cb14d5c2794e1b406e26b6d9612c888bbc98c453131bd9b06f61d7c9", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "11", + "rlp" : "0xf9026df90206a05f58b34c4108e44ab7bfbfe9c70b5b86097cdff8b21ae7a990d8ed0c31a04634a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a056bf73c2776f59118fdb82e8b01dc88c3cbb1e2ded3c1d7ef17c4603c500346da010a81573cb14d5c2794e1b406e26b6d9612c888bbc98c453131bd9b06f61d7c9a0324f8d9eb5892134e0d375c7a4826bbd28ba0f6e73b9b64bbb595e410387ddc3b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201c00b832fefba825208845788dc638d64616f2d686172642d666f726ba089999ed1fac8370a082cb0a364de948d6cf9db298d40c3632936cbe9efe7d58e888ce8d22f2893653cf861f85f0a0182ea6094100000000000000000000000000000000000000101801ca076766ba9925c43448e1ac5c05f7583e6d3a3366eb3dc95a3489ff363b449795ca059b8da33b7aea0d60059f5c1eabce26c1e23e32f31930bff3b49eb1e94cc62a0c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x0a", + "r" : "0x76766ba9925c43448e1ac5c05f7583e6d3a3366eb3dc95a3489ff363b449795c", + "s" : "0x59b8da33b7aea0d60059f5c1eabce26c1e23e32f31930bff3b49eb1e94cc62a0", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1c", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "12", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f0b0182ea6094100000000000000000000000000000000000000101801ca085939abfa5d1d2dd8e1bde2655e44236d8e1940a075000301d6deab472ccd680a078d2ae659006c58f9ccc5af29955f7439e48b30b2efe64abdd001165364faa9ac0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020200", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "d2248eb423eb10de5f570b455f4ada1d53e59b254be9c74a011952412652f96a", + "mixHash" : "6adfeb8c142a16fe8a4ca09d37997694a3d3a55b3cf93ba063cbca9e68e91b79", + "nonce" : "8319bcd74da15bc7", + "number" : "0x0c", + "parentHash" : "851a805fb871ff549a759409ed3b909ec2e3abbca7c4df259a473489c346ba43", + "receiptTrie" : "e150d54f9f244d65a2d906bbb8b0fe9f218119c8b0e00906846ac5cbdab800d1", + "stateRoot" : "c545bccf90c734ea9de210666693ada930bbcdbb0cefcde9a57848dc363e8397", + "timestamp" : "0x5788dc6b", + "transactionsTrie" : "b7757adef51c8c3b9b0433d1a0db70fe5505e8db1848934da1c1d2c6aafc3f65", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "12", + "rlp" : "0xf9026df90206a0851a805fb871ff549a759409ed3b909ec2e3abbca7c4df259a473489c346ba43a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c545bccf90c734ea9de210666693ada930bbcdbb0cefcde9a57848dc363e8397a0b7757adef51c8c3b9b0433d1a0db70fe5505e8db1848934da1c1d2c6aafc3f65a0e150d54f9f244d65a2d906bbb8b0fe9f218119c8b0e00906846ac5cbdab800d1b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830202000c832fefba825208845788dc6b8d64616f2d686172642d666f726ba06adfeb8c142a16fe8a4ca09d37997694a3d3a55b3cf93ba063cbca9e68e91b79888319bcd74da15bc7f861f85f0b0182ea6094100000000000000000000000000000000000000101801ca085939abfa5d1d2dd8e1bde2655e44236d8e1940a075000301d6deab472ccd680a078d2ae659006c58f9ccc5af29955f7439e48b30b2efe64abdd001165364faa9ac0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x0b", + "r" : "0x85939abfa5d1d2dd8e1bde2655e44236d8e1940a075000301d6deab472ccd680", + "s" : "0x78d2ae659006c58f9ccc5af29955f7439e48b30b2efe64abdd001165364faa9a", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1c", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "13", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f0c0182ea6094100000000000000000000000000000000000000101801ca00bb5ae599741966cbd02d6080937bd1f247dfaa266e19891228a4fbfc0c85226a07a4f56371aa5b685bc10d64e180e24850ae18b0fcc675e7d187f877b8d9b1bf6c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020200", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "746b52c52853e38f8b42e10bb36c6325094bd7c49ff77f0e04dd383dfde4b3e5", + "mixHash" : "0e925fa65c46cb3527b304c1a699ba9b9244e58715b3c0be8d30f78fbbf91bb7", + "nonce" : "c43118c563e4752c", + "number" : "0x0d", + "parentHash" : "d2248eb423eb10de5f570b455f4ada1d53e59b254be9c74a011952412652f96a", + "receiptTrie" : "f5e02249f25bfb35d3338fc0b9407ba4a2da198ad27050ee5fe76f434163f789", + "stateRoot" : "0d62f6b628aa29c160a6c6c5462b2395d55fc8699251ef44dd6f7bfb78096359", + "timestamp" : "0x5788dc76", + "transactionsTrie" : "38b9ac6344a8e2cdd0c0b598f70f21997ab1b39d3ecb2f7a8c7af93e300e0398", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "13", + "rlp" : "0xf9026df90206a0d2248eb423eb10de5f570b455f4ada1d53e59b254be9c74a011952412652f96aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a00d62f6b628aa29c160a6c6c5462b2395d55fc8699251ef44dd6f7bfb78096359a038b9ac6344a8e2cdd0c0b598f70f21997ab1b39d3ecb2f7a8c7af93e300e0398a0f5e02249f25bfb35d3338fc0b9407ba4a2da198ad27050ee5fe76f434163f789b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830202000d832fefba825208845788dc768d64616f2d686172642d666f726ba00e925fa65c46cb3527b304c1a699ba9b9244e58715b3c0be8d30f78fbbf91bb788c43118c563e4752cf861f85f0c0182ea6094100000000000000000000000000000000000000101801ca00bb5ae599741966cbd02d6080937bd1f247dfaa266e19891228a4fbfc0c85226a07a4f56371aa5b685bc10d64e180e24850ae18b0fcc675e7d187f877b8d9b1bf6c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x0c", + "r" : "0x0bb5ae599741966cbd02d6080937bd1f247dfaa266e19891228a4fbfc0c85226", + "s" : "0x7a4f56371aa5b685bc10d64e180e24850ae18b0fcc675e7d187f877b8d9b1bf6", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1c", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "14", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f0d0182ea6094100000000000000000000000000000000000000101801ba0db8f9cd690ad1f6481c09a5445a4185d4fcfdeed76f7ba403d303985c1abaa4ca01ed5f2e9fd9a021103acc910cbefcdaa82d2afd44205a8f681f0c17ebf2da192c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020200", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "19831eb58833d70ba74fc813e112201365ac4f4cdd33026d06df377dfae52498", + "mixHash" : "5e7e6fe4790cf6518a643d5351f35fd6b8f6a62b281bb5074138851bac66eb13", + "nonce" : "be71f6cdf480c4a2", + "number" : "0x0e", + "parentHash" : "746b52c52853e38f8b42e10bb36c6325094bd7c49ff77f0e04dd383dfde4b3e5", + "receiptTrie" : "308cbfc04d0a5d4821a96fec27ea00f2e278886545add9ed961c28015970ec5c", + "stateRoot" : "159a6f365d9aa0930979cb60b9d04cd3c72b50c2f830aa27d610f8c014a600b1", + "timestamp" : "0x5788dc80", + "transactionsTrie" : "4b6ff42fd8884c83615bf62830df849b18901c07615aafef9aaf16d33f807349", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "14", + "rlp" : "0xf9026df90206a0746b52c52853e38f8b42e10bb36c6325094bd7c49ff77f0e04dd383dfde4b3e5a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0159a6f365d9aa0930979cb60b9d04cd3c72b50c2f830aa27d610f8c014a600b1a04b6ff42fd8884c83615bf62830df849b18901c07615aafef9aaf16d33f807349a0308cbfc04d0a5d4821a96fec27ea00f2e278886545add9ed961c28015970ec5cb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830202000e832fefba825208845788dc808d64616f2d686172642d666f726ba05e7e6fe4790cf6518a643d5351f35fd6b8f6a62b281bb5074138851bac66eb1388be71f6cdf480c4a2f861f85f0d0182ea6094100000000000000000000000000000000000000101801ba0db8f9cd690ad1f6481c09a5445a4185d4fcfdeed76f7ba403d303985c1abaa4ca01ed5f2e9fd9a021103acc910cbefcdaa82d2afd44205a8f681f0c17ebf2da192c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x0d", + "r" : "0xdb8f9cd690ad1f6481c09a5445a4185d4fcfdeed76f7ba403d303985c1abaa4c", + "s" : "0x1ed5f2e9fd9a021103acc910cbefcdaa82d2afd44205a8f681f0c17ebf2da192", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1b", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "15", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f0e0182ea6094100000000000000000000000000000000000000101801ca0af8f37a08239d55138f8b92680c682d4118da357c79d6a6b148a6dcce4d961d1a057bf5b29fc32419091bd8e170fed46703b7a2640be0ca91d6903d75c932be160c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020200", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "53337dbe188bd181ba13c0b12333b3560b21969c17f4ca2ce73b327d32a1bd17", + "mixHash" : "1203fe51e0609473cbc778ac000373a21d3e4b4b620e869e58281e98b9d46ffe", + "nonce" : "ab0199bac390816d", + "number" : "0x0f", + "parentHash" : "19831eb58833d70ba74fc813e112201365ac4f4cdd33026d06df377dfae52498", + "receiptTrie" : "3ceb3d74ba79019e8aac7a6a4de23c5584109dfcff70ed61c160e24ab46bcd3d", + "stateRoot" : "d2f5a74b3962d04c2124d780ffa38fc2181e1b09eabb7f4bf5a172a18f75d4d7", + "timestamp" : "0x5788dc8e", + "transactionsTrie" : "ce025c4f49fea19fbb8b91252f03fd36d2ff6e9e8817c701452992098534abda", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "15", + "rlp" : "0xf9026df90206a019831eb58833d70ba74fc813e112201365ac4f4cdd33026d06df377dfae52498a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0d2f5a74b3962d04c2124d780ffa38fc2181e1b09eabb7f4bf5a172a18f75d4d7a0ce025c4f49fea19fbb8b91252f03fd36d2ff6e9e8817c701452992098534abdaa03ceb3d74ba79019e8aac7a6a4de23c5584109dfcff70ed61c160e24ab46bcd3db9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830202000f832fefba825208845788dc8e8d64616f2d686172642d666f726ba01203fe51e0609473cbc778ac000373a21d3e4b4b620e869e58281e98b9d46ffe88ab0199bac390816df861f85f0e0182ea6094100000000000000000000000000000000000000101801ca0af8f37a08239d55138f8b92680c682d4118da357c79d6a6b148a6dcce4d961d1a057bf5b29fc32419091bd8e170fed46703b7a2640be0ca91d6903d75c932be160c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x0e", + "r" : "0xaf8f37a08239d55138f8b92680c682d4118da357c79d6a6b148a6dcce4d961d1", + "s" : "0x57bf5b29fc32419091bd8e170fed46703b7a2640be0ca91d6903d75c932be160", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1c", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "16", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f0f0182ea6094100000000000000000000000000000000000000101801ba040a5467881266422758d59ae66fb3d2511f0131038b0e43abc397d01527fd61ea0172ed4b9c3cf917bf071cb6cc716c4f6754949ea94888d4bb9657eac98fd2c10c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020240", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "6b1d0b868bd5920d3edc2d9073a3c9fc4c9dc7656a51e2ebe89ac5fb2f0e90b3", + "mixHash" : "29a4eb947f50b1296aa46d5393e59f002aa01c34a9e7bed6f1fd40e66362e1e2", + "nonce" : "98376d65695940d3", + "number" : "0x10", + "parentHash" : "53337dbe188bd181ba13c0b12333b3560b21969c17f4ca2ce73b327d32a1bd17", + "receiptTrie" : "1139851ae488ee33e16c5ef766d36d924d6c4ead16eb1996a92856a5640e938e", + "stateRoot" : "c57fab6567df96712cd7031f96a3073f6f1706e637d91ed15fcefd308b024b86", + "timestamp" : "0x5788dc97", + "transactionsTrie" : "6f2130deb628c7742532339d5b5f1539f9579edcab16996b3b05836a6883073f", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "16", + "rlp" : "0xf9026df90206a053337dbe188bd181ba13c0b12333b3560b21969c17f4ca2ce73b327d32a1bd17a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c57fab6567df96712cd7031f96a3073f6f1706e637d91ed15fcefd308b024b86a06f2130deb628c7742532339d5b5f1539f9579edcab16996b3b05836a6883073fa01139851ae488ee33e16c5ef766d36d924d6c4ead16eb1996a92856a5640e938eb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302024010832fefba825208845788dc978d64616f2d686172642d666f726ba029a4eb947f50b1296aa46d5393e59f002aa01c34a9e7bed6f1fd40e66362e1e28898376d65695940d3f861f85f0f0182ea6094100000000000000000000000000000000000000101801ba040a5467881266422758d59ae66fb3d2511f0131038b0e43abc397d01527fd61ea0172ed4b9c3cf917bf071cb6cc716c4f6754949ea94888d4bb9657eac98fd2c10c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x0f", + "r" : "0x40a5467881266422758d59ae66fb3d2511f0131038b0e43abc397d01527fd61e", + "s" : "0x172ed4b9c3cf917bf071cb6cc716c4f6754949ea94888d4bb9657eac98fd2c10", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1b", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "17", + "rlp" : "0xf9024af901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f861f85f100182ea6094100000000000000000000000000000000000000101801ba0d7933ba406ea332cdec2d673bbf5789c34a43224629c220bd0ac2c9d81c7b094a05e0a096cbe3bdc9047b18de6be4822165c669bddf712456567dc525547059ff8c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020240", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "7cda04f38d4a31d51370d4d8cc763b3d15e53eb4fe76575a2a87a22f5c53a5cf", + "mixHash" : "38824245bf0d625f30f725a2daa9245035240449cbe011358328fc36066a7d91", + "nonce" : "16893c7414215a57", + "number" : "0x11", + "parentHash" : "6b1d0b868bd5920d3edc2d9073a3c9fc4c9dc7656a51e2ebe89ac5fb2f0e90b3", + "receiptTrie" : "f71904ef163e1bb258f38fba942af54f6f2947ded4702309ff60fb2a70291dc8", + "stateRoot" : "719b70fcc0d130db91c3ec672245c08728fb3636d3e5068de03b1eacb5dec827", + "timestamp" : "0x5788dca1", + "transactionsTrie" : "316f3430ee504cbaa58cec2ce451de2fc9e0f1e7f99b16b33f69ab3ca93130be", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "17", + "rlp" : "0xf9026df90206a06b1d0b868bd5920d3edc2d9073a3c9fc4c9dc7656a51e2ebe89ac5fb2f0e90b3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0719b70fcc0d130db91c3ec672245c08728fb3636d3e5068de03b1eacb5dec827a0316f3430ee504cbaa58cec2ce451de2fc9e0f1e7f99b16b33f69ab3ca93130bea0f71904ef163e1bb258f38fba942af54f6f2947ded4702309ff60fb2a70291dc8b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302024011832fefba825208845788dca18d64616f2d686172642d666f726ba038824245bf0d625f30f725a2daa9245035240449cbe011358328fc36066a7d918816893c7414215a57f861f85f100182ea6094100000000000000000000000000000000000000101801ba0d7933ba406ea332cdec2d673bbf5789c34a43224629c220bd0ac2c9d81c7b094a05e0a096cbe3bdc9047b18de6be4822165c669bddf712456567dc525547059ff8c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x10", + "r" : "0xd7933ba406ea332cdec2d673bbf5789c34a43224629c220bd0ac2c9d81c7b094", + "s" : "0x5e0a096cbe3bdc9047b18de6be4822165c669bddf712456567dc525547059ff8", + "to" : "1000000000000000000000000000000000000001", + "v" : "0x1b", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09", + "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0102030405060708", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "6bff69e94b94f30e1b69f86d3e09712edfb583ac73a46a522345e1965ca9c66d", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06bff69e94b94f30e1b69f86d3e09712edfb583ac73a46a522345e1965ca9c66da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", + "lastblockhash" : "7cda04f38d4a31d51370d4d8cc763b3d15e53eb4fe76575a2a87a22f5c53a5cf", + "postState" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0c243ebe6a031753dc0dd850acf422844a3efb76" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000001" : { + "balance" : "0x09", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x0a", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x02540be400" + } + }, + "1000000000000000000000000000000000000008" : { + "balance" : "0x0a", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "248f0f0f33eadb89e9d87fd5c127f58567f3ffde" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "85c2f277588ea1e6901ed59e587bea222c575f87" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x049b9ca9a6943ace64", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b93fb43", + "code" : "0x", + "nonce" : "0x11", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b1d37cf6180ceb738ca45b5005a2f418c02e204b" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bf4ed7b27f1d666546e30d74d50d173d20bca754" : { + "balance" : "0x010bc166ae40", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x00", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000008" : { + "balance" : "0x00", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b9aca00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x0f4240", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "DaoTransactions_EmptyTransactionAndForkBlocksAhead" : { + "blocks" : [ + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "2d909e451e1b958a488fd067628526a424c0bc3fbb0afe78998e92f6ef92c880", + "mixHash" : "02c435f7b9734da7aa6db2217ba1a4522f3465a99006cbd44942272fc793e5c7", + "nonce" : "c94ecb5430e81c0c", + "number" : "0x01", + "parentHash" : "cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09", + "receiptTrie" : "37aee413d1d4f1335720ed1ee882bac4b2d41c8072453b23445020c951682054", + "stateRoot" : "d3f60d7c23e6d3e8eeaa691dd6d54b653e9d33ce579ed821a1e408c1e89cf01a", + "timestamp" : "0x5788dca6", + "transactionsTrie" : "ac81275d7a81a720240146377982939179218535bfcfa9469c8bdd3e264ef179", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "1", + "rlp" : "0xf9024cf901f9a0cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0d3f60d7c23e6d3e8eeaa691dd6d54b653e9d33ce579ed821a1e408c1e89cf01aa0ac81275d7a81a720240146377982939179218535bfcfa9469c8bdd3e264ef179a037aee413d1d4f1335720ed1ee882bac4b2d41c8072453b23445020c951682054b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba825208845788dca680a002c435f7b9734da7aa6db2217ba1a4522f3465a99006cbd44942272fc793e5c788c94ecb5430e81c0cf84df84b8001827530800a801ca057cb46c0b702929c4fd4127b2370f28a7aeeaa65509699e58eedf7692090a0a9a05ba7c83d99be6a9bca0c81947023ba3b5f2162516d82d0757bf8004f3e9bc03ac0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x57cb46c0b702929c4fd4127b2370f28a7aeeaa65509699e58eedf7692090a0a9", + "s" : "0x5ba7c83d99be6a9bca0c81947023ba3b5f2162516d82d0757bf8004f3e9bc03a", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020040", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "59d2678d1e13c27405ca21d6cc09303c52422c3eb5b9233f0431260e4314a8ff", + "mixHash" : "43d612b9569a9a1e1fcefc3fdff9ee4b15d6844c1b912925c15e852bc2eee47a", + "nonce" : "bc6be4c140452074", + "number" : "0x02", + "parentHash" : "2d909e451e1b958a488fd067628526a424c0bc3fbb0afe78998e92f6ef92c880", + "receiptTrie" : "9a62bdf5dbcf4d27f17a31d5506d3249c5a6ca549787b1902ba01584bb33cf64", + "stateRoot" : "c97eb33ff96a24bd16aaa76040aff370a690e6e52f0172eba3a436d7c867a988", + "timestamp" : "0x5788dcac", + "transactionsTrie" : "76c7a0ce7644661f276c76fb9a82eaee879d0642cf4ed244fc10afc02c646abf", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "2", + "rlp" : "0xf9024cf901f9a02d909e451e1b958a488fd067628526a424c0bc3fbb0afe78998e92f6ef92c880a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c97eb33ff96a24bd16aaa76040aff370a690e6e52f0172eba3a436d7c867a988a076c7a0ce7644661f276c76fb9a82eaee879d0642cf4ed244fc10afc02c646abfa09a62bdf5dbcf4d27f17a31d5506d3249c5a6ca549787b1902ba01584bb33cf64b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba825208845788dcac80a043d612b9569a9a1e1fcefc3fdff9ee4b15d6844c1b912925c15e852bc2eee47a88bc6be4c140452074f84df84b0101827530800a801ca0bb6e3cf3f281af13ef1393d7052b03cab367079a9eb71aa829ec72b231a60e1fa04bcfe1da53f26bb95806d38e9f42fef262aaaf5191e16ec473a695c8978a0b05c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x01", + "r" : "0xbb6e3cf3f281af13ef1393d7052b03cab367079a9eb71aa829ec72b231a60e1f", + "s" : "0x4bcfe1da53f26bb95806d38e9f42fef262aaaf5191e16ec473a695c8978a0b05", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020080", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "7051d31496dd62effea9d15df0bfa702853ccbe9febbcbaac756fe10c48afa31", + "mixHash" : "1267559086eed7764a14877cbc3ef681f1e8b6948d15f06babe3e99004fbe948", + "nonce" : "4806557d56b8ca98", + "number" : "0x03", + "parentHash" : "59d2678d1e13c27405ca21d6cc09303c52422c3eb5b9233f0431260e4314a8ff", + "receiptTrie" : "b9ca869c5641896a8e22fe74b4225c6a43cbc3303b24d13e0af94517180c8097", + "stateRoot" : "9cb74b15edd72a2075b114d9154f4bbdf784054658912024747ea9423e0d2af8", + "timestamp" : "0x5788dcb4", + "transactionsTrie" : "3798aa164b61e27b93484c76a5f319bd93c808dc78ef31cf8b93f4e1b248ca2c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "3", + "rlp" : "0xf9024cf901f9a059d2678d1e13c27405ca21d6cc09303c52422c3eb5b9233f0431260e4314a8ffa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a09cb74b15edd72a2075b114d9154f4bbdf784054658912024747ea9423e0d2af8a03798aa164b61e27b93484c76a5f319bd93c808dc78ef31cf8b93f4e1b248ca2ca0b9ca869c5641896a8e22fe74b4225c6a43cbc3303b24d13e0af94517180c8097b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba825208845788dcb480a01267559086eed7764a14877cbc3ef681f1e8b6948d15f06babe3e99004fbe948884806557d56b8ca98f84df84b0201827530800a801ca0f6d884cae1f86bdff1281e95e416089c544a4a5578a75d5e8ad76118e341b055a075b7d88985ed5acd61f30c9f9570c6c33bb92f3ad1a32b86a0747817fbc5ededc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x02", + "r" : "0xf6d884cae1f86bdff1281e95e416089c544a4a5578a75d5e8ad76118e341b055", + "s" : "0x75b7d88985ed5acd61f30c9f9570c6c33bb92f3ad1a32b86a0747817fbc5eded", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0200c0", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "2d861373e66c78d1d5eaa5833386489938365e7cb368a8666c5fbc215cbce406", + "mixHash" : "db2e0f7741e497b519d547dc38ef0531db80fd5410884545dfdaeb694dc57de1", + "nonce" : "fb70478bc0ec196f", + "number" : "0x04", + "parentHash" : "7051d31496dd62effea9d15df0bfa702853ccbe9febbcbaac756fe10c48afa31", + "receiptTrie" : "d69ea0fac668bb7ece043f8e6ac833c5d10a7d5bf08ebfe40a8dc1721a3aa4fd", + "stateRoot" : "aeaa38b30cbc02db5cd17a91e9212346cd839fafcb1fc06126cf64b5b782b877", + "timestamp" : "0x5788dcb6", + "transactionsTrie" : "4cc1b34b3a9d29bf69842a54e1c48bc97afc433883f66d2c59287f118c9c3c2c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "4", + "rlp" : "0xf9024cf901f9a07051d31496dd62effea9d15df0bfa702853ccbe9febbcbaac756fe10c48afa31a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0aeaa38b30cbc02db5cd17a91e9212346cd839fafcb1fc06126cf64b5b782b877a04cc1b34b3a9d29bf69842a54e1c48bc97afc433883f66d2c59287f118c9c3c2ca0d69ea0fac668bb7ece043f8e6ac833c5d10a7d5bf08ebfe40a8dc1721a3aa4fdb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200c004832fefba825208845788dcb680a0db2e0f7741e497b519d547dc38ef0531db80fd5410884545dfdaeb694dc57de188fb70478bc0ec196ff84df84b0301827530800a801ca0753ee5d896db8d87fe850e7935418587277cd9c010dfaaf7dd09b0a2e73785dca066deb3c241d532c7b880ae7a9a311ee7a92ef1c5e4e2bf3307990a2881bc13b0c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x03", + "r" : "0x753ee5d896db8d87fe850e7935418587277cd9c010dfaaf7dd09b0a2e73785dc", + "s" : "0x66deb3c241d532c7b880ae7a9a311ee7a92ef1c5e4e2bf3307990a2881bc13b0", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020100", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xcf08", + "hash" : "5d08215124863936106a33d44911139e90b5727af7dd7e00f641e69b3651a6f7", + "mixHash" : "936c648b4f2d8097f8f38341961112d5002d725a43c916895af6478db2320dee", + "nonce" : "93aebe2f5096c2f0", + "number" : "0x05", + "parentHash" : "2d861373e66c78d1d5eaa5833386489938365e7cb368a8666c5fbc215cbce406", + "receiptTrie" : "d7f28f5ba69ca1893569465903e8d942153c57912f7d1f6b3e33088e8ad17fee", + "stateRoot" : "f54737efdead0a75d49cc6ceaedf75fd4aacf933e8f361a9a9c0a1647bcf6ab5", + "timestamp" : "0x5788dcbb", + "transactionsTrie" : "165af780d27795ebc80c27759d3d949a9c4b05d35fcc7e9d3da8be357f5340cd", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "5", + "rlp" : "0xf9024cf901f9a02d861373e66c78d1d5eaa5833386489938365e7cb368a8666c5fbc215cbce406a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0f54737efdead0a75d49cc6ceaedf75fd4aacf933e8f361a9a9c0a1647bcf6ab5a0165af780d27795ebc80c27759d3d949a9c4b05d35fcc7e9d3da8be357f5340cda0d7f28f5ba69ca1893569465903e8d942153c57912f7d1f6b3e33088e8ad17feeb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302010005832fefba82cf08845788dcbb80a0936c648b4f2d8097f8f38341961112d5002d725a43c916895af6478db2320dee8893aebe2f5096c2f0f84df84b040182ea60800a801ba0cb1400f01459519ac3dc0426c6d7f95641dc6a7b8008069c9dfbe4f94b167169a07445362aadae8c25e4f0b494ad553bfc652bf34fb2ed0ccbf9a6b089c2b09f62c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x04", + "r" : "0xcb1400f01459519ac3dc0426c6d7f95641dc6a7b8008069c9dfbe4f94b167169", + "s" : "0x7445362aadae8c25e4f0b494ad553bfc652bf34fb2ed0ccbf9a6b089c2b09f62", + "to" : "", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020140", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xcf08", + "hash" : "acbdff199573486fb95c161701899d39b1c185b3d0b47f84e6dfeb523460b23d", + "mixHash" : "68b8605bad23304f622a5c84c7f3fa3b4552147c025ef7c4ccfc6eba9249f73a", + "nonce" : "a7abc8bf394b64c6", + "number" : "0x06", + "parentHash" : "5d08215124863936106a33d44911139e90b5727af7dd7e00f641e69b3651a6f7", + "receiptTrie" : "975eeeb6e46fc2d858080444f0536a1f3a688638fdf0bcbc1958dedc5eda4405", + "stateRoot" : "05ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174", + "timestamp" : "0x5788dcbe", + "transactionsTrie" : "ef009c3c274a522a6e2ca98232fffff747bdfab79189be3e2b5e5dc54e2a51be", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "6", + "rlp" : "0xf9024cf901f9a05d08215124863936106a33d44911139e90b5727af7dd7e00f641e69b3651a6f7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a005ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174a0ef009c3c274a522a6e2ca98232fffff747bdfab79189be3e2b5e5dc54e2a51bea0975eeeb6e46fc2d858080444f0536a1f3a688638fdf0bcbc1958dedc5eda4405b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014006832fefba82cf08845788dcbe80a068b8605bad23304f622a5c84c7f3fa3b4552147c025ef7c4ccfc6eba9249f73a88a7abc8bf394b64c6f84df84b050182ea60800a801ba04d147b172eb81fdb11a21826eabad091084f6e9613d340b5897872843efa6435a023640d906f65fd156b92d518068263d99d94dc88c3e0950fd7633fb0d4d237eec0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x05", + "r" : "0x4d147b172eb81fdb11a21826eabad091084f6e9613d340b5897872843efa6435", + "s" : "0x23640d906f65fd156b92d518068263d99d94dc88c3e0950fd7633fb0d4d237ee", + "to" : "", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xa042", + "hash" : "f49bb56fe54a6b9b5f680fabdda650282ed775dfd61f680b1aa22ae7981ad0f3", + "mixHash" : "fa179ecc633681c23745afc1b9302c33b34713054722cc90fcafa66c4626af9b", + "nonce" : "da2c320a8cf4466b", + "number" : "0x07", + "parentHash" : "acbdff199573486fb95c161701899d39b1c185b3d0b47f84e6dfeb523460b23d", + "receiptTrie" : "aec104fc55d9aa0c1767af2dcf73c512f650f24bf89b9b78eb236d70a2de848f", + "stateRoot" : "40d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029", + "timestamp" : "0x5788dcc4", + "transactionsTrie" : "b2d17fa171d19df4e817ffb15f38526d125a42b7879cd712584b130dc8ad341c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "7", + "rlp" : "0xf90260f901f9a0acbdff199573486fb95c161701899d39b1c185b3d0b47f84e6dfeb523460b23da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a0b2d17fa171d19df4e817ffb15f38526d125a42b7879cd712584b130dc8ad341ca0aec104fc55d9aa0c1767af2dcf73c512f650f24bf89b9b78eb236d70a2de848fb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018007832fefba82a042845788dcc480a0fa179ecc633681c23745afc1b9302c33b34713054722cc90fcafa66c4626af9b88da2c320a8cf4466bf861f85f060182ea609410000000000000000000000000000000000000070a801ba0bb8523d4c53ed16b355d0a2dba02154d23a5480449dc3894be40ef95511d2fe9a010ad725c2df4979b7a071b3fa9b6b719223f0167d68b98f213e8611f84d4d81bc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x06", + "r" : "0xbb8523d4c53ed16b355d0a2dba02154d23a5480449dc3894be40ef95511d2fe9", + "s" : "0x10ad725c2df4979b7a071b3fa9b6b719223f0167d68b98f213e8611f84d4d81b", + "to" : "1000000000000000000000000000000000000007", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "8", + "rlp" : "0xf901e8f901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80c0c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0201c0", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "f72712a3cc7a529b9f546210021b6656869b4b7a087ae7edd46813b3d16d6f33", + "mixHash" : "ce2560cb248158e7d6dc7b91b9c9bfe33ec595e0b8c28949295fd0f3825fb3c5", + "nonce" : "e1456cf26b175da3", + "number" : "0x08", + "parentHash" : "f49bb56fe54a6b9b5f680fabdda650282ed775dfd61f680b1aa22ae7981ad0f3", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "c98502a5a62b5f861b5b8a73b1bdcf94045f2929024e5cc9d8af8e3989c388e1", + "timestamp" : "0x5788dccd", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "8", + "rlp" : "0xf90209f90204a0f49bb56fe54a6b9b5f680fabdda650282ed775dfd61f680b1aa22ae7981ad0f3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c98502a5a62b5f861b5b8a73b1bdcf94045f2929024e5cc9d8af8e3989c388e1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201c008832fefba80845788dccd8d64616f2d686172642d666f726ba0ce2560cb248158e7d6dc7b91b9c9bfe33ec595e0b8c28949295fd0f3825fb3c588e1456cf26b175da3c0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020200", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x65aa", + "hash" : "f413ffd0487431795bb6ddc294a5d1bf3521ec030306c2753d16fad0faa7a75a", + "mixHash" : "0d26e09d369ab5b1fc31616bc6d88eecf0c34f548c5491a508c3ae31dbebb301", + "nonce" : "584a1e99e55da8aa", + "number" : "0x09", + "parentHash" : "f72712a3cc7a529b9f546210021b6656869b4b7a087ae7edd46813b3d16d6f33", + "receiptTrie" : "495e1248e1c24cb86cd27272086718c404d4b87531e03fa943ff149511a0faa6", + "stateRoot" : "deb10c3f01687b15e4c3af95f7d12cf003e80af3196bc77a80fafa75b527c31d", + "timestamp" : "0x5788dcd3", + "transactionsTrie" : "964e2a482dc1856fff3b00f545aaf8720aeef70a3ffe86cebf05bbc2c34bf539", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "9", + "rlp" : "0xf9026df90206a0f72712a3cc7a529b9f546210021b6656869b4b7a087ae7edd46813b3d16d6f33a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0deb10c3f01687b15e4c3af95f7d12cf003e80af3196bc77a80fafa75b527c31da0964e2a482dc1856fff3b00f545aaf8720aeef70a3ffe86cebf05bbc2c34bf539a0495e1248e1c24cb86cd27272086718c404d4b87531e03fa943ff149511a0faa6b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302020009832fefba8265aa845788dcd38d64616f2d686172642d666f726ba00d26e09d369ab5b1fc31616bc6d88eecf0c34f548c5491a508c3ae31dbebb30188584a1e99e55da8aaf861f85f070182ea6094100000000000000000000000000000000000000801801ba09e18981c45e9f6bb54e3f52cae58f2c3c00f2220a9f1c788d0ee3fc2394d4956a038207c17c10faae1fa83bff79770fa38134a19b6ca6f04059d7a307c05f67e6ac0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x07", + "r" : "0x9e18981c45e9f6bb54e3f52cae58f2c3c00f2220a9f1c788d0ee3fc2394d4956", + "s" : "0x38207c17c10faae1fa83bff79770fa38134a19b6ca6f04059d7a307c05f67e6a", + "to" : "1000000000000000000000000000000000000008", + "v" : "0x1b", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "10", + "rlp" : "0xf90236f901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f84df84b080182ea608001801ba066a8a933ff9208ecb2334a7edcf0592751d68e5e9cf155814238cd3072a7d38ba02cd8720983a8172b1304aad194d3f2ea3daeaf5c51bc3dc983d8218448f063bdc0" + }, + { + "blocknumber" : "11", + "rlp" : "0xf90236f901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f84df84b090182ea608001801ba08c41aab2b35a0c8c82f88076fe817d2c3a261e6bbab3c270f2d5f6c8ba077f2ea04861726cfb49b87296466ab8cf0790d7790e7e371168dc7e960361bc3479e985c0" + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09", + "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0102030405060708", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "6bff69e94b94f30e1b69f86d3e09712edfb583ac73a46a522345e1965ca9c66d", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06bff69e94b94f30e1b69f86d3e09712edfb583ac73a46a522345e1965ca9c66da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", + "lastblockhash" : "f413ffd0487431795bb6ddc294a5d1bf3521ec030306c2753d16fad0faa7a75a", + "postState" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0c243ebe6a031753dc0dd850acf422844a3efb76" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x0a", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x02540be400" + } + }, + "1000000000000000000000000000000000000008" : { + "balance" : "0x01", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "248f0f0f33eadb89e9d87fd5c127f58567f3ffde" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "85c2f277588ea1e6901ed59e587bea222c575f87" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x0270801d946c97ec1c", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b96dd9d", + "code" : "0x", + "nonce" : "0x08", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b1d37cf6180ceb738ca45b5005a2f418c02e204b" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bf4ed7b27f1d666546e30d74d50d173d20bca754" : { + "balance" : "0x010bc166ae40", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x00", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000008" : { + "balance" : "0x00", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b9aca00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x0f4240", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "DaoTransactions_UncleExtradata" : { + "blocks" : [ + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "6a6235d2937cb55dd1bb0c84f64943011c6b9aa655ecf949d0f3677d3df37fe9", + "mixHash" : "dc5b0e1a8b5e111a45474596139eceef6e3ef2c96226dacf6e282262a7e69d5a", + "nonce" : "09e6701cc7e04da7", + "number" : "0x01", + "parentHash" : "cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09", + "receiptTrie" : "37aee413d1d4f1335720ed1ee882bac4b2d41c8072453b23445020c951682054", + "stateRoot" : "d3f60d7c23e6d3e8eeaa691dd6d54b653e9d33ce579ed821a1e408c1e89cf01a", + "timestamp" : "0x5788dce1", + "transactionsTrie" : "ac81275d7a81a720240146377982939179218535bfcfa9469c8bdd3e264ef179", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "1", + "rlp" : "0xf9024cf901f9a0cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0d3f60d7c23e6d3e8eeaa691dd6d54b653e9d33ce579ed821a1e408c1e89cf01aa0ac81275d7a81a720240146377982939179218535bfcfa9469c8bdd3e264ef179a037aee413d1d4f1335720ed1ee882bac4b2d41c8072453b23445020c951682054b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba825208845788dce180a0dc5b0e1a8b5e111a45474596139eceef6e3ef2c96226dacf6e282262a7e69d5a8809e6701cc7e04da7f84df84b8001827530800a801ca057cb46c0b702929c4fd4127b2370f28a7aeeaa65509699e58eedf7692090a0a9a05ba7c83d99be6a9bca0c81947023ba3b5f2162516d82d0757bf8004f3e9bc03ac0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x57cb46c0b702929c4fd4127b2370f28a7aeeaa65509699e58eedf7692090a0a9", + "s" : "0x5ba7c83d99be6a9bca0c81947023ba3b5f2162516d82d0757bf8004f3e9bc03a", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020040", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "d79fd92f80a0745c29abc6e28578aeb8f063f2dec88c246e241b5dd5bdb8ba7d", + "mixHash" : "c39d82b340083da577ef2f0299521ecdf7062575dad75cb15566b77869493a4e", + "nonce" : "a0344ef0a4622d51", + "number" : "0x02", + "parentHash" : "6a6235d2937cb55dd1bb0c84f64943011c6b9aa655ecf949d0f3677d3df37fe9", + "receiptTrie" : "9a62bdf5dbcf4d27f17a31d5506d3249c5a6ca549787b1902ba01584bb33cf64", + "stateRoot" : "c97eb33ff96a24bd16aaa76040aff370a690e6e52f0172eba3a436d7c867a988", + "timestamp" : "0x5788dce9", + "transactionsTrie" : "76c7a0ce7644661f276c76fb9a82eaee879d0642cf4ed244fc10afc02c646abf", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "2", + "rlp" : "0xf9024cf901f9a06a6235d2937cb55dd1bb0c84f64943011c6b9aa655ecf949d0f3677d3df37fe9a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c97eb33ff96a24bd16aaa76040aff370a690e6e52f0172eba3a436d7c867a988a076c7a0ce7644661f276c76fb9a82eaee879d0642cf4ed244fc10afc02c646abfa09a62bdf5dbcf4d27f17a31d5506d3249c5a6ca549787b1902ba01584bb33cf64b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba825208845788dce980a0c39d82b340083da577ef2f0299521ecdf7062575dad75cb15566b77869493a4e88a0344ef0a4622d51f84df84b0101827530800a801ca0bb6e3cf3f281af13ef1393d7052b03cab367079a9eb71aa829ec72b231a60e1fa04bcfe1da53f26bb95806d38e9f42fef262aaaf5191e16ec473a695c8978a0b05c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x01", + "r" : "0xbb6e3cf3f281af13ef1393d7052b03cab367079a9eb71aa829ec72b231a60e1f", + "s" : "0x4bcfe1da53f26bb95806d38e9f42fef262aaaf5191e16ec473a695c8978a0b05", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020080", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "a067ecb45dd483817f54e229556952f8eb6ffa57a88b29e989c0e3ea9f21d3fb", + "mixHash" : "2bbcca39f731d951481da431940b17549721062c1d213c6b6f49099030ad5767", + "nonce" : "94eaf9f574478fe4", + "number" : "0x03", + "parentHash" : "d79fd92f80a0745c29abc6e28578aeb8f063f2dec88c246e241b5dd5bdb8ba7d", + "receiptTrie" : "b9ca869c5641896a8e22fe74b4225c6a43cbc3303b24d13e0af94517180c8097", + "stateRoot" : "9cb74b15edd72a2075b114d9154f4bbdf784054658912024747ea9423e0d2af8", + "timestamp" : "0x5788dcec", + "transactionsTrie" : "3798aa164b61e27b93484c76a5f319bd93c808dc78ef31cf8b93f4e1b248ca2c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "3", + "rlp" : "0xf9024cf901f9a0d79fd92f80a0745c29abc6e28578aeb8f063f2dec88c246e241b5dd5bdb8ba7da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a09cb74b15edd72a2075b114d9154f4bbdf784054658912024747ea9423e0d2af8a03798aa164b61e27b93484c76a5f319bd93c808dc78ef31cf8b93f4e1b248ca2ca0b9ca869c5641896a8e22fe74b4225c6a43cbc3303b24d13e0af94517180c8097b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba825208845788dcec80a02bbcca39f731d951481da431940b17549721062c1d213c6b6f49099030ad57678894eaf9f574478fe4f84df84b0201827530800a801ca0f6d884cae1f86bdff1281e95e416089c544a4a5578a75d5e8ad76118e341b055a075b7d88985ed5acd61f30c9f9570c6c33bb92f3ad1a32b86a0747817fbc5ededc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x02", + "r" : "0xf6d884cae1f86bdff1281e95e416089c544a4a5578a75d5e8ad76118e341b055", + "s" : "0x75b7d88985ed5acd61f30c9f9570c6c33bb92f3ad1a32b86a0747817fbc5eded", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0200c0", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "f0b1b300b01ca901967fd47745e84afaf28c2d15f863da355e5791b94a911107", + "mixHash" : "28e1a30ba4c89a6b1a5ff007226250b3091b4bb930ce6b83a07c8e835c83f52d", + "nonce" : "54210a32ae9561fd", + "number" : "0x04", + "parentHash" : "a067ecb45dd483817f54e229556952f8eb6ffa57a88b29e989c0e3ea9f21d3fb", + "receiptTrie" : "d69ea0fac668bb7ece043f8e6ac833c5d10a7d5bf08ebfe40a8dc1721a3aa4fd", + "stateRoot" : "aeaa38b30cbc02db5cd17a91e9212346cd839fafcb1fc06126cf64b5b782b877", + "timestamp" : "0x5788dcf0", + "transactionsTrie" : "4cc1b34b3a9d29bf69842a54e1c48bc97afc433883f66d2c59287f118c9c3c2c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "4", + "rlp" : "0xf9024cf901f9a0a067ecb45dd483817f54e229556952f8eb6ffa57a88b29e989c0e3ea9f21d3fba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0aeaa38b30cbc02db5cd17a91e9212346cd839fafcb1fc06126cf64b5b782b877a04cc1b34b3a9d29bf69842a54e1c48bc97afc433883f66d2c59287f118c9c3c2ca0d69ea0fac668bb7ece043f8e6ac833c5d10a7d5bf08ebfe40a8dc1721a3aa4fdb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200c004832fefba825208845788dcf080a028e1a30ba4c89a6b1a5ff007226250b3091b4bb930ce6b83a07c8e835c83f52d8854210a32ae9561fdf84df84b0301827530800a801ca0753ee5d896db8d87fe850e7935418587277cd9c010dfaaf7dd09b0a2e73785dca066deb3c241d532c7b880ae7a9a311ee7a92ef1c5e4e2bf3307990a2881bc13b0c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0x7530", + "gasPrice" : "0x01", + "nonce" : "0x03", + "r" : "0x753ee5d896db8d87fe850e7935418587277cd9c010dfaaf7dd09b0a2e73785dc", + "s" : "0x66deb3c241d532c7b880ae7a9a311ee7a92ef1c5e4e2bf3307990a2881bc13b0", + "to" : "", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020100", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xcf08", + "hash" : "48c11a9d9affbcd36782770bc512f0fdc5b31dbef334fc6dea2ce6f6a6d1741a", + "mixHash" : "b3c1ccf41831ee494eab1190c9f69a9d671031114342821bc327a30cf3d74bf2", + "nonce" : "395f46219e639a8a", + "number" : "0x05", + "parentHash" : "f0b1b300b01ca901967fd47745e84afaf28c2d15f863da355e5791b94a911107", + "receiptTrie" : "d7f28f5ba69ca1893569465903e8d942153c57912f7d1f6b3e33088e8ad17fee", + "stateRoot" : "f54737efdead0a75d49cc6ceaedf75fd4aacf933e8f361a9a9c0a1647bcf6ab5", + "timestamp" : "0x5788dcf4", + "transactionsTrie" : "165af780d27795ebc80c27759d3d949a9c4b05d35fcc7e9d3da8be357f5340cd", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "5", + "rlp" : "0xf9024cf901f9a0f0b1b300b01ca901967fd47745e84afaf28c2d15f863da355e5791b94a911107a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0f54737efdead0a75d49cc6ceaedf75fd4aacf933e8f361a9a9c0a1647bcf6ab5a0165af780d27795ebc80c27759d3d949a9c4b05d35fcc7e9d3da8be357f5340cda0d7f28f5ba69ca1893569465903e8d942153c57912f7d1f6b3e33088e8ad17feeb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302010005832fefba82cf08845788dcf480a0b3c1ccf41831ee494eab1190c9f69a9d671031114342821bc327a30cf3d74bf288395f46219e639a8af84df84b040182ea60800a801ba0cb1400f01459519ac3dc0426c6d7f95641dc6a7b8008069c9dfbe4f94b167169a07445362aadae8c25e4f0b494ad553bfc652bf34fb2ed0ccbf9a6b089c2b09f62c0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x04", + "r" : "0xcb1400f01459519ac3dc0426c6d7f95641dc6a7b8008069c9dfbe4f94b167169", + "s" : "0x7445362aadae8c25e4f0b494ad553bfc652bf34fb2ed0ccbf9a6b089c2b09f62", + "to" : "", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020140", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xcf08", + "hash" : "5fc71cd93151a07d5c8e223178a472dfadf85c7c0d601c461bb2412ad90008cf", + "mixHash" : "8cf9efd45d62f0c5e539295f5c88f2d41a449fa31413a4ac2fa0b679f41cdd46", + "nonce" : "76c3a1561e24c932", + "number" : "0x06", + "parentHash" : "48c11a9d9affbcd36782770bc512f0fdc5b31dbef334fc6dea2ce6f6a6d1741a", + "receiptTrie" : "975eeeb6e46fc2d858080444f0536a1f3a688638fdf0bcbc1958dedc5eda4405", + "stateRoot" : "05ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174", + "timestamp" : "0x5788dcf7", + "transactionsTrie" : "ef009c3c274a522a6e2ca98232fffff747bdfab79189be3e2b5e5dc54e2a51be", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "6", + "rlp" : "0xf9024cf901f9a048c11a9d9affbcd36782770bc512f0fdc5b31dbef334fc6dea2ce6f6a6d1741aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a005ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174a0ef009c3c274a522a6e2ca98232fffff747bdfab79189be3e2b5e5dc54e2a51bea0975eeeb6e46fc2d858080444f0536a1f3a688638fdf0bcbc1958dedc5eda4405b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014006832fefba82cf08845788dcf780a08cf9efd45d62f0c5e539295f5c88f2d41a449fa31413a4ac2fa0b679f41cdd468876c3a1561e24c932f84df84b050182ea60800a801ba04d147b172eb81fdb11a21826eabad091084f6e9613d340b5897872843efa6435a023640d906f65fd156b92d518068263d99d94dc88c3e0950fd7633fb0d4d237eec0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x05", + "r" : "0x4d147b172eb81fdb11a21826eabad091084f6e9613d340b5897872843efa6435", + "s" : "0x23640d906f65fd156b92d518068263d99d94dc88c3e0950fd7633fb0d4d237ee", + "to" : "", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0xa042", + "hash" : "faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265", + "mixHash" : "f117fd70e501a76776c5dd7c227a2ae6d28aa5a4422b9ce31fdd3d57d411c6b3", + "nonce" : "33b7682fbfa5a723", + "number" : "0x07", + "parentHash" : "5fc71cd93151a07d5c8e223178a472dfadf85c7c0d601c461bb2412ad90008cf", + "receiptTrie" : "aec104fc55d9aa0c1767af2dcf73c512f650f24bf89b9b78eb236d70a2de848f", + "stateRoot" : "40d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029", + "timestamp" : "0x5788dcfc", + "transactionsTrie" : "b2d17fa171d19df4e817ffb15f38526d125a42b7879cd712584b130dc8ad341c", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "7", + "rlp" : "0xf90260f901f9a05fc71cd93151a07d5c8e223178a472dfadf85c7c0d601c461bb2412ad90008cfa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a0b2d17fa171d19df4e817ffb15f38526d125a42b7879cd712584b130dc8ad341ca0aec104fc55d9aa0c1767af2dcf73c512f650f24bf89b9b78eb236d70a2de848fb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018007832fefba82a042845788dcfc80a0f117fd70e501a76776c5dd7c227a2ae6d28aa5a4422b9ce31fdd3d57d411c6b38833b7682fbfa5a723f861f85f060182ea609410000000000000000000000000000000000000070a801ba0bb8523d4c53ed16b355d0a2dba02154d23a5480449dc3894be40ef95511d2fe9a010ad725c2df4979b7a071b3fa9b6b719223f0167d68b98f213e8611f84d4d81bc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x06", + "r" : "0xbb8523d4c53ed16b355d0a2dba02154d23a5480449dc3894be40ef95511d2fe9", + "s" : "0x10ad725c2df4979b7a071b3fa9b6b719223f0167d68b98f213e8611f84d4d81b", + "to" : "1000000000000000000000000000000000000007", + "v" : "0x1b", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + }, + { + "blocknumber" : "8", + "rlp" : "0xf901e8f901e3a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080808080a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80c0c0" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0201c0", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "0101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322", + "mixHash" : "90da7c2e5e892d3ca197843e4d70c4c1b4db9b437f6911c7dc0cb2e9b5ce5be0", + "nonce" : "51dac304188a318e", + "number" : "0x08", + "parentHash" : "faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "2c4f51b520aa26de8db4dc7d8d70eb0bbf8ce35afc6d61ed09881869d2feaa78", + "timestamp" : "0x5788dd05", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "bea28d341a7519c623e60a8f6eb59c216e918b839e87eb3004af1896aea29397" + }, + "blocknumber" : "8", + "rlp" : "0xf90405f90204a0faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265a0bea28d341a7519c623e60a8f6eb59c216e918b839e87eb3004af1896aea29397948888f1f195afa192cfee860698584c030f4c9db1a02c4f51b520aa26de8db4dc7d8d70eb0bbf8ce35afc6d61ed09881869d2feaa78a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201c008832fefba80845788dd058d64616f2d686172642d666f726ba090da7c2e5e892d3ca197843e4d70c4c1b4db9b437f6911c7dc0cb2e9b5ce5be08851dac304188a318ec0f901faf901f7a05fc71cd93151a07d5c8e223178a472dfadf85c7c0d601c461bb2412ad90008cfa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a005ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014007832fefba80845788dd0480a0afe4af48fc8d02068f2f45db556679093e0bff8e468f09bb9cc85565eb4917db88b0ae44f2f84decfb", + "transactions" : [ + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0000000000000000000000000000000000000000", + "difficulty" : "0x020140", + "extraData" : "0x", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "e4dd13214af7bbb7505256ae793b3ab744b9c055a296e31460ff7e8bc5854730", + "mixHash" : "afe4af48fc8d02068f2f45db556679093e0bff8e468f09bb9cc85565eb4917db", + "nonce" : "b0ae44f2f84decfb", + "number" : "0x07", + "parentHash" : "5fc71cd93151a07d5c8e223178a472dfadf85c7c0d601c461bb2412ad90008cf", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "05ecd1a706137ddc9359328005f80a4ca233a4dc443748b04275e3ef6faed174", + "timestamp" : "0x5788dd04", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + }, + { + "blocknumber" : "9", + "rlp" : "0xf90670f90206a00101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322a0e51c2b710360bb753022b0c98232a56129062b29e1c0821d3370f09f9fd41a45948888f1f195afa192cfee860698584c030f4c9db1a0f57f69858375f69a698ad907ede7a2475a95cce18e5f17b612a3e3083c5106ada0964e2a482dc1856fff3b00f545aaf8720aeef70a3ffe86cebf05bbc2c34bf539a05691b60b35567c06fd15723f333ee23a85b059e2a63e05b1bf0dd6a61d10b7d4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201c009832fefba8265aa845788dd188d64616f2d686172642d666f726ba0da8d1ebb0584e85f5eedc7d7468eb7884f13698a02ddc85e880dfc193ca7b3d3887bb80ac0706f11e9f861f85f070182ea6094100000000000000000000000000000000000000801801ba09e18981c45e9f6bb54e3f52cae58f2c3c00f2220a9f1c788d0ee3fc2394d4956a038207c17c10faae1fa83bff79770fa38134a19b6ca6f04059d7a307c05f67e6af90401f90204a0faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018008832fefba80845788dd0c8d64616f2d686172642d666f726ba0ded20d0e31e931d74374026b4b931f0510b1c0b02fb3f76312195b8b74ad83938806b256afd30a542ff901f7a0faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014008832fefba80845788dd1180a05c67667031b65a3d1520ab7fd79fd1dcc53b608155235f19ce92b2104bf7d51a887a3058ce3363d576" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x65aa", + "hash" : "47fbd76ebee44e255941f76197c8ea50697e4b5d2f07477575ad1b1b2d4f0467", + "mixHash" : "fcb6b3c42755d3c943c7b97da78fe729cc791d53631f140f3c2466ad06098282", + "nonce" : "f4e5de74b2c0afd3", + "number" : "0x09", + "parentHash" : "0101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322", + "receiptTrie" : "5691b60b35567c06fd15723f333ee23a85b059e2a63e05b1bf0dd6a61d10b7d4", + "stateRoot" : "f57f69858375f69a698ad907ede7a2475a95cce18e5f17b612a3e3083c5106ad", + "timestamp" : "0x5788dd1f", + "transactionsTrie" : "964e2a482dc1856fff3b00f545aaf8720aeef70a3ffe86cebf05bbc2c34bf539", + "uncleHash" : "c2c05564ceaf59f1a73e832e24ac60cf96e3cc220e0479ebaf09f12977707461" + }, + "blocknumber" : "9", + "rlp" : "0xf90476f90206a00101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322a0c2c05564ceaf59f1a73e832e24ac60cf96e3cc220e0479ebaf09f12977707461948888f1f195afa192cfee860698584c030f4c9db1a0f57f69858375f69a698ad907ede7a2475a95cce18e5f17b612a3e3083c5106ada0964e2a482dc1856fff3b00f545aaf8720aeef70a3ffe86cebf05bbc2c34bf539a05691b60b35567c06fd15723f333ee23a85b059e2a63e05b1bf0dd6a61d10b7d4b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302018009832fefba8265aa845788dd1f8d64616f2d686172642d666f726ba0fcb6b3c42755d3c943c7b97da78fe729cc791d53631f140f3c2466ad0609828288f4e5de74b2c0afd3f861f85f070182ea6094100000000000000000000000000000000000000801801ba09e18981c45e9f6bb54e3f52cae58f2c3c00f2220a9f1c788d0ee3fc2394d4956a038207c17c10faae1fa83bff79770fa38134a19b6ca6f04059d7a307c05f67e6af90207f90204a0faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302010008832fefba80845788dd1d8d64616f2d686172642d666f726ba03ced26fe3256e9f8287b52861a5582a4b551fd0b7f3a65411cb86f141ece54598895fa805c6deebdfd", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x07", + "r" : "0x9e18981c45e9f6bb54e3f52cae58f2c3c00f2220a9f1c788d0ee3fc2394d4956", + "s" : "0x38207c17c10faae1fa83bff79770fa38134a19b6ca6f04059d7a307c05f67e6a", + "to" : "1000000000000000000000000000000000000008", + "v" : "0x1b", + "value" : "0x01" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0000000000000000000000000000000000000000", + "difficulty" : "0x020100", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "7c8dd6f59379615cff1a7edbb0a9060d824d86d19ec8447c1b580ca6859e6c05", + "mixHash" : "3ced26fe3256e9f8287b52861a5582a4b551fd0b7f3a65411cb86f141ece5459", + "nonce" : "95fa805c6deebdfd", + "number" : "0x08", + "parentHash" : "faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "40d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029", + "timestamp" : "0x5788dd1d", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + }, + { + "blocknumber" : "10", + "rlp" : "0xf90455f90206a047fbd76ebee44e255941f76197c8ea50697e4b5d2f07477575ad1b1b2d4f0467a09669b09c1fca3cae0e8a34eca70a63fbc62c36715074e8b75cc649da0a149396948888f1f195afa192cfee860698584c030f4c9db1a0a536759560008986d9adbb774618686a1a7cf849a2c08c5f6a047e9a3de66945a0f49ed12e4a98811e40b2cd24a470e3ff48ab6c1887d36fa68f79440321685d00a0f07f905c4fcfce60993e277c6ccd5bf0eacae30e71b10fa765fd98b046ada645b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201c00a832fefba82cf08845788dd258d64616f2d686172642d666f726ba0340f8760a46bbb41fc96589bc68ff07cf828b32e8a32fbc3fe6f373973472dd288fb347ffe902d0bb1f84df84b080182ea608001801ba066a8a933ff9208ecb2334a7edcf0592751d68e5e9cf155814238cd3072a7d38ba02cd8720983a8172b1304aad194d3f2ea3daeaf5c51bc3dc983d8218448f063bdf901faf901f7a00101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a02c4f51b520aa26de8db4dc7d8d70eb0bbf8ce35afc6d61ed09881869d2feaa78a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014009832fefba80845788dd2380a0eeea53c657dbbb61a2e239cef19464574829fd2284728bf311e1c94230a118b9886f043bd4378b18cd" + }, + { + "blocknumber" : "11", + "rlp" : "0xf905fff90204a047fbd76ebee44e255941f76197c8ea50697e4b5d2f07477575ad1b1b2d4f0467a02332e0883af77a9c57cd2f1dbd55f7c2b6a7b3a0946ebb94e9d29a7d6559428d948888f1f195afa192cfee860698584c030f4c9db1a09e8229dc7d51defa7f3d18c110cb776f2807f6a244dfe9775a5ecbbaa2d97527a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201800a832fefba80845788dd2d8d64616f2d686172642d666f726ba0413905ed55d67309eb11a9d2a12b786f94b7c0e70d79ffa08d9cdce8efaa34cb8852cdc9bfdccf22cac0f903f4f901f7a00101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a02c4f51b520aa26de8db4dc7d8d70eb0bbf8ce35afc6d61ed09881869d2feaa78a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302014009832fefba80845788dd2980a0ec71a16d14838a637784d4f25a4641b290ef1ad4f726d59b659709e38a690f7a88dc1dbd1bb6d69415f901f7a047fbd76ebee44e255941f76197c8ea50697e4b5d2f07477575ad1b1b2d4f0467a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0f57f69858375f69a698ad907ede7a2475a95cce18e5f17b612a3e3083c5106ada056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201800a832fefba80845788dd2a80a0d611411c515295dfe7b7b60021f8542f99e82959d67d00d8ea830a10fdb700d28863bbcc6e20f60707" + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020140", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x5208", + "hash" : "ca32dc51f04be8d5858f1565794edafc5b558c66aabbd5b468fdd9e5f2b0dde2", + "mixHash" : "4c8184afdf266ded8ba03efefb9b383f124af8a420d4b0623724e76c16362309", + "nonce" : "df8d645fe80a1c5f", + "number" : "0x0a", + "parentHash" : "47fbd76ebee44e255941f76197c8ea50697e4b5d2f07477575ad1b1b2d4f0467", + "receiptTrie" : "e3e8a54108fb9689ac6f724e4f0189db4bb7df7ca6f343f939195449e94c54a8", + "stateRoot" : "c1673db25cd7b78891984f84cb2d44a435b87c0408f9faac1b0771f3221034c9", + "timestamp" : "0x5788dd37", + "transactionsTrie" : "916147a0805a950d8cc91ea336b3b7237474ac724029dc99f96b07eef085e4d7", + "uncleHash" : "5c1818947711e59c2039312ff6f53c67abf9c4bdc9aa558ade6acd0fb82d4c68" + }, + "blocknumber" : "10", + "rlp" : "0xf9067df90206a047fbd76ebee44e255941f76197c8ea50697e4b5d2f07477575ad1b1b2d4f0467a05c1818947711e59c2039312ff6f53c67abf9c4bdc9aa558ade6acd0fb82d4c68948888f1f195afa192cfee860698584c030f4c9db1a0c1673db25cd7b78891984f84cb2d44a435b87c0408f9faac1b0771f3221034c9a0916147a0805a950d8cc91ea336b3b7237474ac724029dc99f96b07eef085e4d7a0e3e8a54108fb9689ac6f724e4f0189db4bb7df7ca6f343f939195449e94c54a8b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201400a832fefba825208845788dd378d64616f2d686172642d666f726ba04c8184afdf266ded8ba03efefb9b383f124af8a420d4b0623724e76c1636230988df8d645fe80a1c5ff861f85f080182ea609410000000000000000000000000000000000000106f801ba047acd0e2edbc13fbfed74b1b5e6f5afaae464ff6662fc15fc76cf16f6821a72da02e989a61feb7751d802ec9ec12d30a6c419a65c8ba6acd96857a73c18b6a5564f9040ef90204a0faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a040d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008008832fefba80845788dd338d64616f2d686172642d666f726ba0b4857ee254e0403f258dc214738b57bf08690794e4c438012eb18c507fa2ae9588e806cb4705dd9c46f90204a00101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a02c4f51b520aa26de8db4dc7d8d70eb0bbf8ce35afc6d61ed09881869d2feaa78a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302010009832fefba80845788dd338d64616f2d686172642d666f726ba006254cab91d3348cf91a9db6ea7f1f94943b6647a3b1ac2be6f1d0f2773bf0e088edc8d858b2798c52", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x08", + "r" : "0x47acd0e2edbc13fbfed74b1b5e6f5afaae464ff6662fc15fc76cf16f6821a72d", + "s" : "0x2e989a61feb7751d802ec9ec12d30a6c419a65c8ba6acd96857a73c18b6a5564", + "to" : "1000000000000000000000000000000000000010", + "v" : "0x1b", + "value" : "0x6f" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0000000000000000000000000000000000000000", + "difficulty" : "0x020080", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "12fc96f2e58a510584d8e01a02b2834c293945bba1e1f2fc48b539d345febe90", + "mixHash" : "b4857ee254e0403f258dc214738b57bf08690794e4c438012eb18c507fa2ae95", + "nonce" : "e806cb4705dd9c46", + "number" : "0x08", + "parentHash" : "faf53d9cbf0bb0503e4313936019eb34a342b75770f6c2d92412d1fe38a99265", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "40d119003a07ed2dece2e87393e1affed584f81ee4c8c262e27984b10356a029", + "timestamp" : "0x5788dd33", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0000000000000000000000000000000000000000", + "difficulty" : "0x020100", + "extraData" : "0x64616f2d686172642d666f726b", + "gasLimit" : "0x2fefba", + "gasUsed" : "0x00", + "hash" : "f1ae04879bd8627a69a274c283ed05a38a985bae61d9cf553f4b9453c1d5a601", + "mixHash" : "06254cab91d3348cf91a9db6ea7f1f94943b6647a3b1ac2be6f1d0f2773bf0e0", + "nonce" : "edc8d858b2798c52", + "number" : "0x09", + "parentHash" : "0101dba7ec26e5cbe190ca00a34ce4b6f7ead20b0e77ebc8db7ea02eb4d56322", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "2c4f51b520aa26de8db4dc7d8d70eb0bbf8ce35afc6d61ed09881869d2feaa78", + "timestamp" : "0x5788dd33", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x2fefd8", + "gasUsed" : "0x00", + "hash" : "cad74b3b4723472b370737ffaf503f6f746bcae45bd5a39d767c5647afa5bb09", + "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0102030405060708", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "6bff69e94b94f30e1b69f86d3e09712edfb583ac73a46a522345e1965ca9c66d", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06bff69e94b94f30e1b69f86d3e09712edfb583ac73a46a522345e1965ca9c66da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", + "lastblockhash" : "ca32dc51f04be8d5858f1565794edafc5b558c66aabbd5b468fdd9e5f2b0dde2", + "postState" : { + "0000000000000000000000000000000000000000" : { + "balance" : "0xea300b17a8b78000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0c243ebe6a031753dc0dd850acf422844a3efb76" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x0a", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x02540be400" + } + }, + "1000000000000000000000000000000000000008" : { + "balance" : "0x01", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000010" : { + "balance" : "0x6f", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "248f0f0f33eadb89e9d87fd5c127f58567f3ffde" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "85c2f277588ea1e6901ed59e587bea222c575f87" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x02be902146fa2abe24", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b968b26", + "code" : "0x", + "nonce" : "0x09", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b1d37cf6180ceb738ca45b5005a2f418c02e204b" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bf4ed7b27f1d666546e30d74d50d173d20bca754" : { + "balance" : "0x010bc166ae40", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { + "balance" : "0x0a", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x00", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000008" : { + "balance" : "0x00", + "code" : "0x73807640a13483f8ac783c557fcdf27be11ea4ac7a31600055", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x3b9aca00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x0f4240", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + }, + "DaoTransactions_XBlockm1" : { + "blocks" : [ + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x", + "gasLimit" : "0x12b501f5", + "gasUsed" : "0x00", + "hash" : "7f8d325fa7077dffa1aef268597e0fa735306bb937866e3eb73bfcb11eaeb65b", + "mixHash" : "a41acffbfc68c63efb5df04aaa733d9d6a28826dc367a8a2770bc02486219532", + "nonce" : "14742b9b68fab457", + "number" : "0x01", + "parentHash" : "76de3875ca93859a55779bf4c963c58dda6eed39cb34c9f8d1360580f299b16a", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "17d99e7cdc3d010789109a0d1733004627c114253436be8b343b74dc8bc77dc4", + "timestamp" : "0x5788dd3f", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "1", + "rlp" : "0xf901fdf901f8a076de3875ca93859a55779bf4c963c58dda6eed39cb34c9f8d1360580f299b16aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a017d99e7cdc3d010789109a0d1733004627c114253436be8b343b74dc8bc77dc4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018412b501f580845788dd3f80a0a41acffbfc68c63efb5df04aaa733d9d6a28826dc367a8a2770bc024862195328814742b9b68fab457c0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020040", + "extraData" : "0x", + "gasLimit" : "0x12b054b6", + "gasUsed" : "0x00", + "hash" : "b41308b0a12c1b1a06208b827d9dd659619d47b163b9b8c1b1feedbaad7a64af", + "mixHash" : "e56494277ca75cf1ec6060f31d34b45d76e7a133363acdffc1f512a0528a710b", + "nonce" : "ee6d9193ba857f47", + "number" : "0x02", + "parentHash" : "7f8d325fa7077dffa1aef268597e0fa735306bb937866e3eb73bfcb11eaeb65b", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "a639bc369df2e6dcdb261e53927d3129e7e727054063bdb15fd31b8dfad3e67d", + "timestamp" : "0x5788dd46", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "2", + "rlp" : "0xf901fdf901f8a07f8d325fa7077dffa1aef268597e0fa735306bb937866e3eb73bfcb11eaeb65ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a639bc369df2e6dcdb261e53927d3129e7e727054063bdb15fd31b8dfad3e67da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020040028412b054b680845788dd4680a0e56494277ca75cf1ec6060f31d34b45d76e7a133363acdffc1f512a0528a710b88ee6d9193ba857f47c0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020080", + "extraData" : "0x", + "gasLimit" : "0x12aba8a2", + "gasUsed" : "0x00", + "hash" : "21b654accfe3e0120ee79787bfc95a6f454f66ea5002ba0f0c84f7c2a6aa28ee", + "mixHash" : "b27d43fead80c5cc7c05c6345638d52e8a88e6da13b675a279afffa9aaa90ecb", + "nonce" : "08f46890e77a57a1", + "number" : "0x03", + "parentHash" : "b41308b0a12c1b1a06208b827d9dd659619d47b163b9b8c1b1feedbaad7a64af", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "8cf3da7258f9aa5c4deb300f6fce33a5fb374b363b64ebbd6a05a71ceaf62268", + "timestamp" : "0x5788dd4a", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "3", + "rlp" : "0xf901fdf901f8a0b41308b0a12c1b1a06208b827d9dd659619d47b163b9b8c1b1feedbaad7a64afa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a08cf3da7258f9aa5c4deb300f6fce33a5fb374b363b64ebbd6a05a71ceaf62268a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020080038412aba8a280845788dd4a80a0b27d43fead80c5cc7c05c6345638d52e8a88e6da13b675a279afffa9aaa90ecb8808f46890e77a57a1c0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x0200c0", + "extraData" : "0x", + "gasLimit" : "0x12a6fdb9", + "gasUsed" : "0x00", + "hash" : "5473f8af2b586839c3298a36272c7753f57618fc65093a8af7ac4b6f6ea6e8ce", + "mixHash" : "81a197fb4cbcc54d7924aaa10c039113a4fe9b39aa6caebd4cb678c2c323630d", + "nonce" : "274ccd17ac4b439a", + "number" : "0x04", + "parentHash" : "21b654accfe3e0120ee79787bfc95a6f454f66ea5002ba0f0c84f7c2a6aa28ee", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "f9b0c98fed434c398e22415e46d50b0e928c2dc247c328cb0528ea94728eee3f", + "timestamp" : "0x5788dd50", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "4", + "rlp" : "0xf901fdf901f8a021b654accfe3e0120ee79787bfc95a6f454f66ea5002ba0f0c84f7c2a6aa28eea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0f9b0c98fed434c398e22415e46d50b0e928c2dc247c328cb0528ea94728eee3fa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200c0048412a6fdb980845788dd5080a081a197fb4cbcc54d7924aaa10c039113a4fe9b39aa6caebd4cb678c2c323630d88274ccd17ac4b439ac0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020100", + "extraData" : "0x", + "gasLimit" : "0x12a253fb", + "gasUsed" : "0x00", + "hash" : "31865cc304691e510efdb76576c2b2294545bfcb406aae97337b762ca8ceb91a", + "mixHash" : "01dc5f253639977a6f67487657287d5997ff5bd061e0aa12409a3db38c6c5e4b", + "nonce" : "c645fb05954a417d", + "number" : "0x05", + "parentHash" : "5473f8af2b586839c3298a36272c7753f57618fc65093a8af7ac4b6f6ea6e8ce", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "27d25b8ec2fe581a790cf37c4c2be363799f12c8ebd70d6b703f30f676de6cd2", + "timestamp" : "0x5788dd54", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "5", + "rlp" : "0xf901fdf901f8a05473f8af2b586839c3298a36272c7753f57618fc65093a8af7ac4b6f6ea6e8cea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a027d25b8ec2fe581a790cf37c4c2be363799f12c8ebd70d6b703f30f676de6cd2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020100058412a253fb80845788dd5480a001dc5f253639977a6f67487657287d5997ff5bd061e0aa12409a3db38c6c5e4b88c645fb05954a417dc0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020140", + "extraData" : "0x", + "gasLimit" : "0x129dab68", + "gasUsed" : "0x00", + "hash" : "f4dfacab1c75d769193ff4b46190ab4e758528bcad44e0723347f705de171142", + "mixHash" : "bdd40a39ba235400737c0587dc140a1dc02f51f1f7a716e4ba52a7723b614657", + "nonce" : "dc09580bc9ac6c81", + "number" : "0x06", + "parentHash" : "31865cc304691e510efdb76576c2b2294545bfcb406aae97337b762ca8ceb91a", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "186b7bee2b8ab05978991904147c7b4b58bd498e3c8a9932210f057ea7e38c62", + "timestamp" : "0x5788dd5a", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "6", + "rlp" : "0xf901fdf901f8a031865cc304691e510efdb76576c2b2294545bfcb406aae97337b762ca8ceb91aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0186b7bee2b8ab05978991904147c7b4b58bd498e3c8a9932210f057ea7e38c62a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201400684129dab6880845788dd5a80a0bdd40a39ba235400737c0587dc140a1dc02f51f1f7a716e4ba52a7723b61465788dc09580bc9ac6c81c0c0", + "transactions" : [ + ], + "uncleHeaders" : [ + ] + }, + { + "blockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020180", + "extraData" : "0x", + "gasLimit" : "0x129903ff", + "gasUsed" : "0x5208", + "hash" : "b4fd754ea31355af44d104be9c93c4ff5c69e3de6692b84234bbffa2a8935762", + "mixHash" : "8b3b3daa6fef89706df93df25cd7160359b3029eb183dc0d03279db3e1d668fe", + "nonce" : "b8bc0f59998aca79", + "number" : "0x07", + "parentHash" : "f4dfacab1c75d769193ff4b46190ab4e758528bcad44e0723347f705de171142", + "receiptTrie" : "8494555e17e5455b9b7c734c4e6dd720a575f04e741302abecbb610896e1bdb4", + "stateRoot" : "6d5aa4970c1810949e15062da2fd638123b2b1cab467a18381676cc7dfbcb331", + "timestamp" : "0x5788dd60", + "transactionsTrie" : "2067f9535b492e7070dd88a15bd979eff4f2d03814c8514cdd8cb1b7715c6d6b", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "blocknumber" : "7", + "rlp" : "0xf90261f901faa0f4dfacab1c75d769193ff4b46190ab4e758528bcad44e0723347f705de171142a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a06d5aa4970c1810949e15062da2fd638123b2b1cab467a18381676cc7dfbcb331a02067f9535b492e7070dd88a15bd979eff4f2d03814c8514cdd8cb1b7715c6d6ba08494555e17e5455b9b7c734c4e6dd720a575f04e741302abecbb610896e1bdb4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201800784129903ff825208845788dd6080a08b3b3daa6fef89706df93df25cd7160359b3029eb183dc0d03279db3e1d668fe88b8bc0f59998aca79f861f85f800182ea6094100000000000000000000000000000000000000780801ba065741e61c886da761be2693206b25ef48db266aeb92b120137496d3c3b4a7429a05c16257cbbcd7f1076ca12277fe0f029835c2e5fe36796f1bf2d7b0edeca79afc0", + "transactions" : [ + { + "data" : "0x", + "gasLimit" : "0xea60", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x65741e61c886da761be2693206b25ef48db266aeb92b120137496d3c3b4a7429", + "s" : "0x5c16257cbbcd7f1076ca12277fe0f029835c2e5fe36796f1bf2d7b0edeca79af", + "to" : "1000000000000000000000000000000000000007", + "v" : "0x1b", + "value" : "0x00" + } + ], + "uncleHeaders" : [ + ] + } + ], + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "0x020000", + "extraData" : "0x42", + "gasLimit" : "0x12b9b060", + "gasUsed" : "0x00", + "hash" : "76de3875ca93859a55779bf4c963c58dda6eed39cb34c9f8d1360580f299b16a", + "mixHash" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0102030405060708", + "number" : "0x00", + "parentHash" : "0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "42b6c06dc02697e651f409032cfda2b524b81e1d12443b75648b2bedcbca4865", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "genesisRLP" : "0xf901fdf901f8a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a042b6c06dc02697e651f409032cfda2b524b81e1d12443b75648b2bedcbca4865a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808412b9b060808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", + "lastblockhash" : "b4fd754ea31355af44d104be9c93c4ff5c69e3de6692b84234bbffa2a8935762", + "postState" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1000000000000000000000000000000000000007" : { + "balance" : "0x00", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8888f1f195afa192cfee860698584c030f4c9db1" : { + "balance" : "0x01e5b8fa8fe2ac5208", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0xe8d4a4bdf8", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x0f4240", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + }, + "pre" : { + "005f5cee7a43331d5a3d3eec71305925a62f34b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "057b56736d32b86616a10f619859c6cd6f59092a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "06706dd3f2c9abf0a21ddcc6941d9b86f0596936" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0737a6b837f97f46ebade41b9bc3e1c509c85c53" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "07f5c1e1bc2c93e0402f23341973a0e043f7bf8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0e0da70933f4c7849fc0d203f5d1d43b9ae4532d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0ff30d6de14a8224aa97b78aea5388d1c51c1f00" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "12e626b0eebfe86a56d633b9864e389b45dcb260" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1591fc0f688c81fbeb17f5426a162a7024d430c2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "17802f43a0137c506ba92291391a8a8f207f487d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1975bd06d486162d5dc297798dfc41edd5d160a7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "1cba23d343a983e9b5cfd19496b9a9701ada385f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "200450f06520bdd6c527622a273333384d870efb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "23b75c2f6791eef49c69684db4c6c1f93bf49a50" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "24c4d950dfd4dd1902bbed3508144a54542bba94" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "253488078a4edf4d6f42f113d1e62836a942cf1a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "27b137a85656544b1ccb5a0f2e561a5703c6a68f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2a5ed960395e2a49b1c758cef4aa15213cfd874c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2b3455ec7fedf16e646268bf88846bd7a2319bb2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "2c19c7f9ae8b751e37aeb2d93a699722395ae18f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "304a554a310c7e546dfe434669c62820b7d83490" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "319f70bab6845585f412ec7724b744fec6095c85" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "35a051a0010aba705c9008d7a7eff6fb88f6ea7b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3ba4d81db016dc2890c81f3acec2454bff5aada5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "3c02a7bc0391e86d91b7d144e61c2c01a25a79c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "40b803a9abce16f50f36a77ba41180eb90023925" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "440c59b325d2997a134c2c7c60a8c61611212bad" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4486a3d68fac6967006d7a517b889fd3f98c102b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4613f3bca5c44ea06337a9e439fbc6d42e501d0a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "47e7aa56d6bdf3f36be34619660de61275420af8" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4863226780fe7c0356454236d3b1c8792785748d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "492ea3bb0f3315521c31f273e565b868fc090f17" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4cb31628079fb14e4bc3cd5e30c2f7489b00960c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4deb0033bb26bc534b197e61d19e0733e5679784" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fa802324e929786dbda3b8820dc7834e9134a2a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "4fd6ace747f06ece9c49699c7cabc62d02211f75" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "51e0ddd9998364a2eb38588679f0d2c42653e4a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "52c5317c848ba20c7504cb2c8052abd1fde29d03" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "542a9515200d14b68e934e9830d91645a980dd7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5524c55fb03cf21f549444ccbecb664d0acad706" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "579a80d909f346fbfb1189493f521d7f48d52238" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "58b95c9a9d5d26825e70a82b6adb139d3fd829eb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5c8536898fbb74fc7445814902fd08422eac56d0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5d2b2e6fcbe3b11d26b525e085ff818dae332479" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5dc28b15dffed94048d73806ce4b7a4612a1d48f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "5f9f3392e9f62f63b8eac0beb55541fc8627f42c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6131c42fa982e56929107413a9d526fd99405560" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6231b6d0d5e77fe001c2a460bd9584fee60d409b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "627a0a960c079c21c34f7612d5d230e01b4ad4c7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "63ed5a272de2f6d968408b4acb9024f4cc208ebf" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6966ab0d485353095148a2155858910e0965b6f9" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6d87578288b6cb5549d5076a207456a1f6a63dc0" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "6f6704e5a10332af6672e50b3d9754dc460dfa4d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "7602b46df5390e432ef1c307d4f2c9ff6d65cc97" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "779543a0491a837ca36ce8c635d6154e3c4911a6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "782495b7b3355efb2833d56ecb34dc22ad7dfcc4" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "807640a13483f8ac783c557fcdf27be11ea4ac7a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8163e7fb499e90f8544ea62bbf80d21cd26d9efd" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "84ef4b2357079cd7a7c69fd7a37cd0609a679106" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "86af3e9626fce1957c82e88cbf04ddf3a2ed7915" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "8d9edb3054ce5c5774a420ac37ebae0ac02343c6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "97f43a37f595ab5dd318fb46e7a155eae057317a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9aa008f65de0b923a2a4f02012ad034a5e2e2192" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c15b54878ba618f494b38f0ae7443db6af648ba" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9c50426be05db97f5d64fc54bf89eff947f0a321" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9da397b9e80755301a3b32173283a91c0ef6c87e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9ea779f907f0b315b364b0cfc39a0fde5b02a416" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9f27daea7aca0aa0446220b98d028715e3bc803d" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "9fcd2deaff372a39cc679d5c5e4de7bafb0b1339" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a2f1ccba9395d7fcb155bba8bc92db9bafaeade7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a3acf3a1e16b1d7c315e23510fdd7847b48234f6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a5dc5acd6a7968a4554d89d65e59b7fd3bff0f90" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a82f360a8d3455c5c41366975bde739c37bfeb8a" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0xe8d4a51000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ac1ecab32727358dba8962a0f3b261731aad9723" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "accc230e8a6e5be9160b8cdf2864dd2a001c28b6" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "acd87e28b0c9d1254e868b81cba4cc20d9a32225" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "adf80daec7ba8dcf15392f1ac611fff65d94f880" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "aeeb8ff27288bdabc0fa5ebb731b6f409507516c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b136707642a4ea12fb4bae820f03d2562ebff487" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b3fb0e5aba0e20e5c49d252dfd30e102b171a425" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b52042c8ca3f8aa246fa79c3feaa3d959347c0ab" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "b9637156d330c0d605a791f1c31ba5890582fe1c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bb9bc244d798123fde783fcc1c72d3bb8c189413" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bc07118b9ac290e4622f5e77a0853539789effbe" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "bcf899e6c7d9d5a215ab1e3444c86806fa854c76" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "be8539bfe837b67d1282b2b1d61c3f723966f049" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "c4bbd073882dd2add2424cf47d35213405b01324" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ca544e5c4687d109611d0f8f928b53a25af72448" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cbb9d3703e651b0d496cdefb8b92c25aeb2171f7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "cc34673c6c40e791051898567a1222daf90be287" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ceaeb481747ca6c540a000c1f3641f8cef161fa7" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d131637d5275fd1a68a3200f4ad25c71a2a9522e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d164b088bd9108b60d0ca3751da4bceb207b0782" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d1ac8b1ef1b69ff51d1d401a476e7e612414f091" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d343b217de44030afaa275f54d31a9317c7f441e" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d4fe7bc31cedb7bfb8a345f31e668033056b2728" : { + "balance" : "0x0f4240", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "d9aef3a1e38a39c16b31d1ace71bca8ef58d315b" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "da2fef9e4a3230988ff17df2165440f37e8b1708" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "dbe9b615a3ae8709af8b93336ce9b477e4ac0940" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e308bd1ac5fda103967359b2712dd89deffb7973" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "e4ae1efdfc53b73893af49113d8694a057b9c0d1" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ec8e57756626fdc07c63ad2eafbd28d08e7b0ca5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "ecd135fa4f61a655311e86238c92adcd779555d2" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f0b1aa0eb660754448a7937c022e30aa692fe0c5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f1385fb24aad0cd7432824085e42aff90886fef5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f14c14075d6c4ed84b86798af0956deef67365b5" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "f4c64518ea10f995918a454158c6b61407ea345c" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "fe24cdd8648121a43a7c86d289be4dd2951ed49f" : { + "balance" : "0x02540be400", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} diff --git a/tests/util.go b/tests/util.go index abc67769d..8d1917d15 100644 --- a/tests/util.go +++ b/tests/util.go @@ -141,6 +141,8 @@ type VmTest struct { type RuleSet struct { HomesteadBlock *big.Int + DAOForkBlock *big.Int + DAOForkSupport bool } func (r RuleSet) IsHomestead(n *big.Int) bool { @@ -312,4 +314,5 @@ func (self Message) GasPrice() *big.Int { return self.price } func (self Message) Gas() *big.Int { return self.gas } func (self Message) Value() *big.Int { return self.value } func (self Message) Nonce() uint64 { return self.nonce } +func (self Message) CheckNonce() bool { return true } func (self Message) Data() []byte { return self.data } diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 2f516951b..37f0af33c 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -241,7 +241,7 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, vm.Logs, caller := state.GetOrNewStateObject(from) - vmenv := NewEnvFromMap(RuleSet{params.MainNetHomesteadBlock}, state, env, exec) + vmenv := NewEnvFromMap(RuleSet{params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, true}, state, env, exec) vmenv.vmTest = true vmenv.skipTransfer = true vmenv.initial = true |