diff --git a/pkg/compiler/interop_test.go b/pkg/compiler/interop_test.go index 165247b03..135f1bc61 100644 --- a/pkg/compiler/interop_test.go +++ b/pkg/compiler/interop_test.go @@ -193,7 +193,7 @@ func TestAppCall(t *testing.T) { } fc := fakechain.NewFakeChain() - ic := interop.NewContext(trigger.Application, fc, dao.NewSimple(storage.NewMemoryStore(), false), contractGetter, nil, nil, nil, zaptest.NewLogger(t)) + ic := interop.NewContext(trigger.Application, fc, dao.NewSimple(storage.NewMemoryStore(), false, false), contractGetter, nil, nil, nil, zaptest.NewLogger(t)) t.Run("valid script", func(t *testing.T) { src := getAppCallScript(fmt.Sprintf("%#v", ih.BytesBE())) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index eafbad313..0d699e416 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -235,8 +235,8 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L } bc := &Blockchain{ config: cfg, - dao: dao.NewSimple(s, cfg.StateRootInHeader), - persistent: dao.NewSimple(s, cfg.StateRootInHeader), + dao: dao.NewSimple(s, cfg.StateRootInHeader, cfg.P2PSigExtensions), + persistent: dao.NewSimple(s, cfg.StateRootInHeader, cfg.P2PSigExtensions), stopCh: make(chan struct{}), runToExitCh: make(chan struct{}), memPool: mempool.New(cfg.MemPoolSize, 0, false), diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index b895d1033..93a0d4a56 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -77,12 +77,14 @@ type Simple struct { Store *storage.MemCachedStore // stateRootInHeader specifies if block header contains state root. stateRootInHeader bool + // p2pSigExtensions denotes whether P2PSignatureExtensions are enabled. + p2pSigExtensions bool } // NewSimple creates new simple dao using provided backend store. -func NewSimple(backend storage.Store, stateRootInHeader bool) *Simple { +func NewSimple(backend storage.Store, stateRootInHeader bool, p2pSigExtensions bool) *Simple { st := storage.NewMemCachedStore(backend) - return &Simple{Store: st, stateRootInHeader: stateRootInHeader} + return &Simple{Store: st, stateRootInHeader: stateRootInHeader, p2pSigExtensions: p2pSigExtensions} } // GetBatch returns currently accumulated DB changeset. @@ -93,7 +95,7 @@ func (dao *Simple) GetBatch() *storage.MemBatch { // GetWrapped returns new DAO instance with another layer of wrapped // MemCachedStore around the current DAO Store. func (dao *Simple) GetWrapped() DAO { - d := NewSimple(dao.Store, dao.stateRootInHeader) + d := NewSimple(dao.Store, dao.stateRootInHeader, dao.p2pSigExtensions) return d } @@ -585,6 +587,13 @@ func (dao *Simple) DeleteBlock(h util.Uint256, w *io.BufBinWriter) error { for _, tx := range b.Transactions { copy(key[1:], tx.Hash().BytesBE()) batch.Delete(key) + if dao.p2pSigExtensions { + for _, attr := range tx.GetAttributes(transaction.ConflictsT) { + hash := attr.Value.(*transaction.Conflicts).Hash + copy(key[1:], hash.BytesBE()) + batch.Delete(key) + } + } key[0] = byte(storage.STNotification) batch.Delete(key) } diff --git a/pkg/core/dao/dao_test.go b/pkg/core/dao/dao_test.go index 581b0e521..f6caf6993 100644 --- a/pkg/core/dao/dao_test.go +++ b/pkg/core/dao/dao_test.go @@ -17,7 +17,7 @@ import ( ) func TestPutGetAndDecode(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) serializable := &TestSerializable{field: random.String(4)} hash := []byte{1} err := dao.Put(serializable, hash) @@ -42,7 +42,7 @@ func (t *TestSerializable) DecodeBinary(reader *io.BinReader) { } func TestPutGetAppExecResult(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) hash := random.Uint256() appExecResult := &state.AppExecResult{ Container: hash, @@ -60,7 +60,7 @@ func TestPutGetAppExecResult(t *testing.T) { } func TestPutGetStorageItem(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) id := int32(random.Int(0, 1024)) key := []byte{0} storageItem := state.StorageItem{} @@ -71,7 +71,7 @@ func TestPutGetStorageItem(t *testing.T) { } func TestDeleteStorageItem(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) id := int32(random.Int(0, 1024)) key := []byte{0} storageItem := state.StorageItem{} @@ -84,7 +84,7 @@ func TestDeleteStorageItem(t *testing.T) { } func TestGetBlock_NotExists(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) hash := random.Uint256() block, err := dao.GetBlock(hash) require.Error(t, err) @@ -92,7 +92,7 @@ func TestGetBlock_NotExists(t *testing.T) { } func TestPutGetBlock(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) b := &block.Block{ Header: block.Header{ Script: transaction.Witness{ @@ -110,14 +110,14 @@ func TestPutGetBlock(t *testing.T) { } func TestGetVersion_NoVersion(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) version, err := dao.GetVersion() require.Error(t, err) require.Equal(t, "", version) } func TestGetVersion(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) err := dao.PutVersion("testVersion") require.NoError(t, err) version, err := dao.GetVersion() @@ -126,14 +126,14 @@ func TestGetVersion(t *testing.T) { } func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) height, err := dao.GetCurrentBlockHeight() require.Error(t, err) require.Equal(t, uint32(0), height) } func TestGetCurrentHeaderHeight_Store(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) b := &block.Block{ Header: block.Header{ Script: transaction.Witness{ @@ -150,7 +150,7 @@ func TestGetCurrentHeaderHeight_Store(t *testing.T) { } func TestStoreAsTransaction(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), false) + dao := NewSimple(storage.NewMemoryStore(), false, false) tx := transaction.New([]byte{byte(opcode.PUSH1)}, 1) hash := tx.Hash() err := dao.StoreAsTransaction(tx, 0, nil) @@ -173,7 +173,7 @@ func TestMakeStorageItemKey(t *testing.T) { } func TestPutGetStateSyncPoint(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), true) + dao := NewSimple(storage.NewMemoryStore(), true, false) // empty store _, err := dao.GetStateSyncPoint() @@ -188,7 +188,7 @@ func TestPutGetStateSyncPoint(t *testing.T) { } func TestPutGetStateSyncCurrentBlockHeight(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore(), true) + dao := NewSimple(storage.NewMemoryStore(), true, false) // empty store _, err := dao.GetStateSyncCurrentBlockHeight() diff --git a/pkg/core/interop/crypto/ecdsa_test.go b/pkg/core/interop/crypto/ecdsa_test.go index 0099e35d2..3331d7f25 100644 --- a/pkg/core/interop/crypto/ecdsa_test.go +++ b/pkg/core/interop/crypto/ecdsa_test.go @@ -71,7 +71,7 @@ func initCheckMultisigVMNoArgs(container *transaction.Transaction) *vm.VM { ic := interop.NewContext( trigger.Verification, fakechain.NewFakeChain(), - dao.NewSimple(storage.NewMemoryStore(), false), + dao.NewSimple(storage.NewMemoryStore(), false, false), nil, nil, nil, container, nil) @@ -177,7 +177,7 @@ func TestCheckSig(t *testing.T) { require.NoError(t, err) verifyFunc := ECDSASecp256r1CheckSig - d := dao.NewSimple(storage.NewMemoryStore(), false) + d := dao.NewSimple(storage.NewMemoryStore(), false, false) ic := &interop.Context{Network: uint32(netmode.UnitTestNet), DAO: d} runCase := func(t *testing.T, isErr bool, result interface{}, args ...interface{}) { ic.SpawnVM() diff --git a/pkg/core/interop_system_test.go b/pkg/core/interop_system_test.go index 62e0ab5f6..06d89814f 100644 --- a/pkg/core/interop_system_test.go +++ b/pkg/core/interop_system_test.go @@ -552,7 +552,7 @@ func TestStorageFind(t *testing.T) { func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) { chain := newTestChain(t) context := chain.newInteropContext(trigger.Application, - dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader), nil, nil) + dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader, chain.config.P2PSigExtensions), nil, nil) v := context.SpawnVM() return v, context, chain } @@ -572,7 +572,7 @@ func createVMAndContractState(t testing.TB) (*vm.VM, *state.Contract, *interop.C } chain := newTestChain(t) - d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader) + d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader, chain.config.P2PSigExtensions) context := chain.newInteropContext(trigger.Application, d, nil, nil) v := context.SpawnVM() return v, contractState, context, chain @@ -584,7 +584,7 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Con tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, 4}}} tx.Scripts = []transaction.Witness{{InvocationScript: []byte{}, VerificationScript: []byte{}}} chain := newTestChain(t) - d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader) + d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader, chain.config.P2PSigExtensions) context := chain.newInteropContext(trigger.Application, d, nil, tx) v := context.SpawnVM() return v, tx, context, chain diff --git a/pkg/core/interops_test.go b/pkg/core/interops_test.go index 0db9acd40..ef4dde7bf 100644 --- a/pkg/core/interops_test.go +++ b/pkg/core/interops_test.go @@ -17,7 +17,7 @@ func testNonInterop(t *testing.T, value interface{}, f func(*interop.Context) er v := vm.New() v.Estack().PushVal(value) chain := newTestChain(t) - d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader) + d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader, chain.config.P2PSigExtensions) context := chain.newInteropContext(trigger.Application, d, nil, nil) context.VM = v require.Error(t, f(context)) diff --git a/pkg/core/native/management_test.go b/pkg/core/native/management_test.go index 91f72bdf6..b7715e16e 100644 --- a/pkg/core/native/management_test.go +++ b/pkg/core/native/management_test.go @@ -17,7 +17,7 @@ import ( func TestDeployGetUpdateDestroyContract(t *testing.T) { mgmt := newManagement() - d := dao.NewSimple(storage.NewMemoryStore(), false) + d := dao.NewSimple(storage.NewMemoryStore(), false, false) err := mgmt.Initialize(&interop.Context{DAO: d}) require.NoError(t, err) script := []byte{byte(opcode.RET)} @@ -72,12 +72,12 @@ func TestDeployGetUpdateDestroyContract(t *testing.T) { func TestManagement_Initialize(t *testing.T) { t.Run("good", func(t *testing.T) { - d := dao.NewSimple(storage.NewMemoryStore(), false) + d := dao.NewSimple(storage.NewMemoryStore(), false, false) mgmt := newManagement() require.NoError(t, mgmt.InitializeCache(d)) }) t.Run("invalid contract state", func(t *testing.T) { - d := dao.NewSimple(storage.NewMemoryStore(), false) + d := dao.NewSimple(storage.NewMemoryStore(), false, false) mgmt := newManagement() require.NoError(t, d.PutStorageItem(mgmt.ID, []byte{prefixContract}, state.StorageItem{0xFF})) require.Error(t, mgmt.InitializeCache(d)) @@ -86,7 +86,7 @@ func TestManagement_Initialize(t *testing.T) { func TestManagement_GetNEP17Contracts(t *testing.T) { mgmt := newManagement() - d := dao.NewSimple(storage.NewMemoryStore(), false) + d := dao.NewSimple(storage.NewMemoryStore(), false, false) err := mgmt.Initialize(&interop.Context{DAO: d}) require.NoError(t, err) diff --git a/pkg/core/native_contract_test.go b/pkg/core/native_contract_test.go index eb2403b4b..aea370ef4 100644 --- a/pkg/core/native_contract_test.go +++ b/pkg/core/native_contract_test.go @@ -227,7 +227,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) { }) require.NoError(t, err) - d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader) + d := dao.NewSimple(storage.NewMemoryStore(), chain.config.StateRootInHeader, chain.config.P2PSigExtensions) ic := chain.newInteropContext(trigger.Application, d, nil, nil) sumOffset := 0