dao: combine GetNextContractID and PutNextContractID

And fix contract create to really update the ID, eliminating this difference
in the storage (preview2 testnet):
file BlockStorage_100000/dump-block-39000.json: block 38043: key mismatch: 0c000000617373657464df4ebe92334d1fc7e64b10f1d1e33942d9905e510000000000000009 vs 00000000617373657464df4ebe92334d1fc7e64b10f1d1e33942d9905e510000000000000009
This commit is contained in:
Roman Khimov 2020-06-23 21:09:37 +03:00
parent 5e56c9db29
commit d5c9449a43
3 changed files with 18 additions and 26 deletions

View file

@ -32,7 +32,7 @@ type DAO interface {
GetHeaderHashes() ([]util.Uint256, error)
GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error)
GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error)
GetNextContractID() (int32, error)
GetAndUpdateNextContractID() (int32, error)
GetStorageItem(id int32, key []byte) *state.StorageItem
GetStorageItems(id int32) (map[string]*state.StorageItem, error)
GetStorageItemsWithPrefix(id int32, prefix []byte) (map[string]*state.StorageItem, error)
@ -47,7 +47,6 @@ type DAO interface {
PutCurrentHeader(hashAndIndex []byte) error
PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error
PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error
PutNextContractID(id int32) error
PutStorageItem(id int32, key []byte, si *state.StorageItem) error
PutVersion(v string) error
StoreAsBlock(block *block.Block) error
@ -173,25 +172,19 @@ func (dao *Simple) DeleteContractState(hash util.Uint160) error {
return dao.Store.Delete(key)
}
// GetNextContractID returns id for the next contract and increases stored id.
func (dao *Simple) GetNextContractID() (int32, error) {
// GetAndUpdateNextContractID returns id for the next contract and increases stored ID.
func (dao *Simple) GetAndUpdateNextContractID() (int32, error) {
var id int32
key := storage.SYSContractID.Bytes()
data, err := dao.Store.Get(key)
if err != nil {
if err == storage.ErrKeyNotFound {
err = nil
}
if err == nil {
id = int32(binary.LittleEndian.Uint32(data))
} else if err != storage.ErrKeyNotFound {
return 0, err
}
return int32(binary.LittleEndian.Uint32(data)), nil
}
// PutNextContractID sets next contract id to id.
func (dao *Simple) PutNextContractID(id int32) error {
key := storage.SYSContractID.Bytes()
data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, uint32(id))
return dao.Store.Put(key, data)
data = make([]byte, 4)
binary.LittleEndian.PutUint32(data, uint32(id+1))
return id, dao.Store.Put(key, data)
}
// -- end contracts.

View file

@ -84,15 +84,17 @@ func TestDeleteContractState(t *testing.T) {
require.Nil(t, gotContractState)
}
func TestSimple_GetNextContractID(t *testing.T) {
func TestSimple_GetAndUpdateNextContractID(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
id, err := dao.GetNextContractID()
id, err := dao.GetAndUpdateNextContractID()
require.NoError(t, err)
require.EqualValues(t, 0, id)
require.NoError(t, dao.PutNextContractID(10))
id, err = dao.GetNextContractID()
id, err = dao.GetAndUpdateNextContractID()
require.NoError(t, err)
require.EqualValues(t, 10, id)
require.EqualValues(t, 1, id)
id, err = dao.GetAndUpdateNextContractID()
require.NoError(t, err)
require.EqualValues(t, 2, id)
}
func TestPutGetAppExecResult(t *testing.T) {

View file

@ -91,14 +91,11 @@ func contractCreate(ic *interop.Context, v *vm.VM) error {
if contract != nil {
return errors.New("contract already exists")
}
id, err := ic.DAO.GetNextContractID()
id, err := ic.DAO.GetAndUpdateNextContractID()
if err != nil {
return err
}
newcontract.ID = id
if err := ic.DAO.PutNextContractID(id); err != nil {
return err
}
if err := ic.DAO.PutContractState(newcontract); err != nil {
return err
}