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
3f1f8438
Commit
3f1f8438
authored
Jun 19, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/0.5.14'
parents
5a0e7517
7ad073fb
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
419 additions
and
466 deletions
+419
-466
README.md
README.md
+1
-1
asm.go
ethchain/asm.go
+1
-1
deprecated.go
ethchain/deprecated.go
+0
-236
stack.go
ethchain/stack.go
+8
-2
state.go
ethchain/state.go
+37
-12
state_manager.go
ethchain/state_manager.go
+22
-9
state_object.go
ethchain/state_object.go
+37
-12
state_transition.go
ethchain/state_transition.go
+73
-70
transaction.go
ethchain/transaction.go
+6
-2
types.go
ethchain/types.go
+2
-1
vm.go
ethchain/vm.go
+169
-91
ethereum.go
ethereum.go
+4
-10
miner.go
ethminer/miner.go
+2
-0
pub.go
ethpub/pub.go
+0
-5
types.go
ethpub/types.go
+4
-3
bytes.go
ethutil/bytes.go
+2
-1
config.go
ethutil/config.go
+1
-1
trie_test.go
ethutil/trie_test.go
+16
-7
value.go
ethutil/value.go
+2
-0
peer.go
peer.go
+32
-2
No files found.
README.md
View file @
3f1f8438
...
@@ -6,7 +6,7 @@ Ethereum
...
@@ -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 RC1
3
". For build instructions see the
[
Wiki
](
https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go
)
).
of Concept 5.0 RC1
4
". 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.
...
...
ethchain/asm.go
View file @
3f1f8438
...
@@ -28,7 +28,7 @@ func Disassemble(script []byte) (asm []string) {
...
@@ -28,7 +28,7 @@ func Disassemble(script []byte) (asm []string) {
if
len
(
data
)
==
0
{
if
len
(
data
)
==
0
{
data
=
[]
byte
{
0
}
data
=
[]
byte
{
0
}
}
}
asm
=
append
(
asm
,
fmt
.
Sprintf
(
"
%#
x"
,
data
))
asm
=
append
(
asm
,
fmt
.
Sprintf
(
"
0x%
x"
,
data
))
pc
.
Add
(
pc
,
big
.
NewInt
(
a
-
1
))
pc
.
Add
(
pc
,
big
.
NewInt
(
a
-
1
))
}
}
...
...
ethchain/deprecated.go
deleted
100644 → 0
View file @
5a0e7517
package
ethchain
import
(
"bytes"
"fmt"
"github.com/ethereum/eth-go/ethutil"
"math/big"
)
func
(
sm
*
StateManager
)
MakeStateObject
(
state
*
State
,
tx
*
Transaction
)
*
StateObject
{
contract
:=
MakeContract
(
tx
,
state
)
if
contract
!=
nil
{
state
.
states
[
string
(
tx
.
CreationAddress
())]
=
contract
.
state
return
contract
}
return
nil
}
func
(
sm
*
StateManager
)
EvalScript
(
state
*
State
,
script
[]
byte
,
object
*
StateObject
,
tx
*
Transaction
,
block
*
Block
)
(
ret
[]
byte
,
gas
*
big
.
Int
,
err
error
)
{
account
:=
state
.
GetAccount
(
tx
.
Sender
())
err
=
account
.
ConvertGas
(
tx
.
Gas
,
tx
.
GasPrice
)
if
err
!=
nil
{
ethutil
.
Config
.
Log
.
Debugln
(
err
)
return
}
closure
:=
NewClosure
(
account
,
object
,
script
,
state
,
tx
.
Gas
,
tx
.
GasPrice
)
vm
:=
NewVm
(
state
,
sm
,
RuntimeVars
{
Origin
:
account
.
Address
(),
BlockNumber
:
block
.
BlockInfo
()
.
Number
,
PrevHash
:
block
.
PrevHash
,
Coinbase
:
block
.
Coinbase
,
Time
:
block
.
Time
,
Diff
:
block
.
Difficulty
,
Value
:
tx
.
Value
,
//Price: tx.GasPrice,
})
ret
,
gas
,
err
=
closure
.
Call
(
vm
,
tx
.
Data
,
nil
)
// Update the account (refunds)
state
.
UpdateStateObject
(
account
)
state
.
UpdateStateObject
(
object
)
return
}
func
(
self
*
StateManager
)
ProcessTransaction
(
tx
*
Transaction
,
coinbase
*
StateObject
,
state
*
State
,
toContract
bool
)
(
gas
*
big
.
Int
,
err
error
)
{
fmt
.
Printf
(
"state root before update %x
\n
"
,
state
.
Root
())
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
ethutil
.
Config
.
Log
.
Infoln
(
r
)
err
=
fmt
.
Errorf
(
"%v"
,
r
)
}
}()
gas
=
new
(
big
.
Int
)
addGas
:=
func
(
g
*
big
.
Int
)
{
gas
.
Add
(
gas
,
g
)
}
addGas
(
GasTx
)
// Get the sender
sender
:=
state
.
GetAccount
(
tx
.
Sender
())
if
sender
.
Nonce
!=
tx
.
Nonce
{
err
=
NonceError
(
tx
.
Nonce
,
sender
.
Nonce
)
return
}
sender
.
Nonce
+=
1
defer
func
()
{
//state.UpdateStateObject(sender)
// Notify all subscribers
self
.
Ethereum
.
Reactor
()
.
Post
(
"newTx:post"
,
tx
)
}()
txTotalBytes
:=
big
.
NewInt
(
int64
(
len
(
tx
.
Data
)))
//fmt.Println("txTotalBytes", txTotalBytes)
//txTotalBytes.Div(txTotalBytes, ethutil.Big32)
addGas
(
new
(
big
.
Int
)
.
Mul
(
txTotalBytes
,
GasData
))
rGas
:=
new
(
big
.
Int
)
.
Set
(
gas
)
rGas
.
Mul
(
gas
,
tx
.
GasPrice
)
// Make sure there's enough in the sender's account. Having insufficient
// funds won't invalidate this transaction but simple ignores it.
totAmount
:=
new
(
big
.
Int
)
.
Add
(
tx
.
Value
,
rGas
)
if
sender
.
Amount
.
Cmp
(
totAmount
)
<
0
{
state
.
UpdateStateObject
(
sender
)
err
=
fmt
.
Errorf
(
"[TXPL] Insufficient amount in sender's (%x) account"
,
tx
.
Sender
())
return
}
coinbase
.
BuyGas
(
gas
,
tx
.
GasPrice
)
state
.
UpdateStateObject
(
coinbase
)
fmt
.
Printf
(
"1. root %x
\n
"
,
state
.
Root
())
// Get the receiver
receiver
:=
state
.
GetAccount
(
tx
.
Recipient
)
// Send Tx to self
if
bytes
.
Compare
(
tx
.
Recipient
,
tx
.
Sender
())
==
0
{
// Subtract the fee
sender
.
SubAmount
(
rGas
)
}
else
{
// Subtract the amount from the senders account
sender
.
SubAmount
(
totAmount
)
state
.
UpdateStateObject
(
sender
)
fmt
.
Printf
(
"3. root %x
\n
"
,
state
.
Root
())
// Add the amount to receivers account which should conclude this transaction
receiver
.
AddAmount
(
tx
.
Value
)
state
.
UpdateStateObject
(
receiver
)
fmt
.
Printf
(
"2. root %x
\n
"
,
state
.
Root
())
}
ethutil
.
Config
.
Log
.
Infof
(
"[TXPL] Processed Tx %x
\n
"
,
tx
.
Hash
())
return
}
func
(
sm
*
StateManager
)
ApplyTransaction
(
coinbase
[]
byte
,
state
*
State
,
block
*
Block
,
tx
*
Transaction
)
(
totalGasUsed
*
big
.
Int
,
err
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.
*/
var
(
addTotalGas
=
func
(
gas
*
big
.
Int
)
{
totalGasUsed
.
Add
(
totalGasUsed
,
gas
)
}
gas
=
new
(
big
.
Int
)
script
[]
byte
)
totalGasUsed
=
big
.
NewInt
(
0
)
snapshot
:=
state
.
Snapshot
()
ca
:=
state
.
GetAccount
(
coinbase
)
// Apply the transaction to the current state
gas
,
err
=
sm
.
ProcessTransaction
(
tx
,
ca
,
state
,
false
)
addTotalGas
(
gas
)
fmt
.
Println
(
"gas used by tx"
,
gas
)
if
tx
.
CreatesContract
()
{
if
err
==
nil
{
// Create a new state object and the transaction
// as it's data provider.
contract
:=
sm
.
MakeStateObject
(
state
,
tx
)
if
contract
!=
nil
{
fmt
.
Println
(
Disassemble
(
contract
.
Init
()))
// Evaluate the initialization script
// and use the return value as the
// script section for the state object.
script
,
gas
,
err
=
sm
.
EvalScript
(
state
,
contract
.
Init
(),
contract
,
tx
,
block
)
fmt
.
Println
(
"gas used by eval"
,
gas
)
addTotalGas
(
gas
)
fmt
.
Println
(
"total ="
,
totalGasUsed
)
fmt
.
Println
(
"script len ="
,
len
(
script
))
if
err
!=
nil
{
err
=
fmt
.
Errorf
(
"[STATE] Error during init script run %v"
,
err
)
return
}
contract
.
script
=
script
state
.
UpdateStateObject
(
contract
)
}
else
{
err
=
fmt
.
Errorf
(
"[STATE] Unable to create contract"
)
}
}
else
{
err
=
fmt
.
Errorf
(
"[STATE] contract creation tx: %v for sender %x"
,
err
,
tx
.
Sender
())
}
}
else
{
// Find the state object at the "recipient" address. If
// there's an object attempt to run the script.
stateObject
:=
state
.
GetStateObject
(
tx
.
Recipient
)
if
err
==
nil
&&
stateObject
!=
nil
&&
len
(
stateObject
.
Script
())
>
0
{
_
,
gas
,
err
=
sm
.
EvalScript
(
state
,
stateObject
.
Script
(),
stateObject
,
tx
,
block
)
addTotalGas
(
gas
)
}
}
parent
:=
sm
.
bc
.
GetBlock
(
block
.
PrevHash
)
total
:=
new
(
big
.
Int
)
.
Add
(
block
.
GasUsed
,
totalGasUsed
)
limit
:=
block
.
CalcGasLimit
(
parent
)
if
total
.
Cmp
(
limit
)
>
0
{
state
.
Revert
(
snapshot
)
err
=
GasLimitError
(
total
,
limit
)
}
return
}
// Apply transactions uses the transaction passed to it and applies them onto
// the current processing state.
func
(
sm
*
StateManager
)
ApplyTransactions
(
coinbase
[]
byte
,
state
*
State
,
block
*
Block
,
txs
[]
*
Transaction
)
([]
*
Receipt
,
[]
*
Transaction
)
{
// Process each transaction/contract
var
receipts
[]
*
Receipt
var
validTxs
[]
*
Transaction
var
ignoredTxs
[]
*
Transaction
// Transactions which go over the gasLimit
totalUsedGas
:=
big
.
NewInt
(
0
)
for
_
,
tx
:=
range
txs
{
usedGas
,
err
:=
sm
.
ApplyTransaction
(
coinbase
,
state
,
block
,
tx
)
if
err
!=
nil
{
if
IsNonceErr
(
err
)
{
continue
}
if
IsGasLimitErr
(
err
)
{
ignoredTxs
=
append
(
ignoredTxs
,
tx
)
// We need to figure out if we want to do something with thse txes
ethutil
.
Config
.
Log
.
Debugln
(
"Gastlimit:"
,
err
)
continue
}
ethutil
.
Config
.
Log
.
Infoln
(
err
)
}
accumelative
:=
new
(
big
.
Int
)
.
Set
(
totalUsedGas
.
Add
(
totalUsedGas
,
usedGas
))
receipt
:=
&
Receipt
{
tx
,
ethutil
.
CopyBytes
(
state
.
Root
()
.
([]
byte
)),
accumelative
}
receipts
=
append
(
receipts
,
receipt
)
validTxs
=
append
(
validTxs
,
tx
)
}
fmt
.
Println
(
"################# MADE
\n
"
,
receipts
,
"
\n
############################"
)
// Update the total gas used for the block (to be mined)
block
.
GasUsed
=
totalUsedGas
return
receipts
,
validTxs
}
ethchain/stack.go
View file @
3f1f8438
...
@@ -2,7 +2,7 @@ package ethchain
...
@@ -2,7 +2,7 @@ package ethchain
import
(
import
(
"fmt"
"fmt"
_
"github.com/ethereum/eth-go/ethutil
"
"math
"
"math/big"
"math/big"
)
)
...
@@ -118,7 +118,13 @@ func (m *Memory) Resize(size uint64) {
...
@@ -118,7 +118,13 @@ func (m *Memory) Resize(size uint64) {
}
}
func
(
m
*
Memory
)
Get
(
offset
,
size
int64
)
[]
byte
{
func
(
m
*
Memory
)
Get
(
offset
,
size
int64
)
[]
byte
{
return
m
.
store
[
offset
:
offset
+
size
]
if
len
(
m
.
store
)
>
int
(
offset
)
{
end
:=
int
(
math
.
Min
(
float64
(
len
(
m
.
store
)),
float64
(
offset
+
size
)))
return
m
.
store
[
offset
:
end
]
}
return
nil
}
}
func
(
m
*
Memory
)
Len
()
int
{
func
(
m
*
Memory
)
Len
()
int
{
...
...
ethchain/state.go
View file @
3f1f8438
...
@@ -13,8 +13,6 @@ import (
...
@@ -13,8 +13,6 @@ import (
type
State
struct
{
type
State
struct
{
// The trie for this structure
// The trie for this structure
trie
*
ethutil
.
Trie
trie
*
ethutil
.
Trie
// Nested states
states
map
[
string
]
*
State
stateObjects
map
[
string
]
*
StateObject
stateObjects
map
[
string
]
*
StateObject
...
@@ -23,7 +21,7 @@ type State struct {
...
@@ -23,7 +21,7 @@ type State struct {
// Create a new state from a given trie
// Create a new state from a given trie
func
NewState
(
trie
*
ethutil
.
Trie
)
*
State
{
func
NewState
(
trie
*
ethutil
.
Trie
)
*
State
{
return
&
State
{
trie
:
trie
,
state
s
:
make
(
map
[
string
]
*
State
),
state
Objects
:
make
(
map
[
string
]
*
StateObject
),
manifest
:
NewManifest
()}
return
&
State
{
trie
:
trie
,
stateObjects
:
make
(
map
[
string
]
*
StateObject
),
manifest
:
NewManifest
()}
}
}
// Resets the trie and all siblings
// Resets the trie and all siblings
...
@@ -38,12 +36,16 @@ func (s *State) Reset() {
...
@@ -38,12 +36,16 @@ func (s *State) Reset() {
stateObject
.
state
.
Reset
()
stateObject
.
state
.
Reset
()
}
}
s
.
Empty
()
}
}
// Syncs the trie and all siblings
// Syncs the trie and all siblings
func
(
s
*
State
)
Sync
()
{
func
(
s
*
State
)
Sync
()
{
// Sync all nested states
// Sync all nested states
for
_
,
stateObject
:=
range
s
.
stateObjects
{
for
_
,
stateObject
:=
range
s
.
stateObjects
{
s
.
UpdateStateObject
(
stateObject
)
if
stateObject
.
state
==
nil
{
if
stateObject
.
state
==
nil
{
continue
continue
}
}
...
@@ -52,6 +54,18 @@ func (s *State) Sync() {
...
@@ -52,6 +54,18 @@ func (s *State) Sync() {
}
}
s
.
trie
.
Sync
()
s
.
trie
.
Sync
()
s
.
Empty
()
}
func
(
self
*
State
)
Empty
()
{
self
.
stateObjects
=
make
(
map
[
string
]
*
StateObject
)
}
func
(
self
*
State
)
Update
()
{
for
_
,
stateObject
:=
range
self
.
stateObjects
{
self
.
UpdateStateObject
(
stateObject
)
}
}
}
// Purges the current trie.
// Purges the current trie.
...
@@ -64,6 +78,12 @@ func (s *State) EachStorage(cb ethutil.EachCallback) {
...
@@ -64,6 +78,12 @@ func (s *State) EachStorage(cb ethutil.EachCallback) {
it
.
Each
(
cb
)
it
.
Each
(
cb
)
}
}
func
(
self
*
State
)
ResetStateObject
(
stateObject
*
StateObject
)
{
delete
(
self
.
stateObjects
,
string
(
stateObject
.
Address
()))
stateObject
.
state
.
Reset
()
}
func
(
self
*
State
)
UpdateStateObject
(
stateObject
*
StateObject
)
{
func
(
self
*
State
)
UpdateStateObject
(
stateObject
*
StateObject
)
{
addr
:=
stateObject
.
Address
()
addr
:=
stateObject
.
Address
()
...
@@ -98,13 +118,21 @@ func (self *State) GetStateObject(addr []byte) *StateObject {
...
@@ -98,13 +118,21 @@ func (self *State) GetStateObject(addr []byte) *StateObject {
func
(
self
*
State
)
GetOrNewStateObject
(
addr
[]
byte
)
*
StateObject
{
func
(
self
*
State
)
GetOrNewStateObject
(
addr
[]
byte
)
*
StateObject
{
stateObject
:=
self
.
GetStateObject
(
addr
)
stateObject
:=
self
.
GetStateObject
(
addr
)
if
stateObject
==
nil
{
if
stateObject
==
nil
{
stateObject
=
NewStateObject
(
addr
)
stateObject
=
self
.
NewStateObject
(
addr
)
self
.
stateObjects
[
string
(
addr
)]
=
stateObject
}
}
return
stateObject
return
stateObject
}
}
func
(
self
*
State
)
NewStateObject
(
addr
[]
byte
)
*
StateObject
{
ethutil
.
Config
.
Log
.
Printf
(
ethutil
.
LogLevelInfo
,
"(+) %x
\n
"
,
addr
)
stateObject
:=
NewStateObject
(
addr
)
self
.
stateObjects
[
string
(
addr
)]
=
stateObject
return
stateObject
}
func
(
self
*
State
)
GetAccount
(
addr
[]
byte
)
*
StateObject
{
func
(
self
*
State
)
GetAccount
(
addr
[]
byte
)
*
StateObject
{
return
self
.
GetOrNewStateObject
(
addr
)
return
self
.
GetOrNewStateObject
(
addr
)
}
}
...
@@ -126,13 +154,10 @@ func (self *State) Copy() *State {
...
@@ -126,13 +154,10 @@ func (self *State) Copy() *State {
return
nil
return
nil
}
}
func
(
s
*
State
)
Snapshot
()
*
State
{
func
(
self
*
State
)
Set
(
state
*
State
)
{
return
s
.
Copy
()
//s.trie = snapshot.trie
}
//s.stateObjects = snapshot.stateObjects
self
=
state
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
)
{
...
...
ethchain/state_manager.go
View file @
3f1f8438
...
@@ -127,6 +127,9 @@ done:
...
@@ -127,6 +127,9 @@ done:
// Notify all subscribers
// Notify all subscribers
self
.
Ethereum
.
Reactor
()
.
Post
(
"newTx:post"
,
tx
)
self
.
Ethereum
.
Reactor
()
.
Post
(
"newTx:post"
,
tx
)
// Update the state with pending changes
state
.
Update
()
txGas
.
Sub
(
txGas
,
st
.
gas
)
txGas
.
Sub
(
txGas
,
st
.
gas
)
accumelative
:=
new
(
big
.
Int
)
.
Set
(
totalUsedGas
.
Add
(
totalUsedGas
,
txGas
))
accumelative
:=
new
(
big
.
Int
)
.
Set
(
totalUsedGas
.
Add
(
totalUsedGas
,
txGas
))
receipt
:=
&
Receipt
{
tx
,
ethutil
.
CopyBytes
(
state
.
Root
()
.
([]
byte
)),
accumelative
}
receipt
:=
&
Receipt
{
tx
,
ethutil
.
CopyBytes
(
state
.
Root
()
.
([]
byte
)),
accumelative
}
...
@@ -135,8 +138,6 @@ done:
...
@@ -135,8 +138,6 @@ done:
handled
=
append
(
handled
,
tx
)
handled
=
append
(
handled
,
tx
)
}
}
fmt
.
Println
(
"################# MADE
\n
"
,
receipts
,
"
\n
############################"
)
parent
.
GasUsed
=
totalUsedGas
parent
.
GasUsed
=
totalUsedGas
return
receipts
,
handled
,
unhandled
,
err
return
receipts
,
handled
,
unhandled
,
err
...
@@ -154,7 +155,7 @@ func (sm *StateManager) Process(block *Block, dontReact bool) error {
...
@@ -154,7 +155,7 @@ func (sm *StateManager) Process(block *Block, dontReact bool) error {
}
}
// Block processing and validating with a given (temporarily) state
// Block processing and validating with a given (temporarily) state
func
(
sm
*
StateManager
)
ProcessBlock
(
state
*
State
,
parent
,
block
*
Block
,
dontReact
bool
)
error
{
func
(
sm
*
StateManager
)
ProcessBlock
(
state
*
State
,
parent
,
block
*
Block
,
dontReact
bool
)
(
err
error
)
{
// Processing a blocks may never happen simultaneously
// Processing a blocks may never happen simultaneously
sm
.
mutex
.
Lock
()
sm
.
mutex
.
Lock
()
defer
sm
.
mutex
.
Unlock
()
defer
sm
.
mutex
.
Unlock
()
...
@@ -175,30 +176,40 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
...
@@ -175,30 +176,40 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea
if
!
sm
.
bc
.
HasBlock
(
block
.
PrevHash
)
&&
sm
.
bc
.
CurrentBlock
!=
nil
{
if
!
sm
.
bc
.
HasBlock
(
block
.
PrevHash
)
&&
sm
.
bc
.
CurrentBlock
!=
nil
{
return
ParentError
(
block
.
PrevHash
)
return
ParentError
(
block
.
PrevHash
)
}
}
fmt
.
Println
(
block
.
Receipts
())
coinbase
:=
state
.
GetOrNewStateObject
(
block
.
Coinbase
)
coinbase
:=
state
.
GetOrNewStateObject
(
block
.
Coinbase
)
coinbase
.
SetGasPool
(
block
.
CalcGasLimit
(
parent
))
coinbase
.
SetGasPool
(
block
.
CalcGasLimit
(
parent
))
// Process the transactions on to current block
// Process the transactions on to current block
//sm.ApplyTransactions(block.Coinbase, state, parent, block.Transactions())
receipts
,
_
,
_
,
_
:=
sm
.
ProcessTransactions
(
coinbase
,
state
,
block
,
parent
,
block
.
Transactions
())
sm
.
ProcessTransactions
(
coinbase
,
state
,
block
,
parent
,
block
.
Transactions
())
defer
func
()
{
if
err
!=
nil
{
if
len
(
receipts
)
==
len
(
block
.
Receipts
())
{
for
i
,
receipt
:=
range
block
.
Receipts
()
{
ethutil
.
Config
.
Log
.
Debugf
(
"diff (r) %v ~ %x <=> (c) %v ~ %x (%x)
\n
"
,
receipt
.
CumulativeGasUsed
,
receipt
.
PostState
[
0
:
4
],
receipts
[
i
]
.
CumulativeGasUsed
,
receipts
[
i
]
.
PostState
[
0
:
4
],
receipt
.
Tx
.
Hash
())
}
}
else
{
ethutil
.
Config
.
Log
.
Debugln
(
"Unable to print receipt diff. Length didn't match"
,
len
(
receipts
),
"for"
,
len
(
block
.
Receipts
()))
}
}
}()
// Block validation
// Block validation
if
err
:
=
sm
.
ValidateBlock
(
block
);
err
!=
nil
{
if
err
=
sm
.
ValidateBlock
(
block
);
err
!=
nil
{
fmt
.
Println
(
"[SM] Error validating block:"
,
err
)
fmt
.
Println
(
"[SM] Error validating block:"
,
err
)
return
err
return
err
}
}
// I'm not sure, but I don't know if there should be thrown
// I'm not sure, but I don't know if there should be thrown
// any errors at this time.
// any errors at this time.
if
err
:
=
sm
.
AccumelateRewards
(
state
,
block
);
err
!=
nil
{
if
err
=
sm
.
AccumelateRewards
(
state
,
block
);
err
!=
nil
{
fmt
.
Println
(
"[SM] Error accumulating reward"
,
err
)
fmt
.
Println
(
"[SM] Error accumulating reward"
,
err
)
return
err
return
err
}
}
if
!
block
.
State
()
.
Cmp
(
state
)
{
if
!
block
.
State
()
.
Cmp
(
state
)
{
return
fmt
.
Errorf
(
"Invalid merkle root.
\n
rec: %x
\n
is: %x"
,
block
.
State
()
.
trie
.
Root
,
state
.
trie
.
Root
)
err
=
fmt
.
Errorf
(
"Invalid merkle root.
\n
rec: %x
\n
is: %x"
,
block
.
State
()
.
trie
.
Root
,
state
.
trie
.
Root
)
return
}
}
// Calculate the new total difficulty and sync back to the db
// Calculate the new total difficulty and sync back to the db
...
@@ -270,10 +281,12 @@ func (sm *StateManager) ValidateBlock(block *Block) error {
...
@@ -270,10 +281,12 @@ func (sm *StateManager) ValidateBlock(block *Block) error {
return
ValidationError
(
"Block timestamp less then prev block %v"
,
diff
)
return
ValidationError
(
"Block timestamp less then prev block %v"
,
diff
)
}
}
/* XXX
// New blocks must be within the 15 minute range of the last block.
// New blocks must be within the 15 minute range of the last block.
if diff > int64(15*time.Minute) {
if diff > int64(15*time.Minute) {
return ValidationError("Block is too far in the future of last block (> 15 minutes)")
return ValidationError("Block is too far in the future of last block (> 15 minutes)")
}
}
*/
// Verify the nonce of the block. Return an error if it's not valid
// Verify the nonce of the block. Return an error if it's not valid
if
!
sm
.
Pow
.
Verify
(
block
.
HashNoNonce
(),
block
.
Difficulty
,
block
.
Nonce
)
{
if
!
sm
.
Pow
.
Verify
(
block
.
HashNoNonce
(),
block
.
Difficulty
,
block
.
Nonce
)
{
...
...
ethchain/state_object.go
View file @
3f1f8438
...
@@ -4,8 +4,15 @@ import (
...
@@ -4,8 +4,15 @@ import (
"fmt"
"fmt"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethutil"
"math/big"
"math/big"
"strings"
)
)
type
Code
[]
byte
func
(
self
Code
)
String
()
string
{
return
strings
.
Join
(
Disassemble
(
self
),
" "
)
}
type
StateObject
struct
{
type
StateObject
struct
{
// Address of the object
// Address of the object
address
[]
byte
address
[]
byte
...
@@ -15,8 +22,8 @@ type StateObject struct {
...
@@ -15,8 +22,8 @@ type StateObject struct {
Nonce
uint64
Nonce
uint64
// Contract related attributes
// Contract related attributes
state
*
State
state
*
State
script
[]
byt
e
script
Cod
e
initScript
[]
byt
e
initScript
Cod
e
// Total gas pool is the total amount of gas currently
// Total gas pool is the total amount of gas currently
// left if this object is the coinbase. Gas is directly
// left if this object is the coinbase. Gas is directly
...
@@ -30,12 +37,9 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
...
@@ -30,12 +37,9 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
if
tx
.
IsContract
()
{
if
tx
.
IsContract
()
{
addr
:=
tx
.
CreationAddress
()
addr
:=
tx
.
CreationAddress
()
value
:=
tx
.
Value
contract
:=
state
.
NewStateObject
(
addr
)
contract
:=
NewContract
(
addr
,
value
,
ZeroHash256
)
contract
.
initScript
=
tx
.
Data
contract
.
initScript
=
tx
.
Data
contract
.
state
=
NewState
(
ethutil
.
NewTrie
(
ethutil
.
Config
.
Db
,
""
))
state
.
UpdateStateObject
(
contract
)
return
contract
return
contract
}
}
...
@@ -44,7 +48,7 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
...
@@ -44,7 +48,7 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
}
}
func
NewStateObject
(
addr
[]
byte
)
*
StateObject
{
func
NewStateObject
(
addr
[]
byte
)
*
StateObject
{
return
&
StateObject
{
address
:
addr
,
Amount
:
new
(
big
.
Int
)}
return
&
StateObject
{
address
:
addr
,
Amount
:
new
(
big
.
Int
)
,
gasPool
:
new
(
big
.
Int
)
}
}
}
func
NewContract
(
address
[]
byte
,
Amount
*
big
.
Int
,
root
[]
byte
)
*
StateObject
{
func
NewContract
(
address
[]
byte
,
Amount
*
big
.
Int
,
root
[]
byte
)
*
StateObject
{
...
@@ -120,13 +124,13 @@ func (c *StateObject) ReturnGas(gas, price *big.Int, state *State) {
...
@@ -120,13 +124,13 @@ func (c *StateObject) ReturnGas(gas, price *big.Int, state *State) {
func
(
c
*
StateObject
)
AddAmount
(
amount
*
big
.
Int
)
{
func
(
c
*
StateObject
)
AddAmount
(
amount
*
big
.
Int
)
{
c
.
SetAmount
(
new
(
big
.
Int
)
.
Add
(
c
.
Amount
,
amount
))
c
.
SetAmount
(
new
(
big
.
Int
)
.
Add
(
c
.
Amount
,
amount
))
ethutil
.
Config
.
Log
.
Printf
(
ethutil
.
LogLevel
System
,
"%x: #%d %v (+ %v)
\n
"
,
c
.
Address
(),
c
.
Nonce
,
c
.
Amount
,
amount
)
ethutil
.
Config
.
Log
.
Printf
(
ethutil
.
LogLevel
Info
,
"%x: #%d %v (+ %v)
\n
"
,
c
.
Address
(),
c
.
Nonce
,
c
.
Amount
,
amount
)
}
}
func
(
c
*
StateObject
)
SubAmount
(
amount
*
big
.
Int
)
{
func
(
c
*
StateObject
)
SubAmount
(
amount
*
big
.
Int
)
{
c
.
SetAmount
(
new
(
big
.
Int
)
.
Sub
(
c
.
Amount
,
amount
))
c
.
SetAmount
(
new
(
big
.
Int
)
.
Sub
(
c
.
Amount
,
amount
))
ethutil
.
Config
.
Log
.
Printf
(
ethutil
.
LogLevel
System
,
"%x: #%d %v (- %v)
\n
"
,
c
.
Address
(),
c
.
Nonce
,
c
.
Amount
,
amount
)
ethutil
.
Config
.
Log
.
Printf
(
ethutil
.
LogLevel
Info
,
"%x: #%d %v (- %v)
\n
"
,
c
.
Address
(),
c
.
Nonce
,
c
.
Amount
,
amount
)
}
}
func
(
c
*
StateObject
)
SetAmount
(
amount
*
big
.
Int
)
{
func
(
c
*
StateObject
)
SetAmount
(
amount
*
big
.
Int
)
{
...
@@ -172,6 +176,26 @@ func (self *StateObject) RefundGas(gas, price *big.Int) {
...
@@ -172,6 +176,26 @@ func (self *StateObject) RefundGas(gas, price *big.Int) {
self
.
Amount
.
Sub
(
self
.
Amount
,
rGas
)
self
.
Amount
.
Sub
(
self
.
Amount
,
rGas
)
}
}
func
(
self
*
StateObject
)
Copy
()
*
StateObject
{
stateObject
:=
NewStateObject
(
self
.
Address
())
stateObject
.
Amount
.
Set
(
self
.
Amount
)
stateObject
.
ScriptHash
=
ethutil
.
CopyBytes
(
self
.
ScriptHash
)
stateObject
.
Nonce
=
self
.
Nonce
if
self
.
state
!=
nil
{
stateObject
.
state
=
self
.
state
.
Copy
()
}
stateObject
.
script
=
ethutil
.
CopyBytes
(
self
.
script
)
stateObject
.
initScript
=
ethutil
.
CopyBytes
(
self
.
initScript
)
//stateObject.gasPool.Set(self.gasPool)
return
self
}
func
(
self
*
StateObject
)
Set
(
stateObject
*
StateObject
)
{
self
=
stateObject
}
/*
func (self *StateObject) Copy() *StateObject {
func (self *StateObject) Copy() *StateObject {
stCopy := &StateObject{}
stCopy := &StateObject{}
stCopy.address = make([]byte, len(self.address))
stCopy.address = make([]byte, len(self.address))
...
@@ -190,6 +214,7 @@ func (self *StateObject) Copy() *StateObject {
...
@@ -190,6 +214,7 @@ func (self *StateObject) Copy() *StateObject {
return stCopy
return stCopy
}
}
*/
// Returns the address of the contract/account
// Returns the address of the contract/account
func
(
c
*
StateObject
)
Address
()
[]
byte
{
func
(
c
*
StateObject
)
Address
()
[]
byte
{
...
@@ -197,12 +222,12 @@ func (c *StateObject) Address() []byte {
...
@@ -197,12 +222,12 @@ func (c *StateObject) Address() []byte {
}
}
// Returns the main script body
// Returns the main script body
func
(
c
*
StateObject
)
Script
()
[]
byt
e
{
func
(
c
*
StateObject
)
Script
()
Cod
e
{
return
c
.
script
return
c
.
script
}
}
// Returns the initialization script
// Returns the initialization script
func
(
c
*
StateObject
)
Init
()
[]
byt
e
{
func
(
c
*
StateObject
)
Init
()
Cod
e
{
return
c
.
initScript
return
c
.
initScript
}
}
...
...
ethchain/state_transition.go
View file @
3f1f8438
...
@@ -23,17 +23,19 @@ import (
...
@@ -23,17 +23,19 @@ import (
* 6) Derive new state root
* 6) Derive new state root
*/
*/
type
StateTransition
struct
{
type
StateTransition
struct
{
coinbase
[]
byte
coinbase
,
receiver
[]
byte
tx
*
Transaction
tx
*
Transaction
gas
*
big
.
Int
gas
,
gasPrice
*
big
.
Int
state
*
State
value
*
big
.
Int
block
*
Block
data
[]
byte
state
*
State
block
*
Block
cb
,
rec
,
sen
*
StateObject
cb
,
rec
,
sen
*
StateObject
}
}
func
NewStateTransition
(
coinbase
*
StateObject
,
tx
*
Transaction
,
state
*
State
,
block
*
Block
)
*
StateTransition
{
func
NewStateTransition
(
coinbase
*
StateObject
,
tx
*
Transaction
,
state
*
State
,
block
*
Block
)
*
StateTransition
{
return
&
StateTransition
{
coinbase
.
Address
(),
tx
,
new
(
big
.
Int
)
,
state
,
block
,
coinbase
,
nil
,
nil
}
return
&
StateTransition
{
coinbase
.
Address
(),
tx
.
Recipient
,
tx
,
new
(
big
.
Int
),
new
(
big
.
Int
)
.
Set
(
tx
.
GasPrice
),
tx
.
Value
,
tx
.
Data
,
state
,
block
,
coinbase
,
nil
,
nil
}
}
}
func
(
self
*
StateTransition
)
Coinbase
()
*
StateObject
{
func
(
self
*
StateTransition
)
Coinbase
()
*
StateObject
{
...
@@ -53,7 +55,7 @@ func (self *StateTransition) Sender() *StateObject {
...
@@ -53,7 +55,7 @@ func (self *StateTransition) Sender() *StateObject {
return
self
.
sen
return
self
.
sen
}
}
func
(
self
*
StateTransition
)
Receiver
()
*
StateObject
{
func
(
self
*
StateTransition
)
Receiver
()
*
StateObject
{
if
self
.
tx
.
CreatesContract
()
{
if
self
.
tx
!=
nil
&&
self
.
tx
.
CreatesContract
()
{
return
nil
return
nil
}
}
...
@@ -67,13 +69,8 @@ func (self *StateTransition) Receiver() *StateObject {
...
@@ -67,13 +69,8 @@ func (self *StateTransition) Receiver() *StateObject {
func
(
self
*
StateTransition
)
MakeStateObject
(
state
*
State
,
tx
*
Transaction
)
*
StateObject
{
func
(
self
*
StateTransition
)
MakeStateObject
(
state
*
State
,
tx
*
Transaction
)
*
StateObject
{
contract
:=
MakeContract
(
tx
,
state
)
contract
:=
MakeContract
(
tx
,
state
)
if
contract
!=
nil
{
state
.
states
[
string
(
tx
.
CreationAddress
())]
=
contract
.
state
return
contract
return
contract
}
return
nil
}
}
func
(
self
*
StateTransition
)
UseGas
(
amount
*
big
.
Int
)
error
{
func
(
self
*
StateTransition
)
UseGas
(
amount
*
big
.
Int
)
error
{
...
@@ -94,7 +91,7 @@ func (self *StateTransition) BuyGas() error {
...
@@ -94,7 +91,7 @@ func (self *StateTransition) BuyGas() error {
sender
:=
self
.
Sender
()
sender
:=
self
.
Sender
()
if
sender
.
Amount
.
Cmp
(
self
.
tx
.
GasValue
())
<
0
{
if
sender
.
Amount
.
Cmp
(
self
.
tx
.
GasValue
())
<
0
{
return
fmt
.
Errorf
(
"Insufficient funds to pre-pay gas. Req %v, has %v"
,
self
.
tx
.
GasValue
(),
se
lf
.
tx
.
Value
)
return
fmt
.
Errorf
(
"Insufficient funds to pre-pay gas. Req %v, has %v"
,
self
.
tx
.
GasValue
(),
se
nder
.
Amount
)
}
}
coinbase
:=
self
.
Coinbase
()
coinbase
:=
self
.
Coinbase
()
...
@@ -102,7 +99,6 @@ func (self *StateTransition) BuyGas() error {
...
@@ -102,7 +99,6 @@ func (self *StateTransition) BuyGas() error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
//self.state.UpdateStateObject(coinbase)
self
.
AddGas
(
self
.
tx
.
Gas
)
self
.
AddGas
(
self
.
tx
.
Gas
)
sender
.
SubAmount
(
self
.
tx
.
GasValue
())
sender
.
SubAmount
(
self
.
tx
.
GasValue
())
...
@@ -119,22 +115,10 @@ func (self *StateTransition) RefundGas() {
...
@@ -119,22 +115,10 @@ func (self *StateTransition) RefundGas() {
sender
.
AddAmount
(
remaining
)
sender
.
AddAmount
(
remaining
)
}
}
func
(
self
*
StateTransition
)
TransitionState
()
(
err
error
)
{
func
(
self
*
StateTransition
)
preCheck
()
(
err
error
)
{
//snapshot := st.state.Snapshot()
/*
defer func() {
if r := recover(); r != nil {
ethutil.Config.Log.Infoln(r)
err = fmt.Errorf("state transition err %v", r)
}
}()
*/
var
(
var
(
tx
=
self
.
tx
tx
=
self
.
tx
sender
=
self
.
Sender
()
sender
=
self
.
Sender
()
receiver
*
StateObject
)
)
// Make sure this transaction's nonce is correct
// Make sure this transaction's nonce is correct
...
@@ -147,38 +131,49 @@ func (self *StateTransition) TransitionState() (err error) {
...
@@ -147,38 +131,49 @@ func (self *StateTransition) TransitionState() (err error) {
return
err
return
err
}
}
// XXX Transactions after this point are considered valid.
return
nil
}
defer
func
(
)
{
func
(
self
*
StateTransition
)
TransitionState
()
(
err
error
)
{
self
.
RefundGas
(
)
ethutil
.
Config
.
Log
.
Printf
(
ethutil
.
LogLevelInfo
,
"(~) %x
\n
"
,
self
.
tx
.
Hash
()
)
if
sender
!=
nil
{
/*
self
.
state
.
UpdateStateObject
(
sender
)
defer func() {
}
if r := recover(); r != nil {
ethutil.Config.Log.Infoln(r)
err = fmt.Errorf("state transition err %v", r)
}
}()
*/
if
receiver
!=
nil
{
// XXX Transactions after this point are considered valid.
self
.
state
.
UpdateStateObject
(
receiver
)
if
err
=
self
.
preCheck
();
err
!=
nil
{
}
return
}
var
(
tx
=
self
.
tx
sender
=
self
.
Sender
()
receiver
*
StateObject
)
self
.
state
.
UpdateStateObject
(
self
.
Coinbase
())
defer
self
.
RefundGas
()
}()
// Increment the nonce for the next transaction
// Increment the nonce for the next transaction
sender
.
Nonce
+=
1
sender
.
Nonce
+=
1
// Get the receiver (TODO fix this, if coinbase is the receiver we need to save/retrieve)
receiver
=
self
.
Receiver
()
receiver
=
self
.
Receiver
()
// Transaction gas
// Transaction gas
if
err
=
self
.
UseGas
(
GasTx
);
err
!=
nil
{
if
err
=
self
.
UseGas
(
GasTx
);
err
!=
nil
{
return
err
return
}
}
// Pay data gas
// Pay data gas
dataPrice
:=
big
.
NewInt
(
int64
(
len
(
tx
.
D
ata
)))
dataPrice
:=
big
.
NewInt
(
int64
(
len
(
self
.
d
ata
)))
dataPrice
.
Mul
(
dataPrice
,
GasData
)
dataPrice
.
Mul
(
dataPrice
,
GasData
)
if
err
=
self
.
UseGas
(
dataPrice
);
err
!=
nil
{
if
err
=
self
.
UseGas
(
dataPrice
);
err
!=
nil
{
return
err
return
}
}
// If the receiver is nil it's a contract (\0*32).
// If the receiver is nil it's a contract (\0*32).
...
@@ -186,75 +181,83 @@ func (self *StateTransition) TransitionState() (err error) {
...
@@ -186,75 +181,83 @@ func (self *StateTransition) TransitionState() (err error) {
// Create a new state object for the contract
// Create a new state object for the contract
receiver
=
self
.
MakeStateObject
(
self
.
state
,
tx
)
receiver
=
self
.
MakeStateObject
(
self
.
state
,
tx
)
if
receiver
==
nil
{
if
receiver
==
nil
{
return
fmt
.
Errorf
(
"
ERR. Unable to create contract with transaction %v"
,
tx
)
return
fmt
.
Errorf
(
"
Unable to create contract"
)
}
}
}
}
// Transfer value from sender to receiver
// Transfer value from sender to receiver
if
err
=
self
.
transferValue
(
sender
,
receiver
);
err
!=
nil
{
if
err
=
self
.
transferValue
(
sender
,
receiver
);
err
!=
nil
{
return
err
return
}
}
// Process the init code and create 'valid' contract
// Process the init code and create 'valid' contract
if
tx
.
CreatesContract
(
)
{
if
IsContractAddr
(
self
.
receiver
)
{
// Evaluate the initialization script
// Evaluate the initialization script
// and use the return value as the
// and use the return value as the
// script section for the state object.
// script section for the state object.
//script, gas, err = sm.Eval(state, contract.Init(), contract, tx, block)
self
.
data
=
nil
code
,
err
:=
self
.
Eval
(
receiver
.
Init
(),
receiver
)
if
err
!=
nil
{
code
,
err
,
deepErr
:=
self
.
Eval
(
receiver
.
Init
(),
receiver
)
return
fmt
.
Errorf
(
"Error during init script run %v"
,
err
)
if
err
!=
nil
||
deepErr
{
self
.
state
.
ResetStateObject
(
receiver
)
return
fmt
.
Errorf
(
"Error during init script run %v (deepErr = %v)"
,
err
,
deepErr
)
}
}
receiver
.
script
=
code
receiver
.
script
=
code
}
else
{
}
else
{
if
len
(
receiver
.
Script
())
>
0
{
if
len
(
receiver
.
Script
())
>
0
{
_
,
err
:=
self
.
Eval
(
receiver
.
Script
(),
receiver
)
var
deepErr
bool
_
,
err
,
deepErr
=
self
.
Eval
(
receiver
.
Script
(),
receiver
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Error during code execution %v"
,
err
)
self
.
state
.
ResetStateObject
(
receiver
)
return
fmt
.
Errorf
(
"Error during code execution %v (deepErr = %v)"
,
err
,
deepErr
)
}
}
}
}
}
}
return
nil
return
}
}
func
(
self
*
StateTransition
)
transferValue
(
sender
,
receiver
*
StateObject
)
error
{
func
(
self
*
StateTransition
)
transferValue
(
sender
,
receiver
*
StateObject
)
error
{
if
sender
.
Amount
.
Cmp
(
self
.
tx
.
V
alue
)
<
0
{
if
sender
.
Amount
.
Cmp
(
self
.
v
alue
)
<
0
{
return
fmt
.
Errorf
(
"Insufficient funds to transfer value. Req %v, has %v"
,
self
.
tx
.
V
alue
,
sender
.
Amount
)
return
fmt
.
Errorf
(
"Insufficient funds to transfer value. Req %v, has %v"
,
self
.
v
alue
,
sender
.
Amount
)
}
}
if
self
.
tx
.
V
alue
.
Cmp
(
ethutil
.
Big0
)
>
0
{
//if self.v
alue.Cmp(ethutil.Big0) > 0 {
// Subtract the amount from the senders account
// Subtract the amount from the senders account
sender
.
SubAmount
(
self
.
tx
.
V
alue
)
sender
.
SubAmount
(
self
.
v
alue
)
// Add the amount to receivers account which should conclude this transaction
// Add the amount to receivers account which should conclude this transaction
receiver
.
AddAmount
(
self
.
tx
.
V
alue
)
receiver
.
AddAmount
(
self
.
v
alue
)
ethutil
.
Config
.
Log
.
Debugf
(
"%x => %x (%v) %x
\n
"
,
sender
.
Address
()[
:
4
],
receiver
.
Address
()[
:
4
],
self
.
tx
.
Value
,
self
.
tx
.
Hash
()
)
//ethutil.Config.Log.Debugf("%x => %x (%v)\n", sender.Address()[:4], receiver.Address()[:4], self.value
)
}
//
}
return
nil
return
nil
}
}
func
(
self
*
StateTransition
)
Eval
(
script
[]
byte
,
context
*
StateObject
)
(
ret
[]
byte
,
err
error
)
{
func
(
self
*
StateTransition
)
Eval
(
script
[]
byte
,
context
*
StateObject
)
(
ret
[]
byte
,
err
error
,
deepErr
bool
)
{
var
(
var
(
tx
=
self
.
tx
block
=
self
.
block
block
=
self
.
block
initiator
=
self
.
Sender
()
initiator
=
self
.
Sender
()
state
=
self
.
state
state
=
self
.
state
)
)
closure
:=
NewClosure
(
initiator
,
context
,
script
,
state
,
self
.
gas
,
tx
.
G
asPrice
)
closure
:=
NewClosure
(
initiator
,
context
,
script
,
state
,
self
.
gas
,
self
.
g
asPrice
)
vm
:=
NewVm
(
state
,
nil
,
RuntimeVars
{
vm
:=
NewVm
(
state
,
nil
,
RuntimeVars
{
Origin
:
initiator
.
Address
(),
Origin
:
initiator
.
Address
(),
BlockNumber
:
block
.
BlockInfo
()
.
Number
,
Block
:
block
,
BlockNumber
:
block
.
Number
,
PrevHash
:
block
.
PrevHash
,
PrevHash
:
block
.
PrevHash
,
Coinbase
:
block
.
Coinbase
,
Coinbase
:
block
.
Coinbase
,
Time
:
block
.
Time
,
Time
:
block
.
Time
,
Diff
:
block
.
Difficulty
,
Diff
:
block
.
Difficulty
,
Value
:
tx
.
V
alue
,
Value
:
self
.
v
alue
,
})
})
ret
,
_
,
err
=
closure
.
Call
(
vm
,
tx
.
Data
,
nil
)
vm
.
Verbose
=
true
ret
,
_
,
err
=
closure
.
Call
(
vm
,
self
.
data
,
nil
)
deepErr
=
vm
.
err
!=
nil
return
return
}
}
ethchain/transaction.go
View file @
3f1f8438
...
@@ -10,6 +10,10 @@ import (
...
@@ -10,6 +10,10 @@ import (
var
ContractAddr
=
[]
byte
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
var
ContractAddr
=
[]
byte
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
func
IsContractAddr
(
addr
[]
byte
)
bool
{
return
bytes
.
Compare
(
addr
,
ContractAddr
)
==
0
}
type
Transaction
struct
{
type
Transaction
struct
{
Nonce
uint64
Nonce
uint64
Recipient
[]
byte
Recipient
[]
byte
...
@@ -65,7 +69,7 @@ func (tx *Transaction) CreatesContract() bool {
...
@@ -65,7 +69,7 @@ func (tx *Transaction) CreatesContract() bool {
return
tx
.
contractCreation
return
tx
.
contractCreation
}
}
/* Depr
i
cated */
/* Depr
e
cated */
func
(
tx
*
Transaction
)
IsContract
()
bool
{
func
(
tx
*
Transaction
)
IsContract
()
bool
{
return
tx
.
CreatesContract
()
return
tx
.
CreatesContract
()
}
}
...
@@ -149,7 +153,7 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
...
@@ -149,7 +153,7 @@ 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
()
if
bytes
.
Compare
(
tx
.
Recipient
,
ContractAddr
)
==
0
{
if
IsContractAddr
(
tx
.
Recipient
)
{
tx
.
contractCreation
=
true
tx
.
contractCreation
=
true
}
}
}
}
...
...
ethchain/types.go
View file @
3f1f8438
...
@@ -166,6 +166,7 @@ var opCodeToString = map[OpCode]string{
...
@@ -166,6 +166,7 @@ var opCodeToString = map[OpCode]string{
GASLIMIT
:
"GASLIMIT"
,
GASLIMIT
:
"GASLIMIT"
,
// 0x50 range - 'storage' and execution
// 0x50 range - 'storage' and execution
POP
:
"POP"
,
DUP
:
"DUP"
,
DUP
:
"DUP"
,
SWAP
:
"SWAP"
,
SWAP
:
"SWAP"
,
MLOAD
:
"MLOAD"
,
MLOAD
:
"MLOAD"
,
...
@@ -226,7 +227,7 @@ var opCodeToString = map[OpCode]string{
...
@@ -226,7 +227,7 @@ var opCodeToString = map[OpCode]string{
func
(
o
OpCode
)
String
()
string
{
func
(
o
OpCode
)
String
()
string
{
str
:=
opCodeToString
[
o
]
str
:=
opCodeToString
[
o
]
if
len
(
str
)
==
0
{
if
len
(
str
)
==
0
{
return
fmt
.
Sprintf
(
"Missing opcode
%#
x"
,
int
(
o
))
return
fmt
.
Sprintf
(
"Missing opcode
0x%
x"
,
int
(
o
))
}
}
return
str
return
str
...
...
ethchain/vm.go
View file @
3f1f8438
This diff is collapsed.
Click to expand it.
ethereum.go
View file @
3f1f8438
...
@@ -149,7 +149,9 @@ func (s *Ethereum) IsUpToDate() bool {
...
@@ -149,7 +149,9 @@ func (s *Ethereum) IsUpToDate() bool {
})
})
return
upToDate
return
upToDate
}
}
func
(
s
*
Ethereum
)
PushPeer
(
peer
*
Peer
)
{
s
.
peers
.
PushBack
(
peer
)
}
func
(
s
*
Ethereum
)
IsListening
()
bool
{
func
(
s
*
Ethereum
)
IsListening
()
bool
{
return
s
.
listening
return
s
.
listening
}
}
...
@@ -159,14 +161,11 @@ func (s *Ethereum) AddPeer(conn net.Conn) {
...
@@ -159,14 +161,11 @@ func (s *Ethereum) AddPeer(conn net.Conn) {
if
peer
!=
nil
{
if
peer
!=
nil
{
if
s
.
peers
.
Len
()
<
s
.
MaxPeers
{
if
s
.
peers
.
Len
()
<
s
.
MaxPeers
{
s
.
peers
.
PushBack
(
peer
)
peer
.
Start
()
peer
.
Start
()
}
else
{
}
else
{
ethutil
.
Config
.
Log
.
Debugf
(
"[SERV] Max connected peers reached. Not adding incoming peer."
)
ethutil
.
Config
.
Log
.
Debugf
(
"[SERV] Max connected peers reached. Not adding incoming peer."
)
}
}
}
}
s
.
reactor
.
Post
(
"peerList"
,
s
.
peers
)
}
}
func
(
s
*
Ethereum
)
ProcessPeerList
(
addrs
[]
string
)
{
func
(
s
*
Ethereum
)
ProcessPeerList
(
addrs
[]
string
)
{
...
@@ -233,12 +232,7 @@ func (s *Ethereum) ConnectToPeer(addr string) error {
...
@@ -233,12 +232,7 @@ func (s *Ethereum) ConnectToPeer(addr string) error {
return
nil
return
nil
}
}
peer
:=
NewOutboundPeer
(
addr
,
s
,
s
.
serverCaps
)
NewOutboundPeer
(
addr
,
s
,
s
.
serverCaps
)
s
.
peers
.
PushBack
(
peer
)
ethutil
.
Config
.
Log
.
Infof
(
"[SERV] Adding peer (%s) %d / %d
\n
"
,
addr
,
s
.
peers
.
Len
(),
s
.
MaxPeers
)
s
.
reactor
.
Post
(
"peerList"
,
s
.
peers
)
}
}
return
nil
return
nil
...
...
ethminer/miner.go
View file @
3f1f8438
...
@@ -154,6 +154,8 @@ func (self *Miner) mineNewBlock() {
...
@@ -154,6 +154,8 @@ func (self *Miner) mineNewBlock() {
// 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
)
self
.
block
.
State
()
.
Update
()
ethutil
.
Config
.
Log
.
Infoln
(
"[MINER] Mining on block. Includes"
,
len
(
self
.
txs
),
"transactions"
)
ethutil
.
Config
.
Log
.
Infoln
(
"[MINER] Mining on block. Includes"
,
len
(
self
.
txs
),
"transactions"
)
// Find a valid nonce
// Find a valid nonce
...
...
ethpub/pub.go
View file @
3f1f8438
...
@@ -170,11 +170,6 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, sc
...
@@ -170,11 +170,6 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, sc
tx
=
ethchain
.
NewContractCreationTx
(
value
,
gas
,
gasPrice
,
script
)
tx
=
ethchain
.
NewContractCreationTx
(
value
,
gas
,
gasPrice
,
script
)
}
else
{
}
else
{
// Just in case it was submitted as a 0x prefixed string
if
len
(
scriptStr
)
>
0
&&
scriptStr
[
0
:
2
]
==
"0x"
{
scriptStr
=
scriptStr
[
2
:
len
(
scriptStr
)]
}
data
:=
ethutil
.
StringToByteFunc
(
scriptStr
,
func
(
s
string
)
(
ret
[]
byte
)
{
data
:=
ethutil
.
StringToByteFunc
(
scriptStr
,
func
(
s
string
)
(
ret
[]
byte
)
{
slice
:=
strings
.
Split
(
s
,
"
\n
"
)
slice
:=
strings
.
Split
(
s
,
"
\n
"
)
for
_
,
dataItem
:=
range
slice
{
for
_
,
dataItem
:=
range
slice
{
...
...
ethpub/types.go
View file @
3f1f8438
...
@@ -104,16 +104,17 @@ type PTx struct {
...
@@ -104,16 +104,17 @@ type PTx struct {
func
NewPTx
(
tx
*
ethchain
.
Transaction
)
*
PTx
{
func
NewPTx
(
tx
*
ethchain
.
Transaction
)
*
PTx
{
hash
:=
hex
.
EncodeToString
(
tx
.
Hash
())
hash
:=
hex
.
EncodeToString
(
tx
.
Hash
())
receiver
:=
hex
.
EncodeToString
(
tx
.
Recipient
)
receiver
:=
hex
.
EncodeToString
(
tx
.
Recipient
)
if
receiver
==
"0000000000000000000000000000000000000000"
{
if
receiver
==
""
{
receiver
=
hex
.
EncodeToString
(
tx
.
CreationAddress
())
receiver
=
hex
.
EncodeToString
(
tx
.
CreationAddress
())
}
}
sender
:=
hex
.
EncodeToString
(
tx
.
Sender
())
sender
:=
hex
.
EncodeToString
(
tx
.
Sender
())
createsContract
:=
tx
.
CreatesContract
()
createsContract
:=
tx
.
CreatesContract
()
data
:=
string
(
tx
.
Data
)
var
data
string
if
tx
.
CreatesContract
()
{
if
tx
.
CreatesContract
()
{
data
=
strings
.
Join
(
ethchain
.
Disassemble
(
tx
.
Data
),
"
\n
"
)
data
=
strings
.
Join
(
ethchain
.
Disassemble
(
tx
.
Data
),
"
\n
"
)
}
else
{
data
=
hex
.
EncodeToString
(
tx
.
Data
)
}
}
return
&
PTx
{
ref
:
tx
,
Hash
:
hash
,
Value
:
ethutil
.
CurrencyToString
(
tx
.
Value
),
Address
:
receiver
,
Contract
:
tx
.
CreatesContract
(),
Gas
:
tx
.
Gas
.
String
(),
GasPrice
:
tx
.
GasPrice
.
String
(),
Data
:
data
,
Sender
:
sender
,
CreatesContract
:
createsContract
,
RawData
:
hex
.
EncodeToString
(
tx
.
Data
)}
return
&
PTx
{
ref
:
tx
,
Hash
:
hash
,
Value
:
ethutil
.
CurrencyToString
(
tx
.
Value
),
Address
:
receiver
,
Contract
:
tx
.
CreatesContract
(),
Gas
:
tx
.
Gas
.
String
(),
GasPrice
:
tx
.
GasPrice
.
String
(),
Data
:
data
,
Sender
:
sender
,
CreatesContract
:
createsContract
,
RawData
:
hex
.
EncodeToString
(
tx
.
Data
)}
...
...
ethutil/bytes.go
View file @
3f1f8438
...
@@ -5,6 +5,7 @@ import (
...
@@ -5,6 +5,7 @@ import (
"encoding/binary"
"encoding/binary"
"fmt"
"fmt"
"math/big"
"math/big"
"strings"
)
)
// Number to bytes
// Number to bytes
...
@@ -91,7 +92,7 @@ func IsHex(str string) bool {
...
@@ -91,7 +92,7 @@ func IsHex(str string) bool {
}
}
func
StringToByteFunc
(
str
string
,
cb
func
(
str
string
)
[]
byte
)
(
ret
[]
byte
)
{
func
StringToByteFunc
(
str
string
,
cb
func
(
str
string
)
[]
byte
)
(
ret
[]
byte
)
{
if
len
(
str
)
>
1
&&
str
[
0
:
2
]
==
"0x"
{
if
len
(
str
)
>
1
&&
str
[
0
:
2
]
==
"0x"
&&
!
strings
.
Contains
(
str
,
"
\n
"
)
{
ret
=
FromHex
(
str
[
2
:
])
ret
=
FromHex
(
str
[
2
:
])
}
else
{
}
else
{
ret
=
cb
(
str
)
ret
=
cb
(
str
)
...
...
ethutil/config.go
View file @
3f1f8438
...
@@ -75,7 +75,7 @@ func ReadConfig(base string, logTypes LoggerType, g *globalconf.GlobalConf, id s
...
@@ -75,7 +75,7 @@ func ReadConfig(base string, logTypes LoggerType, g *globalconf.GlobalConf, id s
if
Config
==
nil
{
if
Config
==
nil
{
path
:=
ApplicationFolder
(
base
)
path
:=
ApplicationFolder
(
base
)
Config
=
&
config
{
ExecPath
:
path
,
Debug
:
true
,
Ver
:
"0.5.1
3
"
}
Config
=
&
config
{
ExecPath
:
path
,
Debug
:
true
,
Ver
:
"0.5.1
4
"
}
Config
.
conf
=
g
Config
.
conf
=
g
Config
.
Identifier
=
id
Config
.
Identifier
=
id
Config
.
Log
=
NewLogger
(
logTypes
,
LogLevelDebug
)
Config
.
Log
=
NewLogger
(
logTypes
,
LogLevelDebug
)
...
...
ethutil/trie_test.go
View file @
3f1f8438
...
@@ -173,12 +173,21 @@ func TestTriePurge(t *testing.T) {
...
@@ -173,12 +173,21 @@ func TestTriePurge(t *testing.T) {
func
TestTrieIt
(
t
*
testing
.
T
)
{
func
TestTrieIt
(
t
*
testing
.
T
)
{
_
,
trie
:=
New
()
_
,
trie
:=
New
()
trie
.
Update
(
"c"
,
LONG_WORD
)
trie
.
Update
(
"ca"
,
LONG_WORD
)
trie
.
Update
(
"cat"
,
LONG_WORD
)
it
:=
trie
.
NewIterator
()
data
:=
[][]
string
{
it
.
Each
(
func
(
key
string
,
node
*
Value
)
{
{
"do"
,
"verb"
},
fmt
.
Println
(
key
,
":"
,
node
.
Str
())
{
"ether"
,
"wookiedoo"
},
})
{
"horse"
,
"stallion"
},
{
"shaman"
,
"horse"
},
{
"doge"
,
"coin"
},
{
"ether"
,
""
},
{
"dog"
,
"puppy"
},
{
"shaman"
,
""
},
}
for
_
,
item
:=
range
data
{
trie
.
Update
(
item
[
0
],
item
[
1
])
}
fmt
.
Printf
(
"root %x"
,
trie
.
Root
)
}
}
ethutil/value.go
View file @
3f1f8438
...
@@ -114,6 +114,8 @@ func (val *Value) Str() string {
...
@@ -114,6 +114,8 @@ func (val *Value) Str() string {
func
(
val
*
Value
)
Bytes
()
[]
byte
{
func
(
val
*
Value
)
Bytes
()
[]
byte
{
if
a
,
ok
:=
val
.
Val
.
([]
byte
);
ok
{
if
a
,
ok
:=
val
.
Val
.
([]
byte
);
ok
{
return
a
return
a
}
else
if
s
,
ok
:=
val
.
Val
.
(
byte
);
ok
{
return
[]
byte
{
s
}
}
}
return
[]
byte
{}
return
[]
byte
{}
...
...
peer.go
View file @
3f1f8438
...
@@ -2,6 +2,7 @@ package eth
...
@@ -2,6 +2,7 @@ package eth
import
(
import
(
"bytes"
"bytes"
"container/list"
"fmt"
"fmt"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethutil"
...
@@ -124,6 +125,7 @@ type Peer struct {
...
@@ -124,6 +125,7 @@ type Peer struct {
port
uint16
port
uint16
caps
Caps
caps
Caps
// This peer's public key
pubkey
[]
byte
pubkey
[]
byte
// Indicated whether the node is catching up or not
// Indicated whether the node is catching up or not
...
@@ -171,7 +173,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
...
@@ -171,7 +173,7 @@ func NewOutboundPeer(addr string, ethereum *Ethereum, caps Caps) *Peer {
// Set up the connection in another goroutine so we don't block the main thread
// Set up the connection in another goroutine so we don't block the main thread
go
func
()
{
go
func
()
{
conn
,
err
:=
net
.
DialTimeout
(
"tcp"
,
addr
,
3
0
*
time
.
Second
)
conn
,
err
:=
net
.
DialTimeout
(
"tcp"
,
addr
,
1
0
*
time
.
Second
)
if
err
!=
nil
{
if
err
!=
nil
{
ethutil
.
Config
.
Log
.
Debugln
(
"Connection to peer failed"
,
err
)
ethutil
.
Config
.
Log
.
Debugln
(
"Connection to peer failed"
,
err
)
...
@@ -614,6 +616,30 @@ func (p *Peer) pushPeers() {
...
@@ -614,6 +616,30 @@ func (p *Peer) pushPeers() {
func
(
p
*
Peer
)
handleHandshake
(
msg
*
ethwire
.
Msg
)
{
func
(
p
*
Peer
)
handleHandshake
(
msg
*
ethwire
.
Msg
)
{
c
:=
msg
.
Data
c
:=
msg
.
Data
// Set pubkey
p
.
pubkey
=
c
.
Get
(
5
)
.
Bytes
()
if
p
.
pubkey
==
nil
{
//ethutil.Config.Log.Debugln("Pubkey required, not supplied in handshake.")
p
.
Stop
()
return
}
usedPub
:=
0
// This peer is already added to the peerlist so we expect to find a double pubkey at least once
eachPeer
(
p
.
ethereum
.
Peers
(),
func
(
peer
*
Peer
,
e
*
list
.
Element
)
{
if
bytes
.
Compare
(
p
.
pubkey
,
peer
.
pubkey
)
==
0
{
usedPub
++
}
})
if
usedPub
>
0
{
//ethutil.Config.Log.Debugf("Pubkey %x found more then once. Already connected to client.", p.pubkey)
p
.
Stop
()
return
}
if
c
.
Get
(
0
)
.
Uint
()
!=
ProtocolVersion
{
if
c
.
Get
(
0
)
.
Uint
()
!=
ProtocolVersion
{
ethutil
.
Config
.
Log
.
Debugf
(
"Invalid peer version. Require protocol: %d. Received: %d
\n
"
,
ProtocolVersion
,
c
.
Get
(
0
)
.
Uint
())
ethutil
.
Config
.
Log
.
Debugf
(
"Invalid peer version. Require protocol: %d. Received: %d
\n
"
,
ProtocolVersion
,
c
.
Get
(
0
)
.
Uint
())
p
.
Stop
()
p
.
Stop
()
...
@@ -625,7 +651,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
...
@@ -625,7 +651,6 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
// If this is an inbound connection send an ack back
// If this is an inbound connection send an ack back
if
p
.
inbound
{
if
p
.
inbound
{
p
.
pubkey
=
c
.
Get
(
5
)
.
Bytes
()
p
.
port
=
uint16
(
c
.
Get
(
4
)
.
Uint
())
p
.
port
=
uint16
(
c
.
Get
(
4
)
.
Uint
())
// Self connect detection
// Self connect detection
...
@@ -647,6 +672,11 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
...
@@ -647,6 +672,11 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) {
p
.
SetVersion
(
c
.
Get
(
2
)
.
Str
())
p
.
SetVersion
(
c
.
Get
(
2
)
.
Str
())
}
}
p
.
ethereum
.
PushPeer
(
p
)
p
.
ethereum
.
reactor
.
Post
(
"peerList"
,
p
.
ethereum
.
Peers
())
ethutil
.
Config
.
Log
.
Infof
(
"[SERV] Added peer (%s) %d / %d
\n
"
,
p
.
conn
.
RemoteAddr
(),
p
.
ethereum
.
Peers
()
.
Len
(),
p
.
ethereum
.
MaxPeers
)
// Catch up with the connected peer
// Catch up with the connected peer
if
!
p
.
ethereum
.
IsUpToDate
()
{
if
!
p
.
ethereum
.
IsUpToDate
()
{
ethutil
.
Config
.
Log
.
Debugln
(
"Already syncing up with a peer; sleeping"
)
ethutil
.
Config
.
Log
.
Debugln
(
"Already syncing up with a peer; sleeping"
)
...
...
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