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
3f904bf3
Commit
3f904bf3
authored
Aug 25, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented POST
parent
cdbc3ecc
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
209 additions
and
71 deletions
+209
-71
state_transition.go
ethchain/state_transition.go
+9
-0
state_object.go
ethstate/state_object.go
+6
-0
closure.go
ethvm/closure.go
+1
-0
types.go
ethvm/types.go
+2
-0
vm.go
ethvm/vm.go
+191
-70
natpmp.go
natpmp.go
+0
-1
No files found.
ethchain/state_transition.go
View file @
3f904bf3
...
...
@@ -278,6 +278,15 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context
ret
,
_
,
err
=
callerClosure
.
Call
(
vm
,
self
.
tx
.
Data
)
if
err
==
nil
{
// Execute POSTs
for
e
:=
vm
.
Queue
()
.
Front
();
e
!=
nil
;
e
=
e
.
Next
()
{
msg
:=
e
.
Value
.
(
*
ethvm
.
Message
)
msg
.
Exec
(
transactor
)
}
}
return
}
...
...
ethstate/state_object.go
View file @
3f904bf3
...
...
@@ -245,6 +245,7 @@ func (self *StateObject) Copy() *StateObject {
stateObject
.
InitCode
=
ethutil
.
CopyBytes
(
self
.
InitCode
)
stateObject
.
storage
=
self
.
storage
.
Copy
()
stateObject
.
gasPool
.
Set
(
self
.
gasPool
)
stateObject
.
remove
=
self
.
remove
return
stateObject
}
...
...
@@ -271,6 +272,11 @@ func (c *StateObject) Init() Code {
return
c
.
InitCode
}
// To satisfy ClosureRef
func
(
self
*
StateObject
)
Object
()
*
StateObject
{
return
self
}
// Debug stuff
func
(
self
*
StateObject
)
CreateOutputForDiff
()
{
fmt
.
Printf
(
"%x %x %x %x
\n
"
,
self
.
Address
(),
self
.
State
.
Root
(),
self
.
Balance
.
Bytes
(),
self
.
Nonce
)
...
...
ethvm/closure.go
View file @
3f904bf3
...
...
@@ -12,6 +12,7 @@ import (
type
ClosureRef
interface
{
ReturnGas
(
*
big
.
Int
,
*
big
.
Int
)
Address
()
[]
byte
Object
()
*
ethstate
.
StateObject
GetStorage
(
*
big
.
Int
)
*
ethutil
.
Value
SetStorage
(
*
big
.
Int
,
*
ethutil
.
Value
)
}
...
...
ethvm/types.go
View file @
3f904bf3
...
...
@@ -145,6 +145,7 @@ const (
CREATE
=
0xf0
CALL
=
0xf1
RETURN
=
0xf2
POST
=
0xf3
// 0x70 range - other
LOG
=
0xfe
// XXX Unofficial
...
...
@@ -438,6 +439,7 @@ var OpCodes = map[string]byte{
"CREATE"
:
0xf0
,
"CALL"
:
0xf1
,
"RETURN"
:
0xf2
,
"POST"
:
0xf3
,
// 0x70 range - other
"LOG"
:
0xfe
,
...
...
ethvm/vm.go
View file @
3f904bf3
package
ethvm
import
(
"container/list"
"fmt"
"math"
"math/big"
...
...
@@ -18,11 +19,6 @@ type Debugger interface {
}
type
Vm
struct
{
// Stack for processing contracts
stack
*
Stack
// non-persistent key/value memory storage
mem
map
[
string
]
*
big
.
Int
env
Environment
Verbose
bool
...
...
@@ -40,6 +36,8 @@ type Vm struct {
Fn
string
Recoverable
bool
queue
*
list
.
List
}
type
Environment
interface
{
...
...
@@ -66,7 +64,7 @@ func New(env Environment) *Vm {
lt
=
LogTyDiff
}
return
&
Vm
{
env
:
env
,
logTy
:
lt
,
Recoverable
:
true
}
return
&
Vm
{
env
:
env
,
logTy
:
lt
,
Recoverable
:
true
,
queue
:
list
.
New
()
}
}
func
(
self
*
Vm
)
RunClosure
(
closure
*
Closure
)
(
ret
[]
byte
,
err
error
)
{
...
...
@@ -215,6 +213,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
newMemSize
=
stack
.
data
[
stack
.
Len
()
-
2
]
.
Uint64
()
+
stack
.
data
[
stack
.
Len
()
-
3
]
.
Uint64
()
}
// BUG This will break on overflows. https://github.com/ethereum/eth-go/issues/47
newMemSize
=
(
newMemSize
+
31
)
/
32
*
32
if
newMemSize
>
uint64
(
mem
.
Len
())
{
m
:=
GasMemory
.
Uint64
()
*
(
newMemSize
-
uint64
(
mem
.
Len
()))
/
32
...
...
@@ -711,6 +710,8 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
err
error
value
=
stack
.
Pop
()
size
,
offset
=
stack
.
Popn
()
input
=
mem
.
Get
(
offset
.
Int64
(),
size
.
Int64
())
gas
=
new
(
big
.
Int
)
.
Set
(
closure
.
Gas
)
// Snapshot the current stack so we are able to
// revert back to it later.
...
...
@@ -726,37 +727,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
self
.
Printf
(
" (*) %x"
,
addr
)
.
Endl
()
msg
:=
self
.
env
.
State
()
.
Manifest
()
.
AddMessage
(
&
ethstate
.
Message
{
To
:
addr
,
From
:
closure
.
Address
(),
Origin
:
self
.
env
.
Origin
(),
Block
:
self
.
env
.
BlockHash
(),
Timestamp
:
self
.
env
.
Time
(),
Coinbase
:
self
.
env
.
Coinbase
(),
Number
:
self
.
env
.
BlockNumber
(),
Value
:
value
,
})
// Create a new contract
contract
:=
self
.
env
.
State
()
.
NewStateObject
(
addr
)
if
contract
.
Balance
.
Cmp
(
value
)
>=
0
{
closure
.
object
.
SubAmount
(
value
)
contract
.
AddAmount
(
value
)
// Set the init script
initCode
:=
mem
.
Get
(
offset
.
Int64
(),
size
.
Int64
())
msg
.
Input
=
initCode
// Transfer all remaining gas to the new
// contract so it may run the init script
gas
:=
new
(
big
.
Int
)
.
Set
(
closure
.
Gas
)
closure
.
UseGas
(
closure
.
Gas
)
// Create the closure
c
:=
NewClosure
(
msg
,
closure
,
contract
,
initCode
,
gas
,
closure
.
Price
)
// Call the closure and set the return value as
// main script.
contract
.
Code
,
_
,
err
=
c
.
Call
(
self
,
nil
)
}
else
{
err
=
fmt
.
Errorf
(
"Insufficient funds to transfer value. Req %v, has %v"
,
value
,
closure
.
object
.
Balance
)
}
closure
.
UseGas
(
closure
.
Gas
)
msg
:=
NewMessage
(
self
,
addr
,
input
,
gas
,
closure
.
Price
,
value
)
ret
,
err
:=
msg
.
Exec
(
closure
)
if
err
!=
nil
{
stack
.
Push
(
ethutil
.
BigFalse
)
...
...
@@ -765,10 +739,55 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
self
.
Printf
(
"CREATE err %v"
,
err
)
}
else
{
stack
.
Push
(
ethutil
.
BigD
(
addr
))
msg
.
object
.
Code
=
ret
msg
.
Output
=
contract
.
Code
stack
.
Push
(
ethutil
.
BigD
(
addr
))
}
/*
msg := self.env.State().Manifest().AddMessage(ðstate.Message{
To: addr, From: closure.Address(),
Origin: self.env.Origin(),
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
Value: value,
})
// Create a new contract
contract := self.env.State().NewStateObject(addr)
if contract.Balance.Cmp(value) >= 0 {
closure.object.SubAmount(value)
contract.AddAmount(value)
// Set the init script
initCode := mem.Get(offset.Int64(), size.Int64())
msg.Input = initCode
// Transfer all remaining gas to the new
// contract so it may run the init script
gas := new(big.Int).Set(closure.Gas)
closure.UseGas(closure.Gas)
// Create the closure
c := NewClosure(msg, closure, contract, initCode, gas, closure.Price)
// Call the closure and set the return value as
// main script.
contract.Code, _, err = c.Call(self, nil)
} else {
err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
}
if err != nil {
stack.Push(ethutil.BigFalse)
// Revert the state as it was before.
self.env.State().Set(snapshot)
self.Printf("CREATE err %v", err)
} else {
stack.Push(ethutil.BigD(addr))
msg.Output = contract.Code
}
*/
self
.
Endl
()
// Debug hook
...
...
@@ -791,51 +810,88 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
// Get the arguments from the memory
args
:=
mem
.
Get
(
inOffset
.
Int64
(),
inSize
.
Int64
())
msg
:=
self
.
env
.
State
()
.
Manifest
()
.
AddMessage
(
&
ethstate
.
Message
{
To
:
addr
.
Bytes
(),
From
:
closure
.
Address
(),
Input
:
args
,
Origin
:
self
.
env
.
Origin
(),
Block
:
self
.
env
.
BlockHash
(),
Timestamp
:
self
.
env
.
Time
(),
Coinbase
:
self
.
env
.
Coinbase
(),
Number
:
self
.
env
.
BlockNumber
(),
Value
:
value
,
})
if
closure
.
object
.
Balance
.
Cmp
(
value
)
<
0
{
vmlogger
.
Debugf
(
"Insufficient funds to transfer value. Req %v, has %v"
,
value
,
closure
.
object
.
Balance
)
closure
.
ReturnGas
(
gas
,
nil
)
snapshot
:=
self
.
env
.
State
()
.
Copy
()
msg
:=
NewMessage
(
self
,
addr
.
Bytes
(),
args
,
gas
,
closure
.
Price
,
value
)
ret
,
err
:=
msg
.
Exec
(
closure
)
if
err
!=
nil
{
stack
.
Push
(
ethutil
.
BigFalse
)
self
.
env
.
State
()
.
Set
(
snapshot
)
}
else
{
snapshot
:=
self
.
env
.
State
()
.
Copy
()
stack
.
Push
(
ethutil
.
BigTrue
)
mem
.
Set
(
retOffset
.
Int64
(),
retSize
.
Int64
(),
ret
)
}
// Debug hook
if
self
.
Dbg
!=
nil
{
self
.
Dbg
.
SetCode
(
closure
.
Code
)
}
stateObject
:=
self
.
env
.
State
()
.
GetOrNewStateObject
(
addr
.
Bytes
())
/*
msg := self.env.State().Manifest().AddMessage(ðstate.Message{
To: addr.Bytes(), From: closure.Address(),
Input: args,
Origin: self.env.Origin(),
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
Value: value,
})
closure
.
object
.
SubAmount
(
value
)
stateObject
.
AddAmount
(
value
)
if closure.object.Balance.Cmp(value) < 0 {
vmlogger.Debugf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Balance)
closure.ReturnGas(gas, nil)
// Create a new callable closure
c
:=
NewClosure
(
msg
,
closure
,
stateObject
,
stateObject
.
Code
,
gas
,
closure
.
Price
)
// Executer the closure and get the return value (if any)
ret
,
_
,
err
:=
c
.
Call
(
self
,
args
)
if
err
!=
nil
{
stack.Push(ethutil.BigFalse)
} else {
snapshot := self.env.State().Copy()
vmlogger
.
Debugf
(
"Closure execution failed. %v
\n
"
,
err
)
stateObject := self.env.State().GetOrNewStateObject(addr.Bytes()
)
self
.
env
.
State
()
.
Set
(
snapshot
)
}
else
{
stack
.
Push
(
ethutil
.
BigTrue
)
closure.object.SubAmount(value)
stateObject.AddAmount(value)
mem
.
Set
(
retOffset
.
Int64
(),
retSize
.
Int64
(),
ret
)
}
// Create a new callable closure
c := NewClosure(msg, closure, stateObject, stateObject.Code, gas, closure.Price)
// Executer the closure and get the return value (if any)
ret, _, err := c.Call(self, args)
if err != nil {
stack.Push(ethutil.BigFalse)
msg
.
Output
=
ret
vmlogger.Debugf("Closure execution failed. %v\n", err)
// Debug hook
if
self
.
Dbg
!=
nil
{
self
.
Dbg
.
SetCode
(
closure
.
Code
)
self.env.State().Set(snapshot)
} else {
stack.Push(ethutil.BigTrue)
mem.Set(retOffset.Int64(), retSize.Int64(), ret)
}
msg.Output = ret
// Debug hook
if self.Dbg != nil {
self.Dbg.SetCode(closure.Code)
}
}
}
*/
case
POST
:
require
(
6
)
self
.
Endl
()
gas
:=
stack
.
Pop
()
// Pop gas and value of the stack.
value
,
addr
:=
stack
.
Popn
()
// Pop input size and offset
inSize
,
inOffset
:=
stack
.
Popn
()
// Get the arguments from the memory
args
:=
mem
.
Get
(
inOffset
.
Int64
(),
inSize
.
Int64
())
msg
:=
NewMessage
(
self
,
addr
.
Bytes
(),
args
,
gas
,
closure
.
Price
,
value
)
msg
.
Postpone
()
case
RETURN
:
require
(
2
)
size
,
offset
:=
stack
.
Popn
()
...
...
@@ -887,6 +943,10 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
}
}
func
(
self
*
Vm
)
Queue
()
*
list
.
List
{
return
self
.
queue
}
func
(
self
*
Vm
)
Printf
(
format
string
,
v
...
interface
{})
*
Vm
{
if
self
.
Verbose
&&
self
.
logTy
==
LogTyPretty
{
self
.
logStr
+=
fmt
.
Sprintf
(
format
,
v
...
)
...
...
@@ -918,3 +978,64 @@ func ensure256(x *big.Int) {
x
.
SetInt64
(
0
)
}
}
type
Message
struct
{
vm
*
Vm
closure
*
Closure
address
,
input
[]
byte
gas
,
price
,
value
*
big
.
Int
object
*
ethstate
.
StateObject
}
func
NewMessage
(
vm
*
Vm
,
address
,
input
[]
byte
,
gas
,
gasPrice
,
value
*
big
.
Int
)
*
Message
{
return
&
Message
{
vm
:
vm
,
address
:
address
,
input
:
input
,
gas
:
gas
,
price
:
gasPrice
,
value
:
value
}
}
func
(
self
*
Message
)
Postpone
()
{
self
.
vm
.
queue
.
PushBack
(
self
)
}
func
(
self
*
Message
)
Exec
(
caller
ClosureRef
)
(
ret
[]
byte
,
err
error
)
{
queue
:=
self
.
vm
.
queue
self
.
vm
.
queue
=
list
.
New
()
defer
func
()
{
if
err
==
nil
{
queue
.
PushBackList
(
self
.
vm
.
queue
)
}
self
.
vm
.
queue
=
queue
}()
msg
:=
self
.
vm
.
env
.
State
()
.
Manifest
()
.
AddMessage
(
&
ethstate
.
Message
{
To
:
self
.
address
,
From
:
caller
.
Address
(),
Input
:
self
.
input
,
Origin
:
self
.
vm
.
env
.
Origin
(),
Block
:
self
.
vm
.
env
.
BlockHash
(),
Timestamp
:
self
.
vm
.
env
.
Time
(),
Coinbase
:
self
.
vm
.
env
.
Coinbase
(),
Number
:
self
.
vm
.
env
.
BlockNumber
(),
Value
:
self
.
value
,
})
object
:=
caller
.
Object
()
if
object
.
Balance
.
Cmp
(
self
.
value
)
<
0
{
caller
.
ReturnGas
(
self
.
gas
,
self
.
price
)
err
=
fmt
.
Errorf
(
"Insufficient funds to transfer value. Req %v, has %v"
,
self
.
value
,
object
.
Balance
)
}
else
{
stateObject
:=
self
.
vm
.
env
.
State
()
.
GetOrNewStateObject
(
self
.
address
)
self
.
object
=
stateObject
caller
.
Object
()
.
SubAmount
(
self
.
value
)
stateObject
.
AddAmount
(
self
.
value
)
// Create a new callable closure
c
:=
NewClosure
(
msg
,
caller
,
object
,
object
.
Code
,
self
.
gas
,
self
.
price
)
// Executer the closure and get the return value (if any)
ret
,
_
,
err
=
c
.
Call
(
self
.
vm
,
self
.
input
)
msg
.
Output
=
ret
return
ret
,
err
}
return
}
natpmp.go
View file @
3f904bf3
package
eth
import
(
//natpmp "code.google.com/p/go-nat-pmp"
"fmt"
"net"
...
...
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