mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-16 17:03:46 +00:00
Merge branch 'master' of https://github.com/nkbai/go-ethereum
This commit is contained in:
commit
33cf1c74f2
50 changed files with 905 additions and 346 deletions
26
.travis.yml
26
.travis.yml
|
|
@ -15,11 +15,23 @@ matrix:
|
||||||
- go run build/ci.go install
|
- go run build/ci.go install
|
||||||
- go run build/ci.go test -coverage
|
- go run build/ci.go test -coverage
|
||||||
|
|
||||||
# These are the latest Go versions.
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
go: 1.8.3
|
go: 1.8.3
|
||||||
|
script:
|
||||||
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
|
||||||
|
- sudo modprobe fuse
|
||||||
|
- sudo chmod 666 /dev/fuse
|
||||||
|
- sudo chown root:$USER /etc/fuse.conf
|
||||||
|
- go run build/ci.go install
|
||||||
|
- go run build/ci.go test -coverage
|
||||||
|
|
||||||
|
# These are the latest Go versions.
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
go: 1.9.0
|
||||||
script:
|
script:
|
||||||
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
|
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
|
||||||
- sudo modprobe fuse
|
- sudo modprobe fuse
|
||||||
|
|
@ -29,7 +41,7 @@ matrix:
|
||||||
- go run build/ci.go test -coverage -misspell
|
- go run build/ci.go test -coverage -misspell
|
||||||
|
|
||||||
- os: osx
|
- os: osx
|
||||||
go: 1.8.3
|
go: 1.9.0
|
||||||
sudo: required
|
sudo: required
|
||||||
script:
|
script:
|
||||||
- brew update
|
- brew update
|
||||||
|
|
@ -42,7 +54,7 @@ matrix:
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
go: 1.8.3
|
go: 1.9.0
|
||||||
env:
|
env:
|
||||||
- ubuntu-ppa
|
- ubuntu-ppa
|
||||||
- azure-linux
|
- azure-linux
|
||||||
|
|
@ -81,7 +93,7 @@ matrix:
|
||||||
sudo: required
|
sudo: required
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
go: 1.8.3
|
go: 1.9.0
|
||||||
env:
|
env:
|
||||||
- azure-linux-mips
|
- azure-linux-mips
|
||||||
script:
|
script:
|
||||||
|
|
@ -121,7 +133,7 @@ matrix:
|
||||||
- azure-android
|
- azure-android
|
||||||
- maven-android
|
- maven-android
|
||||||
before_install:
|
before_install:
|
||||||
- curl https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz | tar -xz
|
- curl https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | tar -xz
|
||||||
- export PATH=`pwd`/go/bin:$PATH
|
- export PATH=`pwd`/go/bin:$PATH
|
||||||
- export GOROOT=`pwd`/go
|
- export GOROOT=`pwd`/go
|
||||||
- export GOPATH=$HOME/go
|
- export GOPATH=$HOME/go
|
||||||
|
|
@ -138,7 +150,7 @@ matrix:
|
||||||
|
|
||||||
# This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
|
# This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
|
||||||
- os: osx
|
- os: osx
|
||||||
go: 1.8.3
|
go: 1.9.0
|
||||||
env:
|
env:
|
||||||
- azure-osx
|
- azure-osx
|
||||||
- azure-ios
|
- azure-ios
|
||||||
|
|
@ -164,7 +176,7 @@ matrix:
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
go: 1.8.3
|
go: 1.9.0
|
||||||
env:
|
env:
|
||||||
- azure-purge
|
- azure-purge
|
||||||
script:
|
script:
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,8 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
|
vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
|
||||||
gaspool := new(core.GasPool).AddGas(math.MaxBig256)
|
gaspool := new(core.GasPool).AddGas(math.MaxBig256)
|
||||||
ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
// TODO utilize returned failed flag to help gas estimation.
|
||||||
|
ret, gasUsed, _, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
|
||||||
return ret, gasUsed, err
|
return ret, gasUsed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La
|
||||||
}
|
}
|
||||||
// For Go bindings pass the code through goimports to clean it up and double check
|
// For Go bindings pass the code through goimports to clean it up and double check
|
||||||
if lang == LangGo {
|
if lang == LangGo {
|
||||||
code, err := imports.Process("", buffer.Bytes(), nil)
|
code, err := imports.Process(".", buffer.Bytes(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("%v\n%s", err, buffer)
|
return "", fmt.Errorf("%v\n%s", err, buffer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -459,7 +459,7 @@ func TestBindings(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845)
|
// Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845)
|
||||||
linkTestCode := fmt.Sprintf("package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}")
|
linkTestCode := fmt.Sprintf("package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}")
|
||||||
linkTestDeps, err := imports.Process("", []byte(linkTestCode), nil)
|
linkTestDeps, err := imports.Process(os.TempDir(), []byte(linkTestCode), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed check for goimports symlink bug: %v", err)
|
t.Fatalf("failed check for goimports symlink bug: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ environment:
|
||||||
install:
|
install:
|
||||||
- git submodule update --init
|
- git submodule update --init
|
||||||
- rmdir C:\go /s /q
|
- rmdir C:\go /s /q
|
||||||
- appveyor DownloadFile https://storage.googleapis.com/golang/go1.8.3.windows-%GETH_ARCH%.zip
|
- appveyor DownloadFile https://storage.googleapis.com/golang/go1.9.windows-%GETH_ARCH%.zip
|
||||||
- 7z x go1.8.3.windows-%GETH_ARCH%.zip -y -oC:\ > NUL
|
- 7z x go1.9.windows-%GETH_ARCH%.zip -y -oC:\ > NUL
|
||||||
- go version
|
- go version
|
||||||
- gcc --version
|
- gcc --version
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,11 +57,15 @@ func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureEnd is triggered at end of execution.
|
// CaptureEnd is triggered at end of execution.
|
||||||
func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error {
|
func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||||
type endLog struct {
|
type endLog struct {
|
||||||
Output string `json:"output"`
|
Output string `json:"output"`
|
||||||
GasUsed math.HexOrDecimal64 `json:"gasUsed"`
|
GasUsed math.HexOrDecimal64 `json:"gasUsed"`
|
||||||
Time time.Duration `json:"time"`
|
Time time.Duration `json:"time"`
|
||||||
|
Err string `json:"error,omitempty"`
|
||||||
}
|
}
|
||||||
return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t})
|
if err != nil {
|
||||||
|
return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()})
|
||||||
|
}
|
||||||
|
return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -234,13 +234,13 @@ Gas used: %d
|
||||||
`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas)
|
`, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas)
|
||||||
}
|
}
|
||||||
if tracer != nil {
|
if tracer != nil {
|
||||||
tracer.CaptureEnd(ret, initialGas-leftOverGas, execTime)
|
tracer.CaptureEnd(ret, initialGas-leftOverGas, execTime, err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("0x%x\n", ret)
|
fmt.Printf("0x%x\n", ret)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" error: %v\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf(" error: %v\n", err)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ var (
|
||||||
}
|
}
|
||||||
NoUSBFlag = cli.BoolFlag{
|
NoUSBFlag = cli.BoolFlag{
|
||||||
Name: "nousb",
|
Name: "nousb",
|
||||||
Usage: "Disables monitoring for and managine USB hardware wallets",
|
Usage: "Disables monitoring for and managing USB hardware wallets",
|
||||||
}
|
}
|
||||||
NetworkIdFlag = cli.Uint64Flag{
|
NetworkIdFlag = cli.Uint64Flag{
|
||||||
Name: "networkid",
|
Name: "networkid",
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ func FromHex(s string) []byte {
|
||||||
//
|
//
|
||||||
// Returns an exact copy of the provided bytes
|
// Returns an exact copy of the provided bytes
|
||||||
func CopyBytes(b []byte) (copiedBytes []byte) {
|
func CopyBytes(b []byte) (copiedBytes []byte) {
|
||||||
|
if b == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
copiedBytes = make([]byte, len(b))
|
copiedBytes = make([]byte, len(b))
|
||||||
copy(copiedBytes, b)
|
copy(copiedBytes, b)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,9 @@ import (
|
||||||
|
|
||||||
// Ethash proof-of-work protocol constants.
|
// Ethash proof-of-work protocol constants.
|
||||||
var (
|
var (
|
||||||
blockReward *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
|
frontierBlockReward *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block
|
||||||
maxUncles = 2 // Maximum number of uncles allowed in a single block
|
metropolisBlockReward *big.Int = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Metropolis
|
||||||
|
maxUncles = 2 // Maximum number of uncles allowed in a single block
|
||||||
)
|
)
|
||||||
|
|
||||||
// Various error messages to mark blocks invalid. These should be private to
|
// Various error messages to mark blocks invalid. These should be private to
|
||||||
|
|
@ -306,6 +307,7 @@ var (
|
||||||
big9 = big.NewInt(9)
|
big9 = big.NewInt(9)
|
||||||
big10 = big.NewInt(10)
|
big10 = big.NewInt(10)
|
||||||
bigMinus99 = big.NewInt(-99)
|
bigMinus99 = big.NewInt(-99)
|
||||||
|
big2999999 = big.NewInt(2999999)
|
||||||
)
|
)
|
||||||
|
|
||||||
// calcDifficultyMetropolis is the difficulty adjustment algorithm. It returns
|
// calcDifficultyMetropolis is the difficulty adjustment algorithm. It returns
|
||||||
|
|
@ -346,8 +348,15 @@ func calcDifficultyMetropolis(time uint64, parent *types.Header) *big.Int {
|
||||||
if x.Cmp(params.MinimumDifficulty) < 0 {
|
if x.Cmp(params.MinimumDifficulty) < 0 {
|
||||||
x.Set(params.MinimumDifficulty)
|
x.Set(params.MinimumDifficulty)
|
||||||
}
|
}
|
||||||
|
// calculate a fake block numer for the ice-age delay:
|
||||||
|
// https://github.com/ethereum/EIPs/pull/669
|
||||||
|
// fake_block_number = min(0, block.number - 3_000_000
|
||||||
|
fakeBlockNumber := new(big.Int)
|
||||||
|
if parent.Number.Cmp(big2999999) >= 0 {
|
||||||
|
fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number
|
||||||
|
}
|
||||||
// for the exponential factor
|
// for the exponential factor
|
||||||
periodCount := new(big.Int).Add(parent.Number, big1)
|
periodCount := fakeBlockNumber
|
||||||
periodCount.Div(periodCount, expDiffPeriod)
|
periodCount.Div(periodCount, expDiffPeriod)
|
||||||
|
|
||||||
// the exponential factor, commonly referred to as "the bomb"
|
// the exponential factor, commonly referred to as "the bomb"
|
||||||
|
|
@ -501,7 +510,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header)
|
||||||
// setting the final state and assembling the block.
|
// setting the final state and assembling the block.
|
||||||
func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||||
// Accumulate any block and uncle rewards and commit the final state root
|
// Accumulate any block and uncle rewards and commit the final state root
|
||||||
AccumulateRewards(state, header, uncles)
|
AccumulateRewards(chain.Config(), state, header, uncles)
|
||||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||||
|
|
||||||
// Header seems complete, assemble into a block and return
|
// Header seems complete, assemble into a block and return
|
||||||
|
|
@ -518,7 +527,13 @@ var (
|
||||||
// reward. The total reward consists of the static block reward and rewards for
|
// reward. The total reward consists of the static block reward and rewards for
|
||||||
// included uncles. The coinbase of each uncle block is also rewarded.
|
// included uncles. The coinbase of each uncle block is also rewarded.
|
||||||
// TODO (karalabe): Move the chain maker into this package and make this private!
|
// TODO (karalabe): Move the chain maker into this package and make this private!
|
||||||
func AccumulateRewards(state *state.StateDB, header *types.Header, uncles []*types.Header) {
|
func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
|
||||||
|
// Select the correct block reward based on chain progression
|
||||||
|
blockReward := frontierBlockReward
|
||||||
|
if config.IsMetropolis(header.Number) {
|
||||||
|
blockReward = metropolisBlockReward
|
||||||
|
}
|
||||||
|
// Accumulate the rewards for the miner and any included uncles
|
||||||
reward := new(big.Int).Set(blockReward)
|
reward := new(big.Int).Set(blockReward)
|
||||||
r := new(big.Int)
|
r := new(big.Int)
|
||||||
for _, uncle := range uncles {
|
for _, uncle := range uncles {
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, db ethdb.Dat
|
||||||
if gen != nil {
|
if gen != nil {
|
||||||
gen(i, b)
|
gen(i, b)
|
||||||
}
|
}
|
||||||
ethash.AccumulateRewards(statedb, h, b.uncles)
|
ethash.AccumulateRewards(config, statedb, h, b.uncles)
|
||||||
root, err := statedb.CommitTo(db, config.IsEIP158(h.Number))
|
root, err := statedb.CommitTo(db, config.IsEIP158(h.Number))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("state write error: %v", err))
|
panic(fmt.Sprintf("state write error: %v", err))
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
|
|
||||||
receipt1 := &types.Receipt{
|
receipt1 := &types.Receipt{
|
||||||
PostState: []byte{0x01},
|
Failed: true,
|
||||||
CumulativeGasUsed: big.NewInt(1),
|
CumulativeGasUsed: big.NewInt(1),
|
||||||
Logs: []*types.Log{
|
Logs: []*types.Log{
|
||||||
{Address: common.BytesToAddress([]byte{0x11})},
|
{Address: common.BytesToAddress([]byte{0x11})},
|
||||||
|
|
@ -351,7 +351,7 @@ func TestBlockReceiptStorage(t *testing.T) {
|
||||||
GasUsed: big.NewInt(111111),
|
GasUsed: big.NewInt(111111),
|
||||||
}
|
}
|
||||||
receipt2 := &types.Receipt{
|
receipt2 := &types.Receipt{
|
||||||
PostState: []byte{0x02},
|
PostState: common.Hash{2}.Bytes(),
|
||||||
CumulativeGasUsed: big.NewInt(2),
|
CumulativeGasUsed: big.NewInt(2),
|
||||||
Logs: []*types.Log{
|
Logs: []*types.Log{
|
||||||
{Address: common.BytesToAddress([]byte{0x22})},
|
{Address: common.BytesToAddress([]byte{0x22})},
|
||||||
|
|
@ -461,12 +461,12 @@ func TestMipmapChain(t *testing.T) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
case 1:
|
case 1:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{{Address: addr, Topics: []common.Hash{hash1}}}
|
receipt.Logs = []*types.Log{{Address: addr, Topics: []common.Hash{hash1}}}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
receipts = types.Receipts{receipt}
|
receipts = types.Receipts{receipt}
|
||||||
case 1000:
|
case 1000:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{{Address: addr2}}
|
receipt.Logs = []*types.Log{{Address: addr2}}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
receipts = types.Receipts{receipt}
|
receipts = types.Receipts{receipt}
|
||||||
|
|
|
||||||
|
|
@ -91,11 +91,6 @@ func (ch suicideChange) undo(s *StateDB) {
|
||||||
if obj != nil {
|
if obj != nil {
|
||||||
obj.suicided = ch.prev
|
obj.suicided = ch.prev
|
||||||
obj.setBalance(ch.prevbalance)
|
obj.setBalance(ch.prevbalance)
|
||||||
// if the object wasn't suicided before, remove
|
|
||||||
// it from the list of destructed objects as well.
|
|
||||||
if !obj.suicided {
|
|
||||||
delete(s.stateObjectsDestructed, *ch.account)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,8 @@ type StateDB struct {
|
||||||
trie Trie
|
trie Trie
|
||||||
|
|
||||||
// This map holds 'live' objects, which will get modified while processing a state transition.
|
// This map holds 'live' objects, which will get modified while processing a state transition.
|
||||||
stateObjects map[common.Address]*stateObject
|
stateObjects map[common.Address]*stateObject
|
||||||
stateObjectsDirty map[common.Address]struct{}
|
stateObjectsDirty map[common.Address]struct{}
|
||||||
stateObjectsDestructed map[common.Address]struct{}
|
|
||||||
|
|
||||||
// DB error.
|
// DB error.
|
||||||
// State objects are used by the consensus core and VM which are
|
// State objects are used by the consensus core and VM which are
|
||||||
|
|
@ -83,14 +82,13 @@ func New(root common.Hash, db Database) (*StateDB, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &StateDB{
|
return &StateDB{
|
||||||
db: db,
|
db: db,
|
||||||
trie: tr,
|
trie: tr,
|
||||||
stateObjects: make(map[common.Address]*stateObject),
|
stateObjects: make(map[common.Address]*stateObject),
|
||||||
stateObjectsDirty: make(map[common.Address]struct{}),
|
stateObjectsDirty: make(map[common.Address]struct{}),
|
||||||
stateObjectsDestructed: make(map[common.Address]struct{}),
|
refund: new(big.Int),
|
||||||
refund: new(big.Int),
|
logs: make(map[common.Hash][]*types.Log),
|
||||||
logs: make(map[common.Hash][]*types.Log),
|
preimages: make(map[common.Hash][]byte),
|
||||||
preimages: make(map[common.Hash][]byte),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +113,6 @@ func (self *StateDB) Reset(root common.Hash) error {
|
||||||
self.trie = tr
|
self.trie = tr
|
||||||
self.stateObjects = make(map[common.Address]*stateObject)
|
self.stateObjects = make(map[common.Address]*stateObject)
|
||||||
self.stateObjectsDirty = make(map[common.Address]struct{})
|
self.stateObjectsDirty = make(map[common.Address]struct{})
|
||||||
self.stateObjectsDestructed = make(map[common.Address]struct{})
|
|
||||||
self.thash = common.Hash{}
|
self.thash = common.Hash{}
|
||||||
self.bhash = common.Hash{}
|
self.bhash = common.Hash{}
|
||||||
self.txIndex = 0
|
self.txIndex = 0
|
||||||
|
|
@ -323,7 +320,6 @@ func (self *StateDB) Suicide(addr common.Address) bool {
|
||||||
})
|
})
|
||||||
stateObject.markSuicided()
|
stateObject.markSuicided()
|
||||||
stateObject.data.Balance = new(big.Int)
|
stateObject.data.Balance = new(big.Int)
|
||||||
self.stateObjectsDestructed[addr] = struct{}{}
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -456,23 +452,19 @@ func (self *StateDB) Copy() *StateDB {
|
||||||
|
|
||||||
// Copy all the basic fields, initialize the memory ones
|
// Copy all the basic fields, initialize the memory ones
|
||||||
state := &StateDB{
|
state := &StateDB{
|
||||||
db: self.db,
|
db: self.db,
|
||||||
trie: self.trie,
|
trie: self.trie,
|
||||||
stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)),
|
stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)),
|
||||||
stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)),
|
stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)),
|
||||||
stateObjectsDestructed: make(map[common.Address]struct{}, len(self.stateObjectsDestructed)),
|
refund: new(big.Int).Set(self.refund),
|
||||||
refund: new(big.Int).Set(self.refund),
|
logs: make(map[common.Hash][]*types.Log, len(self.logs)),
|
||||||
logs: make(map[common.Hash][]*types.Log, len(self.logs)),
|
logSize: self.logSize,
|
||||||
logSize: self.logSize,
|
preimages: make(map[common.Hash][]byte),
|
||||||
preimages: make(map[common.Hash][]byte),
|
|
||||||
}
|
}
|
||||||
// Copy the dirty states, logs, and preimages
|
// Copy the dirty states, logs, and preimages
|
||||||
for addr := range self.stateObjectsDirty {
|
for addr := range self.stateObjectsDirty {
|
||||||
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty)
|
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty)
|
||||||
state.stateObjectsDirty[addr] = struct{}{}
|
state.stateObjectsDirty[addr] = struct{}{}
|
||||||
if self.stateObjects[addr].suicided {
|
|
||||||
state.stateObjectsDestructed[addr] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for hash, logs := range self.logs {
|
for hash, logs := range self.logs {
|
||||||
state.logs[hash] = make([]*types.Log, len(logs))
|
state.logs[hash] = make([]*types.Log, len(logs))
|
||||||
|
|
@ -520,10 +512,9 @@ func (self *StateDB) GetRefund() *big.Int {
|
||||||
return self.refund
|
return self.refund
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntermediateRoot computes the current root hash of the state trie.
|
// Finalise finalises the state by removing the self destructed objects
|
||||||
// It is called in between transactions to get the root hash that
|
// and clears the journal as well as the refunds.
|
||||||
// goes into transaction receipts.
|
func (s *StateDB) Finalise(deleteEmptyObjects bool) {
|
||||||
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
|
||||||
for addr := range s.stateObjectsDirty {
|
for addr := range s.stateObjectsDirty {
|
||||||
stateObject := s.stateObjects[addr]
|
stateObject := s.stateObjects[addr]
|
||||||
if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) {
|
if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) {
|
||||||
|
|
@ -535,6 +526,13 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
}
|
}
|
||||||
// Invalidate journal because reverting across transactions is not allowed.
|
// Invalidate journal because reverting across transactions is not allowed.
|
||||||
s.clearJournalAndRefund()
|
s.clearJournalAndRefund()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntermediateRoot computes the current root hash of the state trie.
|
||||||
|
// It is called in between transactions to get the root hash that
|
||||||
|
// goes into transaction receipts.
|
||||||
|
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
|
s.Finalise(deleteEmptyObjects)
|
||||||
return s.trie.Hash()
|
return s.trie.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -546,19 +544,6 @@ func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
|
||||||
self.txIndex = ti
|
self.txIndex = ti
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalise finalises the state by removing the self destructed objects
|
|
||||||
// in the current stateObjectsDestructed buffer and clears the journal
|
|
||||||
// as well as the refunds.
|
|
||||||
//
|
|
||||||
// Please note that Finalise is used by EIP#98 and is used instead of
|
|
||||||
// IntermediateRoot.
|
|
||||||
func (s *StateDB) Finalise() {
|
|
||||||
for addr := range s.stateObjectsDestructed {
|
|
||||||
s.deleteStateObject(s.stateObjects[addr])
|
|
||||||
}
|
|
||||||
s.clearJournalAndRefund()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteSuicides flags the suicided objects for deletion so that it
|
// DeleteSuicides flags the suicided objects for deletion so that it
|
||||||
// won't be referenced again when called / queried up on.
|
// won't be referenced again when called / queried up on.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
|
||||||
// about the transaction and calling mechanisms.
|
// about the transaction and calling mechanisms.
|
||||||
vmenv := vm.NewEVM(context, statedb, config, cfg)
|
vmenv := vm.NewEVM(context, statedb, config, cfg)
|
||||||
// Apply the transaction to the current state (included in the env)
|
// Apply the transaction to the current state (included in the env)
|
||||||
_, gas, err := ApplyMessage(vmenv, msg, gp)
|
_, gas, failed, err := ApplyMessage(vmenv, msg, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +106,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
|
||||||
// Update the state with pending changes
|
// Update the state with pending changes
|
||||||
var root []byte
|
var root []byte
|
||||||
if config.IsMetropolis(header.Number) {
|
if config.IsMetropolis(header.Number) {
|
||||||
statedb.Finalise()
|
statedb.Finalise(true)
|
||||||
} else {
|
} else {
|
||||||
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +114,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common
|
||||||
|
|
||||||
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
||||||
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
||||||
receipt := types.NewReceipt(root, usedGas)
|
receipt := types.NewReceipt(root, failed, usedGas)
|
||||||
receipt.TxHash = tx.Hash()
|
receipt.TxHash = tx.Hash()
|
||||||
receipt.GasUsed = new(big.Int).Set(gas)
|
receipt.GasUsed = new(big.Int).Set(gas)
|
||||||
// if the transaction created a contract, store the creation address in the receipt.
|
// if the transaction created a contract, store the creation address in the receipt.
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,7 @@ type StateTransition struct {
|
||||||
value *big.Int
|
value *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
state vm.StateDB
|
state vm.StateDB
|
||||||
|
evm *vm.EVM
|
||||||
evm *vm.EVM
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message represents a message sent to a contract.
|
// Message represents a message sent to a contract.
|
||||||
|
|
@ -127,11 +126,11 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
|
||||||
// the gas used (which includes gas refunds) and an error if it failed. An error always
|
// the gas used (which includes gas refunds) and an error if it failed. An error always
|
||||||
// indicates a core error meaning that the message would always fail for that particular
|
// indicates a core error meaning that the message would always fail for that particular
|
||||||
// state and would never be accepted within a block.
|
// state and would never be accepted within a block.
|
||||||
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, error) {
|
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, bool, error) {
|
||||||
st := NewStateTransition(evm, msg, gp)
|
st := NewStateTransition(evm, msg, gp)
|
||||||
|
|
||||||
ret, _, gasUsed, err := st.TransitionDb()
|
ret, _, gasUsed, failed, err := st.TransitionDb()
|
||||||
return ret, gasUsed, err
|
return ret, gasUsed, failed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *StateTransition) from() vm.AccountRef {
|
func (st *StateTransition) from() vm.AccountRef {
|
||||||
|
|
@ -208,7 +207,7 @@ func (st *StateTransition) preCheck() error {
|
||||||
// TransitionDb will transition the state by applying the current message and returning the result
|
// TransitionDb will transition the state by applying the current message and returning the result
|
||||||
// including the required gas for the operation as well as the used gas. It returns an error if it
|
// including the required gas for the operation as well as the used gas. It returns an error if it
|
||||||
// failed. An error indicates a consensus issue.
|
// failed. An error indicates a consensus issue.
|
||||||
func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) {
|
func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, failed bool, err error) {
|
||||||
if err = st.preCheck(); err != nil {
|
if err = st.preCheck(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -222,10 +221,10 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
|
||||||
// TODO convert to uint64
|
// TODO convert to uint64
|
||||||
intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead)
|
intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead)
|
||||||
if intrinsicGas.BitLen() > 64 {
|
if intrinsicGas.BitLen() > 64 {
|
||||||
return nil, nil, nil, vm.ErrOutOfGas
|
return nil, nil, nil, false, vm.ErrOutOfGas
|
||||||
}
|
}
|
||||||
if err = st.useGas(intrinsicGas.Uint64()); err != nil {
|
if err = st.useGas(intrinsicGas.Uint64()); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -248,7 +247,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
|
||||||
// sufficient balance to make the transfer happen. The first
|
// sufficient balance to make the transfer happen. The first
|
||||||
// balance transfer may never fail.
|
// balance transfer may never fail.
|
||||||
if vmerr == vm.ErrInsufficientBalance {
|
if vmerr == vm.ErrInsufficientBalance {
|
||||||
return nil, nil, nil, vmerr
|
return nil, nil, nil, false, vmerr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
requiredGas = new(big.Int).Set(st.gasUsed())
|
requiredGas = new(big.Int).Set(st.gasUsed())
|
||||||
|
|
@ -256,7 +255,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big
|
||||||
st.refundGas()
|
st.refundGas()
|
||||||
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice))
|
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice))
|
||||||
|
|
||||||
return ret, requiredGas, st.gasUsed(), err
|
return ret, requiredGas, st.gasUsed(), vmerr != nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *StateTransition) refundGas() {
|
func (st *StateTransition) refundGas() {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import (
|
||||||
func (r Receipt) MarshalJSON() ([]byte, error) {
|
func (r Receipt) MarshalJSON() ([]byte, error) {
|
||||||
type Receipt struct {
|
type Receipt struct {
|
||||||
PostState hexutil.Bytes `json:"root"`
|
PostState hexutil.Bytes `json:"root"`
|
||||||
|
Failed bool `json:"failed"`
|
||||||
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
||||||
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
Logs []*Log `json:"logs" gencodec:"required"`
|
Logs []*Log `json:"logs" gencodec:"required"`
|
||||||
|
|
@ -23,6 +24,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
|
||||||
}
|
}
|
||||||
var enc Receipt
|
var enc Receipt
|
||||||
enc.PostState = r.PostState
|
enc.PostState = r.PostState
|
||||||
|
enc.Failed = r.Failed
|
||||||
enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed)
|
enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed)
|
||||||
enc.Bloom = r.Bloom
|
enc.Bloom = r.Bloom
|
||||||
enc.Logs = r.Logs
|
enc.Logs = r.Logs
|
||||||
|
|
@ -35,6 +37,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
|
||||||
func (r *Receipt) UnmarshalJSON(input []byte) error {
|
func (r *Receipt) UnmarshalJSON(input []byte) error {
|
||||||
type Receipt struct {
|
type Receipt struct {
|
||||||
PostState hexutil.Bytes `json:"root"`
|
PostState hexutil.Bytes `json:"root"`
|
||||||
|
Failed *bool `json:"failed"`
|
||||||
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
|
||||||
Bloom *Bloom `json:"logsBloom" gencodec:"required"`
|
Bloom *Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
Logs []*Log `json:"logs" gencodec:"required"`
|
Logs []*Log `json:"logs" gencodec:"required"`
|
||||||
|
|
@ -49,6 +52,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
|
||||||
if dec.PostState != nil {
|
if dec.PostState != nil {
|
||||||
r.PostState = dec.PostState
|
r.PostState = dec.PostState
|
||||||
}
|
}
|
||||||
|
if dec.Failed != nil {
|
||||||
|
r.Failed = *dec.Failed
|
||||||
|
}
|
||||||
if dec.CumulativeGasUsed == nil {
|
if dec.CumulativeGasUsed == nil {
|
||||||
return errors.New("missing required field 'cumulativeGasUsed' for Receipt")
|
return errors.New("missing required field 'cumulativeGasUsed' for Receipt")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -28,10 +29,16 @@ import (
|
||||||
|
|
||||||
//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go
|
//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go
|
||||||
|
|
||||||
|
var (
|
||||||
|
receiptStatusFailed = []byte{}
|
||||||
|
receiptStatusSuccessful = []byte{0x01}
|
||||||
|
)
|
||||||
|
|
||||||
// Receipt represents the results of a transaction.
|
// Receipt represents the results of a transaction.
|
||||||
type Receipt struct {
|
type Receipt struct {
|
||||||
// Consensus fields
|
// Consensus fields
|
||||||
PostState []byte `json:"root"`
|
PostState []byte `json:"root"`
|
||||||
|
Failed bool `json:"failed"`
|
||||||
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"`
|
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"`
|
||||||
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
||||||
Logs []*Log `json:"logs" gencodec:"required"`
|
Logs []*Log `json:"logs" gencodec:"required"`
|
||||||
|
|
@ -48,87 +55,78 @@ type receiptMarshaling struct {
|
||||||
GasUsed *hexutil.Big
|
GasUsed *hexutil.Big
|
||||||
}
|
}
|
||||||
|
|
||||||
// homesteadReceiptRLP contains the receipt's Homestead consensus fields, used
|
// receiptRLP is the consensus encoding of a receipt.
|
||||||
// during RLP serialization.
|
type receiptRLP struct {
|
||||||
type homesteadReceiptRLP struct {
|
PostStateOrStatus []byte
|
||||||
PostState []byte
|
|
||||||
CumulativeGasUsed *big.Int
|
CumulativeGasUsed *big.Int
|
||||||
Bloom Bloom
|
Bloom Bloom
|
||||||
Logs []*Log
|
Logs []*Log
|
||||||
}
|
}
|
||||||
|
|
||||||
// metropolisReceiptRLP contains the receipt's Metropolis consensus fields, used
|
type receiptStorageRLP struct {
|
||||||
// during RLP serialization.
|
PostStateOrStatus []byte
|
||||||
type metropolisReceiptRLP struct {
|
|
||||||
CumulativeGasUsed *big.Int
|
CumulativeGasUsed *big.Int
|
||||||
Bloom Bloom
|
Bloom Bloom
|
||||||
Logs []*Log
|
TxHash common.Hash
|
||||||
|
ContractAddress common.Address
|
||||||
|
Logs []*LogForStorage
|
||||||
|
GasUsed *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReceipt creates a barebone transaction receipt, copying the init fields.
|
// NewReceipt creates a barebone transaction receipt, copying the init fields.
|
||||||
func NewReceipt(root []byte, cumulativeGasUsed *big.Int) *Receipt {
|
func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt {
|
||||||
return &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)}
|
return &Receipt{PostState: common.CopyBytes(root), Failed: failed, CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt
|
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt
|
||||||
// into an RLP stream. If no post state is present, metropolis fork is assumed.
|
// into an RLP stream. If no post state is present, metropolis fork is assumed.
|
||||||
func (r *Receipt) EncodeRLP(w io.Writer) error {
|
func (r *Receipt) EncodeRLP(w io.Writer) error {
|
||||||
if r.PostState == nil {
|
return rlp.Encode(w, &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs})
|
||||||
return rlp.Encode(w, &metropolisReceiptRLP{r.CumulativeGasUsed, r.Bloom, r.Logs})
|
|
||||||
}
|
|
||||||
return rlp.Encode(w, &homesteadReceiptRLP{r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
|
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
|
||||||
// from an RLP stream.
|
// from an RLP stream.
|
||||||
func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
||||||
// Load the raw bytes since we have multiple possible formats
|
var dec receiptRLP
|
||||||
raw, err := s.Raw()
|
if err := s.Decode(&dec); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
list, _, err := rlp.SplitList(raw)
|
if err := r.setStatus(dec.PostStateOrStatus); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
items, err := rlp.CountValues(list)
|
r.CumulativeGasUsed, r.Bloom, r.Logs = dec.CumulativeGasUsed, dec.Bloom, dec.Logs
|
||||||
if err != nil {
|
return nil
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
// Deserialize based on the number of content items
|
|
||||||
switch items {
|
|
||||||
case 3:
|
|
||||||
// Metropolis receipts have 3 components
|
|
||||||
var metro metropolisReceiptRLP
|
|
||||||
if err := rlp.DecodeBytes(raw, &metro); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
r.CumulativeGasUsed = metro.CumulativeGasUsed
|
|
||||||
r.Bloom = metro.Bloom
|
|
||||||
r.Logs = metro.Logs
|
|
||||||
return nil
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
// Homestead receipts have 4 components
|
|
||||||
var home homesteadReceiptRLP
|
|
||||||
if err := rlp.DecodeBytes(raw, &home); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
r.PostState = home.PostState[:]
|
|
||||||
r.CumulativeGasUsed = home.CumulativeGasUsed
|
|
||||||
r.Bloom = home.Bloom
|
|
||||||
r.Logs = home.Logs
|
|
||||||
return nil
|
|
||||||
|
|
||||||
|
func (r *Receipt) setStatus(postStateOrStatus []byte) error {
|
||||||
|
switch {
|
||||||
|
case bytes.Equal(postStateOrStatus, receiptStatusSuccessful):
|
||||||
|
r.Failed = false
|
||||||
|
case bytes.Equal(postStateOrStatus, receiptStatusFailed):
|
||||||
|
r.Failed = true
|
||||||
|
case len(postStateOrStatus) == len(common.Hash{}):
|
||||||
|
r.PostState = postStateOrStatus
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid receipt components: %v", items)
|
return fmt.Errorf("invalid receipt status %x", postStateOrStatus)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Receipt) statusEncoding() []byte {
|
||||||
|
if len(r.PostState) == 0 {
|
||||||
|
if r.Failed {
|
||||||
|
return receiptStatusFailed
|
||||||
|
} else {
|
||||||
|
return receiptStatusSuccessful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r.PostState
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the Stringer interface.
|
// String implements the Stringer interface.
|
||||||
func (r *Receipt) String() string {
|
func (r *Receipt) String() string {
|
||||||
if r.PostState == nil {
|
if r.PostState == nil {
|
||||||
return fmt.Sprintf("receipt{cgas=%v bloom=%x logs=%v}", r.CumulativeGasUsed, r.Bloom, r.Logs)
|
return fmt.Sprintf("receipt{failed=%t cgas=%v bloom=%x logs=%v}", r.Failed, r.CumulativeGasUsed, r.Bloom, r.Logs)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs)
|
return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs)
|
||||||
}
|
}
|
||||||
|
|
@ -140,37 +138,39 @@ type ReceiptForStorage Receipt
|
||||||
// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt
|
// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt
|
||||||
// into an RLP stream.
|
// into an RLP stream.
|
||||||
func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error {
|
func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error {
|
||||||
logs := make([]*LogForStorage, len(r.Logs))
|
enc := &receiptStorageRLP{
|
||||||
for i, log := range r.Logs {
|
PostStateOrStatus: (*Receipt)(r).statusEncoding(),
|
||||||
logs[i] = (*LogForStorage)(log)
|
CumulativeGasUsed: r.CumulativeGasUsed,
|
||||||
|
Bloom: r.Bloom,
|
||||||
|
TxHash: r.TxHash,
|
||||||
|
ContractAddress: r.ContractAddress,
|
||||||
|
Logs: make([]*LogForStorage, len(r.Logs)),
|
||||||
|
GasUsed: r.GasUsed,
|
||||||
}
|
}
|
||||||
return rlp.Encode(w, []interface{}{r.PostState, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, logs, r.GasUsed})
|
for i, log := range r.Logs {
|
||||||
|
enc.Logs[i] = (*LogForStorage)(log)
|
||||||
|
}
|
||||||
|
return rlp.Encode(w, enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation
|
// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation
|
||||||
// fields of a receipt from an RLP stream.
|
// fields of a receipt from an RLP stream.
|
||||||
func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
|
func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
|
||||||
var receipt struct {
|
var dec receiptStorageRLP
|
||||||
PostState []byte
|
if err := s.Decode(&dec); err != nil {
|
||||||
CumulativeGasUsed *big.Int
|
return err
|
||||||
Bloom Bloom
|
|
||||||
TxHash common.Hash
|
|
||||||
ContractAddress common.Address
|
|
||||||
Logs []*LogForStorage
|
|
||||||
GasUsed *big.Int
|
|
||||||
}
|
}
|
||||||
if err := s.Decode(&receipt); err != nil {
|
if err := (*Receipt)(r).setStatus(dec.PostStateOrStatus); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Assign the consensus fields
|
// Assign the consensus fields
|
||||||
r.PostState, r.CumulativeGasUsed, r.Bloom = receipt.PostState, receipt.CumulativeGasUsed, receipt.Bloom
|
r.CumulativeGasUsed, r.Bloom = dec.CumulativeGasUsed, dec.Bloom
|
||||||
r.Logs = make([]*Log, len(receipt.Logs))
|
r.Logs = make([]*Log, len(dec.Logs))
|
||||||
for i, log := range receipt.Logs {
|
for i, log := range dec.Logs {
|
||||||
r.Logs[i] = (*Log)(log)
|
r.Logs[i] = (*Log)(log)
|
||||||
}
|
}
|
||||||
// Assign the implementation fields
|
// Assign the implementation fields
|
||||||
r.TxHash, r.ContractAddress, r.GasUsed = receipt.TxHash, receipt.ContractAddress, receipt.GasUsed
|
r.TxHash, r.ContractAddress, r.GasUsed = dec.TxHash, dec.ContractAddress, dec.GasUsed
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ type precompiledTest struct {
|
||||||
input, expected string
|
input, expected string
|
||||||
gas uint64
|
gas uint64
|
||||||
name string
|
name string
|
||||||
|
noBenchmark bool // Benchmark primarily the worst-cases
|
||||||
}
|
}
|
||||||
|
|
||||||
// modexpTests are the test and benchmark data for the modexp precompiled contract.
|
// modexpTests are the test and benchmark data for the modexp precompiled contract.
|
||||||
|
|
@ -182,6 +183,78 @@ var bn256ScalarMulTests = []precompiledTest{
|
||||||
input: "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3",
|
input: "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3",
|
||||||
expected: "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27",
|
expected: "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27",
|
||||||
name: "chfast3",
|
name: "chfast3",
|
||||||
|
}, {
|
||||||
|
input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
expected: "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11",
|
||||||
|
name: "cdetrio1",
|
||||||
|
}, {
|
||||||
|
input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
|
||||||
|
expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451",
|
||||||
|
name: "cdetrio2",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000",
|
||||||
|
expected: "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b",
|
||||||
|
name: "cdetrio3",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009",
|
||||||
|
expected: "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575",
|
||||||
|
name: "cdetrio4",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6",
|
||||||
|
name: "cdetrio5",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
expected: "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1",
|
||||||
|
name: "cdetrio6",
|
||||||
|
}, {
|
||||||
|
input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
|
||||||
|
expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb",
|
||||||
|
name: "cdetrio7",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000",
|
||||||
|
expected: "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15",
|
||||||
|
name: "cdetrio8",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009",
|
||||||
|
expected: "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a",
|
||||||
|
name: "cdetrio9",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c",
|
||||||
|
name: "cdetrio10",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
expected: "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024",
|
||||||
|
name: "cdetrio11",
|
||||||
|
}, {
|
||||||
|
input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
|
||||||
|
expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf",
|
||||||
|
name: "cdetrio12",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000",
|
||||||
|
expected: "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434",
|
||||||
|
name: "cdetrio13",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009",
|
||||||
|
expected: "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f",
|
||||||
|
name: "cdetrio14",
|
||||||
|
noBenchmark: true,
|
||||||
|
}, {
|
||||||
|
input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98",
|
||||||
|
name: "cdetrio15",
|
||||||
|
noBenchmark: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,6 +335,9 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
|
func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
|
||||||
|
if test.noBenchmark {
|
||||||
|
return
|
||||||
|
}
|
||||||
p := PrecompiledContractsMetropolis[common.HexToAddress(addr)]
|
p := PrecompiledContractsMetropolis[common.HexToAddress(addr)]
|
||||||
in := common.Hex2Bytes(test.input)
|
in := common.Hex2Bytes(test.input)
|
||||||
reqGas := p.RequiredGas(in)
|
reqGas := p.RequiredGas(in)
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,10 @@ package vm
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrOutOfGas = errors.New("out of gas")
|
ErrOutOfGas = errors.New("out of gas")
|
||||||
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
|
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
|
||||||
ErrDepth = errors.New("max call depth exceeded")
|
ErrDepth = errors.New("max call depth exceeded")
|
||||||
ErrTraceLimitReached = errors.New("the number of logs reached the specified limit")
|
ErrTraceLimitReached = errors.New("the number of logs reached the specified limit")
|
||||||
ErrInsufficientBalance = errors.New("insufficient balance for transfer")
|
ErrInsufficientBalance = errors.New("insufficient balance for transfer")
|
||||||
|
ErrContractAddressCollision = errors.New("contract address collision")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// emptyCodeHash is used by create to ensure deployment is disallowed to already
|
||||||
|
// deployed contract addresses (relevant after the account abstraction).
|
||||||
|
var emptyCodeHash = crypto.Keccak256Hash(nil)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
CanTransferFunc func(StateDB, common.Address, *big.Int) bool
|
CanTransferFunc func(StateDB, common.Address, *big.Int) bool
|
||||||
TransferFunc func(StateDB, common.Address, common.Address, *big.Int)
|
TransferFunc func(StateDB, common.Address, common.Address, *big.Int)
|
||||||
|
|
@ -158,7 +162,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
|
||||||
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)
|
||||||
|
|
||||||
// initialise a new contract and set the code that is to be used by the
|
// initialise a new contract and set the code that is to be used by the
|
||||||
// E The contract is a scoped evmironment for this execution context
|
// E The contract is a scoped environment for this execution context
|
||||||
// only.
|
// only.
|
||||||
contract := NewContract(caller, to, value, gas)
|
contract := NewContract(caller, to, value, gas)
|
||||||
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
|
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
|
||||||
|
|
@ -307,13 +311,17 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
|
||||||
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
|
if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
|
||||||
return nil, common.Address{}, gas, ErrInsufficientBalance
|
return nil, common.Address{}, gas, ErrInsufficientBalance
|
||||||
}
|
}
|
||||||
|
// Ensure there's no existing contract already at the designated address
|
||||||
// Create a new account on the state
|
|
||||||
nonce := evm.StateDB.GetNonce(caller.Address())
|
nonce := evm.StateDB.GetNonce(caller.Address())
|
||||||
evm.StateDB.SetNonce(caller.Address(), nonce+1)
|
evm.StateDB.SetNonce(caller.Address(), nonce+1)
|
||||||
|
|
||||||
snapshot := evm.StateDB.Snapshot()
|
|
||||||
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
|
contractAddr = crypto.CreateAddress(caller.Address(), nonce)
|
||||||
|
contractHash := evm.StateDB.GetCodeHash(contractAddr)
|
||||||
|
if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) {
|
||||||
|
return nil, common.Address{}, 0, ErrContractAddressCollision
|
||||||
|
}
|
||||||
|
// Create a new account on the state
|
||||||
|
snapshot := evm.StateDB.Snapshot()
|
||||||
evm.StateDB.CreateAccount(contractAddr)
|
evm.StateDB.CreateAccount(contractAddr)
|
||||||
if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
|
if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
|
||||||
evm.StateDB.SetNonce(contractAddr, 1)
|
evm.StateDB.SetNonce(contractAddr, 1)
|
||||||
|
|
@ -351,6 +359,10 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
|
||||||
contract.UseGas(contract.Gas)
|
contract.UseGas(contract.Gas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Assign err if contract code size exceeds the max while the err is still empty.
|
||||||
|
if maxCodeSizeExceeded && err == nil {
|
||||||
|
err = errMaxCodeSizeExceeded
|
||||||
|
}
|
||||||
return ret, contractAddr, contract.Gas, err
|
return ret, contractAddr, contract.Gas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ var (
|
||||||
errWriteProtection = errors.New("evm: write protection")
|
errWriteProtection = errors.New("evm: write protection")
|
||||||
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
|
errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
|
||||||
errExecutionReverted = errors.New("evm: execution reverted")
|
errExecutionReverted = errors.New("evm: execution reverted")
|
||||||
|
errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded")
|
||||||
)
|
)
|
||||||
|
|
||||||
func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||||
|
|
@ -619,7 +620,6 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
|
||||||
if value.Sign() != 0 {
|
if value.Sign() != 0 {
|
||||||
gas += params.CallStipend
|
gas += params.CallStipend
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, returnGas, err := evm.Call(contract, address, args, gas, value)
|
ret, returnGas, err := evm.Call(contract, address, args, gas, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stack.push(new(big.Int))
|
stack.push(new(big.Int))
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ func (s *StructLog) OpName() string {
|
||||||
// if you need to retain them beyond the current call.
|
// if you need to retain them beyond the current call.
|
||||||
type Tracer interface {
|
type Tracer interface {
|
||||||
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
|
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
|
||||||
CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error
|
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructLogger is an EVM state logger and implements Tracer.
|
// StructLogger is an EVM state logger and implements Tracer.
|
||||||
|
|
@ -128,18 +128,14 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||||
}
|
}
|
||||||
|
|
||||||
// capture SSTORE opcodes and determine the changed value and store
|
// capture SSTORE opcodes and determine the changed value and store
|
||||||
// it in the local storage container. NOTE: we do not need to do any
|
// it in the local storage container.
|
||||||
// range checks here because that's already handler prior to calling
|
if op == SSTORE && stack.len() >= 2 {
|
||||||
// this function.
|
|
||||||
switch op {
|
|
||||||
case SSTORE:
|
|
||||||
var (
|
var (
|
||||||
value = common.BigToHash(stack.data[stack.len()-2])
|
value = common.BigToHash(stack.data[stack.len()-2])
|
||||||
address = common.BigToHash(stack.data[stack.len()-1])
|
address = common.BigToHash(stack.data[stack.len()-1])
|
||||||
)
|
)
|
||||||
l.changedValues[contract.Address()][address] = value
|
l.changedValues[contract.Address()][address] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy a snapstot of the current memory state to a new buffer
|
// copy a snapstot of the current memory state to a new buffer
|
||||||
var mem []byte
|
var mem []byte
|
||||||
if !l.cfg.DisableMemory {
|
if !l.cfg.DisableMemory {
|
||||||
|
|
@ -183,8 +179,11 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error {
|
func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||||
fmt.Printf("0x%x", output)
|
fmt.Printf("0x%x", output)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" error: %v\n", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -523,7 +523,8 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
|
||||||
|
|
||||||
// Run the transaction with tracing enabled.
|
// Run the transaction with tracing enabled.
|
||||||
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{Debug: true, Tracer: tracer})
|
||||||
ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
|
// TODO utilize failed flag
|
||||||
|
ret, gas, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("tracing failed: %v", err)
|
return nil, fmt.Errorf("tracing failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -570,7 +571,7 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int) (co
|
||||||
|
|
||||||
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{})
|
vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(tx.Gas())
|
gp := new(core.GasPool).AddGas(tx.Gas())
|
||||||
_, _, err := core.ApplyMessage(vmenv, msg, gp)
|
_, _, _, err := core.ApplyMessage(vmenv, msg, gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, vm.Context{}, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err)
|
return nil, vm.Context{}, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ func TestMipmapUpgrade(t *testing.T) {
|
||||||
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) {
|
chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) {
|
||||||
switch i {
|
switch i {
|
||||||
case 1:
|
case 1:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{{Address: addr}}
|
receipt.Logs = []*types.Log{{Address: addr}}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
case 2:
|
case 2:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{{Address: addr}}
|
receipt.Logs = []*types.Log{{Address: addr}}
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeReceipt(addr common.Address) *types.Receipt {
|
func makeReceipt(addr common.Address) *types.Receipt {
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
{Address: addr},
|
{Address: addr},
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +145,7 @@ func TestFilters(t *testing.T) {
|
||||||
var receipts types.Receipts
|
var receipts types.Receipts
|
||||||
switch i {
|
switch i {
|
||||||
case 1:
|
case 1:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
{
|
{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
|
|
@ -155,7 +155,7 @@ func TestFilters(t *testing.T) {
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
receipts = types.Receipts{receipt}
|
receipts = types.Receipts{receipt}
|
||||||
case 2:
|
case 2:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
{
|
{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
|
|
@ -165,7 +165,7 @@ func TestFilters(t *testing.T) {
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
receipts = types.Receipts{receipt}
|
receipts = types.Receipts{receipt}
|
||||||
case 998:
|
case 998:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
{
|
{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
|
|
@ -175,7 +175,7 @@ func TestFilters(t *testing.T) {
|
||||||
gen.AddUncheckedReceipt(receipt)
|
gen.AddUncheckedReceipt(receipt)
|
||||||
receipts = types.Receipts{receipt}
|
receipts = types.Receipts{receipt}
|
||||||
case 999:
|
case 999:
|
||||||
receipt := types.NewReceipt(nil, new(big.Int))
|
receipt := types.NewReceipt(nil, false, new(big.Int))
|
||||||
receipt.Logs = []*types.Log{
|
receipt.Logs = []*types.Log{
|
||||||
{
|
{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
|
|
|
||||||
|
|
@ -635,7 +635,8 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
|
||||||
// Setup the gas pool (also for unmetered requests)
|
// Setup the gas pool (also for unmetered requests)
|
||||||
// and apply the message.
|
// and apply the message.
|
||||||
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
||||||
res, gas, err := core.ApplyMessage(evm, msg, gp)
|
// TODO utilize failed flag to help gas estimation
|
||||||
|
res, gas, _, err := core.ApplyMessage(evm, msg, gp)
|
||||||
if err := vmError(); err != nil {
|
if err := vmError(); err != nil {
|
||||||
return nil, common.Big0, err
|
return nil, common.Big0, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaptureEnd is called after the call finishes
|
// CaptureEnd is called after the call finishes
|
||||||
func (jst *JavascriptTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error {
|
func (jst *JavascriptTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||||
//TODO! @Arachnid please figure out of there's anything we can use this method for
|
//TODO! @Arachnid please figure out of there's anything we can use this method for
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
|
|
||||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -138,7 +138,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
context := core.NewEVMContext(msg, header, lc, nil)
|
context := core.NewEVMContext(msg, header, lc, nil)
|
||||||
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
vmenv := vm.NewEVM(context, state, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
if state.Error() == nil {
|
if state.Error() == nil {
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||||
context := core.NewEVMContext(msg, header, chain, nil)
|
context := core.NewEVMContext(msg, header, chain, nil)
|
||||||
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
vmenv := vm.NewEVM(context, st, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
gp := new(core.GasPool).AddGas(math.MaxBig256)
|
||||||
ret, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
if st.Error() != nil {
|
if st.Error() != nil {
|
||||||
return res, st.Error()
|
return res, st.Error()
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
|
// MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
|
||||||
var MetricsEnabledFlag = "metrics"
|
const MetricsEnabledFlag = "metrics"
|
||||||
|
|
||||||
// Enabled is the flag specifying if metrics are enable or not.
|
// Enabled is the flag specifying if metrics are enable or not.
|
||||||
var Enabled = false
|
var Enabled = false
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,28 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrDatadirUsed = errors.New("datadir already used by another process")
|
||||||
|
ErrNodeStopped = errors.New("node not started")
|
||||||
|
ErrNodeRunning = errors.New("node already running")
|
||||||
|
ErrServiceUnknown = errors.New("unknown service")
|
||||||
|
|
||||||
|
datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
func convertFileLockError(err error) error {
|
||||||
|
if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] {
|
||||||
|
return ErrDatadirUsed
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// DuplicateServiceError is returned during Node startup if a registered service
|
// DuplicateServiceError is returned during Node startup if a registered service
|
||||||
// constructor returns a service of the same type that was already started.
|
// constructor returns a service of the same type that was already started.
|
||||||
type DuplicateServiceError struct {
|
type DuplicateServiceError struct {
|
||||||
|
|
|
||||||
36
node/node.go
36
node/node.go
|
|
@ -25,7 +25,6 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
|
@ -34,16 +33,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/syndtr/goleveldb/leveldb/storage"
|
"github.com/prometheus/prometheus/util/flock"
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrDatadirUsed = errors.New("datadir already used")
|
|
||||||
ErrNodeStopped = errors.New("node not started")
|
|
||||||
ErrNodeRunning = errors.New("node already running")
|
|
||||||
ErrServiceUnknown = errors.New("unknown service")
|
|
||||||
|
|
||||||
datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Node is a container on which services can be registered.
|
// Node is a container on which services can be registered.
|
||||||
|
|
@ -52,8 +42,8 @@ type Node struct {
|
||||||
config *Config
|
config *Config
|
||||||
accman *accounts.Manager
|
accman *accounts.Manager
|
||||||
|
|
||||||
ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop
|
ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop
|
||||||
instanceDirLock storage.Storage // prevents concurrent use of instance directory
|
instanceDirLock flock.Releaser // prevents concurrent use of instance directory
|
||||||
|
|
||||||
serverConfig p2p.Config
|
serverConfig p2p.Config
|
||||||
server *p2p.Server // Currently running P2P networking layer
|
server *p2p.Server // Currently running P2P networking layer
|
||||||
|
|
@ -197,10 +187,7 @@ func (n *Node) Start() error {
|
||||||
running.Protocols = append(running.Protocols, service.Protocols()...)
|
running.Protocols = append(running.Protocols, service.Protocols()...)
|
||||||
}
|
}
|
||||||
if err := running.Start(); err != nil {
|
if err := running.Start(); err != nil {
|
||||||
if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] {
|
return convertFileLockError(err)
|
||||||
return ErrDatadirUsed
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// Start each of the services
|
// Start each of the services
|
||||||
started := []reflect.Type{}
|
started := []reflect.Type{}
|
||||||
|
|
@ -242,14 +229,13 @@ func (n *Node) openDataDir() error {
|
||||||
if err := os.MkdirAll(instdir, 0700); err != nil {
|
if err := os.MkdirAll(instdir, 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Try to open the instance directory as LevelDB storage. This creates a lock file
|
// Lock the instance directory to prevent concurrent use by another instance as well as
|
||||||
// which prevents concurrent use by another instance as well as accidental use of the
|
// accidental use of the instance directory as a database.
|
||||||
// instance directory as a database.
|
release, _, err := flock.New(filepath.Join(instdir, "LOCK"))
|
||||||
storage, err := storage.OpenFile(instdir, true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return convertFileLockError(err)
|
||||||
}
|
}
|
||||||
n.instanceDirLock = storage
|
n.instanceDirLock = release
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -509,7 +495,9 @@ func (n *Node) Stop() error {
|
||||||
|
|
||||||
// Release instance directory lock.
|
// Release instance directory lock.
|
||||||
if n.instanceDirLock != nil {
|
if n.instanceDirLock != nil {
|
||||||
n.instanceDirLock.Close()
|
if err := n.instanceDirLock.Release(); err != nil {
|
||||||
|
log.Error("Can't release datadir lock", "err", err)
|
||||||
|
}
|
||||||
n.instanceDirLock = nil
|
n.instanceDirLock = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -693,7 +693,7 @@ func (s *Stream) Raw() ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if kind == String {
|
if kind == String {
|
||||||
puthead(buf, 0x80, 0xB8, size)
|
puthead(buf, 0x80, 0xB7, size)
|
||||||
} else {
|
} else {
|
||||||
puthead(buf, 0xC0, 0xF7, size)
|
puthead(buf, 0xC0, 0xF7, size)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,16 +256,31 @@ func TestStreamList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamRaw(t *testing.T) {
|
func TestStreamRaw(t *testing.T) {
|
||||||
s := NewStream(bytes.NewReader(unhex("C58401010101")), 0)
|
tests := []struct {
|
||||||
s.List()
|
input string
|
||||||
|
output string
|
||||||
want := unhex("8401010101")
|
}{
|
||||||
raw, err := s.Raw()
|
{
|
||||||
if err != nil {
|
"C58401010101",
|
||||||
t.Fatal(err)
|
"8401010101",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"F842B84001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101",
|
||||||
|
"B84001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if !bytes.Equal(want, raw) {
|
for i, tt := range tests {
|
||||||
t.Errorf("raw mismatch: got %x, want %x", raw, want)
|
s := NewStream(bytes.NewReader(unhex(tt.input)), 0)
|
||||||
|
s.List()
|
||||||
|
|
||||||
|
want := unhex(tt.output)
|
||||||
|
raw, err := s.Raw()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(want, raw) {
|
||||||
|
t.Errorf("test %d: raw mismatch: got %x, want %x", i, raw, want)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,10 @@ func TestBlockchain(t *testing.T) {
|
||||||
// Constantinople is not implemented yet.
|
// Constantinople is not implemented yet.
|
||||||
bt.skipLoad(`(?i)(constantinople)`)
|
bt.skipLoad(`(?i)(constantinople)`)
|
||||||
// Expected failures:
|
// Expected failures:
|
||||||
bt.fails("^TransitionTests/bcEIP158ToByzantium", "byzantium not supported")
|
|
||||||
bt.fails(`^TransitionTests/bcHomesteadToDao/DaoTransactions(|_UncleExtradata|_EmptyTransactionAndForkBlocksAhead)\.json`, "issue in test")
|
bt.fails(`^TransitionTests/bcHomesteadToDao/DaoTransactions(|_UncleExtradata|_EmptyTransactionAndForkBlocksAhead)\.json`, "issue in test")
|
||||||
bt.fails(`^bc(Exploit|Fork|Gas|Multi|Total|State|Random|Uncle|Valid|Wallet).*_Byzantium$`, "byzantium not supported")
|
|
||||||
bt.fails(`^bcBlockGasLimitTest/(BlockGasLimit2p63m1|TransactionGasHigherThanLimit2p63m1|SuicideTransaction|GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideFirst|TransactionGasHigherThanLimit2p63m1_2).*_Byzantium$`, "byzantium not supported")
|
// Still failing tests
|
||||||
|
bt.skipLoad(`^bcWalletTest.*_Byzantium$`)
|
||||||
|
|
||||||
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) {
|
||||||
if err := bt.checkFailure(t, name, test.Run()); err != nil {
|
if err := bt.checkFailure(t, name, test.Run()); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
|
||||||
|
|
||||||
package tests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ = (*stLogMarshaling)(nil)
|
|
||||||
|
|
||||||
func (s stLog) MarshalJSON() ([]byte, error) {
|
|
||||||
type stLog struct {
|
|
||||||
Address common.UnprefixedAddress `json:"address"`
|
|
||||||
Data hexutil.Bytes `json:"data"`
|
|
||||||
Topics []common.UnprefixedHash `json:"topics"`
|
|
||||||
Bloom string `json:"bloom"`
|
|
||||||
}
|
|
||||||
var enc stLog
|
|
||||||
enc.Address = common.UnprefixedAddress(s.Address)
|
|
||||||
enc.Data = s.Data
|
|
||||||
if s.Topics != nil {
|
|
||||||
enc.Topics = make([]common.UnprefixedHash, len(s.Topics))
|
|
||||||
for k, v := range s.Topics {
|
|
||||||
enc.Topics[k] = common.UnprefixedHash(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enc.Bloom = s.Bloom
|
|
||||||
return json.Marshal(&enc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stLog) UnmarshalJSON(input []byte) error {
|
|
||||||
type stLog struct {
|
|
||||||
Address *common.UnprefixedAddress `json:"address"`
|
|
||||||
Data hexutil.Bytes `json:"data"`
|
|
||||||
Topics []common.UnprefixedHash `json:"topics"`
|
|
||||||
Bloom *string `json:"bloom"`
|
|
||||||
}
|
|
||||||
var dec stLog
|
|
||||||
if err := json.Unmarshal(input, &dec); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if dec.Address != nil {
|
|
||||||
s.Address = common.Address(*dec.Address)
|
|
||||||
}
|
|
||||||
if dec.Data != nil {
|
|
||||||
s.Data = dec.Data
|
|
||||||
}
|
|
||||||
if dec.Topics != nil {
|
|
||||||
s.Topics = make([]common.Hash, len(dec.Topics))
|
|
||||||
for k, v := range dec.Topics {
|
|
||||||
s.Topics[k] = common.Hash(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if dec.Bloom != nil {
|
|
||||||
s.Bloom = *dec.Bloom
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -37,10 +37,8 @@ func TestState(t *testing.T) {
|
||||||
// Expected failures:
|
// Expected failures:
|
||||||
st.fails(`^stCodeSizeLimit/codesizeOOGInvalidSize\.json/(Frontier|Homestead|EIP150)`,
|
st.fails(`^stCodeSizeLimit/codesizeOOGInvalidSize\.json/(Frontier|Homestead|EIP150)`,
|
||||||
"code size limit implementation is not conditional on fork")
|
"code size limit implementation is not conditional on fork")
|
||||||
st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/EIP15[08]/[67]`, "bug in test")
|
|
||||||
st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test")
|
st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test")
|
||||||
st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test")
|
st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test")
|
||||||
st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/Byzantium/[67]`, "bug in test")
|
|
||||||
st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test")
|
st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test")
|
||||||
st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/Byzantium`, "bug in test")
|
st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/Byzantium`, "bug in test")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,10 @@
|
||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -33,8 +31,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StateTest checks transaction processing without block context.
|
// StateTest checks transaction processing without block context.
|
||||||
|
|
@ -63,7 +63,7 @@ type stJSON struct {
|
||||||
|
|
||||||
type stPostState struct {
|
type stPostState struct {
|
||||||
Root common.UnprefixedHash `json:"hash"`
|
Root common.UnprefixedHash `json:"hash"`
|
||||||
Logs *[]stLog `json:"logs"`
|
Logs common.UnprefixedHash `json:"logs"`
|
||||||
Indexes struct {
|
Indexes struct {
|
||||||
Data int `json:"data"`
|
Data int `json:"data"`
|
||||||
Gas int `json:"gas"`
|
Gas int `json:"gas"`
|
||||||
|
|
@ -108,21 +108,6 @@ type stTransactionMarshaling struct {
|
||||||
PrivateKey hexutil.Bytes
|
PrivateKey hexutil.Bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate gencodec -type stLog -field-override stLogMarshaling -out gen_stlog.go
|
|
||||||
|
|
||||||
type stLog struct {
|
|
||||||
Address common.Address `json:"address"`
|
|
||||||
Data []byte `json:"data"`
|
|
||||||
Topics []common.Hash `json:"topics"`
|
|
||||||
Bloom string `json:"bloom"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type stLogMarshaling struct {
|
|
||||||
Address common.UnprefixedAddress
|
|
||||||
Data hexutil.Bytes
|
|
||||||
Topics []common.UnprefixedHash
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtests returns all valid subtests of the test.
|
// Subtests returns all valid subtests of the test.
|
||||||
func (t *StateTest) Subtests() []StateSubtest {
|
func (t *StateTest) Subtests() []StateSubtest {
|
||||||
var sub []StateSubtest
|
var sub []StateSubtest
|
||||||
|
|
@ -156,13 +141,11 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) error {
|
||||||
gaspool := new(core.GasPool)
|
gaspool := new(core.GasPool)
|
||||||
gaspool.AddGas(block.GasLimit())
|
gaspool.AddGas(block.GasLimit())
|
||||||
snapshot := statedb.Snapshot()
|
snapshot := statedb.Snapshot()
|
||||||
if _, _, err := core.ApplyMessage(evm, msg, gaspool); err != nil {
|
if _, _, _, err := core.ApplyMessage(evm, msg, gaspool); err != nil {
|
||||||
statedb.RevertToSnapshot(snapshot)
|
statedb.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
if post.Logs != nil {
|
if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) {
|
||||||
if err := checkLogs(statedb.Logs(), *post.Logs); err != nil {
|
return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
root, _ := statedb.CommitTo(db, config.IsEIP158(block.Number()))
|
root, _ := statedb.CommitTo(db, config.IsEIP158(block.Number()))
|
||||||
if root != common.Hash(post.Root) {
|
if root != common.Hash(post.Root) {
|
||||||
|
|
@ -254,28 +237,9 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) {
|
||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLogs(have []*types.Log, want []stLog) error {
|
func rlpHash(x interface{}) (h common.Hash) {
|
||||||
if len(have) != len(want) {
|
hw := sha3.NewKeccak256()
|
||||||
return fmt.Errorf("logs length mismatch: got %d, want %d", len(have), len(want))
|
rlp.Encode(hw, x)
|
||||||
}
|
hw.Sum(h[:0])
|
||||||
for i := range have {
|
return h
|
||||||
if have[i].Address != want[i].Address {
|
|
||||||
return fmt.Errorf("log address %d: got %x, want %x", i, have[i].Address, want[i].Address)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(have[i].Data, want[i].Data) {
|
|
||||||
return fmt.Errorf("log data %d: got %x, want %x", i, have[i].Data, want[i].Data)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(have[i].Topics, want[i].Topics) {
|
|
||||||
return fmt.Errorf("log topics %d:\ngot %x\nwant %x", i, have[i].Topics, want[i].Topics)
|
|
||||||
}
|
|
||||||
genBloom := math.PaddedBigBytes(types.LogsBloom([]*types.Log{have[i]}), 256)
|
|
||||||
var wantBloom types.Bloom
|
|
||||||
if err := hexutil.UnmarshalFixedUnprefixedText("Bloom", []byte(want[i].Bloom), wantBloom[:]); err != nil {
|
|
||||||
return fmt.Errorf("test log %d has invalid bloom: %v", i, err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(genBloom, wantBloom[:]) {
|
|
||||||
return fmt.Errorf("bloom mismatch")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 85f6d7cc01b6bd04e071f5ba579fc675cfd2043b
|
Subproject commit 1d30b4795664f64b1b157971754e14a10cfd9115
|
||||||
|
|
@ -26,6 +26,9 @@ func TestVM(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
vmt := new(testMatcher)
|
vmt := new(testMatcher)
|
||||||
vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution")
|
vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution")
|
||||||
|
|
||||||
|
vmt.skipLoad(`^vmInputLimits(Light)?.json`) // log format broken
|
||||||
|
|
||||||
vmt.skipShortMode("^vmPerformanceTest.json")
|
vmt.skipShortMode("^vmPerformanceTest.json")
|
||||||
vmt.skipShortMode("^vmInputLimits(Light)?.json")
|
vmt.skipShortMode("^vmInputLimits(Light)?.json")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,14 +44,14 @@ func (t *VMTest) UnmarshalJSON(data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type vmJSON struct {
|
type vmJSON struct {
|
||||||
Env stEnv `json:"env"`
|
Env stEnv `json:"env"`
|
||||||
Exec vmExec `json:"exec"`
|
Exec vmExec `json:"exec"`
|
||||||
Logs []stLog `json:"logs"`
|
Logs common.UnprefixedHash `json:"logs"`
|
||||||
GasRemaining *math.HexOrDecimal64 `json:"gas"`
|
GasRemaining *math.HexOrDecimal64 `json:"gas"`
|
||||||
Out hexutil.Bytes `json:"out"`
|
Out hexutil.Bytes `json:"out"`
|
||||||
Pre core.GenesisAlloc `json:"pre"`
|
Pre core.GenesisAlloc `json:"pre"`
|
||||||
Post core.GenesisAlloc `json:"post"`
|
Post core.GenesisAlloc `json:"post"`
|
||||||
PostStateRoot common.Hash `json:"postStateRoot"`
|
PostStateRoot common.Hash `json:"postStateRoot"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate gencodec -type vmExec -field-override vmExecMarshaling -out gen_vmexec.go
|
//go:generate gencodec -type vmExec -field-override vmExecMarshaling -out gen_vmexec.go
|
||||||
|
|
@ -109,7 +109,10 @@ func (t *VMTest) Run(vmconfig vm.Config) error {
|
||||||
// if root := statedb.IntermediateRoot(false); root != t.json.PostStateRoot {
|
// if root := statedb.IntermediateRoot(false); root != t.json.PostStateRoot {
|
||||||
// return fmt.Errorf("post state root mismatch, got %x, want %x", root, t.json.PostStateRoot)
|
// return fmt.Errorf("post state root mismatch, got %x, want %x", root, t.json.PostStateRoot)
|
||||||
// }
|
// }
|
||||||
return checkLogs(statedb.Logs(), t.json.Logs)
|
if logs := rlpHash(statedb.Logs()); logs != common.Hash(t.json.Logs) {
|
||||||
|
return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, t.json.Logs)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) {
|
func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) {
|
||||||
|
|
|
||||||
201
vendor/github.com/prometheus/prometheus/LICENSE
generated
vendored
Normal file
201
vendor/github.com/prometheus/prometheus/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
87
vendor/github.com/prometheus/prometheus/NOTICE
generated
vendored
Normal file
87
vendor/github.com/prometheus/prometheus/NOTICE
generated
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
The Prometheus systems and service monitoring server
|
||||||
|
Copyright 2012-2015 The Prometheus Authors
|
||||||
|
|
||||||
|
This product includes software developed at
|
||||||
|
SoundCloud Ltd. (http://soundcloud.com/).
|
||||||
|
|
||||||
|
|
||||||
|
The following components are included in this product:
|
||||||
|
|
||||||
|
Bootstrap
|
||||||
|
http://getbootstrap.com
|
||||||
|
Copyright 2011-2014 Twitter, Inc.
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
bootstrap3-typeahead.js
|
||||||
|
https://github.com/bassjobsen/Bootstrap-3-Typeahead
|
||||||
|
Original written by @mdo and @fat
|
||||||
|
Copyright 2014 Bass Jobsen @bassjobsen
|
||||||
|
Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
fuzzy
|
||||||
|
https://github.com/mattyork/fuzzy
|
||||||
|
Original written by @mattyork
|
||||||
|
Copyright 2012 Matt York
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
bootstrap-datetimepicker.js
|
||||||
|
https://github.com/Eonasdan/bootstrap-datetimepicker
|
||||||
|
Copyright 2015 Jonathan Peterson (@Eonasdan)
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
moment.js
|
||||||
|
https://github.com/moment/moment/
|
||||||
|
Copyright JS Foundation and other contributors
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
Rickshaw
|
||||||
|
https://github.com/shutterstock/rickshaw
|
||||||
|
Copyright 2011-2014 by Shutterstock Images, LLC
|
||||||
|
See https://github.com/shutterstock/rickshaw/blob/master/LICENSE for license details
|
||||||
|
|
||||||
|
mustache.js
|
||||||
|
https://github.com/janl/mustache.js
|
||||||
|
Copyright 2009 Chris Wanstrath (Ruby)
|
||||||
|
Copyright 2010-2014 Jan Lehnardt (JavaScript)
|
||||||
|
Copyright 2010-2015 The mustache.js community
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
jQuery
|
||||||
|
https://jquery.org
|
||||||
|
Copyright jQuery Foundation and other contributors
|
||||||
|
Licensed under the MIT License
|
||||||
|
|
||||||
|
Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
http://github.com/golang/protobuf/
|
||||||
|
Copyright 2010 The Go Authors
|
||||||
|
See source code for license details.
|
||||||
|
|
||||||
|
Go support for leveled logs, analogous to
|
||||||
|
https://code.google.com/p/google-glog/
|
||||||
|
Copyright 2013 Google Inc.
|
||||||
|
Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
Support for streaming Protocol Buffer messages for the Go language (golang).
|
||||||
|
https://github.com/matttproud/golang_protobuf_extensions
|
||||||
|
Copyright 2013 Matt T. Proud
|
||||||
|
Licensed under the Apache License, Version 2.0
|
||||||
|
|
||||||
|
DNS library in Go
|
||||||
|
http://miek.nl/posts/2014/Aug/16/go-dns-package/
|
||||||
|
Copyright 2009 The Go Authors, 2011 Miek Gieben
|
||||||
|
See https://github.com/miekg/dns/blob/master/LICENSE for license details.
|
||||||
|
|
||||||
|
LevelDB key/value database in Go
|
||||||
|
https://github.com/syndtr/goleveldb
|
||||||
|
Copyright 2012 Suryandaru Triandana
|
||||||
|
See https://github.com/syndtr/goleveldb/blob/master/LICENSE for license details.
|
||||||
|
|
||||||
|
gosnappy - a fork of code.google.com/p/snappy-go
|
||||||
|
https://github.com/syndtr/gosnappy
|
||||||
|
Copyright 2011 The Snappy-Go Authors
|
||||||
|
See https://github.com/syndtr/gosnappy/blob/master/LICENSE for license details.
|
||||||
|
|
||||||
|
go-zookeeper - Native ZooKeeper client for Go
|
||||||
|
https://github.com/samuel/go-zookeeper
|
||||||
|
Copyright (c) 2013, Samuel Stauffer <samuel@descolada.com>
|
||||||
|
See https://github.com/samuel/go-zookeeper/blob/master/LICENSE for license details.
|
||||||
46
vendor/github.com/prometheus/prometheus/util/flock/flock.go
generated
vendored
Normal file
46
vendor/github.com/prometheus/prometheus/util/flock/flock.go
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright 2016 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// Package flock provides portable file locking. It is essentially ripped out
|
||||||
|
// from the code of github.com/syndtr/goleveldb. Strange enough that the
|
||||||
|
// standard library does not provide this functionality. Once this package has
|
||||||
|
// proven to work as expected, we should probably turn it into a separate
|
||||||
|
// general purpose package for humanity.
|
||||||
|
package flock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Releaser provides the Release method to release a file lock.
|
||||||
|
type Releaser interface {
|
||||||
|
Release() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// New locks the file with the provided name. If the file does not exist, it is
|
||||||
|
// created. The returned Releaser is used to release the lock. existed is true
|
||||||
|
// if the file to lock already existed. A non-nil error is returned if the
|
||||||
|
// locking has failed. Neither this function nor the returned Releaser is
|
||||||
|
// goroutine-safe.
|
||||||
|
func New(fileName string) (r Releaser, existed bool, err error) {
|
||||||
|
if err = os.MkdirAll(filepath.Dir(fileName), 0755); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = os.Stat(fileName)
|
||||||
|
existed = err == nil
|
||||||
|
|
||||||
|
r, err = newLock(fileName)
|
||||||
|
return
|
||||||
|
}
|
||||||
32
vendor/github.com/prometheus/prometheus/util/flock/flock_plan9.go
generated
vendored
Normal file
32
vendor/github.com/prometheus/prometheus/util/flock/flock_plan9.go
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2016 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package flock
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
type plan9Lock struct {
|
||||||
|
f *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *plan9Lock) Release() error {
|
||||||
|
return l.f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLock(fileName string) (Releaser, error) {
|
||||||
|
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, os.ModeExclusive|0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &plan9Lock{f}, nil
|
||||||
|
}
|
||||||
59
vendor/github.com/prometheus/prometheus/util/flock/flock_solaris.go
generated
vendored
Normal file
59
vendor/github.com/prometheus/prometheus/util/flock/flock_solaris.go
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright 2016 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package flock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type unixLock struct {
|
||||||
|
f *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *unixLock) Release() error {
|
||||||
|
if err := l.set(false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *unixLock) set(lock bool) error {
|
||||||
|
flock := syscall.Flock_t{
|
||||||
|
Type: syscall.F_UNLCK,
|
||||||
|
Start: 0,
|
||||||
|
Len: 0,
|
||||||
|
Whence: 1,
|
||||||
|
}
|
||||||
|
if lock {
|
||||||
|
flock.Type = syscall.F_WRLCK
|
||||||
|
}
|
||||||
|
return syscall.FcntlFlock(l.f.Fd(), syscall.F_SETLK, &flock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLock(fileName string) (Releaser, error) {
|
||||||
|
f, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l := &unixLock{f}
|
||||||
|
err = l.set(true)
|
||||||
|
if err != nil {
|
||||||
|
f.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return l, nil
|
||||||
|
}
|
||||||
54
vendor/github.com/prometheus/prometheus/util/flock/flock_unix.go
generated
vendored
Normal file
54
vendor/github.com/prometheus/prometheus/util/flock/flock_unix.go
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2016 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
package flock
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type unixLock struct {
|
||||||
|
f *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *unixLock) Release() error {
|
||||||
|
if err := l.set(false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *unixLock) set(lock bool) error {
|
||||||
|
how := syscall.LOCK_UN
|
||||||
|
if lock {
|
||||||
|
how = syscall.LOCK_EX
|
||||||
|
}
|
||||||
|
return syscall.Flock(int(l.f.Fd()), how|syscall.LOCK_NB)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLock(fileName string) (Releaser, error) {
|
||||||
|
f, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l := &unixLock{f}
|
||||||
|
err = l.set(true)
|
||||||
|
if err != nil {
|
||||||
|
f.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return l, nil
|
||||||
|
}
|
||||||
36
vendor/github.com/prometheus/prometheus/util/flock/flock_windows.go
generated
vendored
Normal file
36
vendor/github.com/prometheus/prometheus/util/flock/flock_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2016 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package flock
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
type windowsLock struct {
|
||||||
|
fd syscall.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fl *windowsLock) Release() error {
|
||||||
|
return syscall.Close(fl.fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLock(fileName string) (Releaser, error) {
|
||||||
|
pathp, err := syscall.UTF16PtrFromString(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fd, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &windowsLock{fd}, nil
|
||||||
|
}
|
||||||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
|
@ -255,6 +255,12 @@
|
||||||
"revision": "bf27d3ba8e1d9899d45a457ffac16c953eb2d647",
|
"revision": "bf27d3ba8e1d9899d45a457ffac16c953eb2d647",
|
||||||
"revisionTime": "2017-02-11T19:53:22Z"
|
"revisionTime": "2017-02-11T19:53:22Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "WbbxCn2jUYIL5viqLo0BKXEdPrQ=",
|
||||||
|
"path": "github.com/prometheus/prometheus/util/flock",
|
||||||
|
"revision": "3101606756c53221ed58ba94ecba6b26adf89dcc",
|
||||||
|
"revisionTime": "2017-08-14T17:01:13Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "KAzbLjI9MzW2tjfcAsK75lVRp6I=",
|
"checksumSHA1": "KAzbLjI9MzW2tjfcAsK75lVRp6I=",
|
||||||
"path": "github.com/rcrowley/go-metrics",
|
"path": "github.com/rcrowley/go-metrics",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue