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 Go Development package (C) Jeffrey Wilcke
|
||||||
|
|
||||||
Ethereum is currently in its testing phase. The current state is "Proof
|
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
|
Ethereum Go is split up in several sub packages Please refer to each
|
||||||
individual package for more information.
|
individual package for more information.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ethchain
|
package ethchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -55,6 +56,7 @@ type Block struct {
|
||||||
Nonce []byte
|
Nonce []byte
|
||||||
// List of transactions and/or contracts
|
// List of transactions and/or contracts
|
||||||
transactions []*Transaction
|
transactions []*Transaction
|
||||||
|
receipts []*Receipt
|
||||||
TxSha []byte
|
TxSha []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,12 +86,9 @@ func CreateBlock(root interface{},
|
||||||
base []byte,
|
base []byte,
|
||||||
Difficulty *big.Int,
|
Difficulty *big.Int,
|
||||||
Nonce []byte,
|
Nonce []byte,
|
||||||
extra string,
|
extra string) *Block {
|
||||||
txes []*Transaction) *Block {
|
|
||||||
|
|
||||||
block := &Block{
|
block := &Block{
|
||||||
// Slice of transactions to include in this block
|
|
||||||
transactions: txes,
|
|
||||||
PrevHash: prevHash,
|
PrevHash: prevHash,
|
||||||
Coinbase: base,
|
Coinbase: base,
|
||||||
Difficulty: Difficulty,
|
Difficulty: Difficulty,
|
||||||
|
@ -101,7 +100,6 @@ func CreateBlock(root interface{},
|
||||||
MinGasPrice: new(big.Int),
|
MinGasPrice: new(big.Int),
|
||||||
GasLimit: new(big.Int),
|
GasLimit: new(big.Int),
|
||||||
}
|
}
|
||||||
block.SetTransactions(txes)
|
|
||||||
block.SetUncles([]*Block{})
|
block.SetUncles([]*Block{})
|
||||||
|
|
||||||
block.state = NewState(ethutil.NewTrie(ethutil.Config.Db, root))
|
block.state = NewState(ethutil.NewTrie(ethutil.Config.Db, root))
|
||||||
|
@ -115,7 +113,10 @@ func (block *Block) Hash() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) HashNoNonce() []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 {
|
func (block *Block) State() *State {
|
||||||
|
@ -161,6 +162,16 @@ func (block *Block) BlockInfo() BlockInfo {
|
||||||
return bi
|
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
|
// Sync the block's state and contract respectively
|
||||||
func (block *Block) Sync() {
|
func (block *Block) Sync() {
|
||||||
block.state.Sync()
|
block.state.Sync()
|
||||||
|
@ -172,15 +183,15 @@ func (block *Block) Undo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/////// Block Encoding
|
/////// Block Encoding
|
||||||
func (block *Block) rlpTxs() interface{} {
|
func (block *Block) rlpReceipts() interface{} {
|
||||||
// Marshal the transactions of this block
|
// Marshal the transactions of this block
|
||||||
encTx := make([]interface{}, len(block.transactions))
|
encR := make([]interface{}, len(block.receipts))
|
||||||
for i, tx := range block.transactions {
|
for i, r := range block.receipts {
|
||||||
// Cast it to a string (safe)
|
// Cast it to a string (safe)
|
||||||
encTx[i] = tx.RlpData()
|
encR[i] = r.RlpData()
|
||||||
}
|
}
|
||||||
|
|
||||||
return encTx
|
return encR
|
||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) rlpUncles() interface{} {
|
func (block *Block) rlpUncles() interface{} {
|
||||||
|
@ -201,7 +212,12 @@ func (block *Block) SetUncles(uncles []*Block) {
|
||||||
block.UncleSha = ethutil.Sha3Bin(ethutil.Encode(block.rlpUncles()))
|
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
|
block.transactions = txs
|
||||||
|
|
||||||
trie := ethutil.NewTrie(ethutil.Config.Db, "")
|
trie := ethutil.NewTrie(ethutil.Config.Db, "")
|
||||||
|
@ -221,7 +237,7 @@ func (block *Block) SetTransactions(txs []*Transaction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (block *Block) Value() *ethutil.Value {
|
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 {
|
func (block *Block) RlpEncode() []byte {
|
||||||
|
@ -245,6 +261,7 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
|
||||||
block.TxSha = header.Get(4).Bytes()
|
block.TxSha = header.Get(4).Bytes()
|
||||||
block.Difficulty = header.Get(5).BigInt()
|
block.Difficulty = header.Get(5).BigInt()
|
||||||
block.Number = header.Get(6).BigInt()
|
block.Number = header.Get(6).BigInt()
|
||||||
|
//fmt.Printf("#%v : %x\n", block.Number, block.Coinbase)
|
||||||
block.MinGasPrice = header.Get(7).BigInt()
|
block.MinGasPrice = header.Get(7).BigInt()
|
||||||
block.GasLimit = header.Get(8).BigInt()
|
block.GasLimit = header.Get(8).BigInt()
|
||||||
block.GasUsed = header.Get(9).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
|
// Tx list might be empty if this is an uncle. Uncles only have their
|
||||||
// header set.
|
// header set.
|
||||||
if decoder.Get(1).IsNil() == false { // Yes explicitness
|
if decoder.Get(1).IsNil() == false { // Yes explicitness
|
||||||
txes := decoder.Get(1)
|
receipts := decoder.Get(1)
|
||||||
block.transactions = make([]*Transaction, txes.Len())
|
block.transactions = make([]*Transaction, receipts.Len())
|
||||||
for i := 0; i < txes.Len(); i++ {
|
block.receipts = make([]*Receipt, receipts.Len())
|
||||||
tx := NewTransactionFromValue(txes.Get(i))
|
for i := 0; i < receipts.Len(); i++ {
|
||||||
|
receipt := NewRecieptFromValue(receipts.Get(i))
|
||||||
block.transactions[i] = tx
|
block.transactions[i] = receipt.Tx
|
||||||
|
block.receipts[i] = receipt
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -299,6 +317,10 @@ func (block *Block) GetRoot() interface{} {
|
||||||
return block.state.trie.Root
|
return block.state.trie.Root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Block) Receipts() []*Receipt {
|
||||||
|
return self.receipts
|
||||||
|
}
|
||||||
|
|
||||||
func (block *Block) header() []interface{} {
|
func (block *Block) header() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
// Sha of the previous block
|
// Sha of the previous block
|
||||||
|
@ -346,6 +368,7 @@ func (block *Block) String() string {
|
||||||
Time: %v
|
Time: %v
|
||||||
Extra: %v
|
Extra: %v
|
||||||
Nonce: %x
|
Nonce: %x
|
||||||
|
NumTx: %v
|
||||||
`,
|
`,
|
||||||
block.Hash(),
|
block.Hash(),
|
||||||
block.PrevHash,
|
block.PrevHash,
|
||||||
|
@ -360,5 +383,7 @@ func (block *Block) String() string {
|
||||||
block.GasUsed,
|
block.GasUsed,
|
||||||
block.Time,
|
block.Time,
|
||||||
block.Extra,
|
block.Extra,
|
||||||
block.Nonce)
|
block.Nonce,
|
||||||
|
len(block.transactions),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (bc *BlockChain) Genesis() *Block {
|
||||||
return bc.genesisBlock
|
return bc.genesisBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block {
|
func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
|
||||||
var root interface{}
|
var root interface{}
|
||||||
var lastBlockTime int64
|
var lastBlockTime int64
|
||||||
hash := ZeroHash256
|
hash := ZeroHash256
|
||||||
|
@ -53,8 +53,7 @@ func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block {
|
||||||
coinbase,
|
coinbase,
|
||||||
ethutil.BigPow(2, 32),
|
ethutil.BigPow(2, 32),
|
||||||
nil,
|
nil,
|
||||||
"",
|
"")
|
||||||
txs)
|
|
||||||
|
|
||||||
if bc.CurrentBlock != nil {
|
if bc.CurrentBlock != nil {
|
||||||
var mul *big.Int
|
var mul *big.Int
|
||||||
|
@ -272,16 +271,18 @@ func (bc *BlockChain) GetChain(hash []byte, amount int) []*Block {
|
||||||
|
|
||||||
func AddTestNetFunds(block *Block) {
|
func AddTestNetFunds(block *Block) {
|
||||||
for _, addr := range []string{
|
for _, addr := range []string{
|
||||||
"8a40bfaa73256b60764c1bf40675a99083efb075", // Gavin
|
"8a40bfaa73256b60764c1bf40675a99083efb075",
|
||||||
"e6716f9544a56c530d868e4bfbacb172315bdead", // Jeffrey
|
"e4157b34ea9615cfbde6b4fda419828124b70c78",
|
||||||
"1e12515ce3e0f817a4ddef9ca55788a1d66bd2df", // Vit
|
"1e12515ce3e0f817a4ddef9ca55788a1d66bd2df",
|
||||||
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // Alex
|
"6c386a4b26f73c802f34673f7248bb118f97424a",
|
||||||
"2ef47100e0787b915105fd5e3f4ff6752079d5cb", // Maran
|
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826", // Roman
|
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
|
||||||
|
"e6716f9544a56c530d868e4bfbacb172315bdead",
|
||||||
|
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
|
||||||
} {
|
} {
|
||||||
codedAddr := ethutil.FromHex(addr)
|
codedAddr := ethutil.FromHex(addr)
|
||||||
account := block.state.GetAccount(codedAddr)
|
account := block.state.GetAccount(codedAddr)
|
||||||
account.Amount = ethutil.BigPow(2, 200)
|
account.Amount = ethutil.Big("1606938044258990275541962092341162602522202993782792835301376") //ethutil.BigPow(2, 200)
|
||||||
block.state.UpdateStateObject(account)
|
block.state.UpdateStateObject(account)
|
||||||
}
|
}
|
||||||
log.Printf("%x\n", block.RlpEncode())
|
log.Printf("%x\n", block.RlpEncode())
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (tm *TestManager) Broadcast(msgType ethwire.MsgType, data []interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestManager() *TestManager {
|
func NewTestManager() *TestManager {
|
||||||
ethutil.ReadConfig(".ethtest", ethutil.LogStd)
|
ethutil.ReadConfig(".ethtest", ethutil.LogStd, "")
|
||||||
|
|
||||||
db, err := ethdb.NewMemDatabase()
|
db, err := ethdb.NewMemDatabase()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -74,7 +74,7 @@ func NewTestManager() *TestManager {
|
||||||
func (tm *TestManager) AddFakeBlock(blk []byte) error {
|
func (tm *TestManager) AddFakeBlock(blk []byte) error {
|
||||||
block := NewBlockFromBytes(blk)
|
block := NewBlockFromBytes(blk)
|
||||||
tm.Blocks = append(tm.Blocks, block)
|
tm.Blocks = append(tm.Blocks, block)
|
||||||
err := tm.StateManager().ProcessBlock(tm.StateManager().CurrentState(), block, false)
|
err := tm.StateManager().Process(block, false)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func (tm *TestManager) CreateChain1() error {
|
func (tm *TestManager) CreateChain1() error {
|
||||||
|
|
|
@ -23,7 +23,7 @@ var GenesisHeader = []interface{}{
|
||||||
// Root state
|
// Root state
|
||||||
"",
|
"",
|
||||||
// tx sha
|
// tx sha
|
||||||
ZeroHash256,
|
"",
|
||||||
// Difficulty
|
// Difficulty
|
||||||
ethutil.BigPow(2, 22),
|
ethutil.BigPow(2, 22),
|
||||||
// Number
|
// Number
|
||||||
|
|
|
@ -99,7 +99,21 @@ func (s *State) Cmp(other *State) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) Copy() *State {
|
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) {
|
func (s *State) Put(key, object []byte) {
|
||||||
|
|
|
@ -84,7 +84,7 @@ func (sm *StateManager) BlockChain() *BlockChain {
|
||||||
return sm.bc
|
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)
|
contract := MakeContract(tx, state)
|
||||||
if contract != nil {
|
if contract != nil {
|
||||||
state.states[string(tx.CreationAddress())] = contract.state
|
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
|
// Apply transactions uses the transaction passed to it and applies them onto
|
||||||
// the current processing state.
|
// 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
|
// Process each transaction/contract
|
||||||
|
var receipts []*Receipt
|
||||||
|
var validTxs []*Transaction
|
||||||
|
totalUsedGas := big.NewInt(0)
|
||||||
for _, tx := range txs {
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) error {
|
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, usedGas))
|
||||||
// If there's no recipient, it's a contract
|
receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
|
||||||
// Check if this is a contract creation traction and if so
|
|
||||||
// create a contract of this tx.
|
receipts = append(receipts, receipt)
|
||||||
if tx.IsContract() {
|
validTxs = append(validTxs, tx)
|
||||||
err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
|
}
|
||||||
|
|
||||||
|
return receipts, txs
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
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 {
|
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 {
|
} else {
|
||||||
return fmt.Errorf("[STATE] Unable to create contract")
|
return nil, fmt.Errorf("[STATE] Unable to create contract")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("[STATE] contract create:", err)
|
return nil, fmt.Errorf("[STATE] contract creation tx:", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false)
|
// Find the state object at the "recipient" address. If
|
||||||
contract := state.GetStateObject(tx.Recipient)
|
// there's an object attempt to run the script.
|
||||||
if err == nil && contract != nil && len(contract.Script()) > 0 {
|
stateObject := state.GetStateObject(tx.Recipient)
|
||||||
sm.EvalScript(state, contract.Script(), contract, tx, block)
|
if err == nil && stateObject != nil && len(stateObject.Script()) > 0 {
|
||||||
|
sm.EvalScript(state, stateObject.Script(), stateObject, tx, block)
|
||||||
} else if err != nil {
|
} 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 {
|
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++ {
|
for i := 0; i < uncleLength; i++ {
|
||||||
base.Add(base, UncleInclusionReward)
|
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)
|
return base.Add(base, BlockReward)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,10 +349,10 @@ func (sm *StateManager) Stop() {
|
||||||
sm.bc.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())
|
account := state.GetAccount(tx.Sender())
|
||||||
|
|
||||||
err := account.ConvertGas(tx.Gas, tx.GasPrice)
|
err = account.ConvertGas(tx.Gas, tx.GasPrice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ethutil.Config.Log.Debugln(err)
|
ethutil.Config.Log.Debugln(err)
|
||||||
return
|
return
|
||||||
|
@ -327,11 +369,13 @@ func (sm *StateManager) EvalScript(state *State, script []byte, object *StateObj
|
||||||
Value: tx.Value,
|
Value: tx.Value,
|
||||||
//Price: tx.GasPrice,
|
//Price: tx.GasPrice,
|
||||||
})
|
})
|
||||||
closure.Call(vm, tx.Data, nil)
|
ret, err = closure.Call(vm, tx.Data, nil)
|
||||||
|
|
||||||
// Update the account (refunds)
|
// Update the account (refunds)
|
||||||
state.UpdateStateObject(account)
|
state.UpdateStateObject(account)
|
||||||
state.UpdateStateObject(object)
|
state.UpdateStateObject(object)
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) notifyChanges(state *State) {
|
func (sm *StateManager) notifyChanges(state *State) {
|
||||||
|
|
|
@ -28,8 +28,7 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
|
||||||
value := tx.Value
|
value := tx.Value
|
||||||
contract := NewContract(addr, value, ZeroHash256)
|
contract := NewContract(addr, value, ZeroHash256)
|
||||||
|
|
||||||
contract.script = tx.Data
|
contract.initScript = tx.Data
|
||||||
contract.initScript = tx.Init
|
|
||||||
|
|
||||||
state.UpdateStateObject(contract)
|
state.UpdateStateObject(contract)
|
||||||
|
|
||||||
|
@ -82,12 +81,17 @@ func (c *StateObject) SetStorage(num *big.Int, val *ethutil.Value) {
|
||||||
c.SetAddr(addr, val)
|
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)
|
nb := ethutil.BigToBytes(num, 256)
|
||||||
|
|
||||||
return c.Addr(nb)
|
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 {
|
func (c *StateObject) GetInstr(pc *big.Int) *ethutil.Value {
|
||||||
if int64(len(c.script)-1) < pc.Int64() {
|
if int64(len(c.script)-1) < pc.Int64() {
|
||||||
return ethutil.NewValue(0)
|
return ethutil.NewValue(0)
|
||||||
|
@ -146,7 +150,7 @@ func (c *StateObject) RlpEncode() []byte {
|
||||||
if c.state != nil {
|
if c.state != nil {
|
||||||
root = c.state.trie.Root
|
root = c.state.trie.Root
|
||||||
} else {
|
} else {
|
||||||
root = ZeroHash256
|
root = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, ethutil.Sha3Bin(c.script)})
|
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, ethutil.Sha3Bin(c.script)})
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSync(t *testing.T) {
|
func TestSync(t *testing.T) {
|
||||||
ethutil.ReadConfig("", ethutil.LogStd)
|
ethutil.ReadConfig("", ethutil.LogStd, "")
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
state := NewState(ethutil.NewTrie(db, ""))
|
state := NewState(ethutil.NewTrie(db, ""))
|
||||||
|
@ -28,7 +28,7 @@ func TestSync(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectGet(t *testing.T) {
|
func TestObjectGet(t *testing.T) {
|
||||||
ethutil.ReadConfig("", ethutil.LogStd)
|
ethutil.ReadConfig("", ethutil.LogStd, "")
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
ethutil.Config.Db = db
|
ethutil.Config.Db = db
|
||||||
|
|
|
@ -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
|
package ethchain
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/obscuren/secp256k1-go"
|
"github.com/obscuren/secp256k1-go"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -15,7 +16,6 @@ type Transaction struct {
|
||||||
Gas *big.Int
|
Gas *big.Int
|
||||||
GasPrice *big.Int
|
GasPrice *big.Int
|
||||||
Data []byte
|
Data []byte
|
||||||
Init []byte
|
|
||||||
v byte
|
v byte
|
||||||
r, s []byte
|
r, s []byte
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ type Transaction struct {
|
||||||
contractCreation bool
|
contractCreation bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte, init []byte) *Transaction {
|
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
|
||||||
return &Transaction{Value: value, Gas: gas, GasPrice: gasPrice, Data: script, Init: init, contractCreation: true}
|
return &Transaction{Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
|
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 {
|
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 {
|
if tx.contractCreation {
|
||||||
data = append(data, tx.Init)
|
data = append(data, tx.Init)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return ethutil.Sha3Bin(ethutil.NewValue(data).Encode())
|
return ethutil.Sha3Bin(ethutil.NewValue(data).Encode())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) IsContract() bool {
|
func (tx *Transaction) CreatesContract() bool {
|
||||||
return tx.contractCreation
|
return tx.contractCreation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Depricated */
|
||||||
|
func (tx *Transaction) IsContract() bool {
|
||||||
|
return tx.CreatesContract()
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *Transaction) CreationAddress() []byte {
|
func (tx *Transaction) CreationAddress() []byte {
|
||||||
return ethutil.Sha3Bin(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:]
|
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{} {
|
func (tx *Transaction) RlpData() interface{} {
|
||||||
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, 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 append(data, tx.v, tx.r, tx.s)
|
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.Recipient = decoder.Get(3).Bytes()
|
||||||
tx.Value = decoder.Get(4).BigInt()
|
tx.Value = decoder.Get(4).BigInt()
|
||||||
tx.Data = decoder.Get(5).Bytes()
|
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 the list is of length 10 it's a contract creation tx
|
||||||
if decoder.Len() == 10 {
|
if decoder.Len() == 10 {
|
||||||
tx.contractCreation = true
|
tx.contractCreation = true
|
||||||
|
@ -152,4 +162,69 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
||||||
tx.r = decoder.Get(7).Bytes()
|
tx.r = decoder.Get(7).Bytes()
|
||||||
tx.s = decoder.Get(8).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
|
// Process transaction validates the Tx and processes funds from the
|
||||||
// sender to the recipient.
|
// 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() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
log.Println(r)
|
ethutil.Config.Log.Infoln(r)
|
||||||
err = fmt.Errorf("%v", r)
|
err = fmt.Errorf("%v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Get the sender
|
// Get the sender
|
||||||
sender := block.state.GetAccount(tx.Sender())
|
sender := state.GetAccount(tx.Sender())
|
||||||
|
|
||||||
if sender.Nonce != tx.Nonce {
|
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)
|
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
|
// Make sure there's enough in the sender's account. Having insufficient
|
||||||
// funds won't invalidate this transaction but simple ignores it.
|
// 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 {
|
if sender.Amount.Cmp(totAmount) < 0 {
|
||||||
return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender())
|
return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender())
|
||||||
}
|
}
|
||||||
|
//fmt.Println(tx)
|
||||||
|
|
||||||
// Get the receiver
|
// Get the receiver
|
||||||
receiver := block.state.GetAccount(tx.Recipient)
|
receiver := state.GetAccount(tx.Recipient)
|
||||||
sender.Nonce += 1
|
sender.Nonce += 1
|
||||||
|
|
||||||
// Send Tx to self
|
// Send Tx to self
|
||||||
if bytes.Compare(tx.Recipient, tx.Sender()) == 0 {
|
if bytes.Compare(tx.Recipient, tx.Sender()) == 0 {
|
||||||
// Subtract the fee
|
// Subtract the fee
|
||||||
sender.SubAmount(new(big.Int).Mul(TxFee, TxFeeRat))
|
sender.SubAmount(new(big.Int).Mul(GasTx, tx.GasPrice))
|
||||||
} else {
|
} else {
|
||||||
// Subtract the amount from the senders account
|
// Subtract the amount from the senders account
|
||||||
sender.SubAmount(totAmount)
|
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
|
// Add the amount to receivers account which should conclude this transaction
|
||||||
receiver.AddAmount(tx.Value)
|
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())
|
ethutil.Config.Log.Infof("[TXPL] Processed Tx %x\n", tx.Hash())
|
||||||
|
|
||||||
|
|
|
@ -322,3 +322,10 @@ func IsOpCode(s string) bool {
|
||||||
}
|
}
|
||||||
return false
|
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)
|
GasCreate = big.NewInt(100)
|
||||||
GasCall = big.NewInt(20)
|
GasCall = big.NewInt(20)
|
||||||
GasMemory = big.NewInt(1)
|
GasMemory = big.NewInt(1)
|
||||||
|
GasTx = big.NewInt(500)
|
||||||
)
|
)
|
||||||
|
|
||||||
func CalculateTxGas(initSize, scriptSize *big.Int) *big.Int {
|
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()
|
value := stack.Pop()
|
||||||
size, offset := stack.Popn()
|
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
|
// Generate a new address
|
||||||
addr := ethutil.CreateAddress(closure.callee.Address(), closure.callee.N())
|
addr := ethutil.CreateAddress(closure.callee.Address(), closure.callee.N())
|
||||||
// Create a new contract
|
// 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)
|
closure.Script, err = closure.Call(vm, nil, hook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
|
||||||
|
// Revert the state as it was before.
|
||||||
|
vm.state.Revert(snapshot)
|
||||||
} else {
|
} else {
|
||||||
stack.Push(ethutil.BigD(addr))
|
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
|
// Get the arguments from the memory
|
||||||
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
args := mem.Get(inOffset.Int64(), inSize.Int64())
|
||||||
|
|
||||||
|
snapshot := vm.state.Snapshot()
|
||||||
|
|
||||||
// Fetch the contract which will serve as the closure body
|
// Fetch the contract which will serve as the closure body
|
||||||
contract := vm.state.GetStateObject(addr.Bytes())
|
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 {
|
if err != nil {
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
// Reset the changes applied this object
|
// Reset the changes applied this object
|
||||||
//contract.State().Reset()
|
vm.state.Revert(snapshot)
|
||||||
} else {
|
} else {
|
||||||
stack.Push(ethutil.BigTrue)
|
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 {
|
} else {
|
||||||
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
|
ethutil.Config.Log.Debugf("Contract %x not found\n", addr.Bytes())
|
||||||
stack.Push(ethutil.BigFalse)
|
stack.Push(ethutil.BigFalse)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package ethchain
|
package ethchain
|
||||||
|
|
||||||
/*
|
|
||||||
import (
|
import (
|
||||||
_ "bytes"
|
_ "bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -13,60 +12,33 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRun4(t *testing.T) {
|
func TestRun4(t *testing.T) {
|
||||||
ethutil.ReadConfig("", ethutil.LogStd)
|
ethutil.ReadConfig("", ethutil.LogStd, "")
|
||||||
|
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
state := NewState(ethutil.NewTrie(db, ""))
|
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(`
|
callerScript, err := mutan.Compile(strings.NewReader(`
|
||||||
// Check if there's any cash in the initial store
|
this.store[this.origin()] = 10**20
|
||||||
if this.store[1000] == 0 {
|
hello := "world"
|
||||||
this.store[1000] = 10**20
|
|
||||||
|
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)
|
`), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
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
|
// Contract addr as test address
|
||||||
gas := big.NewInt(1000)
|
gas := big.NewInt(1000)
|
||||||
|
@ -79,7 +51,7 @@ func TestRun4(t *testing.T) {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
fmt.Println("account.Amount =", account.Amount)
|
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{
|
vm := NewVm(state, nil, RuntimeVars{
|
||||||
Origin: account.Address(),
|
Origin: account.Address(),
|
||||||
|
@ -89,10 +61,10 @@ func TestRun4(t *testing.T) {
|
||||||
Time: 1,
|
Time: 1,
|
||||||
Diff: big.NewInt(256),
|
Diff: big.NewInt(256),
|
||||||
})
|
})
|
||||||
_, e = callerClosure.Call(vm, nil, nil)
|
var ret []byte
|
||||||
|
ret, e = callerClosure.Call(vm, nil, nil)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
fmt.Println("error", e)
|
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'
|
// Insert initial TXs in our little miner 'pool'
|
||||||
miner.txs = ethereum.TxPool().Flush()
|
miner.txs = ethereum.TxPool().Flush()
|
||||||
miner.block = ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
|
miner.block = ethereum.BlockChain().NewBlock(miner.coinbase)
|
||||||
|
|
||||||
return miner
|
return miner
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ out:
|
||||||
miner.txs = newtxs
|
miner.txs = newtxs
|
||||||
|
|
||||||
// Setup a fresh state to mine on
|
// 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 {
|
} else {
|
||||||
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
|
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
|
||||||
|
@ -125,7 +125,7 @@ func (self *Miner) Stop() {
|
||||||
func (self *Miner) mineNewBlock() {
|
func (self *Miner) mineNewBlock() {
|
||||||
stateManager := self.ethereum.StateManager()
|
stateManager := self.ethereum.StateManager()
|
||||||
|
|
||||||
self.block = self.ethereum.BlockChain().NewBlock(self.coinbase, self.txs)
|
self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)
|
||||||
|
|
||||||
// Apply uncles
|
// Apply uncles
|
||||||
if len(self.uncles) > 0 {
|
if len(self.uncles) > 0 {
|
||||||
|
@ -133,15 +133,10 @@ func (self *Miner) mineNewBlock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate all valid transaction and apply them to the new state
|
// Accumulate all valid transaction and apply them to the new state
|
||||||
var txs []*ethchain.Transaction
|
receipts, txs := stateManager.ApplyTransactions(self.block.State(), self.block, self.txs)
|
||||||
for _, tx := range self.txs {
|
|
||||||
if err := stateManager.ApplyTransaction(self.block.State(), self.block, tx); err == nil {
|
|
||||||
txs = append(txs, tx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.txs = txs
|
self.txs = txs
|
||||||
// Set the transactions to the block so the new SHA3 can be calculated
|
// 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
|
// Accumulate the rewards included for this block
|
||||||
stateManager.AccumelateRewards(self.block.State(), self.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) {
|
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) {
|
func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, script string) (*PReceipt, error) {
|
||||||
return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, initStr, bodyStr)
|
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 hash []byte
|
||||||
var contractCreation bool
|
var contractCreation bool
|
||||||
if len(recipient) == 0 {
|
if len(recipient) == 0 {
|
||||||
|
@ -121,6 +121,7 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
|
||||||
var tx *ethchain.Transaction
|
var tx *ethchain.Transaction
|
||||||
// Compile and assemble the given data
|
// Compile and assemble the given data
|
||||||
if contractCreation {
|
if contractCreation {
|
||||||
|
/*
|
||||||
var initScript, mainScript []byte
|
var initScript, mainScript []byte
|
||||||
var err error
|
var err error
|
||||||
if ethutil.IsHex(initStr) {
|
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 {
|
} else {
|
||||||
// Just in case it was submitted as a 0x prefixed string
|
// Just in case it was submitted as a 0x prefixed string
|
||||||
if len(initStr) > 0 && initStr[0:2] == "0x" {
|
if len(scriptStr) > 0 && scriptStr[0:2] == "0x" {
|
||||||
initStr = initStr[2:len(initStr)]
|
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())
|
acc := lib.stateManager.TransState().GetStateObject(keyPair.Address())
|
||||||
|
|
|
@ -31,7 +31,18 @@ func (self *PBlock) ToString() string {
|
||||||
return ""
|
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 {
|
type PTx struct {
|
||||||
|
ref *ethchain.Transaction
|
||||||
|
|
||||||
Value, Hash, Address string
|
Value, Hash, Address string
|
||||||
Contract bool
|
Contract bool
|
||||||
}
|
}
|
||||||
|
@ -41,7 +52,11 @@ func NewPTx(tx *ethchain.Transaction) *PTx {
|
||||||
sender := hex.EncodeToString(tx.Recipient)
|
sender := hex.EncodeToString(tx.Recipient)
|
||||||
isContract := len(tx.Data) > 0
|
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 {
|
type PKey struct {
|
||||||
|
|
|
@ -137,7 +137,7 @@ func (p *EthereumApi) Create(args *NewTxArgs, reply *string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
*reply = NewSuccessRes(result)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ type config struct {
|
||||||
Ver string
|
Ver string
|
||||||
ClientString string
|
ClientString string
|
||||||
Pubkey []byte
|
Pubkey []byte
|
||||||
|
Identifier string
|
||||||
}
|
}
|
||||||
|
|
||||||
var Config *config
|
var Config *config
|
||||||
|
@ -26,7 +27,7 @@ var Config *config
|
||||||
// Read config
|
// Read config
|
||||||
//
|
//
|
||||||
// Initialize the global Config variable with default settings
|
// 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 {
|
if Config == nil {
|
||||||
usr, _ := user.Current()
|
usr, _ := user.Current()
|
||||||
path := path.Join(usr.HomeDir, base)
|
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.Log = NewLogger(logTypes, LogLevelDebug)
|
||||||
Config.SetClientString("/Ethereum(G)")
|
Config.SetClientString("/Ethereum(G)")
|
||||||
}
|
}
|
||||||
|
@ -53,7 +55,11 @@ func ReadConfig(base string, logTypes LoggerType) *config {
|
||||||
// Set client string
|
// Set client string
|
||||||
//
|
//
|
||||||
func (c *config) SetClientString(str 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
|
type LoggerType byte
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package ethutil
|
package ethutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,6 @@ func (db *MemDatabase) Delete(key []byte) error {
|
||||||
delete(db.db, string(key))
|
delete(db.db, string(key))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (db *MemDatabase) GetKeys() []*Key { return nil }
|
|
||||||
func (db *MemDatabase) Print() {}
|
func (db *MemDatabase) Print() {}
|
||||||
func (db *MemDatabase) Close() {}
|
func (db *MemDatabase) Close() {}
|
||||||
func (db *MemDatabase) LastKnownTD() []byte { return nil }
|
func (db *MemDatabase) LastKnownTD() []byte { return nil }
|
||||||
|
@ -171,3 +170,17 @@ func TestTrieIterator(t *testing.T) {
|
||||||
t.Errorf("Expected cached nodes to be deleted")
|
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 {
|
func (val *Value) String() string {
|
||||||
return fmt.Sprintf("%q", val.Val)
|
return fmt.Sprintf("%x", val.Val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewValue(val interface{}) *Value {
|
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
|
// The size of the output buffer for writing messages
|
||||||
outputBufferSize = 50
|
outputBufferSize = 50
|
||||||
// Current protocol version
|
// Current protocol version
|
||||||
ProtocolVersion = 12
|
ProtocolVersion = 17
|
||||||
)
|
)
|
||||||
|
|
||||||
type DiscReason byte
|
type DiscReason byte
|
||||||
|
@ -119,7 +119,7 @@ type Peer struct {
|
||||||
// this to prevent receiving false peers.
|
// this to prevent receiving false peers.
|
||||||
requestedPeerList bool
|
requestedPeerList bool
|
||||||
|
|
||||||
host []interface{}
|
host []byte
|
||||||
port uint16
|
port uint16
|
||||||
caps Caps
|
caps Caps
|
||||||
|
|
||||||
|
@ -134,8 +134,7 @@ type Peer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
|
func NewPeer(conn net.Conn, ethereum *Ethereum, inbound bool) *Peer {
|
||||||
data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
|
pubkey := ethutil.GetKeyRing().Get(0).PublicKey[1:]
|
||||||
pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes()
|
|
||||||
|
|
||||||
return &Peer{
|
return &Peer{
|
||||||
outputQueue: make(chan *ethwire.Msg, outputBufferSize),
|
outputQueue: make(chan *ethwire.Msg, outputBufferSize),
|
||||||
|
@ -342,6 +341,7 @@ func (p *Peer) HandleInbound() {
|
||||||
if ethutil.Config.Debug {
|
if ethutil.Config.Debug {
|
||||||
ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash())
|
ethutil.Config.Log.Infof("[PEER] Block %x failed\n", block.Hash())
|
||||||
ethutil.Config.Log.Infof("[PEER] %v\n", err)
|
ethutil.Config.Log.Infof("[PEER] %v\n", err)
|
||||||
|
ethutil.Config.Log.Debugln(block)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
|
@ -437,7 +437,7 @@ func (p *Peer) HandleInbound() {
|
||||||
|
|
||||||
// If a parent is found send back a reply
|
// If a parent is found send back a reply
|
||||||
if parent != nil {
|
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)
|
chain := p.ethereum.BlockChain().GetChainFromHash(parent.Hash(), amountOfBlocks)
|
||||||
if len(chain) > 0 {
|
if len(chain) > 0 {
|
||||||
ethutil.Config.Log.Debugf("[PEER] Returning %d blocks: %x ", len(chain), parent.Hash())
|
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 {
|
func (p *Peer) pushHandshake() error {
|
||||||
data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
|
pubkey := ethutil.GetKeyRing().Get(0).PublicKey
|
||||||
pubkey := ethutil.NewValueFromBytes(data).Get(2).Bytes()
|
|
||||||
|
|
||||||
msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{
|
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)
|
p.QueueMessage(msg)
|
||||||
|
@ -667,23 +666,24 @@ func (p *Peer) RlpData() []interface{} {
|
||||||
return []interface{}{p.host, p.port, p.pubkey}
|
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, ".")
|
addr := strings.Split(address, ".")
|
||||||
a, _ := strconv.Atoi(addr[0])
|
a, _ := strconv.Atoi(addr[0])
|
||||||
b, _ := strconv.Atoi(addr[1])
|
b, _ := strconv.Atoi(addr[1])
|
||||||
c, _ := strconv.Atoi(addr[2])
|
c, _ := strconv.Atoi(addr[2])
|
||||||
d, _ := strconv.Atoi(addr[3])
|
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)
|
prt, _ := strconv.Atoi(port)
|
||||||
|
|
||||||
return host, uint16(prt)
|
return host, uint16(prt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackAddr(value *ethutil.Value, p uint64) string {
|
func unpackAddr(value *ethutil.Value, p uint64) string {
|
||||||
a := strconv.Itoa(int(value.Get(0).Uint()))
|
byts := value.Bytes()
|
||||||
b := strconv.Itoa(int(value.Get(1).Uint()))
|
a := strconv.Itoa(int(byts[0]))
|
||||||
c := strconv.Itoa(int(value.Get(2).Uint()))
|
b := strconv.Itoa(int(byts[1]))
|
||||||
d := strconv.Itoa(int(value.Get(3).Uint()))
|
c := strconv.Itoa(int(byts[2]))
|
||||||
|
d := strconv.Itoa(int(byts[3]))
|
||||||
host := strings.Join([]string{a, b, c, d}, ".")
|
host := strings.Join([]string{a, b, c, d}, ".")
|
||||||
port := strconv.Itoa(int(p))
|
port := strconv.Itoa(int(p))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue