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.
This commit is contained in:
Roman Khimov 2021-01-22 11:28:13 +03:00
parent dfc23c4246
commit 6b9b37f170
4 changed files with 22 additions and 26 deletions

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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{