js api and js console test changes

* fix bigint issue causing trouble
* js: simplify api by separating concerns
 * saveInfo saves a file and calculates hash for Url Hint support
 * register now just takes the trivial 3 params and for bzz nothing else needed
* compiler: SaveInfo simplified
* clean up TestContract
  * use ethash test mining to force mine transactions,
  * get rid of xeth ApplyTxs hack
  * instead watch txs directly and mine with processTxs()
  * return on first error
* no need to specify gas/gasPrice in resolver, use default
* transaction_pool GetTransactions now trigger checkQueue() and validatePool()
* backend now uses ethash test if config.PowTest is set
This commit is contained in:
zelig 2015-06-02 00:52:06 +01:00
parent 1cfa386536
commit b2330c4e2e
8 changed files with 195 additions and 96 deletions

View file

@ -59,6 +59,7 @@ func (js *jsre) adminBindings() {
cinfo.Set("stop", js.stopNatSpec) cinfo.Set("stop", js.stopNatSpec)
cinfo.Set("newRegistry", js.newRegistry) cinfo.Set("newRegistry", js.newRegistry)
cinfo.Set("get", js.getContractInfo) cinfo.Set("get", js.getContractInfo)
cinfo.Set("saveInfo", js.saveInfo)
cinfo.Set("register", js.register) cinfo.Set("register", js.register)
cinfo.Set("registerUrl", js.registerUrl) cinfo.Set("registerUrl", js.registerUrl)
// cinfo.Set("verify", js.verify) // cinfo.Set("verify", js.verify)
@ -678,12 +679,18 @@ func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value {
} }
if args == 0 { if args == 0 {
height = js.xeth.CurrentBlock().Number() height = new(big.Int).Add(js.xeth.CurrentBlock().Number(), common.Big1)
height.Add(height, common.Big1) }
height, err = waitForBlocks(js.wait, height, timer)
if err != nil {
return otto.UndefinedValue()
}
v, _ := call.Otto.ToValue(height.Uint64())
return v
} }
wait := js.wait func waitForBlocks(wait chan *big.Int, height *big.Int, timer <-chan time.Time) (newHeight *big.Int, err error) {
js.wait <- height wait <- height
select { select {
case <-timer: case <-timer:
// if times out make sure the xeth loop does not block // if times out make sure the xeth loop does not block
@ -693,11 +700,10 @@ func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value {
case <-wait: case <-wait:
} }
}() }()
return otto.UndefinedValue() return nil, fmt.Errorf("timeout")
case height = <-wait: case newHeight = <-wait:
} }
v, _ := call.Otto.ToValue(height.Uint64()) return
return v
} }
func (js *jsre) sleep(call otto.FunctionCall) otto.Value { func (js *jsre) sleep(call otto.FunctionCall) otto.Value {
@ -729,23 +735,49 @@ func (js *jsre) setSolc(call otto.FunctionCall) otto.Value {
} }
func (js *jsre) register(call otto.FunctionCall) otto.Value { func (js *jsre) register(call otto.FunctionCall) otto.Value {
if len(call.ArgumentList) != 4 { if len(call.ArgumentList) != 3 {
fmt.Println("requires 4 arguments: admin.contractInfo.register(fromaddress, contractaddress, contract, filename)") fmt.Println("requires 3 arguments: admin.contractInfo.register(fromaddress, contractaddress, contenthash)")
return otto.UndefinedValue() return otto.FalseValue()
} }
sender, err := call.Argument(0).ToString() sender, err := call.Argument(0).ToString()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.FalseValue()
} }
address, err := call.Argument(1).ToString() address, err := call.Argument(1).ToString()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.FalseValue()
} }
raw, err := call.Argument(2).Export() contentHashHex, err := call.Argument(2).ToString()
if err != nil {
fmt.Println(err)
return otto.FalseValue()
}
// sender and contract address are passed as hex strings
codeb := js.xeth.CodeAtBytes(address)
codeHash := common.BytesToHash(crypto.Sha3(codeb))
contentHash := common.HexToHash(contentHashHex)
registry := resolver.New(js.xeth)
_, err = registry.RegisterContentHash(common.HexToAddress(sender), codeHash, contentHash)
if err != nil {
fmt.Println(err)
return otto.FalseValue()
}
return otto.TrueValue()
}
func (js *jsre) saveInfo(call otto.FunctionCall) otto.Value {
if len(call.ArgumentList) != 2 {
fmt.Println("requires 2 arguments: admin.contractInfo.saveInfo(contract.info, filename)")
return otto.UndefinedValue()
}
raw, err := call.Argument(0).Export()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.UndefinedValue()
@ -755,36 +787,20 @@ func (js *jsre) register(call otto.FunctionCall) otto.Value {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.UndefinedValue()
} }
var contract compiler.Contract var contractInfo compiler.ContractInfo
err = json.Unmarshal(jsonraw, &contract) err = json.Unmarshal(jsonraw, &contractInfo)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.UndefinedValue()
} }
filename, err := call.Argument(3).ToString() filename, err := call.Argument(1).ToString()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.UndefinedValue()
} }
contenthash, err := compiler.ExtractInfo(&contract, filename) contenthash, err := compiler.SaveInfo(&contractInfo, filename)
if err != nil {
fmt.Println(err)
return otto.UndefinedValue()
}
// sender and contract address are passed as hex strings
codeb := js.xeth.CodeAtBytes(address)
codehash := common.BytesToHash(crypto.Sha3(codeb))
if err != nil {
fmt.Println(err)
return otto.UndefinedValue()
}
registry := resolver.New(js.xeth)
_, err = registry.RegisterContentHash(common.HexToAddress(sender), codehash, contenthash)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return otto.UndefinedValue() return otto.UndefinedValue()
@ -796,7 +812,7 @@ func (js *jsre) register(call otto.FunctionCall) otto.Value {
func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value { func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value {
if len(call.ArgumentList) != 3 { if len(call.ArgumentList) != 3 {
fmt.Println("requires 3 arguments: admin.contractInfo.register(fromaddress, contenthash, filename)") fmt.Println("requires 3 arguments: admin.contractInfo.registerUrl(fromaddress, contenthash, url)")
return otto.FalseValue() return otto.FalseValue()
} }
sender, err := call.Argument(0).ToString() sender, err := call.Argument(0).ToString()
@ -818,7 +834,6 @@ func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value {
} }
registry := resolver.New(js.xeth) registry := resolver.New(js.xeth)
_, err = registry.RegisterUrl(common.HexToAddress(sender), common.HexToHash(contenthash), url) _, err = registry.RegisterUrl(common.HexToAddress(sender), common.HexToHash(contenthash), url)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -830,7 +845,7 @@ func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value {
func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value { func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value {
if len(call.ArgumentList) != 1 { if len(call.ArgumentList) != 1 {
fmt.Println("requires 1 argument: admin.contractInfo.register(contractaddress)") fmt.Println("requires 1 argument: admin.contractInfo.get(contractaddress)")
return otto.FalseValue() return otto.FalseValue()
} }
addr, err := call.Argument(0).ToString() addr, err := call.Argument(0).ToString()

View file

@ -85,6 +85,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, bzzEnabled bool
js.xeth = xeth.New(ethereum, f) js.xeth = xeth.New(ethereum, f)
js.wait = js.xeth.UpdateState() js.wait = js.xeth.UpdateState()
js.re = re.New(libPath) js.re = re.New(libPath)
// js.apiBindings(js.xeth)
js.apiBindings(f) js.apiBindings(f)
js.adminBindings() js.adminBindings()
if bzzEnabled { if bzzEnabled {
@ -113,6 +114,7 @@ func newJSRE(ethereum *eth.Ethereum, libPath, corsDomain string, bzzEnabled bool
func (js *jsre) apiBindings(f xeth.Frontend) { func (js *jsre) apiBindings(f xeth.Frontend) {
xe := xeth.New(js.ethereum, f) xe := xeth.New(js.ethereum, f)
// func (js *jsre) apiBindings(xe *xeth.XEth) {
ethApi := rpc.NewEthereumApi(xe) ethApi := rpc.NewEthereumApi(xe)
jeth := rpc.NewJeth(ethApi, js.re) jeth := rpc.NewJeth(ethApi, js.re)

View file

@ -3,12 +3,14 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/big"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
"strconv" "strconv"
"testing" "testing"
"time"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -17,7 +19,6 @@ import (
"github.com/ethereum/go-ethereum/common/natspec" "github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/common/resolver" "github.com/ethereum/go-ethereum/common/resolver"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
) )
@ -41,7 +42,6 @@ var (
type testjethre struct { type testjethre struct {
*jsre *jsre
stateDb *state.StateDB
lastConfirm string lastConfirm string
ds *docserver.DocServer ds *docserver.DocServer
} }
@ -79,6 +79,7 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
MaxPeers: 0, MaxPeers: 0,
Name: "test", Name: "test",
SolcPath: testSolcPath, SolcPath: testSolcPath,
PowTest: true,
}) })
if err != nil { if err != nil {
t.Fatal("%v", err) t.Fatal("%v", err)
@ -101,19 +102,12 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
assetPath := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext") assetPath := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext")
ds := docserver.New("/") ds := docserver.New("/")
tf := &testjethre{ds: ds, stateDb: ethereum.ChainManager().State().Copy()} tf := &testjethre{ds: ds}
repl := newJSRE(ethereum, assetPath, "", false, "", false, tf) repl := newJSRE(ethereum, assetPath, "", false, "", false, tf)
tf.jsre = repl tf.jsre = repl
return tmp, tf, ethereum return tmp, tf, ethereum
} }
// this line below is needed for transaction to be applied to the state in testing
// the heavy lifing is done in XEth.ApplyTestTxs
// this is fragile, overwriting xeth will result in
// process leaking since xeth loops cannot quit safely
// should be replaced by proper mining with testDAG for easy full integration tests
// txc, self.xeth = self.xeth.ApplyTestTxs(self.xeth.repl.stateDb, coinbase, txc)
func TestNodeInfo(t *testing.T) { func TestNodeInfo(t *testing.T) {
t.Skip("broken after p2p update") t.Skip("broken after p2p update")
tmp, repl, ethereum := testJEthRE(t) tmp, repl, ethereum := testJEthRE(t)
@ -257,12 +251,9 @@ func TestContract(t *testing.T) {
defer ethereum.Stop() defer ethereum.Stop()
defer os.RemoveAll(tmp) defer os.RemoveAll(tmp)
var txc uint64
coinbase := common.HexToAddress(testAddress) coinbase := common.HexToAddress(testAddress)
resolver.New(repl.xeth).CreateContracts(coinbase) resolver.New(repl.xeth).CreateContracts(coinbase)
// time.Sleep(1000 * time.Millisecond)
// checkEvalJSON(t, repl, `eth.getBlock("pending", true).transactions.length`, `2`)
source := `contract test {\n` + source := `contract test {\n` +
" /// @notice Will multiply `a` by 7." + `\n` + " /// @notice Will multiply `a` by 7." + `\n` +
` function multiply(uint a) returns(uint d) {\n` + ` function multiply(uint a) returns(uint d) {\n` +
@ -270,14 +261,20 @@ func TestContract(t *testing.T) {
` }\n` + ` }\n` +
`}\n` `}\n`
checkEvalJSON(t, repl, `admin.contractInfo.stop()`, `true`) if checkEvalJSON(t, repl, `admin.contractInfo.stop()`, `true`) != nil {
return
}
contractInfo, err := ioutil.ReadFile("info_test.json") contractInfo, err := ioutil.ReadFile("info_test.json")
if err != nil { if err != nil {
t.Fatalf("%v", err) t.Fatalf("%v", err)
} }
checkEvalJSON(t, repl, `primary = eth.accounts[0]`, `"`+testAddress+`"`) if checkEvalJSON(t, repl, `primary = eth.accounts[0]`, `"`+testAddress+`"`) != nil {
checkEvalJSON(t, repl, `source = "`+source+`"`, `"`+source+`"`) return
}
if checkEvalJSON(t, repl, `source = "`+source+`"`, `"`+source+`"`) != nil {
return
}
// if solc is found with right version, test it, otherwise read from file // if solc is found with right version, test it, otherwise read from file
sol, err := compiler.New("") sol, err := compiler.New("")
@ -297,71 +294,156 @@ func TestContract(t *testing.T) {
t.Errorf("%v", err) t.Errorf("%v", err)
} }
} else { } else {
checkEvalJSON(t, repl, `contract = eth.compile.solidity(source).test`, string(contractInfo)) if checkEvalJSON(t, repl, `contract = eth.compile.solidity(source).test`, string(contractInfo)) != nil {
return
}
} }
checkEvalJSON(t, repl, `contract.code`, `"0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"`) if checkEvalJSON(t, repl, `contract.code`, `"0x605880600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b603d6004803590602001506047565b8060005260206000f35b60006007820290506053565b91905056"`) != nil {
return
}
checkEvalJSON( if checkEvalJSON(
t, repl, t, repl,
`contractaddress = eth.sendTransaction({from: primary, data: contract.code })`, `contractaddress = eth.sendTransaction({from: primary, data: contract.code, gasPrice:"1000", gas:"100000", amount:100 })`,
`"0x291293d57e0a0ab47effe97c02577f90d9211567"`, `"0x291293d57e0a0ab47effe97c02577f90d9211567"`,
) ) != nil {
return
}
if !processTxs(repl, t, 7) {
return
}
callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]'); callSetup := `abiDef = JSON.parse('[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}]');
Multiply7 = eth.contract(abiDef); Multiply7 = eth.contract(abiDef);
multiply7 = Multiply7.at(contractaddress); multiply7 = Multiply7.at(contractaddress);
` `
// time.Sleep(1500 * time.Millisecond)
_, err = repl.re.Run(callSetup) _, err = repl.re.Run(callSetup)
if err != nil { if err != nil {
t.Errorf("unexpected error setting up contract, got %v", err) t.Errorf("unexpected error setting up contract, got %v", err)
return
} }
// checkEvalJSON(t, repl, `eth.getBlock("pending", true).transactions.length`, `3`)
// why is this sometimes failing?
// checkEvalJSON(t, repl, `multiply7.multiply.call(6)`, `42`)
expNotice := "" expNotice := ""
if repl.lastConfirm != expNotice { if repl.lastConfirm != expNotice {
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm) t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm)
return
} }
txc, repl.xeth = repl.xeth.ApplyTestTxs(repl.stateDb, coinbase, txc) if checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`) != nil {
return
}
if checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary })`, `undefined`) != nil {
return
}
if !processTxs(repl, t, 1) {
return
}
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`)
checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary, gas: "1000000", gasPrice: "100000" })`, `undefined`)
expNotice = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x87e2802265838c7f14bb69eecd2112911af6767907a702eeaa445239fb20711b'): {"params":[{"to":"0x291293d57e0a0ab47effe97c02577f90d9211567","data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}]}` expNotice = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x87e2802265838c7f14bb69eecd2112911af6767907a702eeaa445239fb20711b'): {"params":[{"to":"0x291293d57e0a0ab47effe97c02577f90d9211567","data": "0xc6888fa10000000000000000000000000000000000000000000000000000000000000006"}]}`
if repl.lastConfirm != expNotice { if repl.lastConfirm != expNotice {
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm) t.Errorf("incorrect confirmation message: expected\n%v, got\n%v", expNotice, repl.lastConfirm)
return
} }
var contenthash = `"0x86d2b7cf1e72e9a7a3f8d96601f0151742a2f780f1526414304fbe413dc7f9bd"` var contentHash = `"0x86d2b7cf1e72e9a7a3f8d96601f0151742a2f780f1526414304fbe413dc7f9bd"`
if sol != nil { if sol != nil && solcVersion != sol.Version() {
modContractInfo := versionRE.ReplaceAll(contractInfo, []byte(`"compilerVersion":"`+sol.Version()+`"`)) modContractInfo := versionRE.ReplaceAll(contractInfo, []byte(`"compilerVersion":"`+sol.Version()+`"`))
_ = modContractInfo fmt.Printf("modified contractinfo:\n%s\n", modContractInfo)
// contenthash = crypto.Sha3(modContractInfo) contentHash = `"` + common.ToHex(crypto.Sha3([]byte(modContractInfo))) + `"`
} }
checkEvalJSON(t, repl, `filename = "/tmp/info.json"`, `"/tmp/info.json"`) if checkEvalJSON(t, repl, `filename = "/tmp/info.json"`, `"/tmp/info.json"`) != nil {
checkEvalJSON(t, repl, `contenthash = admin.contractInfo.register(primary, contractaddress, contract, filename)`, contenthash) return
checkEvalJSON(t, repl, `admin.contractInfo.registerUrl(primary, contenthash, "file://"+filename)`, `true`) }
if err != nil { if checkEvalJSON(t, repl, `contentHash = admin.contractInfo.saveInfo(contract.info, filename)`, contentHash) != nil {
t.Errorf("unexpected error registering, got %v", err) return
}
if checkEvalJSON(t, repl, `admin.contractInfo.register(primary, contractaddress, contentHash)`, `true`) != nil {
return
}
if checkEvalJSON(t, repl, `admin.contractInfo.registerUrl(primary, contentHash, "file://"+filename)`, `true`) != nil {
return
} }
checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`) if checkEvalJSON(t, repl, `admin.contractInfo.start()`, `true`) != nil {
return
}
// update state if !processTxs(repl, t, 3) {
txc, repl.xeth = repl.xeth.ApplyTestTxs(repl.stateDb, coinbase, txc) return
}
if checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary })`, `undefined`) != nil {
return
}
if !processTxs(repl, t, 1) {
return
}
checkEvalJSON(t, repl, `multiply7.multiply.sendTransaction(6, { from: primary, gas: "1000000", gasPrice: "100000" })`, `undefined`)
expNotice = "Will multiply 6 by 7." expNotice = "Will multiply 6 by 7."
if repl.lastConfirm != expNotice { if repl.lastConfirm != expNotice {
t.Errorf("incorrect confirmation message: expected %v, got %v", expNotice, repl.lastConfirm) t.Errorf("incorrect confirmation message: expected\n%v, got\n%v", expNotice, repl.lastConfirm)
return
} }
} }
func pendingTransactions(repl *testjethre, t *testing.T) (txc int64, err error) {
txs := repl.ethereum.TxPool().GetTransactions()
return int64(len(txs)), nil
}
func processTxs(repl *testjethre, t *testing.T, expTxc int) bool {
var txc int64
var err error
for i := 0; i < 50; i++ {
txc, err = pendingTransactions(repl, t)
if err != nil {
t.Errorf("unexpected error checking pending transactions: %v", err)
return false
}
if expTxc < int(txc) {
t.Errorf("too many pending transactions: expected %v, got %v", expTxc, txc)
return false
} else if expTxc == int(txc) {
break
}
time.Sleep(100 * time.Millisecond)
}
if int(txc) != expTxc {
t.Errorf("incorrect number of pending transactions, expected %v, got %v", expTxc, txc)
return false
}
err = repl.ethereum.StartMining(runtime.NumCPU())
if err != nil {
t.Errorf("unexpected error mining: %v", err)
return false
}
defer repl.ethereum.StopMining()
timer := time.NewTimer(100 * time.Second)
height := new(big.Int).Add(repl.xeth.CurrentBlock().Number(), big.NewInt(1))
_, err = waitForBlocks(repl.wait, height, timer.C)
if err != nil {
t.Errorf("error mining transactions: %v", err)
return false
}
txc, err = pendingTransactions(repl, t)
if err != nil {
t.Errorf("unexpected error checking pending transactions: %v", err)
return false
}
if txc != 0 {
t.Errorf("%d trasactions were not mined", txc)
return false
}
return true
}
func checkEvalJSON(t *testing.T, re *testjethre, expr, want string) error { func checkEvalJSON(t *testing.T, re *testjethre, expr, want string) error {
val, err := re.re.Run("JSON.stringify(" + expr + ")") val, err := re.re.Run("JSON.stringify(" + expr + ")")
if err == nil && val.String() != want { if err == nil && val.String() != want {

View file

@ -185,12 +185,12 @@ func (sol *Solidity) Compile(source string) (contracts map[string]*Contract, err
return return
} }
func ExtractInfo(contract *Contract, filename string) (contenthash common.Hash, err error) { func SaveInfo(info *ContractInfo, filename string) (contenthash common.Hash, err error) {
contractInfo, err := json.Marshal(contract.Info) infojson, err := json.Marshal(info)
if err != nil { if err != nil {
return return
} }
contenthash = common.BytesToHash(crypto.Sha3(contractInfo)) contenthash = common.BytesToHash(crypto.Sha3(infojson))
err = ioutil.WriteFile(filename, contractInfo, 0600) err = ioutil.WriteFile(filename, infojson, 0600)
return return
} }

View file

@ -72,19 +72,15 @@ func TestNoCompiler(t *testing.T) {
} }
} }
func TestExtractInfo(t *testing.T) { func TestSaveInfo(t *testing.T) {
var cinfo ContractInfo var cinfo *ContractInfo
err := json.Unmarshal([]byte(info), &cinfo) err := json.Unmarshal([]byte(info), cinfo)
if err != nil { if err != nil {
t.Errorf("%v", err) t.Errorf("%v", err)
} }
contract := &Contract{
Code: "",
Info: cinfo,
}
filename := "/tmp/solctest.info.json" filename := "/tmp/solctest.info.json"
os.Remove(filename) os.Remove(filename)
cinfohash, err := ExtractInfo(contract, filename) cinfohash, err := SaveInfo(cinfo, filename)
if err != nil { if err != nil {
t.Errorf("error extracting info: %v", err) t.Errorf("error extracting info: %v", err)
} }

View file

@ -36,8 +36,8 @@ var (
const ( const (
txValue = "0" txValue = "0"
txGas = "100000" txGas = ""
txGasPrice = "1000000000000" txGasPrice = ""
) )
func abiSignature(s string) string { func abiSignature(s string) string {
@ -284,7 +284,7 @@ func (self *Resolver) RegisterUrl(address common.Address, hash common.Hash, url
// registers key -> conenthash in HashReg and // registers key -> conenthash in HashReg and
// registers contenthash -> url in UrlHint // registers contenthash -> url in UrlHint
// creates 3 transaction using address as sender // creates 3 transaction using address as sender
// transactions need to obe mined to take effect // transactions need to be mined to take effect
func (self *Resolver) RegisterAddrWithUrl(address common.Address, codehash, dochash common.Hash, url string) (txh string, err error) { func (self *Resolver) RegisterAddrWithUrl(address common.Address, codehash, dochash common.Hash, url string) (txh string, err error) {
_, err = self.RegisterContentHash(address, codehash, dochash) _, err = self.RegisterContentHash(address, codehash, dochash)

View file

@ -231,6 +231,9 @@ func (tp *TxPool) GetTransaction(hash common.Hash) *types.Transaction {
} }
func (self *TxPool) GetTransactions() (txs types.Transactions) { func (self *TxPool) GetTransactions() (txs types.Transactions) {
self.checkQueue()
self.validatePool()
self.mu.RLock() self.mu.RLock()
defer self.mu.RUnlock() defer self.mu.RUnlock()

View file

@ -290,6 +290,7 @@ func New(config *Config) (*Ethereum, error) {
} }
if config.PowTest { if config.PowTest {
glog.V(logger.Info).Infof("ethash used in test mode")
eth.pow, err = ethash.NewForTesting() eth.pow, err = ethash.NewForTesting()
if err != nil { if err != nil {
return nil, err return nil, err