Merge branch 'release/poc5-rc9'
This commit is contained in:
commit
b1463b2dc2
@ -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.
|
||||
|
@ -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,12 +86,9 @@ 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,
|
||||
@ -101,7 +100,6 @@ func CreateBlock(root interface{},
|
||||
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),
|
||||
)
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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 {
|
||||
|
@ -23,7 +23,7 @@ var GenesisHeader = []interface{}{
|
||||
// Root state
|
||||
"",
|
||||
// tx sha
|
||||
ZeroHash256,
|
||||
"",
|
||||
// Difficulty
|
||||
ethutil.BigPow(2, 22),
|
||||
// Number
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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)})
|
||||
|
@ -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
|
||||
|
31
ethchain/state_test.go
Normal file
31
ethchain/state_test.go
Normal file
@ -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")
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
*/
|
||||
|
||||
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,7 +141,14 @@ 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()
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
// If the list is of length 10 it's a contract creation tx
|
||||
if decoder.Len() == 10 {
|
||||
tx.contractCreation = true
|
||||
@ -152,4 +162,69 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
||||
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)
|
||||
}
|
||||
|
@ -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())
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
|
||||
}
|
||||
} else {
|
||||
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
|
||||
stack.Push(ethutil.BigFalse)
|
||||
|
@ -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[this.origin()] = 10**20
|
||||
hello := "world"
|
||||
|
||||
return lambda {
|
||||
big to = this.data[0]
|
||||
big from = this.origin()
|
||||
big value = this.data[1]
|
||||
|
||||
if this.store[from] >= value {
|
||||
this.store[from] = this.store[from] - value
|
||||
this.store[to] = this.store[to] + value
|
||||
}
|
||||
|
||||
|
||||
this.store[1001] = this.value() * 20
|
||||
this.store[this.origin()] = this.store[this.origin()] + 1000
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if 10 > 20 {
|
||||
int8 shouldnt = 2
|
||||
} else {
|
||||
int8 should = 1
|
||||
}
|
||||
`), 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)
|
||||
}
|
||||
*/
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,6 +121,7 @@ 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) {
|
||||
@ -141,13 +142,26 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
|
||||
}
|
||||
}
|
||||
|
||||
tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
|
||||
script := ethchain.AppendScript(initScript, mainScript)
|
||||
*/
|
||||
var script []byte
|
||||
var err error
|
||||
if ethutil.IsHex(scriptStr) {
|
||||
script = ethutil.FromHex(scriptStr)
|
||||
} else {
|
||||
script, err = ethutil.Compile(scriptStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
28
peer.go
28
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))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user