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
ed3424ff
Commit
ed3424ff
authored
Jul 17, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Trie fixes
parent
14c4f061
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
129 additions
and
38 deletions
+129
-38
state.go
ethchain/state.go
+4
-0
state_manager.go
ethchain/state_manager.go
+1
-0
state_object.go
ethchain/state_object.go
+31
-10
vm.go
ethchain/vm.go
+1
-1
trie.go
ethtrie/trie.go
+20
-10
trie_test.go
ethtrie/trie_test.go
+61
-8
bytes.go
ethutil/bytes.go
+8
-4
value.go
ethutil/value.go
+3
-5
No files found.
ethchain/state.go
View file @
ed3424ff
...
...
@@ -76,6 +76,8 @@ func (self *State) DeleteStateObject(stateObject *StateObject) {
// Retrieve a state object given my the address. Nil if not found
func
(
self
*
State
)
GetStateObject
(
addr
[]
byte
)
*
StateObject
{
addr
=
ethutil
.
Address
(
addr
)
stateObject
:=
self
.
stateObjects
[
string
(
addr
)]
if
stateObject
!=
nil
{
return
stateObject
...
...
@@ -204,6 +206,8 @@ func (self *State) Update() {
// FIXME trie delete is broken
valid
,
t2
:=
ethtrie
.
ParanoiaCheck
(
self
.
trie
)
if
!
valid
{
statelogger
.
Infof
(
"Warn: PARANOIA: Different state root during copy %x vs %x
\n
"
,
self
.
trie
.
Root
,
t2
.
Root
)
self
.
trie
=
t2
}
}
...
...
ethchain/state_manager.go
View file @
ed3424ff
...
...
@@ -121,6 +121,7 @@ done:
for
i
,
tx
:=
range
txs
{
txGas
:=
new
(
big
.
Int
)
.
Set
(
tx
.
Gas
)
st
:=
NewStateTransition
(
coinbase
,
tx
,
state
,
block
)
//fmt.Printf("#%d\n", i+1)
err
=
st
.
TransitionState
()
if
err
!=
nil
{
switch
{
...
...
ethchain/state_object.go
View file @
ed3424ff
...
...
@@ -75,7 +75,7 @@ func MakeContract(tx *Transaction, state *State) *StateObject {
func
NewStateObject
(
addr
[]
byte
)
*
StateObject
{
// This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter.
address
:=
ethutil
.
LeftPadBytes
(
addr
,
20
)
address
:=
ethutil
.
Address
(
addr
)
object
:=
&
StateObject
{
address
:
address
,
Amount
:
new
(
big
.
Int
),
gasPool
:
new
(
big
.
Int
)}
object
.
state
=
NewState
(
ethtrie
.
NewTrie
(
ethutil
.
Config
.
Db
,
""
))
...
...
@@ -92,13 +92,6 @@ func NewContract(address []byte, Amount *big.Int, root []byte) *StateObject {
return
contract
}
// Returns a newly created account
func
NewAccount
(
address
[]
byte
,
amount
*
big
.
Int
)
*
StateObject
{
account
:=
&
StateObject
{
address
:
address
,
Amount
:
amount
,
Nonce
:
0
}
return
account
}
func
NewStateObjectFromBytes
(
address
,
data
[]
byte
)
*
StateObject
{
object
:=
&
StateObject
{
address
:
address
}
object
.
RlpDecode
(
data
)
...
...
@@ -139,17 +132,37 @@ func (self *StateObject) getStorage(k []byte) *ethutil.Value {
}
return
value
//return self.GetAddr(key)
}
func
(
self
*
StateObject
)
setStorage
(
k
[]
byte
,
value
*
ethutil
.
Value
)
{
key
:=
ethutil
.
LeftPadBytes
(
k
,
32
)
//fmt.Printf("%x %v\n", key, value)
self
.
storage
[
string
(
key
)]
=
value
.
Copy
()
/*
if value.BigInt().Cmp(ethutil.Big0) == 0 {
self.state.trie.Delete(string(key))
return
}
self.SetAddr(key, value)
*/
}
func
(
self
*
StateObject
)
Sync
()
{
/*
fmt.Println("############# BEFORE ################")
self.state.EachStorage(func(key string, value *ethutil.Value) {
fmt.Printf("%x %x %x\n", self.Address(), []byte(key), value.Bytes())
})
fmt.Printf("%x @:%x\n", self.Address(), self.state.Root())
fmt.Println("#####################################")
*/
for
key
,
value
:=
range
self
.
storage
{
if
value
.
BigInt
()
.
Cmp
(
ethutil
.
Big0
)
==
0
{
if
value
.
Len
()
==
0
{
// value.BigInt().Cmp(ethutil.Big0) == 0 {
//data := self.getStorage([]byte(key))
//fmt.Printf("deleting %x %x 0x%x\n", self.Address(), []byte(key), data)
self
.
state
.
trie
.
Delete
(
string
(
key
))
continue
}
...
...
@@ -163,6 +176,14 @@ func (self *StateObject) Sync() {
self
.
state
.
trie
=
t2
}
/*
fmt.Println("############# AFTER ################")
self.state.EachStorage(func(key string, value *ethutil.Value) {
fmt.Printf("%x %x %x\n", self.Address(), []byte(key), value.Bytes())
})
*/
//fmt.Printf("%x @:%x\n", self.Address(), self.state.Root())
}
func
(
c
*
StateObject
)
GetInstr
(
pc
*
big
.
Int
)
*
ethutil
.
Value
{
...
...
ethchain/vm.go
View file @
ed3424ff
...
...
@@ -195,7 +195,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
val
:=
closure
.
GetStorage
(
x
)
if
val
.
BigInt
()
.
Cmp
(
ethutil
.
Big0
)
==
0
&&
len
(
y
.
Bytes
())
>
0
{
mult
=
ethutil
.
Big2
}
else
if
!
val
.
IsEmpty
()
&&
len
(
y
.
Bytes
())
==
0
{
}
else
if
val
.
BigInt
()
.
Cmp
(
ethutil
.
Big0
)
!=
0
&&
len
(
y
.
Bytes
())
==
0
{
mult
=
ethutil
.
Big0
}
else
{
mult
=
ethutil
.
Big1
...
...
ethtrie/trie.go
View file @
ed3424ff
...
...
@@ -5,7 +5,7 @@ import (
"fmt"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethutil"
"reflect"
_
"reflect"
"sync"
)
...
...
@@ -326,7 +326,8 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
// New node
n
:=
ethutil
.
NewValue
(
node
)
if
node
==
nil
||
(
n
.
Type
()
==
reflect
.
String
&&
(
n
.
Str
()
==
""
||
n
.
Get
(
0
)
.
IsNil
()))
||
n
.
Len
()
==
0
{
if
node
==
nil
||
n
.
Len
()
==
0
{
//if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
newNode
:=
[]
interface
{}{
CompactEncode
(
key
),
value
}
return
t
.
Put
(
newNode
)
...
...
@@ -393,13 +394,17 @@ func (t *Trie) InsertState(node interface{}, key []int, value interface{}) inter
func
(
t
*
Trie
)
deleteState
(
node
interface
{},
key
[]
int
)
interface
{}
{
if
len
(
key
)
==
0
{
println
(
"<empty ret>"
)
return
""
}
// New node
n
:=
ethutil
.
NewValue
(
node
)
if
node
==
nil
||
(
n
.
Type
()
==
reflect
.
String
&&
(
n
.
Str
()
==
""
||
n
.
Get
(
0
)
.
IsNil
()))
||
n
.
Len
()
==
0
{
//if node == nil || (n.Type() == reflect.String && (n.Str() == "" || n.Get(0).IsNil())) || n.Len() == 0 {
if
node
==
nil
||
n
.
Len
()
==
0
{
//return nil
//fmt.Printf("<empty ret> %x %d\n", n, len(n.Bytes()))
return
""
}
...
...
@@ -410,17 +415,19 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
k
:=
CompactDecode
(
currentNode
.
Get
(
0
)
.
Str
())
v
:=
currentNode
.
Get
(
1
)
.
Raw
()
matchingLength
:=
MatchingNibbleLength
(
key
,
k
)
// Matching key pair (ie. there's already an object with this key)
if
CompareIntSlice
(
k
,
key
)
{
//fmt.Printf("<delete ret> %x\n", v)
return
""
}
else
if
CompareIntSlice
(
key
[
:
matchingLength
],
k
)
{
}
else
if
CompareIntSlice
(
key
[
:
len
(
k
)
],
k
)
{
hash
:=
t
.
deleteState
(
v
,
key
[
len
(
k
)
:
])
child
:=
t
.
getNode
(
hash
)
/*
if child.IsNil() {
return node
}
*/
var
newNode
[]
interface
{}
if
child
.
Len
()
==
2
{
...
...
@@ -430,6 +437,8 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
newNode
=
[]
interface
{}{
currentNode
.
Get
(
0
)
.
Str
(),
hash
}
}
//fmt.Printf("%x\n", newNode)
return
t
.
Put
(
newNode
)
}
else
{
return
node
...
...
@@ -472,10 +481,11 @@ func (t *Trie) deleteState(node interface{}, key []int) interface{} {
newNode
=
n
}
//fmt.Printf("%x\n", newNode)
return
t
.
Put
(
newNode
)
}
return
""
panic
(
"unexpected return"
)
}
type
TrieIterator
struct
{
...
...
ethtrie/trie_test.go
View file @
ed3424ff
package
ethtrie
import
(
"bytes"
"encoding/hex"
"encoding/json"
_
"bytes"
_
"encoding/hex"
_
"encoding/json"
"fmt"
"github.com/ethereum/eth-go/ethutil"
"io/ioutil"
"math/rand"
"net/http"
"reflect"
_
"io/ioutil"
_
"math/rand"
_
"net/http"
_
"reflect"
"testing"
"time"
_
"time"
)
const
LONG_WORD
=
"1234567890abcdefghijklmnopqrstuvwxxzABCEFGHIJKLMNOPQRSTUVWXYZ"
...
...
@@ -43,6 +43,7 @@ func New() (*MemDatabase, *Trie) {
return
db
,
NewTrie
(
db
,
""
)
}
/*
func TestTrieSync(t *testing.T) {
db, trie := New()
...
...
@@ -365,3 +366,55 @@ func TestDelete(t *testing.T) {
fmt.Printf("o: %x\nc: %x\n", a, b)
}
*/
func
TestRndCase
(
t
*
testing
.
T
)
{
_
,
trie
:=
New
()
data
:=
[]
struct
{
k
,
v
string
}{
{
"0000000000000000000000000000000000000000000000000000000000000001"
,
"a07573657264617461000000000000000000000000000000000000000000000000"
},
{
"0000000000000000000000000000000000000000000000000000000000000003"
,
"8453bb5b31"
},
{
"0000000000000000000000000000000000000000000000000000000000000004"
,
"850218711a00"
},
{
"0000000000000000000000000000000000000000000000000000000000000005"
,
"9462d7705bd0b3ecbc51a8026a25597cb28a650c79"
},
{
"0000000000000000000000000000000000000000000000000000000000000010"
,
"947e70f9460402290a3e487dae01f610a1a8218fda"
},
{
"0000000000000000000000000000000000000000000000000000000000000111"
,
"01"
},
{
"0000000000000000000000000000000000000000000000000000000000000112"
,
"a053656e6174650000000000000000000000000000000000000000000000000000"
},
{
"0000000000000000000000000000000000000000000000000000000000000113"
,
"a053656e6174650000000000000000000000000000000000000000000000000000"
},
{
"53656e6174650000000000000000000000000000000000000000000000000000"
,
"94977e3f62f5e1ed7953697430303a3cfa2b5b736e"
},
}
for
_
,
e
:=
range
data
{
trie
.
Update
(
string
(
ethutil
.
Hex2Bytes
(
e
.
k
)),
string
(
ethutil
.
Hex2Bytes
(
e
.
v
)))
}
fmt
.
Printf
(
"root after update %x
\n
"
,
trie
.
Root
)
trie
.
NewIterator
()
.
Each
(
func
(
k
string
,
v
*
ethutil
.
Value
)
{
fmt
.
Printf
(
"%x %x
\n
"
,
k
,
v
.
Bytes
())
})
data
=
[]
struct
{
k
,
v
string
}{
{
"0000000000000000000000000000000000000000000000000000000000000112"
,
""
},
{
"436974697a656e73000000000000000000000000000000000000000000000001"
,
""
},
{
"436f757274000000000000000000000000000000000000000000000000000002"
,
""
},
{
"53656e6174650000000000000000000000000000000000000000000000000000"
,
""
},
{
"436f757274000000000000000000000000000000000000000000000000000000"
,
""
},
{
"53656e6174650000000000000000000000000000000000000000000000000001"
,
""
},
{
"0000000000000000000000000000000000000000000000000000000000000113"
,
""
},
{
"436974697a656e73000000000000000000000000000000000000000000000000"
,
""
},
{
"436974697a656e73000000000000000000000000000000000000000000000002"
,
""
},
{
"436f757274000000000000000000000000000000000000000000000000000001"
,
""
},
{
"0000000000000000000000000000000000000000000000000000000000000111"
,
""
},
{
"53656e6174650000000000000000000000000000000000000000000000000002"
,
""
},
}
for
_
,
e
:=
range
data
{
trie
.
Delete
(
string
(
ethutil
.
Hex2Bytes
(
e
.
k
)))
}
fmt
.
Printf
(
"root after delete %x
\n
"
,
trie
.
Root
)
trie
.
NewIterator
()
.
Each
(
func
(
k
string
,
v
*
ethutil
.
Value
)
{
fmt
.
Printf
(
"%x %x
\n
"
,
k
,
v
.
Bytes
())
})
fmt
.
Printf
(
"%x
\n
"
,
trie
.
Get
(
string
(
ethutil
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000001"
))))
}
ethutil/bytes.go
View file @
ed3424ff
...
...
@@ -150,12 +150,16 @@ func LeftPadBytes(slice []byte, l int) []byte {
return
padded
}
func
Address
(
slice
[]
byte
)
[]
byte
{
func
Address
(
slice
[]
byte
)
(
addr
[]
byte
)
{
if
len
(
slice
)
<
20
{
slice
=
LeftPadBytes
(
slice
,
20
)
addr
=
LeftPadBytes
(
slice
,
20
)
}
else
if
len
(
slice
)
>
20
{
slice
=
slice
[
len
(
slice
)
-
20
:
]
addr
=
slice
[
len
(
slice
)
-
20
:
]
}
else
{
addr
=
slice
}
return
slice
addr
=
CopyBytes
(
addr
)
return
}
ethutil/value.go
View file @
ed3424ff
...
...
@@ -40,13 +40,9 @@ func (val *Value) Len() int {
//return val.kind.Len()
if
data
,
ok
:=
val
.
Val
.
([]
interface
{});
ok
{
return
len
(
data
)
}
else
if
data
,
ok
:=
val
.
Val
.
([]
byte
);
ok
{
return
len
(
data
)
}
else
if
data
,
ok
:=
val
.
Val
.
(
string
);
ok
{
return
len
(
data
)
}
return
0
return
len
(
val
.
Bytes
())
}
func
(
val
*
Value
)
Raw
()
interface
{}
{
...
...
@@ -118,6 +114,8 @@ func (val *Value) Bytes() []byte {
return
[]
byte
{
s
}
}
else
if
s
,
ok
:=
val
.
Val
.
(
string
);
ok
{
return
[]
byte
(
s
)
}
else
if
s
,
ok
:=
val
.
Val
.
(
*
big
.
Int
);
ok
{
return
s
.
Bytes
()
}
return
[]
byte
{}
...
...
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