forked from cerc-io/plugeth
Merge conflicts
This commit is contained in:
commit
0a88010826
@ -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 {
|
||||
|
@ -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("####################")
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}()
|
||||
*/
|
||||
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{
|
||||
|
@ -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()
|
||||
|
||||
d := decoder.Get(3)
|
||||
tx.Data = make([]string, d.Len())
|
||||
for i := 0; i < d.Len(); i++ {
|
||||
tx.Data[i] = d.Get(i).Str()
|
||||
// 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()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
// TODO something going wrong here
|
||||
tx.v = byte(decoder.Get(4).Uint())
|
||||
tx.r = decoder.Get(5).Bytes()
|
||||
tx.s = decoder.Get(6).Bytes()
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
}
|
||||
*/
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
)
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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"})
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
19
peer.go
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user