github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/services/oracle/broadcaster/oracle.go (about) 1 package broadcaster 2 3 import ( 4 "encoding/base64" 5 "encoding/binary" 6 "time" 7 8 "github.com/nspcc-dev/neo-go/pkg/config" 9 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 10 "github.com/nspcc-dev/neo-go/pkg/crypto/keys" 11 "github.com/nspcc-dev/neo-go/pkg/rpcclient" 12 "github.com/nspcc-dev/neo-go/pkg/services/helpers/rpcbroadcaster" 13 "go.uber.org/zap" 14 ) 15 16 const ( 17 defaultSendTimeout = time.Second * 4 18 19 defaultChanCapacity = 16 20 ) 21 22 // OracleBroadcaster is an oracle broadcaster implementation. 23 type OracleBroadcaster struct { 24 rpcbroadcaster.RPCBroadcaster 25 } 26 27 // New returns a new struct capable of broadcasting oracle responses. 28 func New(cfg config.OracleConfiguration, log *zap.Logger) *OracleBroadcaster { 29 if cfg.ResponseTimeout == 0 { 30 cfg.ResponseTimeout = defaultSendTimeout 31 } 32 r := &OracleBroadcaster{ 33 RPCBroadcaster: *rpcbroadcaster.NewRPCBroadcaster(log, cfg.ResponseTimeout), 34 } 35 for i := range cfg.Nodes { 36 r.Clients[cfg.Nodes[i]] = r.NewRPCClient(cfg.Nodes[i], (*rpcclient.Client).SubmitRawOracleResponse, 37 cfg.ResponseTimeout, make(chan []any, defaultChanCapacity)) 38 } 39 return r 40 } 41 42 // SendResponse implements interfaces.Broadcaster. 43 func (r *OracleBroadcaster) SendResponse(priv *keys.PrivateKey, resp *transaction.OracleResponse, txSig []byte) { 44 pub := priv.PublicKey() 45 data := GetMessage(pub.Bytes(), resp.ID, txSig) 46 msgSig := priv.Sign(data) 47 params := []any{ 48 base64.StdEncoding.EncodeToString(pub.Bytes()), 49 resp.ID, 50 base64.StdEncoding.EncodeToString(txSig), 51 base64.StdEncoding.EncodeToString(msgSig), 52 } 53 r.SendParams(params) 54 } 55 56 // GetMessage returns data which is signed upon sending response by RPC. 57 func GetMessage(pubBytes []byte, reqID uint64, txSig []byte) []byte { 58 data := make([]byte, len(pubBytes)+8+len(txSig)) 59 copy(data, pubBytes) 60 binary.LittleEndian.PutUint64(data[len(pubBytes):], uint64(reqID)) 61 copy(data[len(pubBytes)+8:], txSig) 62 return data 63 }