core: drop old STContractID data

We have it in the ContractManagement now.
This commit is contained in:
Roman Khimov 2022-09-19 23:13:25 +03:00
parent 970862765d
commit 4a626f505e
4 changed files with 18 additions and 78 deletions

View file

@ -45,7 +45,7 @@ import (
// Tuning parameters. // Tuning parameters.
const ( const (
version = "0.2.6" version = "0.2.7"
defaultInitialGAS = 52000000_00000000 defaultInitialGAS = 52000000_00000000
defaultGCPeriod = 10000 defaultGCPeriod = 10000
@ -717,21 +717,9 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
p = time.Now() p = time.Now()
fallthrough fallthrough
case staleBlocksRemoved: case staleBlocksRemoved:
// Completely remove contract IDs to update them later. bc.log.Info("trying to reset contract storage items")
bc.log.Info("trying to reset contract storage items and IDs")
pStorageStart := p pStorageStart := p
cache.Store.Seek(storage.SeekRange{Prefix: []byte{byte(storage.STContractID)}}, func(k, _ []byte) bool {
cache.Store.Delete(k)
return true
})
keys, err = cache.Persist()
if err != nil {
return fmt.Errorf("failed to persist removed contract IDs: %w", err)
}
bc.log.Info("removed contract IDs are persisted", zap.Duration("took", time.Since(p)), zap.Int("keys", keys))
p = time.Now()
// Reset contracts storage and store new contract IDs.
var mode = mpt.ModeAll var mode = mpt.ModeAll
if bc.config.RemoveUntraceableBlocks { if bc.config.RemoveUntraceableBlocks {
mode |= mpt.ModeGCFlag mode |= mpt.ModeGCFlag
@ -739,19 +727,12 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
trieStore := mpt.NewTrieStore(sr.Root, mode, cache.Store) trieStore := mpt.NewTrieStore(sr.Root, mode, cache.Store)
oldStoragePrefix := v.StoragePrefix oldStoragePrefix := v.StoragePrefix
newStoragePrefix := statesync.TemporaryPrefix(oldStoragePrefix) newStoragePrefix := statesync.TemporaryPrefix(oldStoragePrefix)
mgmtCSPrefixLen := 1 + 4 + 1 // STStorage + Management ID + contract state prefix
mgmtContractPrefix := make([]byte, mgmtCSPrefixLen-1)
id := int32(native.ManagementContractID)
binary.BigEndian.PutUint32(mgmtContractPrefix, uint32(id))
mgmtContractPrefix[4] = native.PrefixContract
cs := new(state.Contract)
const persistBatchSize = 200000 const persistBatchSize = 200000
var ( var (
seekErr error seekErr error
cnt int cnt int
storageItmsCnt int storageItmsCnt int
contractIDsCnt int
batchCnt int batchCnt int
) )
trieStore.Seek(storage.SeekRange{Prefix: []byte{byte(oldStoragePrefix)}}, func(k, v []byte) bool { trieStore.Seek(storage.SeekRange{Prefix: []byte{byte(oldStoragePrefix)}}, func(k, v []byte) bool {
@ -775,22 +756,6 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
cnt++ cnt++
storageItmsCnt++ storageItmsCnt++
// @fixme: remove this part after #2702.
if bytes.HasPrefix(k[1:], mgmtContractPrefix) {
var hash util.Uint160
copy(hash[:], k[mgmtCSPrefixLen:])
err = stackitem.DeserializeConvertible(v, cs)
if err != nil {
bc.log.Warn("failed to deserialize contract; ID for this contract won't be stored in the DB",
zap.String("hash", hash.StringLE()),
zap.Error(err))
} else {
cache.PutContractID(cs.ID, hash)
cnt++
contractIDsCnt++
}
}
return true return true
}) })
if seekErr != nil { if seekErr != nil {
@ -806,8 +771,7 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
batchCnt++ batchCnt++
bc.log.Info("last batch of contract storage items and IDs is persisted", zap.Int("batch", batchCnt), zap.Duration("took", time.Since(p)), zap.Int("keys", keys)) bc.log.Info("last batch of contract storage items and IDs is persisted", zap.Int("batch", batchCnt), zap.Duration("took", time.Since(p)), zap.Int("keys", keys))
bc.log.Info("contract storage items and IDs are reset", zap.Duration("took", time.Since(pStorageStart)), bc.log.Info("contract storage items and IDs are reset", zap.Duration("took", time.Since(pStorageStart)),
zap.Int("keys", storageItmsCnt), zap.Int("keys", storageItmsCnt))
zap.Int("ids", contractIDsCnt))
p = time.Now() p = time.Now()
fallthrough fallthrough
case newStorageItemsAdded: case newStorageItemsAdded:
@ -2121,7 +2085,7 @@ func (bc *Blockchain) GetContractState(hash util.Uint160) *state.Contract {
// GetContractScriptHash returns contract script hash by its ID. // GetContractScriptHash returns contract script hash by its ID.
func (bc *Blockchain) GetContractScriptHash(id int32) (util.Uint160, error) { func (bc *Blockchain) GetContractScriptHash(id int32) (util.Uint160, error) {
return bc.dao.GetContractScriptHash(id) return native.GetContractScriptHash(bc.dao, id)
} }
// GetNativeContractScriptHash returns native contract script hash by its name. // GetNativeContractScriptHash returns native contract script hash by its name.

View file

@ -135,32 +135,6 @@ func (dao *Simple) putWithBuffer(entity io.Serializable, key []byte, buf *io.Buf
return nil return nil
} }
func (dao *Simple) makeContractIDKey(id int32) []byte {
key := dao.getKeyBuf(5)
key[0] = byte(storage.STContractID)
binary.BigEndian.PutUint32(key[1:], uint32(id))
return key
}
// DeleteContractID deletes contract's id to hash mapping.
func (dao *Simple) DeleteContractID(id int32) {
dao.Store.Delete(dao.makeContractIDKey(id))
}
// PutContractID adds a mapping from a contract's ID to its hash.
func (dao *Simple) PutContractID(id int32, hash util.Uint160) {
dao.Store.Put(dao.makeContractIDKey(id), hash.BytesBE())
}
// GetContractScriptHash retrieves the contract's hash given its ID.
func (dao *Simple) GetContractScriptHash(id int32) (util.Uint160, error) {
var data = new(util.Uint160)
if err := dao.GetAndDecode(data, dao.makeContractIDKey(id)); err != nil {
return *data, err
}
return *data, nil
}
// -- start NEP-17 transfer info. // -- start NEP-17 transfer info.
func (dao *Simple) makeTTIKey(acc util.Uint160) []byte { func (dao *Simple) makeTTIKey(acc util.Uint160) []byte {

View file

@ -228,19 +228,24 @@ func GetContract(d *dao.Simple, hash util.Uint160) (*state.Contract, error) {
// GetContractByID returns a contract with the given ID from the given DAO. // GetContractByID returns a contract with the given ID from the given DAO.
func GetContractByID(d *dao.Simple, id int32) (*state.Contract, error) { func GetContractByID(d *dao.Simple, id int32) (*state.Contract, error) {
key := make([]byte, 5) hash, err := GetContractScriptHash(d, id)
key = putHashKey(key, id)
si := d.GetStorageItem(ManagementContractID, key)
if si == nil {
return nil, storage.ErrKeyNotFound
}
hash, err := util.Uint160DecodeBytesBE(si)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return GetContract(d, hash) return GetContract(d, hash)
} }
// GetContractScriptHash returns a contract hash associated with the given ID from the given DAO.
func GetContractScriptHash(d *dao.Simple, id int32) (util.Uint160, error) {
key := make([]byte, 5)
key = putHashKey(key, id)
si := d.GetStorageItem(ManagementContractID, key)
if si == nil {
return util.Uint160{}, storage.ErrKeyNotFound
}
return util.Uint160DecodeBytesBE(si)
}
func getLimitedSlice(arg stackitem.Item, max int) ([]byte, error) { func getLimitedSlice(arg stackitem.Item, max int) ([]byte, error) {
_, isNull := arg.(stackitem.Null) _, isNull := arg.(stackitem.Null)
if isNull { if isNull {
@ -492,7 +497,6 @@ func (m *Management) Destroy(d *dao.Simple, hash util.Uint160) error {
d.DeleteStorageItem(m.ID, key) d.DeleteStorageItem(m.ID, key)
key = putHashKey(key, contract.ID) key = putHashKey(key, contract.ID)
d.DeleteStorageItem(ManagementContractID, key) d.DeleteStorageItem(ManagementContractID, key)
d.DeleteContractID(contract.ID)
d.Seek(contract.ID, storage.SeekRange{}, func(k, _ []byte) bool { d.Seek(contract.ID, storage.SeekRange{}, func(k, _ []byte) bool {
d.DeleteStorageItem(contract.ID, k) d.DeleteStorageItem(contract.ID, k)
@ -686,7 +690,6 @@ func putContractState(d *dao.Simple, cs *state.Contract, updateCache bool) error
} }
key = putHashKey(key, cs.ID) key = putHashKey(key, cs.ID)
d.PutStorageItem(ManagementContractID, key, cs.Hash.BytesBE()) d.PutStorageItem(ManagementContractID, key, cs.Hash.BytesBE())
d.PutContractID(cs.ID, cs.Hash)
return nil return nil
} }

View file

@ -17,7 +17,6 @@ const (
// DataMPTAux is used to store additional MPT data like height-root // DataMPTAux is used to store additional MPT data like height-root
// mappings and local/validated heights. // mappings and local/validated heights.
DataMPTAux KeyPrefix = 0x04 DataMPTAux KeyPrefix = 0x04
STContractID KeyPrefix = 0x51
STStorage KeyPrefix = 0x70 STStorage KeyPrefix = 0x70
// STTempStorage is used to store contract storage items during state sync process // STTempStorage is used to store contract storage items during state sync process
// in order not to mess up the previous state which has its own items stored by // in order not to mess up the previous state which has its own items stored by