Commit b2500474 authored by George Hotz's avatar George Hotz

getting close on a block transition

parent 69b6305f
\ No newline at end of file
......@@ -101,8 +101,8 @@ async function getBlock(blockNumber: Number) {
async function main() {
/*await getBlock(13247501)
await getBlock(13247502)*/
await getBlock(13284053)
await getBlock(13284054)
await getBlock(13284491)
await getBlock(13284492)
}
main().then(() => process.exit(0))
......@@ -29,3 +29,9 @@ type Account struct {
The oracle ensures a correct output given the input, these are the high level methods
GetUnproved...need to be written also
# diving in more
core/state/database.go
......@@ -248,7 +248,8 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
if metrics.EnabledExpensive {
meter = &s.db.StorageReads
}
oracle.PrefetchAddress(db.BlockNumber, s.address, key)
oracle.PrefetchStorage(db.BlockNumber, s.address, key)
fmt.Println("get", s.address, key)
if enc, err = s.getTrie(db).TryGet(key.Bytes()); err != nil {
s.setError(err)
return common.Hash{}
......@@ -354,10 +355,13 @@ func (s *stateObject) updateTrie(db Database) Trie {
s.originStorage[key] = value
var v []byte
oracle.PrefetchAddress(db.BlockNumber, s.address, key)
oracle.PrefetchStorage(db.BlockNumber, s.address, key)
//oracle.PrefetchStorage(big.NewInt(db.BlockNumber.Int64()+1), s.address, key)
if (value == common.Hash{}) {
//s.setError(tr.TryDelete(key[:]))
fmt.Println("delete", s.address, key)
s.setError(tr.TryDelete(key[:]))
} else {
fmt.Println("update", s.address, key, value)
// Encoding []byte cannot fail, ok to ignore the error.
v, _ = rlp.EncodeToBytes(common.TrimLeftZeroes(value[:]))
s.setError(tr.TryUpdate(key[:], v))
......
......@@ -513,7 +513,7 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
if metrics.EnabledExpensive {
defer func(start time.Time) { s.AccountReads += time.Since(start) }(time.Now())
}
oracle.PrefetchAddress(s.db.BlockNumber, addr, common.Hash{})
oracle.PrefetchAddress(s.db.BlockNumber, addr)
enc, err := s.trie.TryGet(addr.Bytes())
if err != nil {
s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %v", addr.Bytes(), err))
......@@ -879,6 +879,20 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
// Finalize any pending changes and merge everything into the tries
s.IntermediateRoot(deleteEmptyObjects)
for addr := range s.stateObjectsDirty {
if obj := s.stateObjects[addr]; !obj.deleted {
fmt.Println("dirty state object", addr)
// Write any contract code associated with the state object
if obj.code != nil && obj.dirtyCode {
fmt.Println("write code", common.BytesToHash(obj.CodeHash()))
}
// Write any storage changes in the state object to its storage trie
if err := obj.CommitTrie(s.db); err != nil {
return common.Hash{}, err
}
}
}
// Commit objects to the trie, measuring the elapsed time
/*codeWriter := s.db.TrieDB().DiskDB().NewBatch()
for addr := range s.stateObjectsDirty {
......@@ -943,7 +957,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
}
s.snap, s.snapDestructs, s.snapAccounts, s.snapStorage = nil, nil, nil, nil
}*/
fmt.Println("Commit doesn't work!!!")
//fmt.Println("Commit doesn't work!!!")
return root, err
}
......
......@@ -14,10 +14,12 @@ import (
)
func main() {
//blockNumber := 13284469
blockNumber := 13284491
// read header
var header types.Header
{
f, _ := os.Open("data/block_13284053")
f, _ := os.Open(fmt.Sprintf("data/block_%d", blockNumber))
defer f.Close()
rlpheader := rlp.NewStream(f, 0)
rlpheader.Decode(&header)
......@@ -26,7 +28,7 @@ func main() {
// read header
var newheader types.Header
{
f, _ := os.Open("data/block_13284054")
f, _ := os.Open(fmt.Sprintf("data/block_%d", blockNumber+1))
defer f.Close()
rlpheader := rlp.NewStream(f, 0)
rlpheader.Decode(&newheader)
......@@ -42,7 +44,7 @@ func main() {
// read txs
var txs []*types.Transaction
{
f, _ := os.Open("data/txs_13284054")
f, _ := os.Open(fmt.Sprintf("data/txs_%d", blockNumber+1))
defer f.Close()
rlpheader := rlp.NewStream(f, 0)
rlpheader.Decode(&txs)
......
......@@ -103,16 +103,31 @@ func Preimage(hash common.Hash) []byte {
return val
}
func PrefetchAddress(blockNumber *big.Int, addr common.Address, skey common.Hash) {
key := fmt.Sprintf("proof_%d_%s_%s", blockNumber, addr, skey)
fmt.Println("prefetch", key)
func PrefetchStorage(blockNumber *big.Int, addr common.Address, skey common.Hash) {
/*key := fmt.Sprintf("proof_%d_%s_%s", blockNumber, addr, skey)
if cached[key] {
return
}
cached[key] = true*/
ap := GetProofAccount(blockNumber, addr, skey, true)
//fmt.Println("PrefetchStorage", blockNumber, addr, skey, len(ap))
for _, s := range ap {
ret, _ := hex.DecodeString(s[2:])
hash := crypto.Keccak256Hash(ret)
//fmt.Println(" ", i, hash)
preimages[hash] = ret
}
}
func PrefetchAddress(blockNumber *big.Int, addr common.Address) {
key := fmt.Sprintf("proof_%d_%s", blockNumber, addr)
if cached[key] {
//fmt.Println("hit", key)
return
}
cached[key] = true
ap := GetProofAccount(blockNumber, addr, skey)
ap := GetProofAccount(blockNumber, addr, common.Hash{}, false)
for _, s := range ap {
ret, _ := hex.DecodeString(s[2:])
hash := crypto.Keccak256Hash(ret)
......@@ -120,8 +135,13 @@ func PrefetchAddress(blockNumber *big.Int, addr common.Address, skey common.Hash
}
}
func GetProofAccount(blockNumber *big.Int, addr common.Address, skey common.Hash) []string {
key := fmt.Sprintf("proof_%d_%s_%s", blockNumber, addr, skey)
func GetProofAccount(blockNumber *big.Int, addr common.Address, skey common.Hash, storage bool) []string {
var key string
if storage {
key = fmt.Sprintf("proof_%d_%s_%s", blockNumber, addr, skey)
} else {
key = fmt.Sprintf("proof_%d_%s", blockNumber, addr)
}
addrHash := crypto.Keccak256Hash(addr[:])
unhashMap[addrHash] = addr
......@@ -138,10 +158,14 @@ func GetProofAccount(blockNumber *big.Int, addr common.Address, skey common.Hash
jr := jsonresp{}
json.NewDecoder(resp.Body).Decode(&jr)
arr := jr.Result.AccountProof
arr = append(arr, jr.Result.StorageProof[0].Proof...)
if storage {
arr := jr.Result.StorageProof[0].Proof
cacheWrite(key, []byte(strings.Join(arr, "\n")))
} else {
arr := jr.Result.AccountProof
cacheWrite(key, []byte(strings.Join(arr, "\n")))
}
cacheWrite(key, []byte(strings.Join(arr, "\n")))
}
return strings.Split(string(cacheRead(key)), "\n")
}
......
......@@ -63,9 +63,9 @@ func (db *Database) preimage(hash common.Hash) []byte {
func NewDatabase(header types.Header) Database {
triedb := Database{BlockNumber: header.Number, Root: header.Root}
triedb.preimages = make(map[common.Hash][]byte)
//triedb.preimages = make(map[common.Hash][]byte)
fmt.Println("init database")
oracle.PrefetchAddress(header.Number, common.Address{}, common.Hash{})
oracle.PrefetchAddress(header.Number, common.Address{})
//panic("preseed")
return triedb
......@@ -82,7 +82,7 @@ func (db *Database) Node(hash common.Hash) ([]byte, error) {
// node retrieves a cached trie node from memory, or returns nil if none can be
// found in the memory cache.
func (db *Database) node(hash common.Hash) node {
fmt.Println("node", hash)
//fmt.Println("node", hash)
return mustDecodeNode(hash[:], oracle.Preimage(hash))
}
......@@ -93,4 +93,5 @@ func (db *Database) node(hash common.Hash) node {
func (db *Database) insert(hash common.Hash, size int, node node) {
//panic("insert")
//fmt.Println("insert", hash, size)
// can put things in the oracle here if we care
}
......@@ -368,6 +368,7 @@ func (t *Trie) TryDelete(key []byte) error {
func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
switch n := n.(type) {
case *shortNode:
fmt.Println("delete shortNode", prefix, key, n.Key, n.Val)
matchlen := prefixLen(key, n.Key)
if matchlen < len(n.Key) {
return false, n, nil // don't replace n on mismatch
......@@ -397,6 +398,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
}
case *fullNode:
fmt.Println("delete fullNode", prefix, key)
dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:])
if !dirty || err != nil {
return false, n, err
......@@ -435,12 +437,15 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
}
if pos >= 0 {
if pos != 16 {
fmt.Println("delete fails here", pos, n.Children, prefix, n.Children[pos])
// If the remaining entry is a short node, it replaces
// n and its key gets the missing nibble tacked to the
// front. This avoids creating an invalid
// shortNode{..., shortNode{...}}. Since the entry
// might not be loaded yet, resolve it just for this
// check.
// remove this optimisticly? if it's not a shortNode, it doesn't do anything
cnode, err := t.resolve(n.Children[pos], prefix)
if err != nil {
return false, nil, err
......@@ -464,6 +469,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
return false, nil, nil
case hashNode:
fmt.Println("delete hashNode", prefix, key)
// We've hit a part of the trie that isn't loaded yet. Load
// the node and delete from it. This leaves all child nodes on
// the path to the value in the trie.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment