Add Type field to DioneTask, rename rpcclient to ethclient, rewrite whole signing system in Dione, add some comments to consensus process (w/ mining system)
This commit is contained in:
parent
6636a279e7
commit
0b37896af9
@ -15,9 +15,9 @@ type Response struct {
|
|||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Schedule []BeaconPoint
|
type Queue []BeaconPoint
|
||||||
|
|
||||||
func (bs Schedule) BeaconForEpoch(e types.TaskEpoch) RandomBeacon {
|
func (bs Queue) BeaconForEpoch(e types.TaskEpoch) RandomBeacon {
|
||||||
for i := len(bs) - 1; i >= 0; i-- {
|
for i := len(bs) - 1; i >= 0; i-- {
|
||||||
bp := bs[i]
|
bp := bs[i]
|
||||||
if e >= bp.Start {
|
if e >= bp.Start {
|
||||||
@ -42,10 +42,10 @@ type RandomBeacon interface {
|
|||||||
MaxBeaconRoundForEpoch(types.TaskEpoch) uint64
|
MaxBeaconRoundForEpoch(types.TaskEpoch) uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateTaskValues(bSchedule Schedule, t *types.DioneTask, parentEpoch types.TaskEpoch, prevEntry types.BeaconEntry) error {
|
func ValidateTaskValues(bQueue Queue, t *types.DioneTask, parentEpoch types.TaskEpoch, prevEntry types.BeaconEntry) error {
|
||||||
{
|
{
|
||||||
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
parentBeacon := bQueue.BeaconForEpoch(parentEpoch)
|
||||||
currBeacon := bSchedule.BeaconForEpoch(t.Epoch)
|
currBeacon := bQueue.BeaconForEpoch(t.Epoch)
|
||||||
if parentBeacon != currBeacon {
|
if parentBeacon != currBeacon {
|
||||||
if len(t.BeaconEntries) != 2 {
|
if len(t.BeaconEntries) != 2 {
|
||||||
return fmt.Errorf("expected two beacon entries at beacon fork, got %d", len(t.BeaconEntries))
|
return fmt.Errorf("expected two beacon entries at beacon fork, got %d", len(t.BeaconEntries))
|
||||||
@ -60,7 +60,7 @@ func ValidateTaskValues(bSchedule Schedule, t *types.DioneTask, parentEpoch type
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fork logic
|
// TODO: fork logic
|
||||||
b := bSchedule.BeaconForEpoch(t.Epoch)
|
b := bQueue.BeaconForEpoch(t.Epoch)
|
||||||
maxRound := b.MaxBeaconRoundForEpoch(t.Epoch)
|
maxRound := b.MaxBeaconRoundForEpoch(t.Epoch)
|
||||||
if maxRound == prevEntry.Round {
|
if maxRound == prevEntry.Round {
|
||||||
if len(t.BeaconEntries) != 0 {
|
if len(t.BeaconEntries) != 0 {
|
||||||
@ -88,7 +88,7 @@ func ValidateTaskValues(bSchedule Schedule, t *types.DioneTask, parentEpoch type
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BeaconEntriesForTask(ctx context.Context, bSchedule Schedule, epoch types.TaskEpoch, parentEpoch types.TaskEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
|
func BeaconEntriesForTask(ctx context.Context, bSchedule Queue, epoch types.TaskEpoch, parentEpoch types.TaskEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
|
||||||
{
|
{
|
||||||
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
||||||
currBeacon := bSchedule.BeaconForEpoch(epoch)
|
currBeacon := bSchedule.BeaconForEpoch(epoch)
|
||||||
|
@ -7,15 +7,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ListenPort int `mapstructure:"listen_port"`
|
ListenPort int `mapstructure:"listen_port"`
|
||||||
ListenAddr string `mapstructure:"listen_addr"`
|
ListenAddr string `mapstructure:"listen_addr"`
|
||||||
BootstrapNodes []string `mapstructure:"bootstrap_node_multiaddr"`
|
BootstrapNodes []string `mapstructure:"bootstrap_node_multiaddr"`
|
||||||
Rendezvous string `mapstructure:"rendezvous"`
|
Rendezvous string `mapstructure:"rendezvous"`
|
||||||
Ethereum EthereumConfig `mapstructure:"ethereum"`
|
Ethereum EthereumConfig `mapstructure:"ethereum"`
|
||||||
Filecoin FilecoinConfig `mapstructure:"filecoin"`
|
Filecoin FilecoinConfig `mapstructure:"filecoin"`
|
||||||
PubSub PubSubConfig `mapstructure:"pubSub"`
|
PubSub PubSubConfig `mapstructure:"pubSub"`
|
||||||
Store StoreConfig `mapstructure:"store"`
|
Store StoreConfig `mapstructure:"store"`
|
||||||
ConsensusMaxFaultNodes int `mapstructure:"consensus_max_fault_nodes"`
|
ConsensusMaxFaultNodes int `mapstructure:"consensus_max_fault_nodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type EthereumConfig struct {
|
type EthereumConfig struct {
|
||||||
|
@ -25,12 +25,12 @@ type PBFTConsensusManager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ConsensusData struct {
|
type ConsensusData struct {
|
||||||
preparedCount int
|
preparedCount int
|
||||||
commitCount int
|
commitCount int
|
||||||
State ConsensusState
|
State ConsensusState
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
result string
|
result string
|
||||||
test bool
|
test bool
|
||||||
onConsensusFinishCallback func(finalData string)
|
onConsensusFinishCallback func(finalData string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +50,8 @@ func (pcm *PBFTConsensusManager) NewTestConsensus(data string, consensusID strin
|
|||||||
cData.onConsensusFinishCallback = onConsensusFinishCallback
|
cData.onConsensusFinishCallback = onConsensusFinishCallback
|
||||||
pcm.Consensuses[consensusID] = cData
|
pcm.Consensuses[consensusID] = cData
|
||||||
|
|
||||||
|
// here we will create DioneTask
|
||||||
|
|
||||||
msg := models.Message{}
|
msg := models.Message{}
|
||||||
msg.Type = "prepared"
|
msg.Type = "prepared"
|
||||||
msg.Payload = make(map[string]interface{})
|
msg.Payload = make(map[string]interface{})
|
||||||
@ -71,16 +73,19 @@ func (pcm *PBFTConsensusManager) handlePreparedMessage(message *models.Message)
|
|||||||
logrus.Debug("received prepared msg")
|
logrus.Debug("received prepared msg")
|
||||||
data := pcm.Consensuses[consensusID]
|
data := pcm.Consensuses[consensusID]
|
||||||
|
|
||||||
// validate payload data
|
//// validate payload data
|
||||||
if data.test {
|
//if data.test {
|
||||||
rData := message.Payload["data"].(string)
|
// rData := message.Payload["data"].(string)
|
||||||
if rData != testValidData {
|
// if rData != testValidData {
|
||||||
logrus.Error("Incorrect data was received! Ignoring this message, because it was sent from fault node!")
|
// logrus.Error("Incorrect data was received! Ignoring this message, because it was sent from fault node!")
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
} else {
|
//} else {
|
||||||
// TODO
|
// // TODO
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
// here we can validate miner which produced this task, is he winner, and so on
|
||||||
|
// we must to reconstruct transaction here for validating task itself
|
||||||
|
|
||||||
data.mutex.Lock()
|
data.mutex.Lock()
|
||||||
data.preparedCount++
|
data.preparedCount++
|
||||||
@ -103,7 +108,7 @@ func (pcm *PBFTConsensusManager) handlePreparedMessage(message *models.Message)
|
|||||||
|
|
||||||
func (pcm *PBFTConsensusManager) handleCommitMessage(message *models.Message) {
|
func (pcm *PBFTConsensusManager) handleCommitMessage(message *models.Message) {
|
||||||
// TODO add check on view of the message
|
// TODO add check on view of the message
|
||||||
// TODO add validation of data to this stage
|
// TODO add validation of data by hash to this stage
|
||||||
consensusID := message.Payload["consensusID"].(string)
|
consensusID := message.Payload["consensusID"].(string)
|
||||||
if _, ok := pcm.Consensuses[consensusID]; !ok {
|
if _, ok := pcm.Consensuses[consensusID]; !ok {
|
||||||
logrus.Warn("Unknown consensus ID: " + consensusID)
|
logrus.Warn("Unknown consensus ID: " + consensusID)
|
||||||
|
@ -1,43 +1,39 @@
|
|||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
"github.com/Secured-Finance/dione/types"
|
"github.com/Secured-Finance/dione/types"
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
|
||||||
"go.opencensus.io/trace"
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
type SignFunc func(context.Context, peer.ID, []byte) (*types.Signature, error)
|
||||||
|
|
||||||
func ComputeVRF(ctx context.Context, sign SignFunc, worker address.Address, sigInput []byte) ([]byte, error) {
|
func ComputeVRF(ctx context.Context, sign SignFunc, worker peer.ID, sigInput []byte) ([]byte, error) {
|
||||||
sig, err := sign(ctx, worker, sigInput)
|
sig, err := sign(ctx, worker, sigInput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if sig.Type != crypto.SigTypeBLS {
|
if sig.Type != types.SigTypeEd25519 {
|
||||||
return nil, fmt.Errorf("miner worker address was not a BLS key")
|
return nil, fmt.Errorf("miner worker address was not a Ed25519 key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return sig.Data, nil
|
return sig.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyVRF(ctx context.Context, worker address.Address, vrfBase, vrfproof []byte) error {
|
func VerifyVRF(ctx context.Context, worker peer.ID, vrfBase, vrfproof []byte) error {
|
||||||
_, span := trace.StartSpan(ctx, "VerifyVRF")
|
pKey, err := worker.ExtractPublicKey()
|
||||||
defer span.End()
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to extract public key from worker address: %w", err)
|
||||||
sig := &crypto.Signature{
|
|
||||||
Type: crypto.SigTypeBLS,
|
|
||||||
Data: vrfproof,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sigs.Verify(sig, worker, vrfBase); err != nil {
|
valid, err := pKey.Verify(vrfBase, vrfproof)
|
||||||
|
if err != nil || !valid {
|
||||||
return xerrors.Errorf("vrf was invalid: %w", err)
|
return xerrors.Errorf("vrf was invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,14 +41,14 @@ func VerifyVRF(ctx context.Context, worker address.Address, vrfBase, vrfproof []
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsRoundWinner(ctx context.Context, round types.TaskEpoch,
|
func IsRoundWinner(ctx context.Context, round types.TaskEpoch,
|
||||||
worker address.Address, brand types.BeaconEntry, mb *MinerBase, a MinerAPI) (*types.ElectionProof, error) {
|
worker peer.ID, brand types.BeaconEntry, mb *MinerBase, a MinerAPI) (*types.ElectionProof, error) {
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf, err := worker.MarshalBinary()
|
||||||
if err := worker.MarshalCBOR(buf); err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
|
return nil, xerrors.Errorf("failed to marshal address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
electionRand, err := DrawRandomness(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf.Bytes())
|
electionRand, err := DrawRandomness(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to draw randomness: %w", err)
|
return nil, xerrors.Errorf("failed to draw randomness: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
"github.com/Secured-Finance/dione/types"
|
"github.com/Secured-Finance/dione/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Miner struct {
|
type Miner struct {
|
||||||
address address.Address
|
address peer.ID
|
||||||
api MinerAPI
|
api MinerAPI
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type MinerAPI interface {
|
type MinerAPI interface {
|
||||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
WalletSign(context.Context, peer.ID, []byte) (*types.Signature, error)
|
||||||
// TODO: get miner base based on epoch;
|
// TODO: get miner base based on epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
type MinerBase struct {
|
type MinerBase struct {
|
||||||
MinerStake types.BigInt
|
MinerStake types.BigInt
|
||||||
NetworkStake types.BigInt
|
NetworkStake types.BigInt
|
||||||
WorkerKey address.Address
|
WorkerKey peer.ID
|
||||||
EthWallet common.Address
|
EthWallet common.Address
|
||||||
PrevBeaconEntry types.BeaconEntry
|
PrevBeaconEntry types.BeaconEntry
|
||||||
BeaconEntries []types.BeaconEntry
|
BeaconEntries []types.BeaconEntry
|
||||||
@ -36,15 +36,15 @@ type MinerBase struct {
|
|||||||
|
|
||||||
type MiningBase struct {
|
type MiningBase struct {
|
||||||
epoch types.TaskEpoch
|
epoch types.TaskEpoch
|
||||||
nullRounds types.TaskEpoch
|
nullRounds types.TaskEpoch // currently not used
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMinerBase(minerStake, networkStake types.BigInt, minerWallet address.Address,
|
func NewMinerBase(minerStake, networkStake types.BigInt, minerAddress peer.ID,
|
||||||
minerEthWallet common.Address, prev types.BeaconEntry, entries []types.BeaconEntry) *MinerBase {
|
minerEthWallet common.Address, prev types.BeaconEntry, entries []types.BeaconEntry) *MinerBase {
|
||||||
return &MinerBase{
|
return &MinerBase{
|
||||||
MinerStake: minerStake,
|
MinerStake: minerStake,
|
||||||
NetworkStake: networkStake,
|
NetworkStake: networkStake,
|
||||||
WorkerKey: minerWallet,
|
WorkerKey: minerAddress,
|
||||||
EthWallet: minerEthWallet,
|
EthWallet: minerEthWallet,
|
||||||
PrevBeaconEntry: prev,
|
PrevBeaconEntry: prev,
|
||||||
BeaconEntries: entries,
|
BeaconEntries: entries,
|
||||||
@ -82,21 +82,21 @@ func (m *Miner) MineTask(ctx context.Context, base *MiningBase, mb *MinerBase) (
|
|||||||
Miner: m.address,
|
Miner: m.address,
|
||||||
Ticket: ticket,
|
Ticket: ticket,
|
||||||
ElectionProof: winner,
|
ElectionProof: winner,
|
||||||
BeaconEntries: mb.BeaconEntries,
|
BeaconEntries: mb.BeaconEntries, // TODO decide what we need to do with multiple beacon entries
|
||||||
// TODO: signature
|
// TODO: signature
|
||||||
Epoch: round,
|
Epoch: round,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase, mb *MinerBase) (*types.Ticket, error) {
|
func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase, mb *MinerBase) (*types.Ticket, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf, err := m.address.MarshalBinary()
|
||||||
if err := m.address.MarshalCBOR(buf); err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err)
|
return nil, xerrors.Errorf("failed to marshal address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
round := base.epoch + base.nullRounds + 1
|
round := base.epoch + base.nullRounds + 1
|
||||||
|
|
||||||
input, err := DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, round-types.TicketRandomnessLookback, buf.Bytes())
|
input, err := DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, round-types.TicketRandomnessLookback, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package rpcclient
|
package ethclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,4 +1,4 @@
|
|||||||
package rpcclient
|
package ethclient
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
31
go.mod
31
go.mod
@ -9,37 +9,43 @@ require (
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
|
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
|
||||||
github.com/cespare/cp v1.1.1 // indirect
|
github.com/cespare/cp v1.1.1 // indirect
|
||||||
github.com/deckarep/golang-set v1.7.1 // indirect
|
github.com/deckarep/golang-set v1.7.1 // indirect
|
||||||
|
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
|
||||||
github.com/drand/drand v1.2.1
|
github.com/drand/drand v1.2.1
|
||||||
github.com/drand/kyber v1.1.5
|
github.com/drand/kyber v1.1.5
|
||||||
github.com/elastic/gosigar v0.10.5 // indirect
|
github.com/elastic/gosigar v0.10.5 // indirect
|
||||||
github.com/ethereum/go-ethereum v1.9.5
|
github.com/ethereum/go-ethereum v1.9.5
|
||||||
github.com/filecoin-project/go-address v0.0.4
|
github.com/filecoin-project/go-address v0.0.4
|
||||||
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 // indirect
|
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20201021025442-0ac4de847f4f
|
github.com/filecoin-project/go-state-types v0.0.0-20201021025442-0ac4de847f4f
|
||||||
github.com/filecoin-project/lotus v1.1.2
|
|
||||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
|
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
|
||||||
github.com/go-kit/kit v0.10.0 // indirect
|
|
||||||
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible
|
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||||
github.com/google/uuid v1.1.1 // indirect
|
github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf // indirect
|
||||||
|
github.com/google/gopacket v1.1.18 // indirect
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
|
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
|
||||||
|
github.com/ipfs/go-datastore v0.4.5 // indirect
|
||||||
|
github.com/ipfs/go-ds-badger2 v0.1.1-0.20200708190120-187fc06f714e // indirect
|
||||||
|
github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf // indirect
|
||||||
|
github.com/ipfs/go-ipld-format v0.2.0 // indirect
|
||||||
|
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 // indirect
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
github.com/jmoiron/sqlx v1.2.0
|
||||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||||
|
github.com/lib/pq v1.7.0 // indirect
|
||||||
github.com/libp2p/go-libp2p v0.11.0
|
github.com/libp2p/go-libp2p v0.11.0
|
||||||
github.com/libp2p/go-libp2p-core v0.6.1
|
github.com/libp2p/go-libp2p-core v0.6.1
|
||||||
github.com/libp2p/go-libp2p-discovery v0.5.0 // indirect
|
github.com/libp2p/go-libp2p-noise v0.1.2 // indirect
|
||||||
github.com/libp2p/go-libp2p-kad-dht v0.8.3 // indirect
|
|
||||||
github.com/libp2p/go-libp2p-peerstore v0.2.6 // indirect
|
|
||||||
github.com/libp2p/go-libp2p-pubsub v0.3.6
|
github.com/libp2p/go-libp2p-pubsub v0.3.6
|
||||||
|
github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.9.0
|
||||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
||||||
github.com/multiformats/go-multiaddr v0.3.1
|
github.com/multiformats/go-multiaddr v0.3.1
|
||||||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||||
github.com/prometheus/common v0.10.0 // indirect
|
github.com/onsi/ginkgo v1.14.0 // indirect
|
||||||
|
github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a // indirect
|
||||||
github.com/raulk/clock v1.1.0
|
github.com/raulk/clock v1.1.0
|
||||||
github.com/rjeczalik/notify v0.9.2 // indirect
|
github.com/rjeczalik/notify v0.9.2 // indirect
|
||||||
github.com/rs/cors v1.7.0 // indirect
|
github.com/rs/cors v1.7.0 // indirect
|
||||||
github.com/rs/zerolog v1.20.0 // indirect
|
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/smartystreets/assertions v1.0.1 // indirect
|
github.com/smartystreets/assertions v1.0.1 // indirect
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
@ -47,13 +53,16 @@ require (
|
|||||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
|
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
|
||||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/supranational/blst v0.1.1 // indirect
|
|
||||||
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
|
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
|
||||||
|
github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a // indirect
|
||||||
|
github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163
|
||||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
|
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
|
||||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
||||||
go.opencensus.io v0.22.4
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||||
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
|
||||||
|
golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||||
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect
|
||||||
gopkg.in/urfave/cli.v1 v1.20.0 // indirect
|
gopkg.in/urfave/cli.v1 v1.20.0 // indirect
|
||||||
|
@ -8,9 +8,9 @@ import (
|
|||||||
"github.com/Secured-Finance/dione/drand"
|
"github.com/Secured-Finance/dione/drand"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewBeaconSchedule creates a new beacon chain schedule
|
// NewBeaconQueue creates a new beacon chain schedule
|
||||||
func (n *Node) NewBeaconSchedule() (beacon.Schedule, error) {
|
func (n *Node) NewBeaconQueue() (beacon.Queue, error) {
|
||||||
schedule := beacon.Schedule{}
|
schedule := beacon.Queue{}
|
||||||
bc, err := drand.NewDrandBeacon(config.ChainGenesis, config.TaskEpochInterval, n.PubSubRouter.Pubsub)
|
bc, err := drand.NewDrandBeacon(config.ChainGenesis, config.TaskEpochInterval, n.PubSubRouter.Pubsub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating drand beacon: %w", err)
|
return nil, fmt.Errorf("creating drand beacon: %w", err)
|
||||||
|
12
node/node.go
12
node/node.go
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/Secured-Finance/dione/consensus"
|
"github.com/Secured-Finance/dione/consensus"
|
||||||
"github.com/Secured-Finance/dione/pb"
|
"github.com/Secured-Finance/dione/pb"
|
||||||
"github.com/Secured-Finance/dione/rpc"
|
"github.com/Secured-Finance/dione/rpc"
|
||||||
"github.com/Secured-Finance/dione/rpcclient"
|
"github.com/Secured-Finance/dione/ethclient"
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
crypto "github.com/libp2p/go-libp2p-core/crypto"
|
crypto "github.com/libp2p/go-libp2p-core/crypto"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
@ -32,8 +32,9 @@ type Node struct {
|
|||||||
OracleTopic string
|
OracleTopic string
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
Lotus *rpc.LotusClient
|
Lotus *rpc.LotusClient
|
||||||
Ethereum *rpcclient.EthereumClient
|
Ethereum *ethclient.EthereumClient
|
||||||
ConsensusManager *consensus.PBFTConsensusManager
|
ConsensusManager *consensus.PBFTConsensusManager
|
||||||
|
MinerBase *consensus.MinerBase
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNode(configPath string) (*Node, error) {
|
func NewNode(configPath string) (*Node, error) {
|
||||||
@ -57,8 +58,13 @@ func (n *Node) setupNode(ctx context.Context, prvKey crypto.PrivKey, pexDiscover
|
|||||||
n.setupConsensusManager(n.Config.ConsensusMaxFaultNodes)
|
n.setupConsensusManager(n.Config.ConsensusMaxFaultNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Node) setupMiner() error {
|
||||||
|
// here we do miner base setup
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Node) setupEthereumClient() error {
|
func (n *Node) setupEthereumClient() error {
|
||||||
ethereum := rpcclient.NewEthereumClient()
|
ethereum := ethclient.NewEthereumClient()
|
||||||
n.Ethereum = ethereum
|
n.Ethereum = ethereum
|
||||||
return ethereum.Initialize(context.Background(),
|
return ethereum.Initialize(context.Background(),
|
||||||
n.Config.Ethereum.GatewayAddress,
|
n.Config.Ethereum.GatewayAddress,
|
||||||
|
49
sigs/ed25519/ed25519.go
Normal file
49
sigs/ed25519/ed25519.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package ed25519
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/sigs"
|
||||||
|
"github.com/Secured-Finance/dione/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ed25519Signer struct{}
|
||||||
|
|
||||||
|
func (ed25519Signer) GenPrivate() ([]byte, error) {
|
||||||
|
_, privKey, err := ed25519.GenerateKey(nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return privKey.Seed(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed25519Signer) ToPublic(priv []byte) ([]byte, error) {
|
||||||
|
privKey := ed25519.NewKeyFromSeed(priv)
|
||||||
|
pubKey := privKey.Public().(ed25519.PublicKey)
|
||||||
|
return pubKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed25519Signer) Sign(p []byte, msg []byte) ([]byte, error) {
|
||||||
|
privKey := ed25519.NewKeyFromSeed(p)
|
||||||
|
return ed25519.Sign(privKey, msg), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed25519Signer) Verify(sig []byte, a peer.ID, msg []byte) error {
|
||||||
|
pubKey, err := a.ExtractPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if valid, err := pubKey.Verify(msg, sig); err != nil || !valid {
|
||||||
|
return xerrors.Errorf("failed to verify signature")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sigs.RegisterSignature(types.SigTypeEd25519, ed25519Signer{})
|
||||||
|
}
|
106
sigs/sigs.go
Normal file
106
sigs/sigs.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package sigs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
fmt "fmt"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/types"
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sign takes in signature type, private key and message. Returns a signature for that message.
|
||||||
|
// Valid sigTypes are: "ed25519"
|
||||||
|
func Sign(sigType types.SigType, privkey []byte, msg []byte) (*types.Signature, error) {
|
||||||
|
sv, ok := sigs[sigType]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot sign message with signature of unsupported type: %v", sigType)
|
||||||
|
}
|
||||||
|
|
||||||
|
sb, err := sv.Sign(privkey, msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &types.Signature{
|
||||||
|
Type: sigType,
|
||||||
|
Data: sb,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify verifies signatures
|
||||||
|
func Verify(sig *types.Signature, addr peer.ID, msg []byte) error {
|
||||||
|
if sig == nil {
|
||||||
|
return xerrors.Errorf("signature is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
sv, ok := sigs[sig.Type]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("cannot verify signature of unsupported type: %v", sig.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.Verify(sig.Data, addr, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate generates private key of given type
|
||||||
|
func Generate(sigType types.SigType) ([]byte, error) {
|
||||||
|
sv, ok := sigs[sigType]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot generate private key of unsupported type: %v", sigType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.GenPrivate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToPublic converts private key to public key
|
||||||
|
func ToPublic(sigType types.SigType, pk []byte) ([]byte, error) {
|
||||||
|
sv, ok := sigs[sigType]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("cannot generate public key of unsupported type: %v", sigType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sv.ToPublic(pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckTaskSignature(ctx context.Context, task *types.DioneTask, worker address.Address) error {
|
||||||
|
//if task.IsValidated() {
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//if task.BlockSig == nil {
|
||||||
|
// return xerrors.New("block signature not present")
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//sigb, err := task.SigningBytes()
|
||||||
|
//if err != nil {
|
||||||
|
// return xerrors.Errorf("failed to get block signing bytes: %w", err)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//err = Verify(task.BlockSig, worker, sigb)
|
||||||
|
//if err == nil {
|
||||||
|
// task.SetValidated()
|
||||||
|
//}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SigShim is used for introducing signature functions
|
||||||
|
type SigShim interface {
|
||||||
|
GenPrivate() ([]byte, error)
|
||||||
|
ToPublic(pk []byte) ([]byte, error)
|
||||||
|
Sign(pk []byte, msg []byte) ([]byte, error)
|
||||||
|
Verify(sig []byte, a peer.ID, msg []byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
var sigs map[types.SigType]SigShim
|
||||||
|
|
||||||
|
// RegisterSignature should be only used during init
|
||||||
|
func RegisterSignature(typ types.SigType, vs SigShim) {
|
||||||
|
if sigs == nil {
|
||||||
|
sigs = make(map[types.SigType]SigShim)
|
||||||
|
}
|
||||||
|
sigs[typ] = vs
|
||||||
|
}
|
@ -4,8 +4,8 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/ethclient"
|
||||||
"github.com/Secured-Finance/dione/lib"
|
"github.com/Secured-Finance/dione/lib"
|
||||||
"github.com/Secured-Finance/dione/rpcclient"
|
|
||||||
"github.com/Secured-Finance/dione/types"
|
"github.com/Secured-Finance/dione/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
validation "github.com/go-ozzo/ozzo-validation"
|
validation "github.com/go-ozzo/ozzo-validation"
|
||||||
@ -15,17 +15,17 @@ type DioneStakeInfo struct {
|
|||||||
ID int
|
ID int
|
||||||
MinerStake *big.Int
|
MinerStake *big.Int
|
||||||
TotalStake *big.Int
|
TotalStake *big.Int
|
||||||
MinerWallet string
|
MinerAddress string
|
||||||
MinerEthWallet string
|
MinerEthWallet string
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
Ethereum *rpcclient.EthereumClient
|
Ethereum *ethclient.EthereumClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDioneStakeInfo(minerStake, totalStake *big.Int, minerWallet, minerEthWallet string, ethereumClient *rpcclient.EthereumClient) *DioneStakeInfo {
|
func NewDioneStakeInfo(minerStake, totalStake *big.Int, minerWallet, minerEthWallet string, ethereumClient *ethclient.EthereumClient) *DioneStakeInfo {
|
||||||
return &DioneStakeInfo{
|
return &DioneStakeInfo{
|
||||||
MinerStake: minerStake,
|
MinerStake: minerStake,
|
||||||
TotalStake: totalStake,
|
TotalStake: totalStake,
|
||||||
MinerWallet: minerWallet,
|
MinerAddress: minerWallet,
|
||||||
MinerEthWallet: minerEthWallet,
|
MinerEthWallet: minerEthWallet,
|
||||||
Ethereum: ethereumClient,
|
Ethereum: ethereumClient,
|
||||||
}
|
}
|
||||||
@ -63,10 +63,10 @@ func (s *Store) CreateDioneStakeInfo(stakeStore *DioneStakeInfo) error {
|
|||||||
now := lib.Clock.Now()
|
now := lib.Clock.Now()
|
||||||
|
|
||||||
return s.db.QueryRow(
|
return s.db.QueryRow(
|
||||||
"INSERT INTO staking (miner_stake, total_stake, miner_wallet, miner_eth_wallet, timestamp) VALUES ($1, $2, $3, $4, $5) RETURNING id",
|
"INSERT INTO staking (miner_stake, total_stake, miner_address, miner_eth_wallet, timestamp) VALUES ($1, $2, $3, $4, $5) RETURNING id",
|
||||||
stakeStore.MinerStake,
|
stakeStore.MinerStake,
|
||||||
stakeStore.TotalStake,
|
stakeStore.TotalStake,
|
||||||
stakeStore.MinerWallet,
|
stakeStore.MinerAddress,
|
||||||
stakeStore.MinerEthWallet,
|
stakeStore.MinerEthWallet,
|
||||||
now,
|
now,
|
||||||
).Scan(&stakeStore.ID)
|
).Scan(&stakeStore.ID)
|
||||||
@ -75,7 +75,7 @@ func (s *Store) CreateDioneStakeInfo(stakeStore *DioneStakeInfo) error {
|
|||||||
func (s *Store) GetLastStakeInfo(wallet, ethWallet string) (*DioneStakeInfo, error) {
|
func (s *Store) GetLastStakeInfo(wallet, ethWallet string) (*DioneStakeInfo, error) {
|
||||||
var stake *DioneStakeInfo
|
var stake *DioneStakeInfo
|
||||||
if err := s.db.Select(&stake,
|
if err := s.db.Select(&stake,
|
||||||
`SELECT miner_stake, total_stake, miner_wallet, miner_eth_wallet, timestamp FROM staking ORDER BY TIMESTAMP DESC LIMIT 1 WHERE miner_wallet=$1, miner_eth_wallet=$2`,
|
`SELECT miner_stake, total_stake, miner_address, miner_eth_wallet, timestamp FROM staking ORDER BY TIMESTAMP DESC LIMIT 1 WHERE miner_address=$1, miner_eth_wallet=$2`,
|
||||||
wallet,
|
wallet,
|
||||||
ethWallet,
|
ethWallet,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
@ -91,7 +91,7 @@ func (s *DioneStakeInfo) Validate() error {
|
|||||||
s,
|
s,
|
||||||
validation.Field(&s.MinerStake, validation.Required, validation.By(types.ValidateBigInt(s.MinerStake))),
|
validation.Field(&s.MinerStake, validation.Required, validation.By(types.ValidateBigInt(s.MinerStake))),
|
||||||
validation.Field(&s.TotalStake, validation.Required, validation.By(types.ValidateBigInt(s.TotalStake))),
|
validation.Field(&s.TotalStake, validation.Required, validation.By(types.ValidateBigInt(s.TotalStake))),
|
||||||
validation.Field(&s.MinerWallet, validation.Required),
|
validation.Field(&s.MinerAddress, validation.Required),
|
||||||
validation.Field(&s.MinerEthWallet, validation.Required),
|
validation.Field(&s.MinerEthWallet, validation.Required),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package store
|
|||||||
import (
|
import (
|
||||||
"github.com/Secured-Finance/dione/node"
|
"github.com/Secured-Finance/dione/node"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Store struct {
|
type Store struct {
|
||||||
@ -29,7 +30,7 @@ func NewStore(node *node.Node, genesisTs uint64) (*Store, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newDB(databaseURL string) (*sqlx.DB, error) {
|
func newDB(databaseURL string) (*sqlx.DB, error) {
|
||||||
db, err := sqlx.Connect("postgres", databaseURL)
|
db, err := sqlx.Connect("sqlite3", databaseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,8 +16,7 @@ var (
|
|||||||
type KeyType string
|
type KeyType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
KTBLS KeyType = "bls"
|
KTEd25519 KeyType = "ed25519"
|
||||||
KTSecp256k1 KeyType = "secp256k1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (kt *KeyType) UnmarshalJSON(bb []byte) error {
|
func (kt *KeyType) UnmarshalJSON(bb []byte) error {
|
||||||
@ -38,13 +36,11 @@ func (kt *KeyType) UnmarshalJSON(bb []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not unmarshal KeyType either as string nor integer: %w", err)
|
return fmt.Errorf("could not unmarshal KeyType either as string nor integer: %w", err)
|
||||||
}
|
}
|
||||||
bst := crypto.SigType(b)
|
bst := SigType(b)
|
||||||
|
|
||||||
switch bst {
|
switch bst {
|
||||||
case crypto.SigTypeBLS:
|
case SigTypeEd25519:
|
||||||
*kt = KTBLS
|
*kt = KTEd25519
|
||||||
case crypto.SigTypeSecp256k1:
|
|
||||||
*kt = KTSecp256k1
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown sigtype: %d", bst)
|
return fmt.Errorf("unknown sigtype: %d", bst)
|
||||||
}
|
}
|
||||||
|
107
types/signature.go
Normal file
107
types/signature.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SigType byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
SigTypeUnknown = SigType(math.MaxUint8)
|
||||||
|
|
||||||
|
SigTypeEd25519 = SigType(iota)
|
||||||
|
)
|
||||||
|
|
||||||
|
const SignatureMaxLength = 200
|
||||||
|
|
||||||
|
type Signature struct {
|
||||||
|
Type SigType
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signature) Equals(o *Signature) bool {
|
||||||
|
if s == nil || o == nil {
|
||||||
|
return s == o
|
||||||
|
}
|
||||||
|
return s.Type == o.Type && bytes.Equal(s.Data, o.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signature) MarshalCBOR(w io.Writer) error {
|
||||||
|
if s == nil {
|
||||||
|
_, err := w.Write(cbg.CborNull)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(s.Data)+1))
|
||||||
|
if _, err := w.Write(header); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write([]byte{byte(s.Type)}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write(s.Data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signature) UnmarshalCBOR(br io.Reader) error {
|
||||||
|
maj, l, err := cbg.CborReadHeader(br)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if maj != cbg.MajByteString {
|
||||||
|
return fmt.Errorf("not a byte string")
|
||||||
|
}
|
||||||
|
if l > SignatureMaxLength {
|
||||||
|
return fmt.Errorf("string too long")
|
||||||
|
}
|
||||||
|
if l == 0 {
|
||||||
|
return fmt.Errorf("string empty")
|
||||||
|
}
|
||||||
|
buf := make([]byte, l)
|
||||||
|
if _, err = io.ReadFull(br, buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch SigType(buf[0]) {
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid signature type in cbor input: %d", buf[0])
|
||||||
|
case SigTypeEd25519:
|
||||||
|
s.Type = SigTypeEd25519
|
||||||
|
}
|
||||||
|
s.Data = buf[1:]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signature) MarshalBinary() ([]byte, error) {
|
||||||
|
bs := make([]byte, len(s.Data)+1)
|
||||||
|
bs[0] = byte(s.Type)
|
||||||
|
copy(bs[1:], s.Data)
|
||||||
|
return bs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signature) UnmarshalBinary(bs []byte) error {
|
||||||
|
if len(bs) > SignatureMaxLength {
|
||||||
|
return fmt.Errorf("invalid signature bytes, too long (%d)", len(bs))
|
||||||
|
}
|
||||||
|
if len(bs) == 0 {
|
||||||
|
return fmt.Errorf("invalid signature bytes of length 0")
|
||||||
|
}
|
||||||
|
switch SigType(bs[0]) {
|
||||||
|
default:
|
||||||
|
// Do not error during unmarshal but leave a standard value.
|
||||||
|
// unmarshal(marshal(zero valued sig)) is valuable for test
|
||||||
|
// and type needs to be checked by caller anyway.
|
||||||
|
s.Type = SigTypeUnknown
|
||||||
|
case SigTypeEd25519:
|
||||||
|
s.Type = SigTypeEd25519
|
||||||
|
}
|
||||||
|
s.Data = bs[1:]
|
||||||
|
return nil
|
||||||
|
}
|
@ -3,9 +3,17 @@ package types
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
"github.com/Secured-Finance/dione/config"
|
"github.com/Secured-Finance/dione/config"
|
||||||
"github.com/filecoin-project/go-address"
|
)
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
|
type TaskType byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
EthereumTaskType = TaskType(iota)
|
||||||
|
FilecoinTaskType
|
||||||
|
SolanaTaskType
|
||||||
)
|
)
|
||||||
|
|
||||||
// TaskEpoch represents the timestamp of Task computed by the Dione miner
|
// TaskEpoch represents the timestamp of Task computed by the Dione miner
|
||||||
@ -20,11 +28,12 @@ func (e TaskEpoch) String() string {
|
|||||||
// DioneTask represents the values of task computation
|
// DioneTask represents the values of task computation
|
||||||
// Miner is an address of miner node
|
// Miner is an address of miner node
|
||||||
type DioneTask struct {
|
type DioneTask struct {
|
||||||
Miner address.Address
|
Type TaskType
|
||||||
|
Miner peer.ID
|
||||||
Ticket *Ticket
|
Ticket *Ticket
|
||||||
ElectionProof *ElectionProof
|
ElectionProof *ElectionProof
|
||||||
BeaconEntries []BeaconEntry
|
BeaconEntries []BeaconEntry
|
||||||
Signature *crypto.Signature
|
Signature *Signature
|
||||||
Epoch TaskEpoch
|
Epoch TaskEpoch
|
||||||
Payload []byte
|
Payload []byte
|
||||||
}
|
}
|
||||||
|
@ -3,22 +3,23 @@ package wallet
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/crypto"
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/sigs"
|
||||||
"github.com/Secured-Finance/dione/types"
|
"github.com/Secured-Finance/dione/types"
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Key struct {
|
type Key struct {
|
||||||
types.KeyInfo
|
types.KeyInfo
|
||||||
|
|
||||||
PublicKey []byte
|
PublicKey []byte
|
||||||
Address address.Address
|
Address peer.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateKey(typ types.KeyType) (*Key, error) {
|
func GenerateKey(typ types.KeyType) (*Key, error) {
|
||||||
ctyp := ActSigType(typ)
|
ctyp := ActSigType(typ)
|
||||||
if ctyp == crypto.SigTypeUnknown {
|
if ctyp == types.SigTypeUnknown {
|
||||||
return nil, fmt.Errorf("unknown sig type: %s", typ)
|
return nil, fmt.Errorf("unknown sig type: %s", typ)
|
||||||
}
|
}
|
||||||
pk, err := sigs.Generate(ctyp)
|
pk, err := sigs.Generate(ctyp)
|
||||||
@ -46,16 +47,15 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch k.Type {
|
switch k.Type {
|
||||||
case types.KTSecp256k1:
|
case types.KTEd25519:
|
||||||
k.Address, err = address.NewSecp256k1Address(k.PublicKey)
|
pubKey, err := crypto.UnmarshalEd25519PublicKey(k.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal ed25519 public key: %w", err)
|
||||||
|
}
|
||||||
|
k.Address, err = peer.IDFromPublicKey(pubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("converting Secp256k1 to address: %w", err)
|
return nil, fmt.Errorf("converting Secp256k1 to address: %w", err)
|
||||||
}
|
}
|
||||||
case types.KTBLS:
|
|
||||||
k.Address, err = address.NewBLSAddress(k.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("converting BLS to address: %w", err)
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported key type: %s", k.Type)
|
return nil, fmt.Errorf("unsupported key type: %s", k.Type)
|
||||||
}
|
}
|
||||||
@ -63,13 +63,11 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ActSigType(typ types.KeyType) crypto.SigType {
|
func ActSigType(typ types.KeyType) types.SigType {
|
||||||
switch typ {
|
switch typ {
|
||||||
case types.KTBLS:
|
case types.KTEd25519:
|
||||||
return crypto.SigTypeBLS
|
return types.SigTypeEd25519
|
||||||
case types.KTSecp256k1:
|
|
||||||
return crypto.SigTypeSecp256k1
|
|
||||||
default:
|
default:
|
||||||
return crypto.SigTypeUnknown
|
return types.SigTypeUnknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/sigs"
|
||||||
"github.com/Secured-Finance/dione/types"
|
"github.com/Secured-Finance/dione/types"
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
@ -18,7 +19,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type LocalWallet struct {
|
type LocalWallet struct {
|
||||||
keys map[address.Address]*Key
|
keys map[peer.ID]*Key
|
||||||
keystore types.KeyStore
|
keystore types.KeyStore
|
||||||
|
|
||||||
lk sync.Mutex
|
lk sync.Mutex
|
||||||
@ -30,7 +31,7 @@ type Default interface {
|
|||||||
|
|
||||||
func NewWallet(keystore types.KeyStore) (*LocalWallet, error) {
|
func NewWallet(keystore types.KeyStore) (*LocalWallet, error) {
|
||||||
w := &LocalWallet{
|
w := &LocalWallet{
|
||||||
keys: make(map[address.Address]*Key),
|
keys: make(map[peer.ID]*Key),
|
||||||
keystore: keystore,
|
keystore: keystore,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ func NewWallet(keystore types.KeyStore) (*LocalWallet, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func KeyWallet(keys ...*Key) *LocalWallet {
|
func KeyWallet(keys ...*Key) *LocalWallet {
|
||||||
m := make(map[address.Address]*Key)
|
m := make(map[peer.ID]*Key)
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
m[key.Address] = key
|
m[key.Address] = key
|
||||||
}
|
}
|
||||||
@ -48,7 +49,7 @@ func KeyWallet(keys ...*Key) *LocalWallet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LocalWallet) WalletSign(ctx context.Context, addr address.Address, msg []byte) (*crypto.Signature, error) {
|
func (w *LocalWallet) WalletSign(ctx context.Context, addr peer.ID, msg []byte) (*types.Signature, error) {
|
||||||
ki, err := w.findKey(addr)
|
ki, err := w.findKey(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -60,7 +61,7 @@ func (w *LocalWallet) WalletSign(ctx context.Context, addr address.Address, msg
|
|||||||
return sigs.Sign(ActSigType(ki.Type), ki.PrivateKey, msg)
|
return sigs.Sign(ActSigType(ki.Type), ki.PrivateKey, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LocalWallet) findKey(addr address.Address) (*Key, error) {
|
func (w *LocalWallet) findKey(addr peer.ID) (*Key, error) {
|
||||||
w.lk.Lock()
|
w.lk.Lock()
|
||||||
defer w.lk.Unlock()
|
defer w.lk.Unlock()
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ func (w *LocalWallet) findKey(addr address.Address) (*Key, error) {
|
|||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LocalWallet) tryFind(addr address.Address) (types.KeyInfo, error) {
|
func (w *LocalWallet) tryFind(addr peer.ID) (types.KeyInfo, error) {
|
||||||
|
|
||||||
ki, err := w.keystore.Get(KNamePrefix + addr.String())
|
ki, err := w.keystore.Get(KNamePrefix + addr.String())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -122,52 +123,52 @@ func (w *LocalWallet) tryFind(addr address.Address) (types.KeyInfo, error) {
|
|||||||
return ki, nil
|
return ki, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LocalWallet) GetDefault() (address.Address, error) {
|
func (w *LocalWallet) GetDefault() (peer.ID, error) {
|
||||||
w.lk.Lock()
|
w.lk.Lock()
|
||||||
defer w.lk.Unlock()
|
defer w.lk.Unlock()
|
||||||
|
|
||||||
ki, err := w.keystore.Get(KDefault)
|
ki, err := w.keystore.Get(KDefault)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, xerrors.Errorf("failed to get default key: %w", err)
|
return "", xerrors.Errorf("failed to get default key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
k, err := NewKey(ki)
|
k, err := NewKey(ki)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, xerrors.Errorf("failed to read default key from keystore: %w", err)
|
return "", xerrors.Errorf("failed to read default key from keystore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return k.Address, nil
|
return k.Address, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LocalWallet) WalletNew(ctx context.Context, typ types.KeyType) (address.Address, error) {
|
func (w *LocalWallet) WalletNew(ctx context.Context, typ types.KeyType) (peer.ID, error) {
|
||||||
w.lk.Lock()
|
w.lk.Lock()
|
||||||
defer w.lk.Unlock()
|
defer w.lk.Unlock()
|
||||||
|
|
||||||
k, err := GenerateKey(typ)
|
k, err := GenerateKey(typ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.keystore.Put(KNamePrefix+k.Address.String(), k.KeyInfo); err != nil {
|
if err := w.keystore.Put(KNamePrefix+k.Address.String(), k.KeyInfo); err != nil {
|
||||||
return address.Undef, xerrors.Errorf("saving to keystore: %w", err)
|
return "", xerrors.Errorf("saving to keystore: %w", err)
|
||||||
}
|
}
|
||||||
w.keys[k.Address] = k
|
w.keys[k.Address] = k
|
||||||
|
|
||||||
_, err = w.keystore.Get(KDefault)
|
_, err = w.keystore.Get(KDefault)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !xerrors.Is(err, types.ErrKeyInfoNotFound) {
|
if !xerrors.Is(err, types.ErrKeyInfoNotFound) {
|
||||||
return address.Undef, err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.keystore.Put(KDefault, k.KeyInfo); err != nil {
|
if err := w.keystore.Put(KDefault, k.KeyInfo); err != nil {
|
||||||
return address.Undef, xerrors.Errorf("failed to set new key as default: %w", err)
|
return "", xerrors.Errorf("failed to set new key as default: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return k.Address, nil
|
return k.Address, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *LocalWallet) WalletHas(ctx context.Context, addr address.Address) (bool, error) {
|
func (w *LocalWallet) WalletHas(ctx context.Context, addr peer.ID) (bool, error) {
|
||||||
k, err := w.findKey(addr)
|
k, err := w.findKey(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
Loading…
Reference in New Issue
Block a user