diff --git a/ethchain/block.go b/ethchain/block.go index a7a1f787b8..0678f64e21 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -102,7 +102,7 @@ func CreateBlock(root interface{}, // Returns a hash of the block func (block *Block) Hash() []byte { - return ethutil.Sha3Bin(block.RlpValue().Encode()) + return ethutil.Sha3Bin(block.Value().Encode()) } func (block *Block) HashNoNonce() []byte { @@ -261,14 +261,14 @@ func (block *Block) SetTransactions(txs []*Transaction) { block.TxSha = ethutil.Sha3Bin(ethutil.Encode(block.rlpTxs())) } -func (block *Block) RlpValue() *ethutil.RlpValue { - return ethutil.NewRlpValue([]interface{}{block.header(), block.rlpTxs(), block.rlpUncles()}) +func (block *Block) Value() *ethutil.Value { + return ethutil.NewValue([]interface{}{block.header(), block.rlpTxs(), block.rlpUncles()}) } func (block *Block) RlpEncode() []byte { // Encode a slice interface which contains the header and the list of // transactions. - return block.RlpValue().Encode() + return block.Value().Encode() } func (block *Block) RlpDecode(data []byte) { diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 56bc43a8e4..54f48bc601 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -103,7 +103,7 @@ func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} { block := bc.GetBlock(currentHash) currentHash = block.PrevHash - chain = append(chain, block.RlpValue().Value) + chain = append(chain, block.Value().Val) //chain = append([]interface{}{block.RlpValue().Value}, chain...) num-- diff --git a/ethchain/block_manager.go b/ethchain/block_manager.go index 92f20e2532..7d83977906 100644 --- a/ethchain/block_manager.go +++ b/ethchain/block_manager.go @@ -553,9 +553,9 @@ out: // Load the value in storage and push it on the stack x := bm.stack.Pop() // decode the object as a big integer - decoder := ethutil.NewRlpValueFromBytes([]byte(contract.State().Get(x.String()))) + decoder := ethutil.NewValueFromBytes([]byte(contract.State().Get(x.String()))) if !decoder.IsNil() { - bm.stack.Push(decoder.AsBigInt()) + bm.stack.Push(decoder.BigInt()) } else { bm.stack.Push(ethutil.BigFalse) } @@ -618,10 +618,10 @@ func getContractMemory(block *Block, contractAddr []byte, memAddr *big.Int) *big val := contract.State().Get(memAddr.String()) // decode the object as a big integer - decoder := ethutil.NewRlpValueFromBytes([]byte(val)) + decoder := ethutil.NewValueFromBytes([]byte(val)) if decoder.IsNil() { return ethutil.BigFalse } - return decoder.AsBigInt() + return decoder.BigInt() } diff --git a/ethchain/contract.go b/ethchain/contract.go index d1fcec3b46..70189593b6 100644 --- a/ethchain/contract.go +++ b/ethchain/contract.go @@ -23,11 +23,11 @@ func (c *Contract) RlpEncode() []byte { } func (c *Contract) RlpDecode(data []byte) { - decoder := ethutil.NewRlpValueFromBytes(data) + decoder := ethutil.NewValueFromBytes(data) - c.Amount = decoder.Get(0).AsBigInt() - c.Nonce = decoder.Get(1).AsUint() - c.state = ethutil.NewTrie(ethutil.Config.Db, decoder.Get(2).AsRaw()) + c.Amount = decoder.Get(0).BigInt() + c.Nonce = decoder.Get(1).Uint() + c.state = ethutil.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()) } func (c *Contract) State() *ethutil.Trie { @@ -59,8 +59,8 @@ func (a *Address) RlpEncode() []byte { } func (a *Address) RlpDecode(data []byte) { - decoder := ethutil.NewRlpValueFromBytes(data) + decoder := ethutil.NewValueFromBytes(data) - a.Amount = decoder.Get(0).AsBigInt() - a.Nonce = decoder.Get(1).AsUint() + a.Amount = decoder.Get(0).BigInt() + a.Nonce = decoder.Get(1).Uint() } diff --git a/ethdb/memory_database.go b/ethdb/memory_database.go index 656de9f0ef..cd9f240005 100644 --- a/ethdb/memory_database.go +++ b/ethdb/memory_database.go @@ -29,9 +29,8 @@ func (db *MemDatabase) Get(key []byte) ([]byte, error) { func (db *MemDatabase) Print() { for key, val := range db.db { fmt.Printf("%x(%d): ", key, len(key)) - dec, _ := ethutil.Decode(val, 0) - node := ethutil.Conv(dec) - fmt.Printf("%q\n", node.AsRaw()) + node := ethutil.NewValueFromBytes(val) + fmt.Printf("%q\n", node.Interface()) } } diff --git a/ethereum.go b/ethereum.go index 9feb5a15c6..bd6caac089 100644 --- a/ethereum.go +++ b/ethereum.go @@ -60,8 +60,8 @@ type Ethereum struct { } func New(caps Caps, usePnp bool) (*Ethereum, error) { - //db, err := ethdb.NewLDBDatabase() - db, err := ethdb.NewMemDatabase() + db, err := ethdb.NewLDBDatabase() + //db, err := ethdb.NewMemDatabase() if err != nil { return nil, err } diff --git a/ethutil/rlp.go b/ethutil/rlp.go index 0f88933b3e..025d269a0d 100644 --- a/ethutil/rlp.go +++ b/ethutil/rlp.go @@ -7,19 +7,8 @@ import ( _ "log" _ "math" "math/big" - "reflect" ) -/////////////////////////////////////// -type EthEncoder interface { - EncodeData(rlpData interface{}) []byte -} -type EthDecoder interface { - Get(idx int) *RlpValue -} - -////////////////////////////////////// - type RlpEncoder struct { rlpData []byte } @@ -33,180 +22,6 @@ func (coder *RlpEncoder) EncodeData(rlpData interface{}) []byte { return Encode(rlpData) } -// Data rlpValueutes are returned by the rlp decoder. The data rlpValueutes represents -// one item within the rlp data structure. It's responsible for all the casting -// It always returns something rlpValueid -type RlpValue struct { - Value interface{} - kind reflect.Value -} - -func (rlpValue *RlpValue) String() string { - return fmt.Sprintf("%q", rlpValue.Value) -} - -func Conv(rlpValue interface{}) *RlpValue { - return &RlpValue{Value: rlpValue, kind: reflect.ValueOf(rlpValue)} -} - -func NewRlpValue(rlpValue interface{}) *RlpValue { - return &RlpValue{Value: rlpValue} -} - -func (rlpValue *RlpValue) Type() reflect.Kind { - return reflect.TypeOf(rlpValue.Value).Kind() -} - -func (rlpValue *RlpValue) IsNil() bool { - return rlpValue.Value == nil -} - -func (rlpValue *RlpValue) Length() int { - //return rlpValue.kind.Len() - if data, ok := rlpValue.Value.([]interface{}); ok { - return len(data) - } - - return 0 -} - -func (rlpValue *RlpValue) AsRaw() interface{} { - return rlpValue.Value -} - -func (rlpValue *RlpValue) AsUint() uint64 { - if Value, ok := rlpValue.Value.(uint8); ok { - return uint64(Value) - } else if Value, ok := rlpValue.Value.(uint16); ok { - return uint64(Value) - } else if Value, ok := rlpValue.Value.(uint32); ok { - return uint64(Value) - } else if Value, ok := rlpValue.Value.(uint64); ok { - return Value - } - - return 0 -} - -func (rlpValue *RlpValue) AsByte() byte { - if Value, ok := rlpValue.Value.(byte); ok { - return Value - } - - return 0x0 -} - -func (rlpValue *RlpValue) AsBigInt() *big.Int { - if a, ok := rlpValue.Value.([]byte); ok { - b := new(big.Int) - b.SetBytes(a) - return b - } - - return big.NewInt(0) -} - -func (rlpValue *RlpValue) AsString() string { - if a, ok := rlpValue.Value.([]byte); ok { - return string(a) - } else if a, ok := rlpValue.Value.(string); ok { - return a - } else { - //panic(fmt.Sprintf("not string %T: %v", rlpValue.Value, rlpValue.Value)) - } - - return "" -} - -func (rlpValue *RlpValue) AsBytes() []byte { - if a, ok := rlpValue.Value.([]byte); ok { - return a - } - - return make([]byte, 0) -} - -func (rlpValue *RlpValue) AsSlice() []interface{} { - if d, ok := rlpValue.Value.([]interface{}); ok { - return d - } - - return []interface{}{} -} - -func (rlpValue *RlpValue) AsSliceFrom(from int) *RlpValue { - slice := rlpValue.AsSlice() - - return NewRlpValue(slice[from:]) -} - -func (rlpValue *RlpValue) AsSliceTo(to int) *RlpValue { - slice := rlpValue.AsSlice() - - return NewRlpValue(slice[:to]) -} - -func (rlpValue *RlpValue) AsSliceFromTo(from, to int) *RlpValue { - slice := rlpValue.AsSlice() - - return NewRlpValue(slice[from:to]) -} - -// Threat the rlpValueute as a slice -func (rlpValue *RlpValue) Get(idx int) *RlpValue { - if d, ok := rlpValue.Value.([]interface{}); ok { - // Guard for oob - if len(d) <= idx { - return NewRlpValue(nil) - } - - if idx < 0 { - panic("negative idx for Rlp Get") - } - - return NewRlpValue(d[idx]) - } - - // If this wasn't a slice you probably shouldn't be using this function - return NewRlpValue(nil) -} - -func (rlpValue *RlpValue) Cmp(o *RlpValue) bool { - return reflect.DeepEqual(rlpValue.Value, o.Value) -} - -func (rlpValue *RlpValue) Encode() []byte { - return Encode(rlpValue.Value) -} - -func NewRlpValueFromBytes(rlpData []byte) *RlpValue { - if len(rlpData) != 0 { - data, _ := Decode(rlpData, 0) - return NewRlpValue(data) - } - - return NewRlpValue(nil) -} - -// RlpValue value setters -// An empty rlp value is always a list -func EmptyRlpValue() *RlpValue { - return NewRlpValue([]interface{}{}) -} - -func (rlpValue *RlpValue) AppendList() *RlpValue { - list := EmptyRlpValue() - rlpValue.Value = append(rlpValue.AsSlice(), list) - - return list -} - -func (rlpValue *RlpValue) Append(v interface{}) *RlpValue { - rlpValue.Value = append(rlpValue.AsSlice(), v) - - return rlpValue -} - /* func FromBin(data []byte) uint64 { if len(data) == 0 { @@ -351,8 +166,8 @@ func Encode(object interface{}) []byte { if object != nil { switch t := object.(type) { - case *RlpValue: - buff.Write(Encode(t.AsRaw())) + case *Value: + buff.Write(Encode(t.Raw())) // Code dup :-/ case int: buff.Write(Encode(big.NewInt(int64(t)))) diff --git a/ethutil/trie.go b/ethutil/trie.go index 44d2d5774a..0a3f731362 100644 --- a/ethutil/trie.go +++ b/ethutil/trie.go @@ -82,7 +82,12 @@ func (cache *Cache) Undo() { } } -// A (modified) Radix Trie implementation +// A (modified) Radix Trie implementation. The Trie implements +// a caching mechanism and will used cached values if they are +// present. If a node is not present in the cache it will try to +// fetch it from the database and store the cached value. +// Please note that the data isn't persisted unless `Sync` is +// explicitly called. type Trie struct { Root interface{} //db Database @@ -93,6 +98,7 @@ func NewTrie(db Database, Root interface{}) *Trie { return &Trie{cache: NewCache(db), Root: Root} } +// Save the cached value to the database. func (t *Trie) Sync() { t.cache.Commit() } @@ -157,20 +163,8 @@ func (t *Trie) GetNode(node interface{}) *Value { } else if len(str) < 32 { return NewValueFromBytes([]byte(str)) } - /* - else { - // Fetch the encoded node from the db - o, err := t.db.Get(n.Bytes()) - if err != nil { - fmt.Println("Error InsertState", err) - return NewValue("") - } - return NewValueFromBytes(o) - } - */ return t.cache.Get(n.Bytes()) - } func (t *Trie) UpdateState(node interface{}, key []int, value string) interface{} { @@ -302,53 +296,3 @@ func (t *Trie) Copy() *Trie { return trie } - -/* - * Trie helper functions - */ -// Helper function for printing out the raw contents of a slice -func PrintSlice(slice []string) { - fmt.Printf("[") - for i, val := range slice { - fmt.Printf("%q", val) - if i != len(slice)-1 { - fmt.Printf(",") - } - } - fmt.Printf("]\n") -} - -func PrintSliceT(slice interface{}) { - c := Conv(slice) - for i := 0; i < c.Length(); i++ { - val := c.Get(i) - if val.Type() == reflect.Slice { - PrintSliceT(val.AsRaw()) - } else { - fmt.Printf("%q", val) - if i != c.Length()-1 { - fmt.Printf(",") - } - } - } -} - -// RLP Decodes a node in to a [2] or [17] string slice -func DecodeNode(data []byte) []string { - dec, _ := Decode(data, 0) - if slice, ok := dec.([]interface{}); ok { - strSlice := make([]string, len(slice)) - - for i, s := range slice { - if str, ok := s.([]byte); ok { - strSlice[i] = string(str) - } - } - - return strSlice - } else { - fmt.Printf("It wasn't a []. It's a %T\n", dec) - } - - return nil -}