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
3a9a252f
Commit
3a9a252f
authored
Apr 23, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed minor issue with gas and added state object init
parent
61cd1594
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
135 additions
and
56 deletions
+135
-56
state_manager.go
ethchain/state_manager.go
+46
-7
transaction.go
ethchain/transaction.go
+7
-7
transaction_pool.go
ethchain/transaction_pool.go
+1
-3
types.go
ethchain/types.go
+3
-3
vm.go
ethchain/vm.go
+11
-13
parsing.go
ethutil/parsing.go
+47
-2
parsing_test.go
ethutil/parsing_test.go
+20
-21
No files found.
ethchain/state_manager.go
View file @
3a9a252f
...
...
@@ -91,23 +91,60 @@ func (sm *StateManager) BlockChain() *BlockChain {
return
sm
.
bc
}
func
(
sm
*
StateManager
)
MakeContract
(
tx
*
Transaction
)
{
func
(
sm
*
StateManager
)
MakeContract
(
tx
*
Transaction
)
*
StateObject
{
contract
:=
MakeContract
(
tx
,
sm
.
procState
)
if
contract
!=
nil
{
sm
.
procState
.
states
[
string
(
tx
.
Hash
()[
12
:
])]
=
contract
.
state
return
contract
}
return
nil
}
// 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
{
fmt
.
Printf
(
"Processing Tx: %x
\n
"
,
tx
.
Hash
())
// 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
()
{
err
:=
sm
.
Ethereum
.
TxPool
()
.
ProcessTransaction
(
tx
,
block
,
false
)
if
err
==
nil
{
contract
:=
sm
.
MakeContract
(
tx
)
if
contract
!=
nil
{
sm
.
EvalScript
(
contract
.
Init
(),
contract
,
tx
,
block
)
}
else
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] Unable to create contract"
)
}
}
else
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] contract create:"
,
err
)
}
}
else
{
err
:=
sm
.
Ethereum
.
TxPool
()
.
ProcessTransaction
(
tx
,
block
,
false
)
contract
:=
sm
.
procState
.
GetContract
(
tx
.
Recipient
)
if
err
==
nil
&&
len
(
contract
.
Script
())
>
0
{
sm
.
EvalScript
(
contract
.
Script
(),
contract
,
tx
,
block
)
}
else
if
err
!=
nil
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] process:"
,
err
)
}
}
}
// 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
)
contract
:=
sm
.
MakeContract
(
tx
)
if
contract
!=
nil
{
sm
.
EvalScript
(
contract
.
Init
(),
contract
,
tx
,
block
)
}
else
{
ethutil
.
Config
.
Log
.
Infoln
(
"[STATE] Unable to create contract"
)
}
}
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
...
...
@@ -303,11 +340,13 @@ func (sm *StateManager) Stop() {
func
(
sm
*
StateManager
)
EvalScript
(
script
[]
byte
,
object
*
StateObject
,
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
,
object
,
script
,
sm
.
procState
,
tx
.
Gas
,
tx
.
GasPrice
,
tx
.
Value
)
...
...
ethchain/transaction.go
View file @
3a9a252f
...
...
@@ -23,12 +23,12 @@ type Transaction struct {
contractCreation
bool
}
func
NewContractCreationTx
(
value
,
gas
p
rice
*
big
.
Int
,
script
[]
byte
,
init
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Value
:
value
,
Gas
Price
:
gasp
rice
,
Data
:
script
,
Init
:
init
,
contractCreation
:
true
}
func
NewContractCreationTx
(
value
,
gas
,
gasP
rice
*
big
.
Int
,
script
[]
byte
,
init
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Value
:
value
,
Gas
:
gas
,
GasPrice
:
gasP
rice
,
Data
:
script
,
Init
:
init
,
contractCreation
:
true
}
}
func
NewTransactionMessage
(
to
[]
byte
,
value
,
gas
price
,
gas
*
big
.
Int
,
data
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Recipient
:
to
,
Value
:
value
,
GasPrice
:
gas
p
rice
,
Gas
:
gas
,
Data
:
data
}
func
NewTransactionMessage
(
to
[]
byte
,
value
,
gas
,
gasPrice
*
big
.
Int
,
data
[]
byte
)
*
Transaction
{
return
&
Transaction
{
Recipient
:
to
,
Value
:
value
,
GasPrice
:
gas
P
rice
,
Gas
:
gas
,
Data
:
data
}
}
func
NewTransactionFromBytes
(
data
[]
byte
)
*
Transaction
{
...
...
@@ -46,9 +46,10 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
}
func
(
tx
*
Transaction
)
Hash
()
[]
byte
{
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
GasPrice
,
tx
.
Gas
,
tx
.
Recipient
,
string
(
tx
.
Data
)}
data
:=
[]
interface
{}{
tx
.
Nonce
,
tx
.
Value
,
tx
.
GasPrice
,
tx
.
Gas
,
tx
.
Recipient
,
tx
.
Data
}
if
tx
.
contractCreation
{
data
=
append
(
data
,
string
(
tx
.
Init
)
)
data
=
append
(
data
,
tx
.
Init
)
}
return
ethutil
.
Sha3Bin
(
ethutil
.
NewValue
(
data
)
.
Encode
())
...
...
@@ -112,7 +113,6 @@ func (tx *Transaction) RlpData() interface{} {
if
tx
.
contractCreation
{
data
=
append
(
data
,
tx
.
Init
)
}
//d := ethutil.NewSliceValue(tx.Data).Slice()
return
append
(
data
,
tx
.
v
,
tx
.
r
,
tx
.
s
)
}
...
...
ethchain/transaction_pool.go
View file @
3a9a252f
...
...
@@ -104,7 +104,7 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
// funds won't invalidate this transaction but simple ignores it.
totAmount
:=
new
(
big
.
Int
)
.
Add
(
tx
.
Value
,
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
if
sender
.
Amount
.
Cmp
(
totAmount
)
<
0
{
return
errors
.
New
(
"[TXPL] Insufficient amount in sender's account"
)
return
fmt
.
Errorf
(
"[TXPL] Insufficient amount in sender's (%x) account"
,
tx
.
Sender
()
)
}
if
sender
.
Nonce
!=
tx
.
Nonce
{
...
...
@@ -119,8 +119,6 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
if
bytes
.
Compare
(
tx
.
Recipient
,
tx
.
Sender
())
==
0
{
// Subtract the fee
sender
.
SubAmount
(
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
}
else
if
toContract
{
sender
.
SubAmount
(
new
(
big
.
Int
)
.
Mul
(
TxFee
,
TxFeeRat
))
}
else
{
// Subtract the amount from the senders account
sender
.
SubAmount
(
totAmount
)
...
...
ethchain/types.go
View file @
3a9a252f
...
...
@@ -35,7 +35,7 @@ const (
oORIGIN
=
0x32
oCALLER
=
0x33
oCALLVALUE
=
0x34
oCALLDATA
=
0x35
oCALLDATA
LOAD
=
0x35
oCALLDATASIZE
=
0x36
oGASPRICE
=
0x37
...
...
@@ -106,7 +106,7 @@ var opCodeToString = map[OpCode]string{
oORIGIN
:
"ORIGIN"
,
oCALLER
:
"CALLER"
,
oCALLVALUE
:
"CALLVALUE"
,
oCALLDATA
:
"CALLDATA
"
,
oCALLDATA
LOAD
:
"CALLDATALOAD
"
,
oCALLDATASIZE
:
"CALLDATASIZE"
,
oGASPRICE
:
"TXGASPRICE"
,
...
...
@@ -180,7 +180,7 @@ var OpCodes = map[string]byte{
"ORIGIN"
:
0x32
,
"CALLER"
:
0x33
,
"CALLVALUE"
:
0x34
,
"CALLDATA
"
:
0x35
,
"CALLDATA
LOAD"
:
0x35
,
"CALLDATASIZE"
:
0x36
,
"GASPRICE"
:
0x38
,
...
...
ethchain/vm.go
View file @
3a9a252f
...
...
@@ -84,11 +84,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
// The base for all big integer arithmetic
base
:=
new
(
big
.
Int
)
/*
if ethutil.Config.Debug {
ethutil.Config.Log.Debugf("# op\n")
}
*/
if
ethutil
.
Config
.
Debug
{
ethutil
.
Config
.
Log
.
Debugf
(
"# op
\n
"
)
}
for
{
step
++
...
...
@@ -96,11 +94,9 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
val
:=
closure
.
Get
(
pc
)
// Get the opcode (it must be an opcode!)
op
:=
OpCode
(
val
.
Uint
())
/*
if ethutil.Config.Debug {
ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
}
*/
if
ethutil
.
Config
.
Debug
{
ethutil
.
Config
.
Log
.
Debugf
(
"%-3d %-4s"
,
pc
,
op
.
String
())
}
gas
:=
new
(
big
.
Int
)
useGas
:=
func
(
amount
*
big
.
Int
)
{
...
...
@@ -316,10 +312,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro
case
oCALLVALUE
:
// FIXME: Original value of the call, not the current value
stack
.
Push
(
closure
.
Value
)
case
oCALLDATA
:
case
oCALLDATA
LOAD
:
require
(
1
)
offset
:=
stack
.
Pop
()
mem
.
Set
(
offset
.
Int64
(),
int64
(
len
(
closure
.
Args
)),
closure
.
Args
)
offset
:=
stack
.
Pop
()
.
Int64
()
val
:=
closure
.
Args
[
offset
:
offset
+
31
]
stack
.
Push
(
ethutil
.
BigD
(
val
))
case
oCALLDATASIZE
:
stack
.
Push
(
big
.
NewInt
(
int64
(
len
(
closure
.
Args
))))
case
oGASPRICE
:
...
...
ethutil/parsing.go
View file @
3a9a252f
...
...
@@ -3,7 +3,7 @@ package ethutil
import
(
_
"fmt"
"math/big"
"regexp"
_
"regexp"
)
// Op codes
...
...
@@ -143,7 +143,6 @@ init() {
main() {
// main something
}
*/
func PreProcess(data string) (mainInput, initInput string) {
reg := "\\(\\)\\s*{([\\d\\w\\W\\n\\s]+?)}"
mainReg := regexp.MustCompile("main" + reg)
...
...
@@ -163,3 +162,49 @@ func PreProcess(data string) (mainInput, initInput string) {
return
}
*/
// Very, very dumb parser. Heed no attention :-)
func
FindFor
(
blockMatcher
,
input
string
)
string
{
curCount
:=
-
1
length
:=
len
(
blockMatcher
)
matchfst
:=
rune
(
blockMatcher
[
0
])
var
currStr
string
for
i
,
run
:=
range
input
{
// Find init
if
curCount
==
-
1
&&
run
==
matchfst
&&
input
[
i
:
i
+
length
]
==
blockMatcher
{
curCount
=
0
}
else
if
curCount
>
-
1
{
if
run
==
'{'
{
curCount
++
if
curCount
==
1
{
continue
}
}
else
if
run
==
'}'
{
curCount
--
if
curCount
==
0
{
// we are done
curCount
=
-
1
break
}
}
if
curCount
>
0
{
currStr
+=
string
(
run
)
}
}
}
return
currStr
}
func
PreProcess
(
data
string
)
(
mainInput
,
initInput
string
)
{
mainInput
=
FindFor
(
"main"
,
data
)
if
mainInput
==
""
{
mainInput
=
data
}
initInput
=
FindFor
(
"init"
,
data
)
return
}
ethutil/parsing_test.go
View file @
3a9a252f
package
ethutil
/*
import
(
"
math
"
"
fmt
"
"testing"
)
func TestCompile(t *testing.T) {
instr, err := CompileInstr("PUSH")
if err != nil {
t.Error("Failed compiling instruction")
func
TestPreProcess
(
t
*
testing
.
T
)
{
main
,
init
:=
PreProcess
(
`
init {
// init
if a > b {
if {
}
}
}
calc := (48 + 0*256 + 0*int64(math.Pow(256, 2)))
if BigD(instr).Int64() != calc {
t.Error("Expected", calc, ", got:", instr)
main {
// main
if a > b {
if c > d {
}
}
}
}
func TestValidInstr(t *testing.T) {
op, args, err := Instr("68163")
if err != nil {
t.Error("Error decoding instruction")
}
}
`
)
func TestInvalidInstr(t *testing.T) {
fmt
.
Println
(
"main"
)
fmt
.
Println
(
main
)
fmt
.
Println
(
"init"
)
fmt
.
Println
(
init
)
}
*/
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