From 6b9b37f170e19db4fa9d422da8fe0c3ca94bbc3c Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 22 Jan 2021 11:28:13 +0300 Subject: [PATCH] native: don't call CreateNativeContractHash() in oracle contract Move oracleScript from global context to Oracle itself. We have the hash already computed by NewContractMD, there is no need to repeat this calculation. --- pkg/core/blockchain.go | 2 +- pkg/core/blockchain_test.go | 2 +- pkg/core/native/oracle.go | 40 +++++++++++++++------------------- pkg/core/native_oracle_test.go | 4 ++-- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 3af24d84b..f143259e8 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1395,7 +1395,7 @@ func (bc *Blockchain) verifyTxAttributes(tx *transaction.Transaction, isPartialT if !hasOracle { return fmt.Errorf("%w: oracle tx is not signed by oracle nodes", ErrInvalidAttribute) } - if !bytes.Equal(tx.Script, native.GetOracleResponseScript()) { + if !bytes.Equal(tx.Script, bc.contracts.Oracle.GetOracleResponseScript()) { return fmt.Errorf("%w: oracle tx has invalid script", ErrInvalidAttribute) } resp := tx.Attributes[i].Value.(*transaction.OracleResponse) diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index b7548d6d2..af8bfa062 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -500,7 +500,7 @@ func TestVerifyTx(t *testing.T) { // We need to create new transaction, // because hashes are cached after signing. getOracleTx := func(t *testing.T) *transaction.Transaction { - tx := bc.newTestTx(h, native.GetOracleResponseScript()) + tx := bc.newTestTx(h, orc.GetOracleResponseScript()) resp := &transaction.OracleResponse{ ID: 1, Code: transaction.Success, diff --git a/pkg/core/native/oracle.go b/pkg/core/native/oracle.go index 88e9360cd..9c84570b5 100644 --- a/pkg/core/native/oracle.go +++ b/pkg/core/native/oracle.go @@ -34,7 +34,8 @@ type Oracle struct { GAS *GAS NEO *NEO - Desig *Designate + Desig *Designate + oracleScript []byte } const ( @@ -49,20 +50,6 @@ const ( oracleRequestPrice = 5000_0000 ) -var oracleScript []byte - -func init() { - _, h := state.CreateNativeContractHash(oracleContractID) - w := io.NewBufBinWriter() - emit.Int(w.BinWriter, 0) - emit.Opcodes(w.BinWriter, opcode.NEWARRAY) - emit.Int(w.BinWriter, int64(callflag.All)) - emit.String(w.BinWriter, "finish") - emit.Bytes(w.BinWriter, h.BytesBE()) - emit.Syscall(w.BinWriter, interopnames.SystemContractCall) - oracleScript = w.Bytes() -} - var ( prefixIDList = []byte{6} prefixRequest = []byte{7} @@ -78,16 +65,18 @@ var ( ErrResponseNotFound = errors.New("oracle response not found") ) -// GetOracleResponseScript returns script for transaction with oracle response. -func GetOracleResponseScript() []byte { - b := make([]byte, len(oracleScript)) - copy(b, oracleScript) - return b -} - func newOracle() *Oracle { o := &Oracle{ContractMD: *interop.NewContractMD(nativenames.Oracle, oracleContractID)} + w := io.NewBufBinWriter() + emit.Int(w.BinWriter, 0) + emit.Opcodes(w.BinWriter, opcode.NEWARRAY) + emit.Int(w.BinWriter, int64(callflag.All)) + emit.String(w.BinWriter, "finish") + emit.Bytes(w.BinWriter, o.Hash.BytesBE()) + emit.Syscall(w.BinWriter, interopnames.SystemContractCall) + o.oracleScript = w.Bytes() + desc := newDescriptor("request", smartcontract.VoidType, manifest.NewParameter("url", smartcontract.StringType), manifest.NewParameter("filter", smartcontract.StringType), @@ -115,6 +104,13 @@ func newOracle() *Oracle { return o } +// GetOracleResponseScript returns script for transaction with oracle response. +func (o *Oracle) GetOracleResponseScript() []byte { + b := make([]byte, len(o.oracleScript)) + copy(b, o.oracleScript) + return b +} + // OnPersist implements Contract interface. func (o *Oracle) OnPersist(ic *interop.Context) error { return nil diff --git a/pkg/core/native_oracle_test.go b/pkg/core/native_oracle_test.go index b316bc3e5..b6ac58d64 100644 --- a/pkg/core/native_oracle_test.go +++ b/pkg/core/native_oracle_test.go @@ -153,7 +153,7 @@ func TestOracle_Request(t *testing.T) { err = bc.contracts.Designate.DesignateAsRole(ic, native.RoleOracle, keys.PublicKeys{pub}) require.NoError(t, err) - tx = transaction.New(netmode.UnitTestNet, native.GetOracleResponseScript(), 0) + tx = transaction.New(netmode.UnitTestNet, orc.GetOracleResponseScript(), 0) ic.Tx = tx ic.Block = bc.newBlock(tx) @@ -203,7 +203,7 @@ func TestOracle_Request(t *testing.T) { _, err := orc.GetRequestInternal(bc.dao, reqID) // ensure ID is 2 require.NoError(t, err) - tx = transaction.New(netmode.UnitTestNet, native.GetOracleResponseScript(), 0) + tx = transaction.New(netmode.UnitTestNet, orc.GetOracleResponseScript(), 0) tx.Attributes = []transaction.Attribute{{ Type: transaction.OracleResponseT, Value: &transaction.OracleResponse{