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
9df4c745
Commit
9df4c745
authored
Jan 02, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP rewrite vm
parent
5b3d4fae
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
150 additions
and
36 deletions
+150
-36
block.go
block.go
+32
-6
block_manager.go
block_manager.go
+3
-3
parsing.go
parsing.go
+3
-0
parsing_test.go
parsing_test.go
+2
-11
testing.go
testing.go
+9
-14
trie_test.go
trie_test.go
+8
-0
vm.go
vm.go
+66
-2
vm_test.go
vm_test.go
+27
-0
No files found.
block.go
View file @
9df4c745
...
...
@@ -15,6 +15,7 @@ type Block struct {
uncles
[]
*
Block
coinbase
string
// state xxx
state
*
Trie
difficulty
uint32
// Creation time
time
int64
...
...
@@ -34,7 +35,7 @@ func NewBlock(raw []byte) *Block {
}
// Creates a new block. This is currently for testing
func
CreateBlock
(
/* TODO use raw data */
transactions
[]
*
Transaction
)
*
Block
{
func
Create
Test
Block
(
/* TODO use raw data */
transactions
[]
*
Transaction
)
*
Block
{
block
:=
&
Block
{
// Slice of transactions to include in this block
transactions
:
transactions
,
...
...
@@ -49,12 +50,32 @@ func CreateBlock(/* TODO use raw data */transactions []*Transaction) *Block {
return
block
}
func
CreateBlock
(
root
string
,
num
int
,
prevHash
string
,
base
string
,
difficulty
int
,
nonce
int
,
extra
string
,
txes
[]
*
Transaction
)
*
Block
{
block
:=
&
Block
{
// Slice of transactions to include in this block
transactions
:
txes
,
number
:
uint32
(
num
),
prevHash
:
prevHash
,
coinbase
:
base
,
difficulty
:
uint32
(
difficulty
),
nonce
:
uint32
(
nonce
),
time
:
time
.
Now
()
.
Unix
(),
extra
:
extra
,
}
block
.
state
=
NewTrie
(
Db
,
root
)
for
_
,
tx
:=
range
txes
{
block
.
state
.
Update
(
tx
.
recipient
,
string
(
tx
.
MarshalRlp
()))
}
return
block
}
func
(
block
*
Block
)
Update
()
{
}
// Returns a hash of the block
func
(
block
*
Block
)
Hash
()
string
{
return
Sha256
Hex
(
block
.
MarshalRlp
())
func
(
block
*
Block
)
Hash
()
[]
byte
{
return
Sha256
Bin
(
block
.
MarshalRlp
())
}
func
(
block
*
Block
)
MarshalRlp
()
[]
byte
{
...
...
@@ -73,7 +94,7 @@ func (block *Block) MarshalRlp() []byte {
""
,
block
.
coinbase
,
// root state
""
,
block
.
state
.
root
,
// Sha of tx
string
(
Sha256Bin
([]
byte
(
Encode
(
encTx
)))),
block
.
difficulty
,
...
...
@@ -99,7 +120,7 @@ func (block *Block) UnmarshalRlp(data []byte) {
block
.
number
=
uint32
(
number
)
}
if
prevHash
,
ok
:=
header
[
1
]
.
([]
byte
);
ok
{
if
prevHash
,
ok
:=
header
[
1
]
.
([]
uint8
);
ok
{
block
.
prevHash
=
string
(
prevHash
)
}
...
...
@@ -109,7 +130,12 @@ func (block *Block) UnmarshalRlp(data []byte) {
block
.
coinbase
=
string
(
coinbase
)
}
// state is header[header[4]
if
state
,
ok
:=
header
[
4
]
.
([]
uint8
);
ok
{
// XXX The database is currently a global variable defined in testing.go
// This will eventually go away and the database will grabbed from the public server
// interface
block
.
state
=
NewTrie
(
Db
,
string
(
state
))
}
// sha is header[5]
...
...
block_manager.go
View file @
9df4c745
...
...
@@ -33,7 +33,7 @@ func (bm *BlockManager) ProcessBlock(block *Block) error {
// Process each transaction/contract
for
_
,
tx
:=
range
block
.
transactions
{
go
bm
.
ProcessTransaction
(
tx
,
lockChan
)
go
bm
.
ProcessTransaction
(
tx
,
block
,
lockChan
)
}
// Wait for all Tx to finish processing
...
...
@@ -44,9 +44,9 @@ func (bm *BlockManager) ProcessBlock(block *Block) error {
return
nil
}
func
(
bm
*
BlockManager
)
ProcessTransaction
(
tx
*
Transaction
,
lockChan
chan
bool
)
{
func
(
bm
*
BlockManager
)
ProcessTransaction
(
tx
*
Transaction
,
block
*
Block
,
lockChan
chan
bool
)
{
if
tx
.
recipient
==
"
\x00
"
{
bm
.
vm
.
RunTransaction
(
tx
,
func
(
opType
OpType
)
bool
{
bm
.
vm
.
RunTransaction
(
tx
,
block
,
func
(
opType
OpType
)
bool
{
// TODO calculate fees
return
true
// Continue
...
...
parsing.go
View file @
9df4c745
...
...
@@ -11,6 +11,8 @@ import (
// Op codes
var
OpCodes
=
map
[
string
]
string
{
"STOP"
:
"0"
,
"PSH"
:
"30"
,
// 0x30
/*
"ADD": "16", // 0x10
"SUB": "17", // 0x11
"MUL": "18", // 0x12
...
...
@@ -48,6 +50,7 @@ var OpCodes = map[string]string{
"BLKHASH": "145", // 0x91
"COINBASE": "146", // 0x92
"SUICIDE": "255", // 0xff
*/
}
...
...
parsing_test.go
View file @
9df4c745
...
...
@@ -19,22 +19,13 @@ func TestCompile(t *testing.T) {
}
func
TestValidInstr
(
t
*
testing
.
T
)
{
/*
op, args, err := Instr("68163")
if err != nil {
t.Error("Error decoding instruction")
}
*/
if
op
!=
oSET
{
t
.
Error
(
"Expected op to be 43, got:"
,
op
)
}
if
args
[
0
]
!=
"10"
{
t
.
Error
(
"Expect args[0] to be 10, got:"
,
args
[
0
])
}
if
args
[
1
]
!=
"1"
{
t
.
Error
(
"Expected args[1] to be 1, got:"
,
args
[
1
])
}
}
func
TestInvalidInstr
(
t
*
testing
.
T
)
{
...
...
testing.go
View file @
9df4c745
...
...
@@ -4,22 +4,17 @@ import (
"fmt"
)
// This will eventually go away
var
Db
*
MemDatabase
func
Testing
()
{
db
,
_
:=
NewMemDatabase
()
Db
=
db
bm
:=
NewBlockManager
()
tx
:=
NewTransaction
(
"
\x00
"
,
20
,
[]
string
{
"SET 10 6"
,
"LD 10 10"
,
"LT 10 1 20"
,
"SET 255 7"
,
"JMPI 20 255"
,
"STOP"
,
"SET 30 200"
,
"LD 30 31"
,
"SET 255 22"
,
"JMPI 31 255"
,
"SET 255 15"
,
"JMP 255"
,
"PSH 10"
,
})
txData
:=
tx
.
MarshalRlp
()
...
...
@@ -28,9 +23,9 @@ func Testing() {
tx2
:=
NewTransaction
(
"
\x00
"
,
20
,
[]
string
{
"SET 10 6"
,
"LD 10 10"
})
blck
:=
CreateBlock
([]
*
Transaction
{
tx2
,
tx
})
blck
:=
Create
Test
Block
([]
*
Transaction
{
tx2
,
tx
})
bm
.
ProcessBlock
(
blck
)
fmt
.
Println
(
"GenesisBlock:"
,
GenisisBlock
,
"hash
ed"
,
GenisisBlock
.
Hash
(
))
fmt
.
Println
(
"GenesisBlock:"
,
GenisisBlock
,
"hash
"
,
string
(
GenisisBlock
.
Hash
()
))
}
trie_test.go
View file @
9df4c745
...
...
@@ -3,6 +3,7 @@ package main
import
(
"testing"
"encoding/hex"
_
"fmt"
)
func
TestTriePut
(
t
*
testing
.
T
)
{
...
...
@@ -41,6 +42,13 @@ func TestTrieUpdate(t *testing.T) {
trie
.
Update
(
"doe"
,
"reindeer"
)
trie
.
Update
(
"dog"
,
"puppy"
)
/*
data, _ := db.Get([]byte(trie.root))
data, _ = db.Get([]byte(DecodeNode(data)[1]))
data, _ = db.Get([]byte(DecodeNode(data)[7]))
PrintSlice(DecodeNode(data))
*/
trie
.
Update
(
"dogglesworth"
,
"cat"
)
root
:=
hex
.
EncodeToString
([]
byte
(
trie
.
root
))
req
:=
"e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c"
...
...
vm.go
View file @
9df4c745
package
main
import
(
"math"
_
"math"
"math/big"
"fmt"
"strconv"
_
"strconv"
_
"encoding/hex"
)
// Op codes
const
(
oSTOP
int
=
0x00
oPSH
int
=
0x30
/*
oADD int = 0x10
oSUB int = 0x11
oMUL int = 0x12
...
...
@@ -46,6 +48,7 @@ const (
oDATAN int = 0x81
oMYADDRESS int = 0x90
oSUICIDE int = 0xff
*/
)
type
OpType
int
...
...
@@ -57,6 +60,66 @@ const (
)
type
TxCallback
func
(
opType
OpType
)
bool
// Simple push/pop stack mechanism
type
Stack
struct
{
data
[]
string
}
func
NewStack
()
*
Stack
{
return
&
Stack
{}
}
func
(
st
*
Stack
)
Pop
()
string
{
s
:=
len
(
st
.
data
)
str
:=
st
.
data
[
s
]
st
.
data
=
st
.
data
[
:
s
-
1
]
return
str
}
func
(
st
*
Stack
)
Push
(
d
string
)
{
st
.
data
=
append
(
st
.
data
,
d
)
}
type
Vm
struct
{
// Stack
stack
*
Stack
}
func
NewVm
()
*
Vm
{
return
&
Vm
{
stack
:
NewStack
(),
}
}
func
(
vm
*
Vm
)
RunTransaction
(
tx
*
Transaction
,
block
*
Block
,
cb
TxCallback
)
{
// Instruction pointer
iptr
:=
0
// Index pointer for the memory
memIndex
:=
0
fmt
.
Printf
(
"# op arg
\n
"
)
for
iptr
<
len
(
tx
.
data
)
{
memIndex
++
// The base big int for all calculations. Use this for any results.
base
:=
new
(
big
.
Int
)
base
.
SetString
(
"0"
,
0
)
// so it doesn't whine about it
// XXX Should Instr return big int slice instead of string slice?
op
,
args
,
_
:=
Instr
(
tx
.
data
[
iptr
])
if
Debug
{
fmt
.
Printf
(
"%-3d %-4d %v
\n
"
,
iptr
,
op
,
args
)
}
switch
op
{
case
oPSH
:
}
// Increment instruction pointer
iptr
++
}
}
/*
type Vm struct {
// Memory stack
stack map[string]string
...
...
@@ -183,3 +246,4 @@ out:
}
}
}
*/
vm_test.go
0 → 100644
View file @
9df4c745
package
main
import
(
"fmt"
"testing"
_
"encoding/hex"
)
func
TestVm
(
t
*
testing
.
T
)
{
db
,
_
:=
NewMemDatabase
()
Db
=
db
tx
:=
NewTransaction
(
"
\x00
"
,
20
,
[]
string
{
"PSH 10"
,
})
block
:=
CreateBlock
(
""
,
0
,
""
,
""
,
0
,
0
,
""
,
[]
*
Transaction
{
tx
})
db
.
Put
(
block
.
Hash
(),
block
.
MarshalRlp
())
bm
:=
NewBlockManager
()
bm
.
ProcessBlock
(
block
)
tx1
:=
&
Transaction
{}
tx1
.
UnmarshalRlp
([]
byte
(
block
.
state
.
Get
(
tx
.
recipient
)))
fmt
.
Println
(
tx1
)
}
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