forked from TrueCloudLab/neoneo-go
Merge pull request #572 from nspcc-dev/tiny-vm-and-core-speedups
This eliminates some easy to fix blocks, but the overall improvement is on the order of ~1-2%, so it's hardly visible in a 100K block import test. Still, it slightly reduces the DB pressure and eliminates useless hashing, so it's nice to have.
This commit is contained in:
commit
f92e84c4cf
2 changed files with 27 additions and 1 deletions
|
@ -55,6 +55,9 @@ type Blockchain struct {
|
||||||
// Write access should only happen in storeBlock().
|
// Write access should only happen in storeBlock().
|
||||||
blockHeight uint32
|
blockHeight uint32
|
||||||
|
|
||||||
|
// Current top Block wrapped in an atomic.Value for safe access.
|
||||||
|
topBlock atomic.Value
|
||||||
|
|
||||||
// Current persisted block count.
|
// Current persisted block count.
|
||||||
persistedHeight uint32
|
persistedHeight uint32
|
||||||
|
|
||||||
|
@ -558,6 +561,7 @@ func (bc *Blockchain) storeBlock(block *Block) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
bc.topBlock.Store(block)
|
||||||
atomic.StoreUint32(&bc.blockHeight, block.Index)
|
atomic.StoreUint32(&bc.blockHeight, block.Index)
|
||||||
updateBlockHeightMetric(block.Index)
|
updateBlockHeightMetric(block.Index)
|
||||||
for _, tx := range block.Transactions {
|
for _, tx := range block.Transactions {
|
||||||
|
@ -749,6 +753,13 @@ func (bc *Blockchain) GetStorageItems(hash util.Uint160) (map[string]*state.Stor
|
||||||
|
|
||||||
// GetBlock returns a Block by the given hash.
|
// GetBlock returns a Block by the given hash.
|
||||||
func (bc *Blockchain) GetBlock(hash util.Uint256) (*Block, error) {
|
func (bc *Blockchain) GetBlock(hash util.Uint256) (*Block, error) {
|
||||||
|
topBlock := bc.topBlock.Load()
|
||||||
|
if topBlock != nil {
|
||||||
|
if tb, ok := topBlock.(*Block); ok && tb.Hash().Equals(hash) {
|
||||||
|
return tb, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
block, err := bc.dao.GetBlock(hash)
|
block, err := bc.dao.GetBlock(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -768,6 +779,12 @@ func (bc *Blockchain) GetBlock(hash util.Uint256) (*Block, error) {
|
||||||
|
|
||||||
// GetHeader returns data block header identified with the given hash value.
|
// GetHeader returns data block header identified with the given hash value.
|
||||||
func (bc *Blockchain) GetHeader(hash util.Uint256) (*Header, error) {
|
func (bc *Blockchain) GetHeader(hash util.Uint256) (*Header, error) {
|
||||||
|
topBlock := bc.topBlock.Load()
|
||||||
|
if topBlock != nil {
|
||||||
|
if tb, ok := topBlock.(*Block); ok && tb.Hash().Equals(hash) {
|
||||||
|
return tb.Header(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
block, err := bc.dao.GetBlock(hash)
|
block, err := bc.dao.GetBlock(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
11
pkg/vm/vm.go
11
pkg/vm/vm.go
|
@ -238,6 +238,14 @@ func (v *VM) LoadScript(b []byte) {
|
||||||
v.istack.PushVal(ctx)
|
v.istack.PushVal(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadScriptWithHash if similar to the LoadScript method, but it also loads
|
||||||
|
// given script hash directly into the Context to avoid its recalculations. It's
|
||||||
|
// up to user of this function to make sure the script and hash match each other.
|
||||||
|
func (v *VM) loadScriptWithHash(b []byte, hash util.Uint160) {
|
||||||
|
v.LoadScript(b)
|
||||||
|
v.istack.Top().Value().(*Context).scriptHash = hash
|
||||||
|
}
|
||||||
|
|
||||||
// Context returns the current executed context. Nil if there is no context,
|
// Context returns the current executed context. Nil if there is no context,
|
||||||
// which implies no program is loaded.
|
// which implies no program is loaded.
|
||||||
func (v *VM) Context() *Context {
|
func (v *VM) Context() *Context {
|
||||||
|
@ -1120,7 +1128,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
_ = v.istack.Pop()
|
_ = v.istack.Pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
v.LoadScript(script)
|
v.loadScriptWithHash(script, hash)
|
||||||
|
|
||||||
case opcode.RET:
|
case opcode.RET:
|
||||||
oldCtx := v.istack.Pop().Value().(*Context)
|
oldCtx := v.istack.Pop().Value().(*Context)
|
||||||
|
@ -1336,6 +1344,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
panic(fmt.Sprintf("could not find script %s", hash))
|
panic(fmt.Sprintf("could not find script %s", hash))
|
||||||
}
|
}
|
||||||
newCtx = NewContext(script)
|
newCtx = NewContext(script)
|
||||||
|
newCtx.scriptHash = hash
|
||||||
}
|
}
|
||||||
newCtx.rvcount = rvcount
|
newCtx.rvcount = rvcount
|
||||||
newCtx.estack = NewStack("evaluation")
|
newCtx.estack = NewStack("evaluation")
|
||||||
|
|
Loading…
Reference in a new issue