diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index 978121feb..f24c7267c 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -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. diff --git a/pkg/core/dao/dao_test.go b/pkg/core/dao/dao_test.go index 2da5f7f70..a94649467 100644 --- a/pkg/core/dao/dao_test.go +++ b/pkg/core/dao/dao_test.go @@ -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) { diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index a2ad11d09..0c77bbc23 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -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 }