Godeps, vendor: convert dependency management to trash (#3198)
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
This commit is contained in:
committed by
Felix Lange
parent
7770304576
commit
289b30715d
@ -1,262 +0,0 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package natspec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/httpclient"
|
||||
"github.com/ethereum/go-ethereum/common/registrar"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/xeth"
|
||||
"github.com/robertkrimen/otto"
|
||||
)
|
||||
|
||||
type abi2method map[[8]byte]*method
|
||||
|
||||
type NatSpec struct {
|
||||
jsvm *otto.Otto
|
||||
abiDocJson []byte
|
||||
userDoc userDoc
|
||||
tx, data string
|
||||
}
|
||||
|
||||
// main entry point for to get natspec notice for a transaction
|
||||
// the implementation is frontend friendly in that it always gives back
|
||||
// a notice that is safe to display
|
||||
// :FIXME: the second return value is an error, which can be used to fine-tune bahaviour
|
||||
func GetNotice(xeth *xeth.XEth, tx string, http *httpclient.HTTPClient) (notice string) {
|
||||
ns, err := New(xeth, tx, http)
|
||||
if err != nil {
|
||||
if ns == nil {
|
||||
return getFallbackNotice(fmt.Sprintf("no NatSpec info found for contract: %v", err), tx)
|
||||
} else {
|
||||
return getFallbackNotice(fmt.Sprintf("invalid NatSpec info: %v", err), tx)
|
||||
}
|
||||
}
|
||||
|
||||
notice, err = ns.Notice()
|
||||
if err != nil {
|
||||
return getFallbackNotice(fmt.Sprintf("NatSpec notice error: %v", err), tx)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getFallbackNotice(comment, tx string) string {
|
||||
return fmt.Sprintf("About to submit transaction (%s): %s", comment, tx)
|
||||
}
|
||||
|
||||
type transaction struct {
|
||||
To string `json:"to"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type jsonTx struct {
|
||||
Params []transaction `json:"params"`
|
||||
}
|
||||
|
||||
type contractInfo struct {
|
||||
Source string `json:"source"`
|
||||
Language string `json:"language"`
|
||||
Version string `json:"compilerVersion"`
|
||||
AbiDefinition json.RawMessage `json:"abiDefinition"`
|
||||
UserDoc userDoc `json:"userDoc"`
|
||||
DeveloperDoc json.RawMessage `json:"developerDoc"`
|
||||
}
|
||||
|
||||
func New(xeth *xeth.XEth, jsontx string, http *httpclient.HTTPClient) (self *NatSpec, err error) {
|
||||
|
||||
// extract contract address from tx
|
||||
var tx jsonTx
|
||||
err = json.Unmarshal([]byte(jsontx), &tx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
t := tx.Params[0]
|
||||
contractAddress := t.To
|
||||
|
||||
content, err := FetchDocsForContract(contractAddress, xeth, http)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
self, err = NewWithDocs(content, jsontx, t.Data)
|
||||
return
|
||||
}
|
||||
|
||||
// also called by admin.contractInfo.get
|
||||
func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, client *httpclient.HTTPClient) (content []byte, err error) {
|
||||
// retrieve contract hash from state
|
||||
codehex := xeth.CodeAt(contractAddress)
|
||||
codeb := xeth.CodeAtBytes(contractAddress)
|
||||
|
||||
if codehex == "0x" {
|
||||
err = fmt.Errorf("contract (%v) not found", contractAddress)
|
||||
return
|
||||
}
|
||||
codehash := common.BytesToHash(crypto.Keccak256(codeb))
|
||||
// set up nameresolver with natspecreg + urlhint contract addresses
|
||||
reg := registrar.New(xeth)
|
||||
|
||||
// resolve host via HashReg/UrlHint Resolver
|
||||
hash, err := reg.HashToHash(codehash)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if client.HasScheme("bzz") {
|
||||
content, err = client.Get("bzz://"+hash.Hex()[2:], "")
|
||||
if err == nil { // non-fatal
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
//falling back to urlhint
|
||||
}
|
||||
|
||||
uri, err := reg.HashToUrl(hash)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// get content via http client and authenticate content using hash
|
||||
content, err = client.GetAuthContent(uri, hash)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NewWithDocs(infoDoc []byte, tx string, data string) (self *NatSpec, err error) {
|
||||
|
||||
var contract contractInfo
|
||||
err = json.Unmarshal(infoDoc, &contract)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
self = &NatSpec{
|
||||
jsvm: otto.New(),
|
||||
abiDocJson: []byte(contract.AbiDefinition),
|
||||
userDoc: contract.UserDoc,
|
||||
tx: tx,
|
||||
data: data,
|
||||
}
|
||||
|
||||
// load and require natspec js (but it is meant to be protected environment)
|
||||
_, err = self.jsvm.Run(natspecJS)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = self.jsvm.Run("var natspec = require('natspec');")
|
||||
return
|
||||
}
|
||||
|
||||
// type abiDoc []method
|
||||
|
||||
// type method struct {
|
||||
// Name string `json:name`
|
||||
// Inputs []input `json:inputs`
|
||||
// abiKey [8]byte
|
||||
// }
|
||||
|
||||
// type input struct {
|
||||
// Name string `json:name`
|
||||
// Type string `json:type`
|
||||
// }
|
||||
|
||||
// json skeleton for abi doc (contract method definitions)
|
||||
type method struct {
|
||||
Notice string `json:notice`
|
||||
name string
|
||||
}
|
||||
|
||||
type userDoc struct {
|
||||
Methods map[string]*method `json:methods`
|
||||
}
|
||||
|
||||
func (self *NatSpec) makeAbi2method(abiKey [8]byte) (meth *method) {
|
||||
for signature, m := range self.userDoc.Methods {
|
||||
name := strings.Split(signature, "(")[0]
|
||||
hash := []byte(common.Bytes2Hex(crypto.Keccak256([]byte(signature))))
|
||||
var key [8]byte
|
||||
copy(key[:], hash[:8])
|
||||
if bytes.Equal(key[:], abiKey[:]) {
|
||||
meth = m
|
||||
meth.name = name
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *NatSpec) Notice() (notice string, err error) {
|
||||
var abiKey [8]byte
|
||||
if len(self.data) < 10 {
|
||||
err = fmt.Errorf("Invalid transaction data")
|
||||
return
|
||||
}
|
||||
copy(abiKey[:], self.data[2:10])
|
||||
meth := self.makeAbi2method(abiKey)
|
||||
|
||||
if meth == nil {
|
||||
err = fmt.Errorf("abi key does not match any method")
|
||||
return
|
||||
}
|
||||
notice, err = self.noticeForMethod(self.tx, meth.name, meth.Notice)
|
||||
return
|
||||
}
|
||||
|
||||
func (self *NatSpec) noticeForMethod(tx string, name, expression string) (notice string, err error) {
|
||||
|
||||
if _, err = self.jsvm.Run("var transaction = " + tx + ";"); err != nil {
|
||||
return "", fmt.Errorf("natspec.js error setting transaction: %v", err)
|
||||
}
|
||||
|
||||
if _, err = self.jsvm.Run("var abi = " + string(self.abiDocJson) + ";"); err != nil {
|
||||
return "", fmt.Errorf("natspec.js error setting abi: %v", err)
|
||||
}
|
||||
|
||||
if _, err = self.jsvm.Run("var method = '" + name + "';"); err != nil {
|
||||
return "", fmt.Errorf("natspec.js error setting method: %v", err)
|
||||
}
|
||||
|
||||
if _, err = self.jsvm.Run("var expression = \"" + expression + "\";"); err != nil {
|
||||
return "", fmt.Errorf("natspec.js error setting expression: %v", err)
|
||||
}
|
||||
|
||||
self.jsvm.Run("var call = {method: method,abi: abi,transaction: transaction};")
|
||||
value, err := self.jsvm.Run("natspec.evaluateExpression(expression, call);")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("natspec.js error evaluating expression: %v", err)
|
||||
}
|
||||
evalError := "Natspec evaluation failed, wrong input params"
|
||||
if value.String() == evalError {
|
||||
return "", fmt.Errorf("natspec.js error evaluating expression: wrong input params in expression '%s'", expression)
|
||||
}
|
||||
if len(value.String()) == 0 {
|
||||
return "", fmt.Errorf("natspec.js error evaluating expression")
|
||||
}
|
||||
|
||||
return value.String(), nil
|
||||
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package natspec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/httpclient"
|
||||
"github.com/ethereum/go-ethereum/common/registrar"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
xe "github.com/ethereum/go-ethereum/xeth"
|
||||
)
|
||||
|
||||
const (
|
||||
testAddress = "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
|
||||
testBalance = "10000000000000000000"
|
||||
testKey = "e6fab74a43941f82d89cb7faa408e227cdad3153c4720e540e855c19b15e6674"
|
||||
|
||||
testFileName = "long_file_name_for_testing_registration_of_URLs_longer_than_32_bytes.content"
|
||||
|
||||
testNotice = "Register key `utils.toHex(_key)` <- content `utils.toHex(_content)`"
|
||||
|
||||
testExpNotice = "Register key 0xadd1a7d961cff0242089674ec2ef6fca671ab15e1fe80e38859fc815b98d88ab <- content 0xb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7"
|
||||
|
||||
testExpNotice2 = `About to submit transaction (NatSpec notice error: abi key does not match any method): {"params":[{"to":"%s","data": "0x31e12c20"}]}`
|
||||
|
||||
testExpNotice3 = `About to submit transaction (no NatSpec info found for contract: HashToHash: content hash not found for '0x1392c62d05b2d149e22a339c531157ae06b44d39a674cce500064b12b9aeb019'): {"params":[{"to":"%s","data": "0x300a3bbfb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}`
|
||||
)
|
||||
|
||||
const (
|
||||
testUserDoc = `
|
||||
{
|
||||
"methods": {
|
||||
"register(uint256,uint256)": {
|
||||
"notice": "` + testNotice + `"
|
||||
}
|
||||
},
|
||||
"invariants": [
|
||||
{ "notice": "" }
|
||||
],
|
||||
"construction": [
|
||||
{ "notice": "" }
|
||||
]
|
||||
}
|
||||
`
|
||||
testAbiDefinition = `
|
||||
[{
|
||||
"name": "register",
|
||||
"constant": false,
|
||||
"type": "function",
|
||||
"inputs": [{
|
||||
"name": "_key",
|
||||
"type": "uint256"
|
||||
}, {
|
||||
"name": "_content",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"outputs": []
|
||||
}]
|
||||
`
|
||||
|
||||
testContractInfo = `
|
||||
{
|
||||
"userDoc": ` + testUserDoc + `,
|
||||
"abiDefinition": ` + testAbiDefinition + `
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
type testFrontend struct {
|
||||
t *testing.T
|
||||
ethereum *eth.Ethereum
|
||||
xeth *xe.XEth
|
||||
wait chan *big.Int
|
||||
lastConfirm string
|
||||
wantNatSpec bool
|
||||
}
|
||||
|
||||
func (self *testFrontend) AskPassword() (string, bool) {
|
||||
return "", true
|
||||
}
|
||||
|
||||
func (self *testFrontend) UnlockAccount(acc []byte) bool {
|
||||
self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "password")
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *testFrontend) ConfirmTransaction(tx string) bool {
|
||||
if self.wantNatSpec {
|
||||
client := httpclient.New("/tmp/")
|
||||
self.lastConfirm = GetNotice(self.xeth, tx, client)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
|
||||
|
||||
tmp, err := ioutil.TempDir("", "natspec-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
addr := common.HexToAddress(testAddress)
|
||||
core.WriteGenesisBlockForTesting(db, core.GenesisAccount{addr, common.String2Big(testBalance)})
|
||||
ks := crypto.NewKeyStorePassphrase(filepath.Join(tmp, "keystore"), crypto.LightScryptN, crypto.LightScryptP)
|
||||
am := accounts.NewManager(ks)
|
||||
keyb, err := crypto.HexToECDSA(testKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
key := crypto.NewKeyFromECDSA(keyb)
|
||||
err = ks.StoreKey(key, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = am.Unlock(key.Address, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// only use minimalistic stack with no networking
|
||||
return eth.New(&node.ServiceContext{EventMux: new(event.TypeMux)}, ð.Config{
|
||||
AccountManager: am,
|
||||
Etherbase: common.HexToAddress(testAddress),
|
||||
PowTest: true,
|
||||
TestGenesisState: db,
|
||||
GpoMinGasPrice: common.Big1,
|
||||
GpobaseCorrectionFactor: 1,
|
||||
GpoMaxGasPrice: common.Big1,
|
||||
})
|
||||
}
|
||||
|
||||
func testInit(t *testing.T) (self *testFrontend) {
|
||||
// initialise and start minimal ethereum stack
|
||||
ethereum, err := testEth(t)
|
||||
if err != nil {
|
||||
t.Errorf("error creating ethereum: %v", err)
|
||||
return
|
||||
}
|
||||
err = ethereum.Start(nil)
|
||||
if err != nil {
|
||||
t.Errorf("error starting ethereum: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// mock frontend
|
||||
self = &testFrontend{t: t, ethereum: ethereum}
|
||||
self.xeth = xe.New(nil, self)
|
||||
self.wait = self.xeth.UpdateState()
|
||||
addr, _ := self.ethereum.Etherbase()
|
||||
|
||||
// initialise the registry contracts
|
||||
reg := registrar.New(self.xeth)
|
||||
registrar.GlobalRegistrarAddr = "0x0"
|
||||
|
||||
var txG, txH, txU string
|
||||
txG, err = reg.SetGlobalRegistrar("", addr)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating GlobalRegistrar: %v", err)
|
||||
}
|
||||
if !processTxs(self, t, 1) {
|
||||
t.Fatalf("error mining txs")
|
||||
}
|
||||
recG := self.xeth.GetTxReceipt(common.HexToHash(txG))
|
||||
if recG == nil {
|
||||
t.Fatalf("blockchain error creating GlobalRegistrar")
|
||||
}
|
||||
registrar.GlobalRegistrarAddr = recG.ContractAddress.Hex()
|
||||
|
||||
txH, err = reg.SetHashReg("", addr)
|
||||
if err != nil {
|
||||
t.Errorf("error creating HashReg: %v", err)
|
||||
}
|
||||
if !processTxs(self, t, 1) {
|
||||
t.Errorf("error mining txs")
|
||||
}
|
||||
recH := self.xeth.GetTxReceipt(common.HexToHash(txH))
|
||||
if recH == nil {
|
||||
t.Fatalf("blockchain error creating HashReg")
|
||||
}
|
||||
registrar.HashRegAddr = recH.ContractAddress.Hex()
|
||||
|
||||
txU, err = reg.SetUrlHint("", addr)
|
||||
if err != nil {
|
||||
t.Errorf("error creating UrlHint: %v", err)
|
||||
}
|
||||
if !processTxs(self, t, 1) {
|
||||
t.Errorf("error mining txs")
|
||||
}
|
||||
recU := self.xeth.GetTxReceipt(common.HexToHash(txU))
|
||||
if recU == nil {
|
||||
t.Fatalf("blockchain error creating UrlHint")
|
||||
}
|
||||
registrar.UrlHintAddr = recU.ContractAddress.Hex()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// end to end test
|
||||
func TestNatspecE2E(t *testing.T) {
|
||||
t.Skip()
|
||||
|
||||
tf := testInit(t)
|
||||
defer tf.ethereum.Stop()
|
||||
addr, _ := tf.ethereum.Etherbase()
|
||||
|
||||
// create a contractInfo file (mock cloud-deployed contract metadocs)
|
||||
// incidentally this is the info for the HashReg contract itself
|
||||
ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
|
||||
dochash := crypto.Keccak256Hash([]byte(testContractInfo))
|
||||
|
||||
// take the codehash for the contract we wanna test
|
||||
codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
|
||||
codehash := crypto.Keccak256Hash(codeb)
|
||||
|
||||
reg := registrar.New(tf.xeth)
|
||||
_, err := reg.SetHashToHash(addr, codehash, dochash)
|
||||
if err != nil {
|
||||
t.Errorf("error registering: %v", err)
|
||||
}
|
||||
_, err = reg.SetUrlToHash(addr, dochash, "file:///"+testFileName)
|
||||
if err != nil {
|
||||
t.Errorf("error registering: %v", err)
|
||||
}
|
||||
if !processTxs(tf, t, 5) {
|
||||
return
|
||||
}
|
||||
|
||||
// NatSpec info for register method of HashReg contract installed
|
||||
// now using the same transactions to check confirm messages
|
||||
|
||||
tf.wantNatSpec = true // this is set so now the backend uses natspec confirmation
|
||||
_, err = reg.SetHashToHash(addr, codehash, dochash)
|
||||
if err != nil {
|
||||
t.Errorf("error calling contract registry: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("GlobalRegistrar: %v, HashReg: %v, UrlHint: %v\n", registrar.GlobalRegistrarAddr, registrar.HashRegAddr, registrar.UrlHintAddr)
|
||||
if tf.lastConfirm != testExpNotice {
|
||||
t.Errorf("Wrong confirm message. expected\n'%v', got\n'%v'", testExpNotice, tf.lastConfirm)
|
||||
}
|
||||
|
||||
// test unknown method
|
||||
exp := fmt.Sprintf(testExpNotice2, registrar.HashRegAddr)
|
||||
_, err = reg.SetOwner(addr)
|
||||
if err != nil {
|
||||
t.Errorf("error setting owner: %v", err)
|
||||
}
|
||||
|
||||
if tf.lastConfirm != exp {
|
||||
t.Errorf("Wrong confirm message, expected\n'%v', got\n'%v'", exp, tf.lastConfirm)
|
||||
}
|
||||
|
||||
// test unknown contract
|
||||
exp = fmt.Sprintf(testExpNotice3, registrar.UrlHintAddr)
|
||||
|
||||
_, err = reg.SetUrlToHash(addr, dochash, "file:///test.content")
|
||||
if err != nil {
|
||||
t.Errorf("error registering: %v", err)
|
||||
}
|
||||
|
||||
if tf.lastConfirm != exp {
|
||||
t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func pendingTransactions(repl *testFrontend, t *testing.T) (txc int64, err error) {
|
||||
txs := repl.ethereum.TxPool().GetTransactions()
|
||||
return int64(len(txs)), nil
|
||||
}
|
||||
|
||||
func processTxs(repl *testFrontend, t *testing.T, expTxc int) bool {
|
||||
var txc int64
|
||||
var err error
|
||||
for i := 0; i < 50; i++ {
|
||||
txc, err = pendingTransactions(repl, t)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error checking pending transactions: %v", err)
|
||||
return false
|
||||
}
|
||||
if expTxc < int(txc) {
|
||||
t.Errorf("too many pending transactions: expected %v, got %v", expTxc, txc)
|
||||
return false
|
||||
} else if expTxc == int(txc) {
|
||||
break
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
if int(txc) != expTxc {
|
||||
t.Errorf("incorrect number of pending transactions, expected %v, got %v", expTxc, txc)
|
||||
return false
|
||||
}
|
||||
|
||||
err = repl.ethereum.StartMining(runtime.NumCPU(), "")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error mining: %v", err)
|
||||
return false
|
||||
}
|
||||
defer repl.ethereum.StopMining()
|
||||
|
||||
timer := time.NewTimer(100 * time.Second)
|
||||
height := new(big.Int).Add(repl.xeth.CurrentBlock().Number(), big.NewInt(1))
|
||||
repl.wait <- height
|
||||
select {
|
||||
case <-timer.C:
|
||||
// if times out make sure the xeth loop does not block
|
||||
go func() {
|
||||
select {
|
||||
case repl.wait <- nil:
|
||||
case <-repl.wait:
|
||||
}
|
||||
}()
|
||||
case <-repl.wait:
|
||||
}
|
||||
txc, err = pendingTransactions(repl, t)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error checking pending transactions: %v", err)
|
||||
return false
|
||||
}
|
||||
if txc != 0 {
|
||||
t.Errorf("%d trasactions were not mined", txc)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -1,160 +0,0 @@
|
||||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package natspec
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func makeInfoDoc(desc string) []byte {
|
||||
return []byte(`
|
||||
{
|
||||
"source": "contract test { }",
|
||||
"language": "Solidity",
|
||||
"compilerVersion": "1",
|
||||
"userDoc": {
|
||||
"methods": {
|
||||
"multiply(uint256)": {
|
||||
"notice": "` + desc + `"
|
||||
},
|
||||
"balance(address)": {
|
||||
"notice": "` + "`(balanceInmGAV / 1000).fixed(0,3)`" + ` GAV is the total funds available to ` + "`who.address()`." + `"
|
||||
}
|
||||
},
|
||||
"invariants": [
|
||||
{ "notice": "The sum total amount of GAV in the system is 1 million." }
|
||||
],
|
||||
"construction": [
|
||||
{ "notice": "Endows ` + "`message.caller.address()`" + ` with 1m GAV." }
|
||||
]
|
||||
},
|
||||
"abiDefinition": [{
|
||||
"name": "multiply",
|
||||
"constant": false,
|
||||
"type": "function",
|
||||
"inputs": [{
|
||||
"name": "a",
|
||||
"type": "uint256"
|
||||
}],
|
||||
"outputs": [{
|
||||
"name": "d",
|
||||
"type": "uint256"
|
||||
}]
|
||||
}]
|
||||
}`)
|
||||
}
|
||||
|
||||
var data = "0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a"
|
||||
|
||||
var tx = `
|
||||
{
|
||||
"params": [{
|
||||
"to": "0x8521742d3f456bd237e312d6e30724960f72517a",
|
||||
"data": "0xc6888fa1000000000000000000000000000000000000000000000000000000000000007a"
|
||||
}],
|
||||
}
|
||||
`
|
||||
|
||||
func TestNotice(t *testing.T) {
|
||||
|
||||
desc := "Will multiply `a` by 7 and return `a * 7`."
|
||||
expected := "Will multiply 122 by 7 and return 854."
|
||||
|
||||
infodoc := makeInfoDoc(desc)
|
||||
ns, err := NewWithDocs(infodoc, tx, data)
|
||||
if err != nil {
|
||||
t.Errorf("New: error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
notice, err := ns.Notice()
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if notice != expected {
|
||||
t.Errorf("incorrect notice. expected %v, got %v", expected, notice)
|
||||
}
|
||||
}
|
||||
|
||||
// test missing method
|
||||
func TestMissingMethod(t *testing.T) {
|
||||
|
||||
desc := "Will multiply `a` by 7 and return `a * 7`."
|
||||
expected := "natspec.js error evaluating expression: Natspec evaluation failed, method does not exist"
|
||||
|
||||
infodoc := makeInfoDoc(desc)
|
||||
ns, err := NewWithDocs(infodoc, tx, data)
|
||||
if err != nil {
|
||||
t.Errorf("New: error: %v", err)
|
||||
}
|
||||
|
||||
notice, err := ns.noticeForMethod(tx, "missing_method", "")
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("expected error, got nothing (notice: '%v')", notice)
|
||||
} else {
|
||||
if err.Error() != expected {
|
||||
t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test invalid desc
|
||||
|
||||
func TestInvalidDesc(t *testing.T) {
|
||||
|
||||
desc := "Will multiply 122 by \"7\" and return 854."
|
||||
expected := "invalid character '7' after object key:value pair"
|
||||
|
||||
infodoc := makeInfoDoc(desc)
|
||||
_, err := NewWithDocs(infodoc, tx, data)
|
||||
if err == nil {
|
||||
t.Errorf("expected error, got nothing", err)
|
||||
} else {
|
||||
if err.Error() != expected {
|
||||
t.Errorf("expected error '%s' got '%v'", expected, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test wrong input params
|
||||
func TestWrongInputParams(t *testing.T) {
|
||||
|
||||
desc := "Will multiply `e` by 7 and return `a * 7`."
|
||||
expected := "natspec.js error evaluating expression: Natspec evaluation failed, wrong input params"
|
||||
|
||||
infodoc := makeInfoDoc(desc)
|
||||
ns, err := NewWithDocs(infodoc, tx, data)
|
||||
if err != nil {
|
||||
t.Errorf("New: error: %v", err)
|
||||
}
|
||||
|
||||
notice, err := ns.Notice()
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("expected error, got nothing (notice: '%v')", notice)
|
||||
} else {
|
||||
if err.Error() != expected {
|
||||
t.Errorf("expected error '%s' got '%v' (notice: '%v')", expected, err, notice)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user