Merge conflicts

This commit is contained in:
Maran 2014-04-01 14:20:55 +02:00
commit 0a88010826
14 changed files with 234 additions and 182 deletions

View File

@ -34,6 +34,7 @@ func (k *KeyPair) Account() *Account {
// Create transaction, creates a new and signed transaction, ready for processing
func (k *KeyPair) CreateTx(receiver []byte, value *big.Int, data []string) *Transaction {
/* TODO
tx := NewTransaction(receiver, value, data)
tx.Nonce = k.account.Nonce
@ -41,6 +42,8 @@ func (k *KeyPair) CreateTx(receiver []byte, value *big.Int, data []string) *Tran
tx.Sign(k.PrivateKey)
return tx
*/
return nil
}
func (k *KeyPair) RlpEncode() []byte {

View File

@ -173,21 +173,25 @@ func NewStack() *Stack {
}
func (st *Stack) Pop() *big.Int {
str := st.data[0]
st.data = st.data[1:]
str := st.data[len(st.data)-1]
copy(st.data[:len(st.data)-1], st.data[:len(st.data)-1])
st.data = st.data[:len(st.data)-1]
return str
}
func (st *Stack) Popn() (*big.Int, *big.Int) {
ints := st.data[:2]
st.data = st.data[2:]
ints := st.data[len(st.data)-2:]
copy(st.data[:len(st.data)-2], st.data[:len(st.data)-2])
st.data = st.data[:len(st.data)-2]
return ints[0], ints[1]
}
func (st *Stack) Peek() *big.Int {
str := st.data[0]
str := st.data[len(st.data)-1]
return str
}
@ -202,7 +206,7 @@ func (st *Stack) Push(d *big.Int) {
st.data = append(st.data, d)
}
func (st *Stack) Print() {
fmt.Println("### STACK ###")
fmt.Println("### stack ###")
if len(st.data) > 0 {
for i, val := range st.data {
fmt.Printf("%-3d %v\n", i, val)
@ -242,15 +246,15 @@ func (m *Memory) Len() int {
}
func (m *Memory) Print() {
fmt.Println("### MEM ###")
fmt.Printf("### mem %d bytes ###\n", len(m.store))
if len(m.store) > 0 {
addr := 0
for i := 0; i+32 < len(m.store); i += 32 {
for i := 0; i+32 <= len(m.store); i += 32 {
fmt.Printf("%03d %v\n", addr, m.store[i:i+32])
addr++
}
} else {
fmt.Println("-- empty --")
}
fmt.Println("###########")
fmt.Println("####################")
}

View File

@ -80,7 +80,7 @@ func (sm *StateManager) WatchAddr(addr []byte) *AccountState {
func (sm *StateManager) GetAddrState(addr []byte) *AccountState {
account := sm.addrStateStore.Get(addr)
if account == nil {
a := sm.bc.CurrentBlock.state.GetAccount(addr)
a := sm.procState.GetAccount(addr)
account = &AccountState{Nonce: a.Nonce, Account: a}
}
@ -98,16 +98,21 @@ func (sm *StateManager) MakeContract(tx *Transaction) {
}
}
// Apply transactions uses the transaction passed to it and applies them onto
// the current processing state.
func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) {
// Process each transaction/contract
for _, tx := range txs {
// 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() {
sm.MakeContract(tx)
//XXX block.MakeContract(tx)
} else {
// Figure out if the address this transaction was sent to is a
// contract or an actual account. In case of a contract, we process that
// contract instead of moving funds between accounts.
if contract := sm.procState.GetContract(tx.Recipient); contract != nil {
//XXX if contract := block.state.GetContract(tx.Recipient); contract != nil {
sm.ProcessContract(contract, tx, block)
} else {
err := sm.Ethereum.TxPool().ProcessTransaction(tx, block)
@ -121,9 +126,9 @@ func (sm *StateManager) ApplyTransactions(block *Block, txs []*Transaction) {
// The prepare function, prepares the state manager for the next
// "ProcessBlock" action.
func (sm *StateManager) Prepare(processer *State, comparative *State) {
func (sm *StateManager) Prepare(processor *State, comparative *State) {
sm.compState = comparative
sm.procState = processer
sm.procState = processor
}
// Default prepare function
@ -172,14 +177,12 @@ func (sm *StateManager) ProcessBlock(block *Block, dontReact bool) error {
// if !sm.compState.Cmp(sm.procState)
if !sm.compState.Cmp(sm.procState) {
//XXX return fmt.Errorf("Invalid merkle root. Expected %x, got %x", block.State().trie.Root, sm.bc.CurrentBlock.State().trie.Root)
return fmt.Errorf("Invalid merkle root. Expected %x, got %x", sm.compState.trie.Root, sm.procState.trie.Root)
}
// Calculate the new total difficulty and sync back to the db
if sm.CalculateTD(block) {
// Sync the current block's state to the database and cancelling out the deferred Undo
//XXX sm.bc.CurrentBlock.Sync()
sm.procState.Sync()
// Broadcast the valid block back to the wire
@ -276,14 +279,14 @@ func CalculateUncleReward(block *Block) *big.Int {
func (sm *StateManager) AccumelateRewards(block *Block) error {
// Get the coinbase rlp data
//XXX addr := processor.state.GetAccount(block.Coinbase)
addr := sm.procState.GetAccount(block.Coinbase)
// Reward amount of ether to the coinbase address
addr.AddFee(CalculateBlockReward(block, len(block.Uncles)))
//XXX processor.state.UpdateAccount(block.Coinbase, addr)
var acc []byte
copy(acc, block.Coinbase)
sm.procState.UpdateAccount(acc, addr)
for _, uncle := range block.Uncles {
uncleAddr := sm.procState.GetAccount(uncle.Coinbase)
uncleAddr.AddFee(CalculateUncleReward(uncle))
@ -301,13 +304,12 @@ func (sm *StateManager) Stop() {
func (sm *StateManager) ProcessContract(contract *Contract, tx *Transaction, block *Block) {
// Recovering function in case the VM had any errors
/*
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from VM execution with err =", r)
}
}()
*/
caller := sm.procState.GetAccount(tx.Sender())
closure := NewClosure(caller, contract, sm.procState, tx.Gas, tx.Value)
vm := NewVm(sm.procState, RuntimeVars{

View File

@ -1,7 +1,6 @@
package ethchain
import (
"bytes"
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/secp256k1-go"
"math/big"
@ -18,31 +17,19 @@ type Transaction struct {
Data []string
v byte
r, s []byte
}
func NewTransaction(to []byte, value *big.Int, data []string) *Transaction {
tx := Transaction{Recipient: to, Value: value, Nonce: 0, Data: data}
return &tx
// Indicates whether this tx is a contract creation transaction
contractCreation bool
}
func NewContractCreationTx(value, gasprice *big.Int, data []string) *Transaction {
return &Transaction{Value: value, Gasprice: gasprice, Data: data}
return &Transaction{Value: value, Gasprice: gasprice, Data: data, contractCreation: true}
}
func NewContractMessageTx(to []byte, value, gasprice, gas *big.Int, data []string) *Transaction {
func NewTransactionMessage(to []byte, value, gasprice, gas *big.Int, data []string) *Transaction {
return &Transaction{Recipient: to, Value: value, Gasprice: gasprice, Gas: gas, Data: data}
}
func NewTx(to []byte, value *big.Int, data []string) *Transaction {
return &Transaction{Recipient: to, Value: value, Gasprice: big.NewInt(0), Gas: big.NewInt(0), Nonce: 0, Data: data}
}
// XXX Deprecated
func NewTransactionFromData(data []byte) *Transaction {
return NewTransactionFromBytes(data)
}
func NewTransactionFromBytes(data []byte) *Transaction {
tx := &Transaction{}
tx.RlpDecode(data)
@ -74,7 +61,7 @@ func (tx *Transaction) Hash() []byte {
}
func (tx *Transaction) IsContract() bool {
return bytes.Compare(tx.Recipient, ContractAddr) == 0
return tx.contractCreation
}
func (tx *Transaction) Signature(key []byte) []byte {
@ -124,16 +111,14 @@ func (tx *Transaction) Sign(privk []byte) error {
}
func (tx *Transaction) RlpData() interface{} {
// Prepare the transaction for serialization
return []interface{}{
tx.Nonce,
tx.Recipient,
tx.Value,
ethutil.NewSliceValue(tx.Data).Slice(),
tx.v,
tx.r,
tx.s,
data := []interface{}{tx.Nonce, tx.Value, tx.Gasprice}
if !tx.contractCreation {
data = append(data, tx.Recipient, tx.Gas)
}
d := ethutil.NewSliceValue(tx.Data).Slice()
return append(data, d, tx.v, tx.r, tx.s)
}
func (tx *Transaction) RlpValue() *ethutil.Value {
@ -150,17 +135,35 @@ func (tx *Transaction) RlpDecode(data []byte) {
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.Nonce = decoder.Get(0).Uint()
tx.Recipient = decoder.Get(1).Bytes()
tx.Value = decoder.Get(2).BigInt()
tx.Value = decoder.Get(1).BigInt()
tx.Gasprice = decoder.Get(2).BigInt()
// If the 4th item is a list(slice) this tx
// is a contract creation tx
if decoder.Get(3).IsList() {
d := decoder.Get(3)
tx.Data = make([]string, d.Len())
for i := 0; i < d.Len(); i++ {
tx.Data[i] = d.Get(i).Str()
}
// TODO something going wrong here
tx.v = byte(decoder.Get(4).Uint())
tx.r = decoder.Get(5).Bytes()
tx.s = decoder.Get(6).Bytes()
tx.contractCreation = true
} else {
tx.Recipient = decoder.Get(3).Bytes()
tx.Gas = decoder.Get(4).BigInt()
d := decoder.Get(5)
tx.Data = make([]string, d.Len())
for i := 0; i < d.Len(); i++ {
tx.Data[i] = d.Get(i).Str()
}
tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes()
}
}

View File

@ -208,7 +208,7 @@ func (pool *TxPool) QueueTransaction(tx *Transaction) {
pool.queueChan <- tx
}
func (pool *TxPool) Flush() []*Transaction {
func (pool *TxPool) CurrentTransactions() []*Transaction {
pool.mutex.Lock()
defer pool.mutex.Unlock()
@ -222,6 +222,12 @@ func (pool *TxPool) Flush() []*Transaction {
i++
}
return txList
}
func (pool *TxPool) Flush() []*Transaction {
txList := pool.CurrentTransactions()
// Recreate a new list all together
// XXX Is this the fastest way?
pool.pool = list.New()

View File

@ -2,14 +2,24 @@ package ethchain
import (
_ "bytes"
_ "fmt"
"fmt"
"github.com/ethereum/eth-go/ethutil"
_ "github.com/obscuren/secp256k1-go"
"log"
_ "math"
"math/big"
)
var (
GasStep = big.NewInt(1)
GasSha = big.NewInt(20)
GasSLoad = big.NewInt(20)
GasSStore = big.NewInt(100)
GasBalance = big.NewInt(20)
GasCreate = big.NewInt(100)
GasCall = big.NewInt(20)
GasMemory = big.NewInt(1)
)
type Vm struct {
txPool *TxPool
// Stack for processing contracts
@ -70,10 +80,43 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
}
// TODO Get each instruction cost properly
fee := new(big.Int)
fee.Add(fee, big.NewInt(1000))
gas := new(big.Int)
useGas := func(amount *big.Int) {
gas.Add(gas, amount)
}
switch op {
case oSHA3:
useGas(GasSha)
case oSLOAD:
useGas(GasSLoad)
case oSSTORE:
var mult *big.Int
y, x := stack.Peekn()
val := closure.GetMem(x)
if val.IsEmpty() && len(y.Bytes()) > 0 {
mult = ethutil.Big2
} else if !val.IsEmpty() && len(y.Bytes()) == 0 {
mult = ethutil.Big0
} else {
mult = ethutil.Big1
}
useGas(base.Mul(mult, GasSStore))
case oBALANCE:
useGas(GasBalance)
case oCREATE:
useGas(GasCreate)
case oCALL:
useGas(GasCall)
case oMLOAD, oMSIZE, oMSTORE8, oMSTORE:
useGas(GasMemory)
default:
useGas(GasStep)
}
if closure.Gas.Cmp(gas) < 0 {
ethutil.Config.Log.Debugln("Insufficient gas", closure.Gas, gas)
if closure.Gas.Cmp(fee) < 0 {
return closure.Return(nil)
}
@ -172,10 +215,17 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
} else {
stack.Push(ethutil.BigFalse)
}
case oNOT:
case oEQ:
x, y := stack.Popn()
// x != y
if x.Cmp(y) != 0 {
// x == y
if x.Cmp(y) == 0 {
stack.Push(ethutil.BigTrue)
} else {
stack.Push(ethutil.BigFalse)
}
case oNOT:
x := stack.Pop()
if x.Cmp(ethutil.BigFalse) == 0 {
stack.Push(ethutil.BigTrue)
} else {
stack.Push(ethutil.BigFalse)
@ -259,8 +309,8 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
case oJUMP:
pc = stack.Pop()
case oJUMPI:
pos, cond := stack.Popn()
if cond.Cmp(big.NewInt(0)) > 0 {
cond, pos := stack.Popn()
if cond.Cmp(ethutil.BigTrue) == 0 {
pc = pos
}
case oPC:
@ -273,6 +323,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
retSize, retOffset := stack.Popn()
// Pop input size and offset
inSize, inOffset := stack.Popn()
fmt.Println(inSize, inOffset)
// Get the arguments from the memory
args := mem.Get(inOffset.Int64(), inSize.Int64())
// Pop gas and value of the stack.
@ -317,6 +368,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
}
}
/*
func makeInlineTx(addr []byte, value, from, length *big.Int, contract *Contract, state *State) {
ethutil.Config.Log.Debugf(" => creating inline tx %x %v %v %v", addr, value, from, length)
j := int64(0)
@ -353,3 +405,4 @@ func contractMemory(state *State, contractAddr []byte, memAddr *big.Int) *big.In
return decoder.BigInt()
}
*/

View File

@ -1,114 +1,17 @@
package ethchain
import (
"bytes"
_ "bytes"
"fmt"
"github.com/ethereum/eth-go/ethdb"
"github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/mutan"
"math/big"
"strings"
"testing"
)
/*
func TestRun(t *testing.T) {
InitFees()
ethutil.ReadConfig("")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
script := Compile([]string{
"TXSENDER",
"SUICIDE",
})
tx := NewTransaction(ContractAddr, big.NewInt(1e17), script)
fmt.Printf("contract addr %x\n", tx.Hash()[12:])
contract := MakeContract(tx, state)
vm := &Vm{}
vm.Process(contract, state, RuntimeVars{
address: tx.Hash()[12:],
blockNumber: 1,
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
time: 1,
diff: big.NewInt(256),
txValue: tx.Value,
txData: tx.Data,
})
}
func TestRun1(t *testing.T) {
ethutil.ReadConfig("")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
script := Compile([]string{
"PUSH", "0",
"PUSH", "0",
"TXSENDER",
"PUSH", "10000000",
"MKTX",
})
fmt.Println(ethutil.NewValue(script))
tx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), script)
fmt.Printf("contract addr %x\n", tx.Hash()[12:])
contract := MakeContract(tx, state)
vm := &Vm{}
vm.Process(contract, state, RuntimeVars{
address: tx.Hash()[12:],
blockNumber: 1,
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
time: 1,
diff: big.NewInt(256),
txValue: tx.Value,
txData: tx.Data,
})
}
func TestRun2(t *testing.T) {
ethutil.ReadConfig("")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
script := Compile([]string{
"PUSH", "0",
"PUSH", "0",
"TXSENDER",
"PUSH", "10000000",
"MKTX",
})
fmt.Println(ethutil.NewValue(script))
tx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), script)
fmt.Printf("contract addr %x\n", tx.Hash()[12:])
contract := MakeContract(tx, state)
vm := &Vm{}
vm.Process(contract, state, RuntimeVars{
address: tx.Hash()[12:],
blockNumber: 1,
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
time: 1,
diff: big.NewInt(256),
txValue: tx.Value,
txData: tx.Data,
})
}
*/
// XXX Full stack test
func TestRun3(t *testing.T) {
ethutil.ReadConfig("")
@ -127,12 +30,12 @@ func TestRun3(t *testing.T) {
"PUSH", "0",
"RETURN",
})
tx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), script)
tx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), script)
addr := tx.Hash()[12:]
contract := MakeContract(tx, state)
state.UpdateContract(contract)
callerScript := ethutil.Compile(
callerScript := ethutil.Assemble(
"PUSH", 1337, // Argument
"PUSH", 65, // argument mem offset
"MSTORE",
@ -149,7 +52,7 @@ func TestRun3(t *testing.T) {
"PUSH", 0,
"RETURN",
)
callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript)
callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), callerScript)
// Contract addr as test address
account := NewAccount(ContractAddr, big.NewInt(10000000))
@ -171,4 +74,50 @@ func TestRun3(t *testing.T) {
if bytes.Compare(ret, exp) != 0 {
t.Errorf("expected return value to be %v, got %v", exp, ret)
}
}*/
func TestRun4(t *testing.T) {
ethutil.ReadConfig("")
db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, ""))
asm, err := mutan.Compile(strings.NewReader(`
a = 10
b = 10
if a == b {
c = 10
if c == 10 {
d = 1000
e = 10
}
}
store[0] = 20
store[a] = 20
`), false)
if err != nil {
fmt.Println(err)
}
//asm = append(asm, "LOG")
fmt.Println(asm)
callerScript := ethutil.Assemble(asm...)
callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), callerScript)
// Contract addr as test address
account := NewAccount(ContractAddr, big.NewInt(10000000))
callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
vm := NewVm(state, RuntimeVars{
origin: account.Address(),
blockNumber: 1,
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
time: 1,
diff: big.NewInt(256),
// XXX Tx data? Could be just an argument to the closure instead
txData: nil,
})
callerClosure.Call(vm, nil)
}

View File

@ -36,6 +36,7 @@ func CurrencyToString(num *big.Int) string {
var (
Big1 = big.NewInt(1)
Big2 = big.NewInt(1)
Big0 = big.NewInt(0)
Big256 = big.NewInt(0xff)
)

View File

@ -131,7 +131,7 @@ func Instr(instr string) (int, []string, error) {
// Script compilation functions
// Compiles strings to machine code
func Compile(instructions ...interface{}) (script []string) {
func Assemble(instructions ...interface{}) (script []string) {
script = make([]string, len(instructions))
for i, val := range instructions {

View File

@ -57,7 +57,7 @@ func DecodeWithReader(reader *bytes.Buffer) interface{} {
switch {
case char == 0:
return nil
case char <= 0x7c:
case char <= 0x7f:
return char
case char <= 0xb7:

View File

@ -129,6 +129,11 @@ func TestEncodeDecodeBytes(t *testing.T) {
}
}
func TestEncodeZero(t *testing.T) {
b := NewValue(0).Encode()
fmt.Println(b)
}
func BenchmarkEncodeDecode(b *testing.B) {
for i := 0; i < b.N; i++ {
bytes := Encode([]interface{}{"dog", "god", "cat"})

View File

@ -149,6 +149,15 @@ func (val *Value) IsStr() bool {
return val.Type() == reflect.String
}
// Special list checking function. Something is considered
// a list if it's of type []interface{}. The list is usually
// used in conjunction with rlp decoded streams.
func (val *Value) IsList() bool {
_, ok := val.Val.([]interface{})
return ok
}
func (val *Value) IsEmpty() bool {
return val.Val == nil || ((val.IsSlice() || val.IsStr()) && val.Len() == 0)
}

View File

@ -32,6 +32,7 @@ const (
MsgBlockTy = 0x13
MsgGetChainTy = 0x14
MsgNotInChainTy = 0x15
MsgGetTxsTy = 0x16
MsgTalkTy = 0xff
)
@ -46,6 +47,7 @@ var msgTypeToString = map[MsgType]string{
MsgTxTy: "Transactions",
MsgBlockTy: "Blocks",
MsgGetChainTy: "Get chain",
MsgGetTxsTy: "Get Txs",
MsgNotInChainTy: "Not in chain",
}

19
peer.go
View File

@ -396,7 +396,8 @@ func (p *Peer) HandleInbound() {
// in the TxPool where it will undergo validation and
// processing when a new block is found
for i := 0; i < msg.Data.Len(); i++ {
p.ethereum.TxPool().QueueTransaction(ethchain.NewTransactionFromData(msg.Data.Get(i).Encode()))
tx := ethchain.NewTransactionFromValue(msg.Data.Get(i))
p.ethereum.TxPool().QueueTransaction(tx)
}
case ethwire.MsgGetPeersTy:
// Flag this peer as a 'requested of new peers' this to
@ -462,6 +463,16 @@ func (p *Peer) HandleInbound() {
case ethwire.MsgNotInChainTy:
ethutil.Config.Log.Infof("Not in chain %x\n", msg.Data)
// TODO
case ethwire.MsgGetTxsTy:
// Get the current transactions of the pool
txs := p.ethereum.TxPool().CurrentTransactions()
// Get the RlpData values from the txs
txsInterface := make([]interface{}, len(txs))
for i, tx := range txs {
txsInterface[i] = tx.RlpData()
}
// Broadcast it back to the peer
p.QueueMessage(ethwire.NewMessage(ethwire.MsgTxTy, txsInterface))
// Unofficial but fun nonetheless
case ethwire.MsgTalkTy:
@ -649,7 +660,11 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) {
msg := ethwire.NewMessage(ethwire.MsgGetChainTy, []interface{}{blockHash, uint64(50)})
p.QueueMessage(msg)
ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", blockHash[:4])
ethutil.Config.Log.Debugf("Requesting blockchain %x...\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4])
msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{})
p.QueueMessage(msg)
ethutil.Config.Log.Debugln("Requested transactions")
}
}