neoneo-go/pkg/services/oracle/broadcaster/oracle.go
Anna Shaleva 6b21ad9922 *: replace interface{} with any keyword
Everywhere including examples, external interop APIs, bindings generators
code and in other valuable places. A couple of `interface{}` usages are
intentionally left in the CHANGELOG.md, documentation and tests.
2023-04-04 13:22:42 +03:00

63 lines
1.9 KiB
Go

package broadcaster
import (
"encoding/base64"
"encoding/binary"
"time"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/services/helpers/rpcbroadcaster"
"go.uber.org/zap"
)
const (
defaultSendTimeout = time.Second * 4
defaultChanCapacity = 16
)
// OracleBroadcaster is an oracle broadcaster implementation.
type OracleBroadcaster struct {
rpcbroadcaster.RPCBroadcaster
}
// New returns a new struct capable of broadcasting oracle responses.
func New(cfg config.OracleConfiguration, log *zap.Logger) *OracleBroadcaster {
if cfg.ResponseTimeout == 0 {
cfg.ResponseTimeout = defaultSendTimeout
}
r := &OracleBroadcaster{
RPCBroadcaster: *rpcbroadcaster.NewRPCBroadcaster(log, cfg.ResponseTimeout),
}
for i := range cfg.Nodes {
r.Clients[cfg.Nodes[i]] = r.NewRPCClient(cfg.Nodes[i], (*rpcclient.Client).SubmitRawOracleResponse,
cfg.ResponseTimeout, make(chan []any, defaultChanCapacity))
}
return r
}
// SendResponse implements interfaces.Broadcaster.
func (r *OracleBroadcaster) SendResponse(priv *keys.PrivateKey, resp *transaction.OracleResponse, txSig []byte) {
pub := priv.PublicKey()
data := GetMessage(pub.Bytes(), resp.ID, txSig)
msgSig := priv.Sign(data)
params := []any{
base64.StdEncoding.EncodeToString(pub.Bytes()),
resp.ID,
base64.StdEncoding.EncodeToString(txSig),
base64.StdEncoding.EncodeToString(msgSig),
}
r.SendParams(params)
}
// GetMessage returns data which is signed upon sending response by RPC.
func GetMessage(pubBytes []byte, reqID uint64, txSig []byte) []byte {
data := make([]byte, len(pubBytes)+8+len(txSig))
copy(data, pubBytes)
binary.LittleEndian.PutUint64(data[len(pubBytes):], uint64(reqID))
copy(data[len(pubBytes)+8:], txSig)
return data
}