diff --git a/README.md b/README.md index 8190c5f2d3..b10a04c259 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ethereum Ethereum Go Development package (C) Jeffrey Wilcke Ethereum is currently in its testing phase. The current state is "Proof -of Concept 5.0 RC11". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)). +of Concept 5.0 RC12". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)). Ethereum Go is split up in several sub packages Please refer to each individual package for more information. diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 8479e9f446..f1c09b8192 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -22,6 +22,7 @@ type Peer interface { Host() []byte Port() uint16 Version() string + PingTime() string Connected() *int32 } @@ -177,7 +178,7 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac err = fmt.Errorf("[STATE] Unable to create contract") } } else { - err = fmt.Errorf("[STATE] contract creation tx: %v", err) + err = fmt.Errorf("[STATE] contract creation tx: %v for sender %x", err, tx.Sender()) } } else { // Find the state object at the "recipient" address. If diff --git a/ethchain/vm.go b/ethchain/vm.go index 9720d8be1d..955be847f0 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -309,7 +309,7 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro case SHA3: require(2) size, offset := stack.Popn() - data := mem.Get(offset.Int64(), size.Int64()) + data := ethutil.Sha3Bin(mem.Get(offset.Int64(), size.Int64())) stack.Push(ethutil.BigD(data)) // 0x30 range diff --git a/ethpub/pub.go b/ethpub/pub.go index 6d4c230add..e00bd0dbef 100644 --- a/ethpub/pub.go +++ b/ethpub/pub.go @@ -56,6 +56,7 @@ func (lib *PEthereum) GetPeers() []PPeer { var peers []PPeer for peer := lib.manager.Peers().Front(); peer != nil; peer = peer.Next() { p := peer.Value.(ethchain.Peer) + // we only want connected peers if atomic.LoadInt32(p.Connected()) != 0 { peers = append(peers, *NewPPeer(p)) } diff --git a/ethpub/types.go b/ethpub/types.go index 1079f09b4f..6893c7e09b 100644 --- a/ethpub/types.go +++ b/ethpub/types.go @@ -20,6 +20,7 @@ type PPeer struct { Port int `json:"port"` Version string `json:"version"` LastResponse string `json:"lastResponse"` + Latency string `json:"latency"` } func NewPPeer(peer ethchain.Peer) *PPeer { @@ -34,7 +35,7 @@ func NewPPeer(peer ethchain.Peer) *PPeer { } ipAddress := strings.Join(ip, ".") - return &PPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port())} + return &PPeer{ref: &peer, Inbound: peer.Inbound(), LastSend: peer.LastSend().Unix(), LastPong: peer.LastPong(), Version: peer.Version(), Ip: ipAddress, Port: int(peer.Port()), Latency: peer.PingTime()} } // Block interface exposed to QML @@ -206,6 +207,31 @@ func (c *PStateObject) IsContract() bool { return false } +type KeyVal struct { + Key string + Value string +} + +func (c *PStateObject) StateKeyVal(asJson bool) interface{} { + var values []KeyVal + if c.object != nil { + c.object.State().EachStorage(func(name string, value *ethutil.Value) { + values = append(values, KeyVal{name, ethutil.Hex(value.Bytes())}) + }) + } + + if asJson { + valuesJson, err := json.Marshal(values) + if err != nil { + return nil + } + fmt.Println(string(valuesJson)) + return string(valuesJson) + } + + return values +} + func (c *PStateObject) Script() string { if c.object != nil { return strings.Join(ethchain.Disassemble(c.object.Script()), " ") diff --git a/ethutil/common.go b/ethutil/common.go index 771dfc723c..c7973eb929 100644 --- a/ethutil/common.go +++ b/ethutil/common.go @@ -7,13 +7,15 @@ import ( // The different number of units var ( - Ether = BigPow(10, 18) - Finney = BigPow(10, 15) - Szabo = BigPow(10, 12) - Shannon = BigPow(10, 9) - Babbage = BigPow(10, 6) - Ada = BigPow(10, 3) - Wei = big.NewInt(1) + Douglas = BigPow(10, 42) + Einstein = BigPow(10, 21) + Ether = BigPow(10, 18) + Finney = BigPow(10, 15) + Szabo = BigPow(10, 12) + Shannon = BigPow(10, 9) + Babbage = BigPow(10, 6) + Ada = BigPow(10, 3) + Wei = big.NewInt(1) ) // Currency to string @@ -21,6 +23,10 @@ var ( // Returns a string representing a human readable format func CurrencyToString(num *big.Int) string { switch { + case num.Cmp(Douglas) >= 0: + return fmt.Sprintf("%v Douglas", new(big.Int).Div(num, Douglas)) + case num.Cmp(Einstein) >= 0: + return fmt.Sprintf("%v Einstein", new(big.Int).Div(num, Einstein)) case num.Cmp(Ether) >= 0: return fmt.Sprintf("%v Ether", new(big.Int).Div(num, Ether)) case num.Cmp(Finney) >= 0: diff --git a/ethutil/config.go b/ethutil/config.go index 4f7820eed5..e992bda12b 100644 --- a/ethutil/config.go +++ b/ethutil/config.go @@ -75,7 +75,7 @@ func ReadConfig(base string, logTypes LoggerType, g *globalconf.GlobalConf, id s if Config == nil { path := ApplicationFolder(base) - Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC11"} + Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC12"} Config.conf = g Config.Identifier = id Config.Log = NewLogger(logTypes, LogLevelDebug) diff --git a/peer.go b/peer.go index 71ad914614..eed5bec308 100644 --- a/peer.go +++ b/peer.go @@ -130,6 +130,10 @@ type Peer struct { blocksRequested int version string + + // We use this to give some kind of pingtime to a node, not very accurate, could be improved. + pingTime time.Duration + pingStartTime time.Time } func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer { @@ -185,6 +189,9 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer { } // Getters +func (p *Peer) PingTime() string { + return p.pingTime.String() +} func (p *Peer) Inbound() bool { return p.inbound } @@ -246,7 +253,7 @@ func (p *Peer) writeMessage(msg *ethwire.Msg) { // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer - pingTimer := time.NewTicker(2 * time.Minute) + pingTimer := time.NewTicker(30 * time.Second) serviceTimer := time.NewTicker(5 * time.Minute) out: @@ -255,12 +262,12 @@ out: // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: p.writeMessage(msg) - p.lastSend = time.Now() // Ping timer sends a ping to the peer each 2 minutes case <-pingTimer.C: p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) + p.pingStartTime = time.Now() // Service timer takes care of peer broadcasting, transaction // posting or block posting @@ -290,8 +297,8 @@ clean: // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { - for atomic.LoadInt32(&p.disconnect) == 0 { + // HMM? time.Sleep(500 * time.Millisecond) // Wait for a message from the peer @@ -319,6 +326,7 @@ func (p *Peer) HandleInbound() { // last pong so the peer handler knows this peer is still // active. p.lastPong = time.Now().Unix() + p.pingTime = time.Now().Sub(p.pingStartTime) case ethwire.MsgBlockTy: // Get all blocks and process them var block, lastBlock *ethchain.Block @@ -531,11 +539,15 @@ func (p *Peer) Start() { return } - // Run the outbound handler in a new goroutine go p.HandleOutbound() // Run the inbound handler in a new goroutine go p.HandleInbound() + // Wait a few seconds for startup and then ask for an initial ping + time.Sleep(2 * time.Second) + p.writeMessage(ethwire.NewMessage(ethwire.MsgPingTy, "")) + p.pingStartTime = time.Now() + } func (p *Peer) Stop() {