aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-05-26 06:42:07 +0800
committerobscuren <geffobscura@gmail.com>2014-05-26 06:42:07 +0800
commitb1463b2dc23ebd072f5e1e2c9a74842fc7ff51db (patch)
tree96e360fc19b7c0a37172d6d27d1221bf175228e6
parent4e1c6a8a22924d06a2a972c024891cebcf8ea054 (diff)
parent1f3f76cb092e84bd2e90950f0d43d7657eae878e (diff)
downloaddexon-b1463b2dc23ebd072f5e1e2c9a74842fc7ff51db.tar.gz
dexon-b1463b2dc23ebd072f5e1e2c9a74842fc7ff51db.tar.zst
dexon-b1463b2dc23ebd072f5e1e2c9a74842fc7ff51db.zip
Merge branch 'release/poc5-rc9'
-rw-r--r--README.md2
-rw-r--r--ethchain/block.go85
-rw-r--r--ethchain/block_chain.go21
-rw-r--r--ethchain/block_chain_test.go4
-rw-r--r--ethchain/genesis.go2
-rw-r--r--ethchain/state.go16
-rw-r--r--ethchain/state_manager.go88
-rw-r--r--ethchain/state_object.go12
-rw-r--r--ethchain/state_object_test.go4
-rw-r--r--ethchain/state_test.go31
-rw-r--r--ethchain/transaction.go123
-rw-r--r--ethchain/transaction_pool.go18
-rw-r--r--ethchain/types.go7
-rw-r--r--ethchain/vm.go18
-rw-r--r--ethchain/vm_test.go64
-rw-r--r--ethminer/miner.go15
-rw-r--r--ethpub/pub.go52
-rw-r--r--ethpub/types.go17
-rw-r--r--ethrpc/packages.go2
-rw-r--r--ethutil/config.go12
-rw-r--r--ethutil/trie_test.go17
-rw-r--r--ethutil/value.go2
-rw-r--r--peer.go28
23 files changed, 434 insertions, 206 deletions
diff --git a/README.md b/README.md
index 2b080273b..081d9481e 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 RC8". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)).
+of Concept 5.0 RC9". 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/block.go b/ethchain/block.go
index 3401632b1..73e29f878 100644
--- a/ethchain/block.go
+++ b/ethchain/block.go
@@ -1,6 +1,7 @@
package ethchain
import (
+ "bytes"
"fmt"
"github.com/ethereum/eth-go/ethutil"
"math/big"
@@ -55,6 +56,7 @@ type Block struct {
Nonce []byte
// List of transactions and/or contracts
transactions []*Transaction
+ receipts []*Receipt
TxSha []byte
}
@@ -84,24 +86,20 @@ func CreateBlock(root interface{},
base []byte,
Difficulty *big.Int,
Nonce []byte,
- extra string,
- txes []*Transaction) *Block {
+ extra string) *Block {
block := &Block{
- // Slice of transactions to include in this block
- transactions: txes,
- PrevHash: prevHash,
- Coinbase: base,
- Difficulty: Difficulty,
- Nonce: Nonce,
- Time: time.Now().Unix(),
- Extra: extra,
- UncleSha: EmptyShaList,
- GasUsed: new(big.Int),
- MinGasPrice: new(big.Int),
- GasLimit: new(big.Int),
+ PrevHash: prevHash,
+ Coinbase: base,
+ Difficulty: Difficulty,
+ Nonce: Nonce,
+ Time: time.Now().Unix(),
+ Extra: extra,
+ UncleSha: EmptyShaList,
+ GasUsed: new(big.Int),
+ MinGasPrice: new(big.Int),
+ GasLimit: new(big.Int),
}
- block.SetTransactions(txes)
block.SetUncles([]*Block{})
block.state = NewState(ethutil.NewTrie(ethutil.Config.Db, root))
@@ -115,7 +113,10 @@ func (block *Block) Hash() []byte {
}
func (block *Block) HashNoNonce() []byte {
- return ethutil.Sha3Bin(ethutil.Encode([]interface{}{block.PrevHash, block.UncleSha, block.Coinbase, block.state.trie.Root, block.TxSha, block.Difficulty, block.Time, block.Extra}))
+ return ethutil.Sha3Bin(ethutil.Encode([]interface{}{block.PrevHash,
+ block.UncleSha, block.Coinbase, block.state.trie.Root,
+ block.TxSha, block.Difficulty, block.Number, block.MinGasPrice,
+ block.GasLimit, block.GasUsed, block.Time, block.Extra}))
}
func (block *Block) State() *State {
@@ -161,6 +162,16 @@ func (block *Block) BlockInfo() BlockInfo {
return bi
}
+func (self *Block) GetTransaction(hash []byte) *Transaction {
+ for _, receipt := range self.receipts {
+ if bytes.Compare(receipt.Tx.Hash(), hash) == 0 {
+ return receipt.Tx
+ }
+ }
+
+ return nil
+}
+
// Sync the block's state and contract respectively
func (block *Block) Sync() {
block.state.Sync()
@@ -172,15 +183,15 @@ func (block *Block) Undo() {
}
/////// Block Encoding
-func (block *Block) rlpTxs() interface{} {
+func (block *Block) rlpReceipts() interface{} {
// Marshal the transactions of this block
- encTx := make([]interface{}, len(block.transactions))
- for i, tx := range block.transactions {
+ encR := make([]interface{}, len(block.receipts))
+ for i, r := range block.receipts {
// Cast it to a string (safe)
- encTx[i] = tx.RlpData()
+ encR[i] = r.RlpData()
}
- return encTx
+ return encR
}
func (block *Block) rlpUncles() interface{} {
@@ -201,7 +212,12 @@ func (block *Block) SetUncles(uncles []*Block) {
block.UncleSha = ethutil.Sha3Bin(ethutil.Encode(block.rlpUncles()))
}
-func (block *Block) SetTransactions(txs []*Transaction) {
+func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) {
+ self.receipts = receipts
+ self.setTransactions(txs)
+}
+
+func (block *Block) setTransactions(txs []*Transaction) {
block.transactions = txs
trie := ethutil.NewTrie(ethutil.Config.Db, "")
@@ -221,7 +237,7 @@ func (block *Block) SetTransactions(txs []*Transaction) {
}
func (block *Block) Value() *ethutil.Value {
- return ethutil.NewValue([]interface{}{block.header(), block.rlpTxs(), block.rlpUncles()})
+ return ethutil.NewValue([]interface{}{block.header(), block.rlpReceipts(), block.rlpUncles()})
}
func (block *Block) RlpEncode() []byte {
@@ -245,6 +261,7 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
block.TxSha = header.Get(4).Bytes()
block.Difficulty = header.Get(5).BigInt()
block.Number = header.Get(6).BigInt()
+ //fmt.Printf("#%v : %x\n", block.Number, block.Coinbase)
block.MinGasPrice = header.Get(7).BigInt()
block.GasLimit = header.Get(8).BigInt()
block.GasUsed = header.Get(9).BigInt()
@@ -255,12 +272,13 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
// Tx list might be empty if this is an uncle. Uncles only have their
// header set.
if decoder.Get(1).IsNil() == false { // Yes explicitness
- txes := decoder.Get(1)
- block.transactions = make([]*Transaction, txes.Len())
- for i := 0; i < txes.Len(); i++ {
- tx := NewTransactionFromValue(txes.Get(i))
-
- block.transactions[i] = tx
+ receipts := decoder.Get(1)
+ block.transactions = make([]*Transaction, receipts.Len())
+ block.receipts = make([]*Receipt, receipts.Len())
+ for i := 0; i < receipts.Len(); i++ {
+ receipt := NewRecieptFromValue(receipts.Get(i))
+ block.transactions[i] = receipt.Tx
+ block.receipts[i] = receipt
}
}
@@ -299,6 +317,10 @@ func (block *Block) GetRoot() interface{} {
return block.state.trie.Root
}
+func (self *Block) Receipts() []*Receipt {
+ return self.receipts
+}
+
func (block *Block) header() []interface{} {
return []interface{}{
// Sha of the previous block
@@ -346,6 +368,7 @@ func (block *Block) String() string {
Time: %v
Extra: %v
Nonce: %x
+ NumTx: %v
`,
block.Hash(),
block.PrevHash,
@@ -360,5 +383,7 @@ func (block *Block) String() string {
block.GasUsed,
block.Time,
block.Extra,
- block.Nonce)
+ block.Nonce,
+ len(block.transactions),
+ )
}
diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go
index b72c78cdb..b45d254b5 100644
--- a/ethchain/block_chain.go
+++ b/ethchain/block_chain.go
@@ -36,7 +36,7 @@ func (bc *BlockChain) Genesis() *Block {
return bc.genesisBlock
}
-func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block {
+func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
var root interface{}
var lastBlockTime int64
hash := ZeroHash256
@@ -53,8 +53,7 @@ func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block {
coinbase,
ethutil.BigPow(2, 32),
nil,
- "",
- txs)
+ "")
if bc.CurrentBlock != nil {
var mul *big.Int
@@ -272,16 +271,18 @@ func (bc *BlockChain) GetChain(hash []byte, amount int) []*Block {
func AddTestNetFunds(block *Block) {
for _, addr := range []string{
- "8a40bfaa73256b60764c1bf40675a99083efb075", // Gavin
- "e6716f9544a56c530d868e4bfbacb172315bdead", // Jeffrey
- "1e12515ce3e0f817a4ddef9ca55788a1d66bd2df", // Vit
- "1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // Alex
- "2ef47100e0787b915105fd5e3f4ff6752079d5cb", // Maran
- "cd2a3d9f938e13cd947ec05abc7fe734df8dd826", // Roman
+ "8a40bfaa73256b60764c1bf40675a99083efb075",
+ "e4157b34ea9615cfbde6b4fda419828124b70c78",
+ "1e12515ce3e0f817a4ddef9ca55788a1d66bd2df",
+ "6c386a4b26f73c802f34673f7248bb118f97424a",
+ "cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
+ "2ef47100e0787b915105fd5e3f4ff6752079d5cb",
+ "e6716f9544a56c530d868e4bfbacb172315bdead",
+ "1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
} {
codedAddr := ethutil.FromHex(addr)
account := block.state.GetAccount(codedAddr)
- account.Amount = ethutil.BigPow(2, 200)
+ account.Amount = ethutil.Big("1606938044258990275541962092341162602522202993782792835301376") //ethutil.BigPow(2, 200)
block.state.UpdateStateObject(account)
}
log.Printf("%x\n", block.RlpEncode())
diff --git a/ethchain/block_chain_test.go b/ethchain/block_chain_test.go
index 4e4bb9dd4..ecaf8ca89 100644
--- a/ethchain/block_chain_test.go
+++ b/ethchain/block_chain_test.go
@@ -50,7 +50,7 @@ func (tm *TestManager) Broadcast(msgType ethwire.MsgType, data []interface{}) {
}
func NewTestManager() *TestManager {
- ethutil.ReadConfig(".ethtest", ethutil.LogStd)
+ ethutil.ReadConfig(".ethtest", ethutil.LogStd, "")
db, err := ethdb.NewMemDatabase()
if err != nil {
@@ -74,7 +74,7 @@ func NewTestManager() *TestManager {
func (tm *TestManager) AddFakeBlock(blk []byte) error {
block := NewBlockFromBytes(blk)
tm.Blocks = append(tm.Blocks, block)
- err := tm.StateManager().ProcessBlock(tm.StateManager().CurrentState(), block, false)
+ err := tm.StateManager().Process(block, false)
return err
}
func (tm *TestManager) CreateChain1() error {
diff --git a/ethchain/genesis.go b/ethchain/genesis.go
index b8f9f865a..359c47c26 100644
--- a/ethchain/genesis.go
+++ b/ethchain/genesis.go
@@ -23,7 +23,7 @@ var GenesisHeader = []interface{}{
// Root state
"",
// tx sha
- ZeroHash256,
+ "",
// Difficulty
ethutil.BigPow(2, 22),
// Number
diff --git a/ethchain/state.go b/ethchain/state.go
index 6ec6916f4..e209e0e2f 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -99,7 +99,21 @@ func (s *State) Cmp(other *State) bool {
}
func (s *State) Copy() *State {
- return NewState(s.trie.Copy())
+ state := NewState(s.trie.Copy())
+ for k, subState := range s.states {
+ state.states[k] = subState.Copy()
+ }
+
+ return state
+}
+
+func (s *State) Snapshot() *State {
+ return s.Copy()
+}
+
+func (s *State) Revert(snapshot *State) {
+ s.trie = snapshot.trie
+ s.states = snapshot.states
}
func (s *State) Put(key, object []byte) {
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 8b56d65bb..2d2a32e2f 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -84,7 +84,7 @@ func (sm *StateManager) BlockChain() *BlockChain {
return sm.bc
}
-func (sm *StateManager) MakeContract(state *State, tx *Transaction) *StateObject {
+func (sm *StateManager) MakeStateObject(state *State, tx *Transaction) *StateObject {
contract := MakeContract(tx, state)
if contract != nil {
state.states[string(tx.CreationAddress())] = contract.state
@@ -97,40 +97,74 @@ func (sm *StateManager) MakeContract(state *State, tx *Transaction) *StateObject
// Apply transactions uses the transaction passed to it and applies them onto
// the current processing state.
-func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Transaction) {
+func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Transaction) ([]*Receipt, []*Transaction) {
// Process each transaction/contract
+ var receipts []*Receipt
+ var validTxs []*Transaction
+ totalUsedGas := big.NewInt(0)
for _, tx := range txs {
- sm.ApplyTransaction(state, block, tx)
+ usedGas, err := sm.ApplyTransaction(state, block, tx)
+ if err != nil {
+ ethutil.Config.Log.Infoln(err)
+ continue
+ }
+
+ accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, usedGas))
+ receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
+
+ receipts = append(receipts, receipt)
+ validTxs = append(validTxs, tx)
}
+
+ return receipts, txs
}
-func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) error {
- // If there's no recipient, it's a contract
- // Check if this is a contract creation traction and if so
- // create a contract of this tx.
- if tx.IsContract() {
- err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
+func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) (*big.Int, error) {
+ /*
+ Applies transactions to the given state and creates new
+ state objects where needed.
+
+ If said objects needs to be created
+ run the initialization script provided by the transaction and
+ assume there's a return value. The return value will be set to
+ the script section of the state object.
+ */
+ totalGasUsed := big.NewInt(0)
+ // Apply the transaction to the current state
+ err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
+ if tx.CreatesContract() {
if err == nil {
- contract := sm.MakeContract(state, tx)
+ // Create a new state object and the transaction
+ // as it's data provider.
+ contract := sm.MakeStateObject(state, tx)
if contract != nil {
- sm.EvalScript(state, contract.Init(), contract, tx, block)
+ // Evaluate the initialization script
+ // and use the return value as the
+ // script section for the state object.
+ script, err := sm.EvalScript(state, contract.Init(), contract, tx, block)
+ if err != nil {
+ return nil, fmt.Errorf("[STATE] Error during init script run %v", err)
+ }
+ contract.script = script
+ state.UpdateStateObject(contract)
} else {
- return fmt.Errorf("[STATE] Unable to create contract")
+ return nil, fmt.Errorf("[STATE] Unable to create contract")
}
} else {
- return fmt.Errorf("[STATE] contract create:", err)
+ return nil, fmt.Errorf("[STATE] contract creation tx:", err)
}
} else {
- err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
- contract := state.GetStateObject(tx.Recipient)
- if err == nil && contract != nil && len(contract.Script()) > 0 {
- sm.EvalScript(state, contract.Script(), contract, tx, block)
+ // Find the state object at the "recipient" address. If
+ // there's an object attempt to run the script.
+ stateObject := state.GetStateObject(tx.Recipient)
+ if err == nil && stateObject != nil && len(stateObject.Script()) > 0 {
+ sm.EvalScript(state, stateObject.Script(), stateObject, tx, block)
} else if err != nil {
- return fmt.Errorf("[STATE] process:", err)
+ return nil, fmt.Errorf("[STATE] process:", err)
}
}
- return nil
+ return totalGasUsed, nil
}
func (sm *StateManager) Process(block *Block, dontReact bool) error {
@@ -276,6 +310,14 @@ func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
for i := 0; i < uncleLength; i++ {
base.Add(base, UncleInclusionReward)
}
+
+ lastCumulGasUsed := big.NewInt(0)
+ for _, r := range block.Receipts() {
+ usedGas := new(big.Int).Sub(r.CumulativeGasUsed, lastCumulGasUsed)
+ usedGas.Add(usedGas, r.Tx.GasPrice)
+ base.Add(base, usedGas)
+ }
+
return base.Add(base, BlockReward)
}
@@ -307,10 +349,10 @@ func (sm *StateManager) Stop() {
sm.bc.Stop()
}
-func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObject, tx *Transaction, block *Block) {
+func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObject, tx *Transaction, block *Block) (ret []byte, err error) {
account := state.GetAccount(tx.Sender())
- err := account.ConvertGas(tx.Gas, tx.GasPrice)
+ err = account.ConvertGas(tx.Gas, tx.GasPrice)
if err != nil {
ethutil.Config.Log.Debugln(err)
return
@@ -327,11 +369,13 @@ func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObj
Value: tx.Value,
//Price: tx.GasPrice,
})
- closure.Call(vm, tx.Data, nil)
+ ret, err = closure.Call(vm, tx.Data, nil)
// Update the account (refunds)
state.UpdateStateObject(account)
state.UpdateStateObject(object)
+
+ return
}
func (sm *StateManager) notifyChanges(state *State) {
diff --git a/ethchain/state_object.go b/ethchain/state_object.go
index 8e059f334..3e9c6df40 100644
--- a/ethchain/state_object.go
+++ b/ethchain/state_object.go
@@ -28,8 +28,7 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
value := tx.Value
contract := NewContract(addr, value, ZeroHash256)
- contract.script = tx.Data
- contract.initScript = tx.Init
+ contract.initScript = tx.Data
state.UpdateStateObject(contract)
@@ -82,12 +81,17 @@ func (c *StateObject) SetStorage(num *big.Int, val *ethutil.Value) {
c.SetAddr(addr, val)
}
-func (c *StateObject) GetMem(num *big.Int) *ethutil.Value {
+func (c *StateObject) GetStorage(num *big.Int) *ethutil.Value {
nb := ethutil.BigToBytes(num, 256)
return c.Addr(nb)
}
+/* DEPRECATED */
+func (c *StateObject) GetMem(num *big.Int) *ethutil.Value {
+ return c.GetStorage(num)
+}
+
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
if int64(len(c.script)-1) < pc.Int64() {
return ethutil.NewValue(0)
@@ -146,7 +150,7 @@ func (c *StateObject) RlpEncode() []byte {
if c.state != nil {
root = c.state.trie.Root
} else {
- root = ZeroHash256
+ root = ""
}
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, ethutil.Sha3Bin(c.script)})
diff --git a/ethchain/state_object_test.go b/ethchain/state_object_test.go
index e955acc56..91ed7c0dd 100644
--- a/ethchain/state_object_test.go
+++ b/ethchain/state_object_test.go
@@ -9,7 +9,7 @@ import (
)
func TestSync(t *testing.T) {
- ethutil.ReadConfig("", ethutil.LogStd)
+ ethutil.ReadConfig("", ethutil.LogStd, "")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
@@ -28,7 +28,7 @@ func TestSync(t *testing.T) {
}
func TestObjectGet(t *testing.T) {
- ethutil.ReadConfig("", ethutil.LogStd)
+ ethutil.ReadConfig("", ethutil.LogStd, "")
db, _ := ethdb.NewMemDatabase()
ethutil.Config.Db = db
diff --git a/ethchain/state_test.go b/ethchain/state_test.go
new file mode 100644
index 000000000..4cc3fdf75
--- /dev/null
+++ b/ethchain/state_test.go
@@ -0,0 +1,31 @@
+package ethchain
+
+import (
+ "fmt"
+ "github.com/ethereum/eth-go/ethdb"
+ "github.com/ethereum/eth-go/ethutil"
+ "testing"
+)
+
+func TestSnapshot(t *testing.T) {
+ ethutil.ReadConfig("", ethutil.LogStd, "")
+
+ db, _ := ethdb.NewMemDatabase()
+ state := NewState(ethutil.NewTrie(db, ""))
+
+ stateObject := NewContract([]byte("aa"), ethutil.Big1, ZeroHash256)
+ state.UpdateStateObject(stateObject)
+ stateObject.SetStorage(ethutil.Big("0"), ethutil.NewValue(42))
+
+ snapshot := state.Snapshot()
+
+ stateObject = state.GetStateObject([]byte("aa"))
+ stateObject.SetStorage(ethutil.Big("0"), ethutil.NewValue(43))
+
+ state.Revert(snapshot)
+
+ stateObject = state.GetStateObject([]byte("aa"))
+ if !stateObject.GetStorage(ethutil.Big("0")).Cmp(ethutil.NewValue(42)) {
+ t.Error("Expected storage 0 to be 42")
+ }
+}
diff --git a/ethchain/transaction.go b/ethchain/transaction.go
index bd7a0e424..2c5615f99 100644
--- a/ethchain/transaction.go
+++ b/ethchain/transaction.go
@@ -1,6 +1,7 @@
package ethchain
import (
+ "fmt"
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/secp256k1-go"
"math/big"
@@ -15,7 +16,6 @@ type Transaction struct {
Gas *big.Int
GasPrice *big.Int
Data []byte
- Init []byte
v byte
r, s []byte
@@ -23,8 +23,8 @@ type Transaction struct {
contractCreation bool
}
-func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte, init []byte) *Transaction {
- return &Transaction{Value: value, Gas: gas, GasPrice: gasPrice, Data: script, Init: init, contractCreation: true}
+func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
+ return &Transaction{Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true}
}
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
@@ -46,19 +46,26 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
func (tx *Transaction) Hash() []byte {
- data := []interface{}{tx.Nonce, tx.Value, tx.GasPrice, tx.Gas, tx.Recipient, tx.Data}
+ data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
- if tx.contractCreation {
- data = append(data, tx.Init)
- }
+ /*
+ if tx.contractCreation {
+ data = append(data, tx.Init)
+ }
+ */
return ethutil.Sha3Bin(ethutil.NewValue(data).Encode())
}
-func (tx *Transaction) IsContract() bool {
+func (tx *Transaction) CreatesContract() bool {
return tx.contractCreation
}
+/* Depricated */
+func (tx *Transaction) IsContract() bool {
+ return tx.CreatesContract()
+}
+
func (tx *Transaction) CreationAddress() []byte {
return ethutil.Sha3Bin(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:]
}
@@ -112,10 +119,6 @@ func (tx *Transaction) Sign(privk []byte) error {
func (tx *Transaction) RlpData() interface{} {
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
- if tx.contractCreation {
- data = append(data, tx.Init)
- }
-
return append(data, tx.v, tx.r, tx.s)
}
@@ -138,18 +141,90 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.Recipient = decoder.Get(3).Bytes()
tx.Value = decoder.Get(4).BigInt()
tx.Data = decoder.Get(5).Bytes()
-
- // If the list is of length 10 it's a contract creation tx
- if decoder.Len() == 10 {
+ tx.v = byte(decoder.Get(6).Uint())
+ tx.r = decoder.Get(7).Bytes()
+ tx.s = decoder.Get(8).Bytes()
+ if len(tx.Recipient) == 0 {
tx.contractCreation = true
- tx.Init = decoder.Get(6).Bytes()
-
- tx.v = byte(decoder.Get(7).Uint())
- tx.r = decoder.Get(8).Bytes()
- tx.s = decoder.Get(9).Bytes()
- } else {
- tx.v = byte(decoder.Get(6).Uint())
- tx.r = decoder.Get(7).Bytes()
- tx.s = decoder.Get(8).Bytes()
}
+
+ /*
+ // If the list is of length 10 it's a contract creation tx
+ if decoder.Len() == 10 {
+ tx.contractCreation = true
+ tx.Init = decoder.Get(6).Bytes()
+
+ tx.v = byte(decoder.Get(7).Uint())
+ tx.r = decoder.Get(8).Bytes()
+ tx.s = decoder.Get(9).Bytes()
+ } else {
+ tx.v = byte(decoder.Get(6).Uint())
+ tx.r = decoder.Get(7).Bytes()
+ tx.s = decoder.Get(8).Bytes()
+ }
+ */
+}
+
+func (tx *Transaction) String() string {
+ return fmt.Sprintf(`
+ TX(%x)
+ Contract: %v
+ From: %x
+ To: %x
+ Nonce: %v
+ GasPrice: %v
+ Gas: %v
+ Value: %v
+ Data: 0x%x
+ V: 0x%x
+ R: 0x%x
+ S: 0x%x
+ `,
+ tx.Hash(),
+ len(tx.Recipient) == 0,
+ tx.Sender(),
+ tx.Recipient,
+ tx.Nonce,
+ tx.GasPrice,
+ tx.Gas,
+ tx.Value,
+ tx.Data,
+ tx.v,
+ tx.r,
+ tx.s)
+}
+
+type Receipt struct {
+ Tx *Transaction
+ PostState []byte
+ CumulativeGasUsed *big.Int
+}
+
+func NewRecieptFromValue(val *ethutil.Value) *Receipt {
+ r := &Receipt{}
+ r.RlpValueDecode(val)
+
+ return r
+}
+
+func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) {
+ self.Tx = NewTransactionFromValue(decoder.Get(0))
+ self.PostState = decoder.Get(1).Bytes()
+ self.CumulativeGasUsed = decoder.Get(2).BigInt()
+}
+
+func (self *Receipt) RlpData() interface{} {
+ return []interface{}{self.Tx.RlpData(), self.PostState, self.CumulativeGasUsed}
+}
+
+func (self *Receipt) String() string {
+ return fmt.Sprintf(`
+ R
+ Tx:[ %v]
+ PostState: 0x%x
+ CumulativeGasUsed: %v
+ `,
+ self.Tx,
+ self.PostState,
+ self.CumulativeGasUsed)
}
diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go
index dcf0c4c31..ee026ffdd 100644
--- a/ethchain/transaction_pool.go
+++ b/ethchain/transaction_pool.go
@@ -91,15 +91,15 @@ func (pool *TxPool) addTransaction(tx *Transaction) {
// Process transaction validates the Tx and processes funds from the
// sender to the recipient.
-func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract bool) (err error) {
+func (pool *TxPool) ProcessTransaction(tx *Transaction, state *State, toContract bool) (err error) {
defer func() {
if r := recover(); r != nil {
- log.Println(r)
+ ethutil.Config.Log.Infoln(r)
err = fmt.Errorf("%v", r)
}
}()
// Get the sender
- sender := block.state.GetAccount(tx.Sender())
+ sender := state.GetAccount(tx.Sender())
if sender.Nonce != tx.Nonce {
return fmt.Errorf("[TXPL] Invalid account nonce, state nonce is %d transaction nonce is %d instead", sender.Nonce, tx.Nonce)
@@ -107,19 +107,21 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
// Make sure there's enough in the sender's account. Having insufficient
// funds won't invalidate this transaction but simple ignores it.
- totAmount := new(big.Int).Add(tx.Value, new(big.Int).Mul(TxFee, TxFeeRat))
+ //totAmount := new(big.Int).Add(tx.Value, new(big.Int).Mul(TxFee, TxFeeRat))
+ totAmount := new(big.Int).Add(tx.Value, new(big.Int).Mul(tx.Gas, tx.GasPrice))
if sender.Amount.Cmp(totAmount) < 0 {
return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender())
}
+ //fmt.Println(tx)
// Get the receiver
- receiver := block.state.GetAccount(tx.Recipient)
+ receiver := state.GetAccount(tx.Recipient)
sender.Nonce += 1
// Send Tx to self
if bytes.Compare(tx.Recipient, tx.Sender()) == 0 {
// Subtract the fee
- sender.SubAmount(new(big.Int).Mul(TxFee, TxFeeRat))
+ sender.SubAmount(new(big.Int).Mul(GasTx, tx.GasPrice))
} else {
// Subtract the amount from the senders account
sender.SubAmount(totAmount)
@@ -127,10 +129,10 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
// Add the amount to receivers account which should conclude this transaction
receiver.AddAmount(tx.Value)
- block.state.UpdateStateObject(receiver)
+ state.UpdateStateObject(receiver)
}
- block.state.UpdateStateObject(sender)
+ state.UpdateStateObject(sender)
ethutil.Config.Log.Infof("[TXPL] Processed Tx %x\n", tx.Hash())
diff --git a/ethchain/types.go b/ethchain/types.go
index 9964bbe3b..e0fdd5191 100644
--- a/ethchain/types.go
+++ b/ethchain/types.go
@@ -322,3 +322,10 @@ func IsOpCode(s string) bool {
}
return false
}
+
+func AppendScript(init, script []byte) []byte {
+ s := append(init, byte(oRETURN))
+ s = append(s, script...)
+
+ return s
+}
diff --git a/ethchain/vm.go b/ethchain/vm.go
index d8254998e..e025920f3 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -18,6 +18,7 @@ var (
GasCreate = big.NewInt(100)
GasCall = big.NewInt(20)
GasMemory = big.NewInt(1)
+ GasTx = big.NewInt(500)
)
func CalculateTxGas(initSize, scriptSize *big.Int) *big.Int {
@@ -425,6 +426,10 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
value := stack.Pop()
size, offset := stack.Popn()
+ // Snapshot the current stack so we are able to
+ // revert back to it later.
+ snapshot := vm.state.Snapshot()
+
// Generate a new address
addr := ethutil.CreateAddress(closure.callee.Address(), closure.callee.N())
// Create a new contract
@@ -447,6 +452,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
closure.Script, err = closure.Call(vm, nil, hook)
if err != nil {
stack.Push(ethutil.BigFalse)
+
+ // Revert the state as it was before.
+ vm.state.Revert(snapshot)
} else {
stack.Push(ethutil.BigD(addr))
@@ -472,6 +480,8 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
// Get the arguments from the memory
args := mem.Get(inOffset.Int64(), inSize.Int64())
+ snapshot := vm.state.Snapshot()
+
// Fetch the contract which will serve as the closure body
contract := vm.state.GetStateObject(addr.Bytes())
@@ -494,14 +504,14 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
if err != nil {
stack.Push(ethutil.BigFalse)
// Reset the changes applied this object
- //contract.State().Reset()
+ vm.state.Revert(snapshot)
} else {
stack.Push(ethutil.BigTrue)
- }
- vm.state.UpdateStateObject(contract)
+ vm.state.UpdateStateObject(contract)
- mem.Set(retOffset.Int64(), retSize.Int64(), ret)
+ mem.Set(retOffset.Int64(), retSize.Int64(), ret)
+ }
} else {
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
stack.Push(ethutil.BigFalse)
diff --git a/ethchain/vm_test.go b/ethchain/vm_test.go
index 2ec70536a..520f9a2ed 100644
--- a/ethchain/vm_test.go
+++ b/ethchain/vm_test.go
@@ -1,6 +1,5 @@
package ethchain
-/*
import (
_ "bytes"
"fmt"
@@ -13,60 +12,33 @@ import (
)
func TestRun4(t *testing.T) {
- ethutil.ReadConfig("", ethutil.LogStd)
+ ethutil.ReadConfig("", ethutil.LogStd, "")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
- script, err := mutan.Compile(strings.NewReader(`
- int32 a = 10
- int32 b = 20
- if a > b {
- int32 c = this.caller()
- }
- exit()
- `), false)
- tx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), script, nil)
- tx.Sign(ContractAddr)
- addr := tx.CreationAddress()
- contract := MakeContract(tx, state)
- state.UpdateStateObject(contract)
- fmt.Printf("%x\n", addr)
-
callerScript, err := mutan.Compile(strings.NewReader(`
- // Check if there's any cash in the initial store
- if this.store[1000] == 0 {
- this.store[1000] = 10**20
- }
-
-
- this.store[1001] = this.value() * 20
- this.store[this.origin()] = this.store[this.origin()] + 1000
+ this.store[this.origin()] = 10**20
+ hello := "world"
- if this.store[1001] > 20 {
- this.store[1001] = 10^50
- }
-
- int8 ret = 0
- int8 arg = 10
- call(0xe6a12555fad1fb6eaaaed69001a87313d1fd7b54, 0, 100, arg, ret)
-
- big t
- for int8 i = 0; i < 10; i++ {
- t = i
- }
+ return lambda {
+ big to = this.data[0]
+ big from = this.origin()
+ big value = this.data[1]
- if 10 > 20 {
- int8 shouldnt = 2
- } else {
- int8 should = 1
+ if this.store[from] >= value {
+ this.store[from] = this.store[from] - value
+ this.store[to] = this.store[to] + value
}
+ }
`), false)
if err != nil {
fmt.Println(err)
}
+ fmt.Println(Disassemble(callerScript))
- callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), callerScript, nil)
+ callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), callerScript)
+ callerTx.Sign([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
// Contract addr as test address
gas := big.NewInt(1000)
@@ -79,7 +51,7 @@ func TestRun4(t *testing.T) {
fmt.Println(err)
}
fmt.Println("account.Amount =", account.Amount)
- callerClosure := NewClosure(account, c, c.script, state, gas, gasPrice)
+ callerClosure := NewClosure(account, c, callerScript, state, gas, gasPrice)
vm := NewVm(state, nil, RuntimeVars{
Origin: account.Address(),
@@ -89,10 +61,10 @@ func TestRun4(t *testing.T) {
Time: 1,
Diff: big.NewInt(256),
})
- _, e = callerClosure.Call(vm, nil, nil)
+ var ret []byte
+ ret, e = callerClosure.Call(vm, nil, nil)
if e != nil {
fmt.Println("error", e)
}
- fmt.Println("account.Amount =", account.Amount)
+ fmt.Println(ret)
}
-*/
diff --git a/ethminer/miner.go b/ethminer/miner.go
index 166f7bc2f..00e04cde2 100644
--- a/ethminer/miner.go
+++ b/ethminer/miner.go
@@ -48,7 +48,7 @@ func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) Miner {
// Insert initial TXs in our little miner 'pool'
miner.txs = ethereum.TxPool().Flush()
- miner.block = ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
+ miner.block = ethereum.BlockChain().NewBlock(miner.coinbase)
return miner
}
@@ -86,7 +86,7 @@ out:
miner.txs = newtxs
// Setup a fresh state to mine on
- miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
+ //miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
} else {
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
@@ -125,7 +125,7 @@ func (self *Miner) Stop() {
func (self *Miner) mineNewBlock() {
stateManager := self.ethereum.StateManager()
- self.block = self.ethereum.BlockChain().NewBlock(self.coinbase, self.txs)
+ self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)
// Apply uncles
if len(self.uncles) > 0 {
@@ -133,15 +133,10 @@ func (self *Miner) mineNewBlock() {
}
// Accumulate all valid transaction and apply them to the new state
- var txs []*ethchain.Transaction
- for _, tx := range self.txs {
- if err := stateManager.ApplyTransaction(self.block.State(), self.block, tx); err == nil {
- txs = append(txs, tx)
- }
- }
+ receipts, txs := stateManager.ApplyTransactions(self.block.State(), self.block, self.txs)
self.txs = txs
// Set the transactions to the block so the new SHA3 can be calculated
- self.block.SetTransactions(self.txs)
+ self.block.SetReceipts(receipts, txs)
// Accumulate the rewards included for this block
stateManager.AccumelateRewards(self.block.State(), self.block)
diff --git a/ethpub/pub.go b/ethpub/pub.go
index cd002b500..b75d3abc8 100644
--- a/ethpub/pub.go
+++ b/ethpub/pub.go
@@ -87,14 +87,14 @@ func (lib *PEthereum) SecretToAddress(key string) string {
}
func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (*PReceipt, error) {
- return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr, "")
+ return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
}
-func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) (*PReceipt, error) {
- return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, initStr, bodyStr)
+func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, script string) (*PReceipt, error) {
+ return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, script)
}
-func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, initStr, scriptStr string) (*PReceipt, error) {
+func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, scriptStr string) (*PReceipt, error) {
var hash []byte
var contractCreation bool
if len(recipient) == 0 {
@@ -121,33 +121,47 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
var tx *ethchain.Transaction
// Compile and assemble the given data
if contractCreation {
- var initScript, mainScript []byte
- var err error
- if ethutil.IsHex(initStr) {
- initScript = ethutil.FromHex(initStr[2:])
- } else {
- initScript, err = ethutil.Compile(initStr)
- if err != nil {
- return nil, err
+ /*
+ var initScript, mainScript []byte
+ var err error
+ if ethutil.IsHex(initStr) {
+ initScript = ethutil.FromHex(initStr[2:])
+ } else {
+ initScript, err = ethutil.Compile(initStr)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if ethutil.IsHex(scriptStr) {
+ mainScript = ethutil.FromHex(scriptStr[2:])
+ } else {
+ mainScript, err = ethutil.Compile(scriptStr)
+ if err != nil {
+ return nil, err
+ }
}
- }
+ script := ethchain.AppendScript(initScript, mainScript)
+ */
+ var script []byte
+ var err error
if ethutil.IsHex(scriptStr) {
- mainScript = ethutil.FromHex(scriptStr[2:])
+ script = ethutil.FromHex(scriptStr)
} else {
- mainScript, err = ethutil.Compile(scriptStr)
+ script, err = ethutil.Compile(scriptStr)
if err != nil {
return nil, err
}
}
- tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
+ tx = ethchain.NewContractCreationTx(value, gas, gasPrice, script)
} else {
// Just in case it was submitted as a 0x prefixed string
- if len(initStr) > 0 && initStr[0:2] == "0x" {
- initStr = initStr[2:len(initStr)]
+ if len(scriptStr) > 0 && scriptStr[0:2] == "0x" {
+ scriptStr = scriptStr[2:len(scriptStr)]
}
- tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(initStr))
+ tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(scriptStr))
}
acc := lib.stateManager.TransState().GetStateObject(keyPair.Address())
diff --git a/ethpub/types.go b/ethpub/types.go
index 7194de372..e8a2164a7 100644
--- a/ethpub/types.go
+++ b/ethpub/types.go
@@ -31,7 +31,18 @@ func (self *PBlock) ToString() string {
return ""
}
+func (self *PBlock) GetTransaction(hash string) *PTx {
+ tx := self.ref.GetTransaction(ethutil.FromHex(hash))
+ if tx == nil {
+ return nil
+ }
+
+ return NewPTx(tx)
+}
+
type PTx struct {
+ ref *ethchain.Transaction
+
Value, Hash, Address string
Contract bool
}
@@ -41,7 +52,11 @@ func NewPTx(tx *ethchain.Transaction) *PTx {
sender := hex.EncodeToString(tx.Recipient)
isContract := len(tx.Data) > 0
- return &PTx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender, Contract: isContract}
+ return &PTx{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender, Contract: isContract}
+}
+
+func (self *PTx) ToString() string {
+ return self.ref.String()
}
type PKey struct {
diff --git a/ethrpc/packages.go b/ethrpc/packages.go
index 87cfc99b2..1c4fb99f6 100644
--- a/ethrpc/packages.go
+++ b/ethrpc/packages.go
@@ -137,7 +137,7 @@ func (p *EthereumApi) Create(args *NewTxArgs, reply *string) error {
if err != nil {
return err
}
- result, _ := p.ethp.Create(p.ethp.GetKey().PrivateKey, args.Value, args.Gas, args.GasPrice, args.Init, args.Body)
+ result, _ := p.ethp.Create(p.ethp.GetKey().PrivateKey, args.Value, args.Gas, args.GasPrice, args.Body)
*reply = NewSuccessRes(result)
return nil
}
diff --git a/ethutil/config.go b/ethutil/config.go
index 1b41c4634..40ab3aa69 100644
--- a/ethutil/config.go
+++ b/ethutil/config.go
@@ -19,6 +19,7 @@ type config struct {
Ver string
ClientString string
Pubkey []byte
+ Identifier string
}
var Config *config
@@ -26,7 +27,7 @@ var Config *config
// Read config
//
// Initialize the global Config variable with default settings
-func ReadConfig(base string, logTypes LoggerType) *config {
+func ReadConfig(base string, logTypes LoggerType, id string) *config {
if Config == nil {
usr, _ := user.Current()
path := path.Join(usr.HomeDir, base)
@@ -42,7 +43,8 @@ func ReadConfig(base string, logTypes LoggerType) *config {
}
}
- Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC8"}
+ Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC9"}
+ Config.Identifier = id
Config.Log = NewLogger(logTypes, LogLevelDebug)
Config.SetClientString("/Ethereum(G)")
}
@@ -53,7 +55,11 @@ func ReadConfig(base string, logTypes LoggerType) *config {
// Set client string
//
func (c *config) SetClientString(str string) {
- Config.ClientString = fmt.Sprintf("%s nv%s/%s", str, c.Ver, runtime.GOOS)
+ id := runtime.GOOS
+ if len(c.Identifier) > 0 {
+ id = c.Identifier
+ }
+ Config.ClientString = fmt.Sprintf("%s nv%s/%s", str, c.Ver, id)
}
type LoggerType byte
diff --git a/ethutil/trie_test.go b/ethutil/trie_test.go
index 0be512d9f..d74d129ac 100644
--- a/ethutil/trie_test.go
+++ b/ethutil/trie_test.go
@@ -1,7 +1,7 @@
package ethutil
import (
- _ "fmt"
+ "fmt"
"reflect"
"testing"
)
@@ -26,7 +26,6 @@ func (db *MemDatabase) Delete(key []byte) error {
delete(db.db, string(key))
return nil
}
-func (db *MemDatabase) GetKeys() []*Key { return nil }
func (db *MemDatabase) Print() {}
func (db *MemDatabase) Close() {}
func (db *MemDatabase) LastKnownTD() []byte { return nil }
@@ -171,3 +170,17 @@ func TestTrieIterator(t *testing.T) {
t.Errorf("Expected cached nodes to be deleted")
}
}
+
+func TestHashes(t *testing.T) {
+ _, trie := New()
+ trie.Update("cat", "dog")
+ trie.Update("ca", "dude")
+ trie.Update("doge", "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ")
+ trie.Update("dog", "test")
+ trie.Update("test", "1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ")
+ fmt.Printf("%x\n", trie.Root)
+ trie.Delete("dog")
+ fmt.Printf("%x\n", trie.Root)
+ trie.Delete("test")
+ fmt.Printf("%x\n", trie.Root)
+}
diff --git a/ethutil/value.go b/ethutil/value.go
index b7756f9b1..83600abc2 100644
--- a/ethutil/value.go
+++ b/ethutil/value.go
@@ -16,7 +16,7 @@ type Value struct {
}
func (val *Value) String() string {
- return fmt.Sprintf("%q", val.Val)
+ return fmt.Sprintf("%x", val.Val)
}
func NewValue(val interface{}) *Value {
diff --git a/peer.go b/peer.go
index 7f81489b6..7e505d680 100644
--- a/peer.go
+++ b/peer.go
@@ -18,7 +18,7 @@ const (
// The size of the output buffer for writing messages
outputBufferSize = 50
// Current protocol version
- ProtocolVersion = 12
+ ProtocolVersion = 17
)
type DiscReason byte
@@ -119,7 +119,7 @@ type Peer struct {
// this to prevent receiving false peers.
requestedPeerList bool
- host []interface{}
+ host []byte
port uint16
caps Caps
@@ -134,8 +134,7 @@ type Peer struct {
}
func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
- data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
- pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes()
+ pubkey := ethutil.GetKeyRing().Get(0).PublicKey[1:]
return &Peer{
outputQueue: make(chan *ethwire.Msg, outputBufferSize),
@@ -342,6 +341,7 @@ func (p *Peer) HandleInbound() {
if ethutil.Config.Debug {
ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash())
ethutil.Config.Log.Infof("[PEER] %v\n", err)
+ ethutil.Config.Log.Debugln(block)
}
break
} else {
@@ -437,7 +437,7 @@ func (p *Peer) HandleInbound() {
// If a parent is found send back a reply
if parent != nil {
- ethutil.Config.Log.Debugf("[PEER] Found conical block, returning chain from: %x ", parent.Hash())
+ ethutil.Config.Log.Debugf("[PEER] Found canonical block, returning chain from: %x ", parent.Hash())
chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks)
if len(chain) > 0 {
ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash())
@@ -531,11 +531,10 @@ func (p *Peer) Stop() {
}
func (p *Peer) pushHandshake() error {
- data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
- pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes()
+ pubkey := ethutil.GetKeyRing().Get(0).PublicKey
msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{
- uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey,
+ uint32(ProtocolVersion), uint32(0), p.Version, byte(p.caps), p.port, pubkey[1:],
})
p.QueueMessage(msg)
@@ -667,23 +666,24 @@ func (p *Peer) RlpData() []interface{} {
return []interface{}{p.host, p.port, p.pubkey}
}
-func packAddr(address, port string) ([]interface{}, uint16) {
+func packAddr(address, port string) ([]byte, uint16) {
addr := strings.Split(address, ".")
a, _ := strconv.Atoi(addr[0])
b, _ := strconv.Atoi(addr[1])
c, _ := strconv.Atoi(addr[2])
d, _ := strconv.Atoi(addr[3])
- host := []interface{}{int32(a), int32(b), int32(c), int32(d)}
+ host := []byte{byte(a), byte(b), byte(c), byte(d)}
prt, _ := strconv.Atoi(port)
return host, uint16(prt)
}
func unpackAddr(value *ethutil.Value, p uint64) string {
- a := strconv.Itoa(int(value.Get(0).Uint()))
- b := strconv.Itoa(int(value.Get(1).Uint()))
- c := strconv.Itoa(int(value.Get(2).Uint()))
- d := strconv.Itoa(int(value.Get(3).Uint()))
+ byts := value.Bytes()
+ a := strconv.Itoa(int(byts[0]))
+ b := strconv.Itoa(int(byts[1]))
+ c := strconv.Itoa(int(byts[2]))
+ d := strconv.Itoa(int(byts[3]))
host := strings.Join([]string{a, b, c, d}, ".")
port := strconv.Itoa(int(p))