Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
0a880108
Commit
0a880108
authored
Apr 01, 2014
by
Maran
Browse files
Options
Browse Files
Download
Plain Diff
Merge conflicts
parents
5f49a659
7277c420
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
235 additions
and
183 deletions
+235
-183
keypair.go
ethchain/keypair.go
+3
-0
stack.go
ethchain/stack.go
+13
-9
state_manager.go
ethchain/state_manager.go
+18
-16
transaction.go
ethchain/transaction.go
+42
-39
transaction_pool.go
ethchain/transaction_pool.go
+7
-1
vm.go
ethchain/vm.go
+63
-10
vm_test.go
ethchain/vm_test.go
+53
-104
common.go
ethutil/common.go
+1
-0
parsing.go
ethutil/parsing.go
+1
-1
rlp.go
ethutil/rlp.go
+1
-1
rlp_test.go
ethutil/rlp_test.go
+5
-0
value.go
ethutil/value.go
+9
-0
messaging.go
ethwire/messaging.go
+2
-0
peer.go
peer.go
+17
-2
No files found.
ethchain/keypair.go
View file @
0a880108
...
...
@@ -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
{
...
...
ethchain/stack.go
View file @
0a880108
...
...
@@ -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
.
Print
ln
(
"### MEM ###"
)
fmt
.
Print
f
(
"### 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
(
"###########
#########
"
)
}
ethchain/state_manager.go
View file @
0a880108
...
...
@@ -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
.
s
tate
.
GetAccount
(
addr
)
a
:=
sm
.
procS
tate
.
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
(
process
e
r
*
State
,
comparative
*
State
)
{
func
(
sm
*
StateManager
)
Prepare
(
process
o
r
*
State
,
comparative
*
State
)
{
sm
.
compState
=
comparative
sm
.
procState
=
process
e
r
sm
.
procState
=
process
o
r
}
// 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
{
...
...
ethchain/transaction.go
View file @
0a880108
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
New
ContractMessageTx
(
to
[]
byte
,
value
,
gasprice
,
gas
*
big
.
Int
,
data
[]
string
)
*
Transaction
{
func
New
TransactionMessage
(
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
()
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
.
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
()
}
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
()
}
ethchain/transaction_pool.go
View file @
0a880108
...
...
@@ -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
()
...
...
ethchain/vm.go
View file @
0a880108
...
...
@@ -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
o
NOT
:
case
o
EQ
:
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()
}
*/
ethchain/vm_test.go
View file @
0a880108
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
:=
New
Transaction
(
ContractAddr
,
ethutil
.
Big
(
"100000000000000000000000000000000000000000000000
000"
),
script
)
tx := New
ContractCreationTx(ethutil.Big("0"), ethutil.Big("1
000"), script)
addr := tx.Hash()[12:]
contract := MakeContract(tx, state)
state.UpdateContract(contract)
callerScript
:=
ethutil
.
Compi
le
(
callerScript := ethutil.
Assemb
le(
"PUSH", 1337, // Argument
"PUSH", 65, // argument mem offset
"MSTORE",
...
...
@@ -149,7 +52,7 @@ func TestRun3(t *testing.T) {
"PUSH", 0,
"RETURN",
)
callerTx
:=
New
Transaction
(
ContractAddr
,
ethutil
.
Big
(
"100000000000000000000000000000000000000000000000
000"
),
callerScript
)
callerTx := New
ContractCreationTx(ethutil.Big("0"), ethutil.Big("1
000"), 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
)
}
ethutil/common.go
View file @
0a880108
...
...
@@ -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
)
)
ethutil/parsing.go
View file @
0a880108
...
...
@@ -131,7 +131,7 @@ func Instr(instr string) (int, []string, error) {
// Script compilation functions
// Compiles strings to machine code
func
Compi
le
(
instructions
...
interface
{})
(
script
[]
string
)
{
func
Assemb
le
(
instructions
...
interface
{})
(
script
[]
string
)
{
script
=
make
([]
string
,
len
(
instructions
))
for
i
,
val
:=
range
instructions
{
...
...
ethutil/rlp.go
View file @
0a880108
...
...
@@ -57,7 +57,7 @@ func DecodeWithReader(reader *bytes.Buffer) interface{} {
switch
{
case
char
==
0
:
return
nil
case
char
<=
0x7
c
:
case
char
<=
0x7
f
:
return
char
case
char
<=
0xb7
:
...
...
ethutil/rlp_test.go
View file @
0a880108
...
...
@@ -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"
})
...
...
ethutil/value.go
View file @
0a880108
...
...
@@ -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
)
}
...
...
ethwire/messaging.go
View file @
0a880108
...
...
@@ -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"
,
}
...
...
peer.go
View file @
0a880108
...
...
@@ -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"
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment