From 4df622e101030f0f8cb428e92ab14fa78a5e8f24 Mon Sep 17 00:00:00 2001 From: Ricardo Pinto Date: Mon, 28 Mar 2022 13:40:47 +0100 Subject: [PATCH 1/8] Persisted DkgState --- .../dkg/dkgtasks/dispute_missing_gpkj_task.go | 2 +- .../dispute_missing_key_shares_task.go | 2 +- .../dispute_missing_registration_task.go | 2 +- ...dispute_missing_share_distribution_task.go | 2 +- blockchain/objects/dkg_state.go | 83 ++++++------ blockchain/objects/dkg_state_test.go | 118 ++++++++++++++++++ docker/generate-bridge/Dockerfile | 2 +- scripts/main.sh | 2 + 8 files changed, 165 insertions(+), 48 deletions(-) diff --git a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go index f3a6554a..5bd771cc 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go @@ -158,7 +158,7 @@ func (t *DisputeMissingGPKjTask) getAccusableParticipants(ctx context.Context, e for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != uint8(objects.GPKJSubmission) || + p.Phase != objects.GPKJSubmission || (p.GPKj[0].Cmp(big.NewInt(0)) == 0 && p.GPKj[1].Cmp(big.NewInt(0)) == 0 && p.GPKj[2].Cmp(big.NewInt(0)) == 0 && diff --git a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go index a7f6df5e..0f28c20d 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go @@ -156,7 +156,7 @@ func (t *DisputeMissingKeySharesTask) getAccusableParticipants(ctx context.Conte for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != uint8(objects.KeyShareSubmission) || + p.Phase != objects.KeyShareSubmission || (p.KeyShareG1s[0].Cmp(big.NewInt(0)) == 0 && p.KeyShareG1s[1].Cmp(big.NewInt(0)) == 0) || (p.KeyShareG1CorrectnessProofs[0].Cmp(big.NewInt(0)) == 0 && diff --git a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go index 96188efb..b3d2fd30 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go @@ -161,7 +161,7 @@ func (t *DisputeMissingRegistrationTask) getAccusableParticipants(ctx context.Co if isValidator && (!ok || participant.Nonce != t.State.Nonce || - participant.Phase != uint8(objects.RegistrationOpen) || + participant.Phase != objects.RegistrationOpen || (participant.PublicKey[0].Cmp(big.NewInt(0)) == 0 && participant.PublicKey[1].Cmp(big.NewInt(0)) == 0)) { diff --git a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go index 5e6eaa3e..0148a77c 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go @@ -157,7 +157,7 @@ func (t *DisputeMissingShareDistributionTask) getAccusableParticipants(ctx conte for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != uint8(objects.ShareDistribution) || + p.Phase != objects.ShareDistribution || p.DistributedSharesHash == emptySharesHash) { // did not distribute shares accusableParticipants = append(accusableParticipants, p.Address) diff --git a/blockchain/objects/dkg_state.go b/blockchain/objects/dkg_state.go index c6b06e9e..63a502eb 100644 --- a/blockchain/objects/dkg_state.go +++ b/blockchain/objects/dkg_state.go @@ -19,79 +19,77 @@ var ( // DkgState is used to track the state of the ETHDKG type DkgState struct { - sync.RWMutex + sync.RWMutex `json:"-"` - IsValidator bool - Phase EthDKGPhase - PhaseLength uint64 - ConfirmationLength uint64 - PhaseStart uint64 - MPKSetAtBlock uint64 - CompletionAtBlock uint64 + IsValidator bool `json:"isValidator"` + Phase EthDKGPhase `json:"phase"` + PhaseLength uint64 `json:"phaseLength"` + ConfirmationLength uint64 `json:"confirmationLength"` + PhaseStart uint64 `json:"phaseStart"` // Local validator info //////////////////////////////////////////////////////////////////////////// // Account is the Ethereum account corresponding to the Ethereum Public Key // of the local Validator - Account accounts.Account + Account accounts.Account `json:"account"` // Index is the Base-1 index of the local Validator which is used // during the Share Distribution phase for verifiable secret sharing. // REPEAT: THIS IS BASE-1 - Index int + Index int `json:"index"` // ValidatorAddresses stores all validator addresses at the beginning of ETHDKG - ValidatorAddresses []common.Address + ValidatorAddresses []common.Address `json:"validatorAddresses"` // NumberOfValidators is equal to len(ValidatorAddresses) - NumberOfValidators int + NumberOfValidators int `json:"numberOfValidators"` // ETHDKG nonce - Nonce uint64 + Nonce uint64 `json:"nonce"` // ValidatorThreshold is the threshold number of validators for the system. // If n = NumberOfValidators and t = threshold, then // t+1 > 2*n/3 - ValidatorThreshold int + ValidatorThreshold int `json:"validatorThreshold"` // TransportPrivateKey is the private key corresponding to TransportPublicKey. - TransportPrivateKey *big.Int + TransportPrivateKey *big.Int `json:"transportPrivateKey"` // TransportPublicKey is the public key used in EthDKG. // This public key is used for secret communication over the open channel // of Ethereum. - TransportPublicKey [2]*big.Int + TransportPublicKey [2]*big.Int `json:"transportPublicKey"` // SecretValue is the secret value which is to be shared during // the verifiable secret sharing. // The sum of all the secret values of all the participants // is the master secret key, the secret key of the master public key // (MasterPublicKey) - SecretValue *big.Int + SecretValue *big.Int `json:"secretValue"` // PrivateCoefficients is the private polynomial which is used to share // the shared secret. This is performed via Shamir Secret Sharing. - PrivateCoefficients []*big.Int + PrivateCoefficients []*big.Int `json:"privateCoefficients"` // MasterPublicKey is the public key for the entire group. // As mentioned above, the secret key called the master secret key // and is the sum of all the shared secrets of all the participants. - MasterPublicKey [4]*big.Int + MasterPublicKey [4]*big.Int `json:"masterPublicKey"` // GroupPrivateKey is the local Validator's portion of the master secret key. // This is also denoted gskj. - GroupPrivateKey *big.Int + GroupPrivateKey *big.Int `json:"groupPrivateKey"` // Remote validator info //////////////////////////////////////////////////////////////////////////// // Participants is the list of Validators - Participants map[common.Address]*Participant // Index, Address & PublicKey + Participants map[common.Address]*Participant `json:"participants"` // Share Dispute Phase ////////////////////////////////////////////////// // These are the participants with bad shares - BadShares map[common.Address]*Participant + BadShares map[common.Address]*Participant `json:"badShares"` // Group Public Key (GPKj) Accusation Phase ////////////////////////////////////////////////// // DishonestValidatorsIndices stores the list indices of dishonest // validators - DishonestValidators ParticipantList // Calculated for group accusation + DishonestValidators ParticipantList `json:"dishonestValidators"` // HonestValidatorsIndices stores the list indices of honest // validators - HonestValidators ParticipantList // " + HonestValidators ParticipantList `json:"honestValidators"` // Inverse stores the multiplicative inverses // of elements. This may be used in GPKJGroupAccusation logic. - Inverse []*big.Int // " + Inverse []*big.Int `json:"inverse"` } // GetSortedParticipants returns the participant list sorted by Index field @@ -120,7 +118,7 @@ func (state *DkgState) OnAddressRegistered(account common.Address, index int, no Address: account, Index: index, PublicKey: publicKey, - Phase: uint8(RegistrationOpen), + Phase: RegistrationOpen, Nonce: nonce, } @@ -144,7 +142,7 @@ func (state *DkgState) OnSharesDistributed(logger *logrus.Entry, account common. return dkg.LogReturnErrorf(logger, "ProcessShareDistribution: error calculating distributed shares hash: %v", err) } - state.Participants[account].Phase = uint8(ShareDistribution) + state.Participants[account].Phase = ShareDistribution state.Participants[account].DistributedSharesHash = distributedSharesHash state.Participants[account].Commitments = commitments state.Participants[account].EncryptedShares = encryptedShares @@ -171,7 +169,6 @@ func (state *DkgState) OnKeyShareSubmissionComplete(mpkSubmissionStartBlock uint func (state *DkgState) OnMPKSet(gpkjSubmissionStartBlock uint64) { state.Phase = GPKJSubmission state.PhaseStart = gpkjSubmissionStartBlock - state.MPKSetAtBlock = gpkjSubmissionStartBlock } // OnGPKJSubmissionComplete processes data from GPKJSubmissionComplete event @@ -184,7 +181,7 @@ func (state *DkgState) OnGPKJSubmissionComplete(disputeGPKjStartBlock uint64) { func (state *DkgState) OnKeyShareSubmitted(account common.Address, keyShareG1 [2]*big.Int, keyShareG1CorrectnessProof [2]*big.Int, keyShareG2 [4]*big.Int) { state.Phase = KeyShareSubmission - state.Participants[account].Phase = uint8(KeyShareSubmission) + state.Participants[account].Phase = KeyShareSubmission state.Participants[account].KeyShareG1s = keyShareG1 state.Participants[account].KeyShareG1CorrectnessProofs = keyShareG1CorrectnessProof state.Participants[account].KeyShareG2s = keyShareG2 @@ -193,7 +190,7 @@ func (state *DkgState) OnKeyShareSubmitted(account common.Address, keyShareG1 [2 // OnGPKjSubmitted processes data from GPKjSubmitted event func (state *DkgState) OnGPKjSubmitted(account common.Address, gpkj [4]*big.Int) { state.Participants[account].GPKj = gpkj - state.Participants[account].Phase = uint8(GPKJSubmission) + state.Participants[account].Phase = GPKJSubmission } // OnCompletion processes data from ValidatorSetCompleted event @@ -214,16 +211,16 @@ func NewDkgState(account accounts.Account) *DkgState { type Participant struct { // Address is the Ethereum address corresponding to the Ethereum Public Key // for the Participant. - Address common.Address + Address common.Address `json:"address"` // Index is the Base-1 index of the participant. // This is used during the Share Distribution phase to perform // verifyiable secret sharing. // REPEAT: THIS IS BASE-1 - Index int + Index int `json:"index"` // PublicKey is the TransportPublicKey of Participant. - PublicKey [2]*big.Int - Nonce uint64 - Phase uint8 + PublicKey [2]*big.Int `json:"publicKey"` + Nonce uint64 `json:"nonce"` + Phase EthDKGPhase `json:"phase"` // Share Distribution Phase ////////////////////////////////////////////////// @@ -232,33 +229,33 @@ type Participant struct { // in Shamir Secret Sharing protocol. // The first coefficient (constant term) is the public commitment // corresponding to the secret share (SecretValue). - Commitments [][2]*big.Int + Commitments [][2]*big.Int `json:"commitments"` // EncryptedShares are the encrypted secret shares // in the Shamir Secret Sharing protocol. - EncryptedShares []*big.Int - DistributedSharesHash [32]byte + EncryptedShares []*big.Int `json:"encryptedShares"` + DistributedSharesHash [32]byte `json:"distributedSharesHash"` - CommitmentsFirstCoefficient [2]*big.Int + CommitmentsFirstCoefficient [2]*big.Int `json:"commitmentsFirstCoefficient"` // Key Share Submission Phase ////////////////////////////////////////////////// // KeyShareG1s stores the key shares of G1 element // for each participant - KeyShareG1s [2]*big.Int + KeyShareG1s [2]*big.Int `json:"keyShareG1s"` // KeyShareG1CorrectnessProofs stores the proofs of each // G1 element for each participant. - KeyShareG1CorrectnessProofs [2]*big.Int + KeyShareG1CorrectnessProofs [2]*big.Int `json:"keyShareG1CorrectnessProofs"` // KeyShareG2s stores the key shares of G2 element // for each participant. // Adding all the G2 shares together produces the // master public key (MasterPublicKey). - KeyShareG2s [4]*big.Int + KeyShareG2s [4]*big.Int `json:"keyShareG2s"` // GPKj is the local Validator's portion of the master public key. // This is also denoted GroupPublicKey. - GPKj [4]*big.Int + GPKj [4]*big.Int `json:"gpkj"` } // ParticipantList is a required type alias since the Sort interface is awful diff --git a/blockchain/objects/dkg_state_test.go b/blockchain/objects/dkg_state_test.go index a3d72c7c..1ba4b2e0 100644 --- a/blockchain/objects/dkg_state_test.go +++ b/blockchain/objects/dkg_state_test.go @@ -2,10 +2,15 @@ package objects_test import ( "bytes" + "encoding/json" "math/big" "testing" + "github.com/MadBase/MadNet/blockchain/dkg/math" "github.com/MadBase/MadNet/blockchain/objects" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" ) func TestParticipantCopy(t *testing.T) { @@ -59,3 +64,116 @@ func TestParticipantListExtractIndices(t *testing.T) { } } } + +func TestMarshalAndUnmarshalBigInt(t *testing.T) { + + // generate transport keys + priv, pub, err := math.GenerateKeys() + assert.Nil(t, err) + + // marshal privkey + rawPrivData, err := json.Marshal(priv) + assert.Nil(t, err) + rawPubData, err := json.Marshal(pub) + assert.Nil(t, err) + + priv2 := &big.Int{} + pub2 := [2]*big.Int{} + + err = json.Unmarshal(rawPrivData, priv2) + assert.Nil(t, err) + err = json.Unmarshal(rawPubData, &pub2) + assert.Nil(t, err) + + assert.Equal(t, priv, priv2) + assert.Equal(t, pub, pub2) +} + +func TestMarshalAndUnmarshalAccount(t *testing.T) { + addr := common.Address{} + addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + + // create a DkgState obj + acct := accounts.Account{ + Address: addr, + URL: accounts.URL{ + Scheme: "http", + Path: "", + }, + } + + // marshal acct + rawData, err := json.Marshal(acct) + assert.Nil(t, err) + + acct2 := &accounts.Account{} + + err = json.Unmarshal(rawData, acct2) + assert.Nil(t, err) + + assert.Equal(t, acct, *acct2) +} + +func TestMarshalAndUnmarshalParticipant(t *testing.T) { + addr := common.Address{} + addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + + // generate transport keys + _, pub, err := math.GenerateKeys() + assert.Nil(t, err) + + // create a Participant obj + participant := objects.Participant{ + Address: addr, + Index: 1, + PublicKey: pub, + Nonce: 1, + Phase: objects.RegistrationOpen, + } + + // marshal + rawData, err := json.Marshal(participant) + assert.Nil(t, err) + + t.Logf("rawData: %s", rawData) + + participant2 := &objects.Participant{} + + err = json.Unmarshal(rawData, participant2) + assert.Nil(t, err) + assert.Equal(t, participant.PublicKey, participant2.PublicKey) + +} + +func TestMarshalAndUnmarshalDkgState(t *testing.T) { + addr := common.Address{} + addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + + // create a DkgState obj + state := objects.NewDkgState(accounts.Account{ + Address: addr, + URL: accounts.URL{ + Scheme: "file", + Path: "", + }, + }) + + // generate transport keys + priv, pub, err := math.GenerateKeys() + assert.Nil(t, err) + state.TransportPrivateKey = priv + state.TransportPublicKey = pub + + // marshal + rawData, err := json.Marshal(state) + assert.Nil(t, err) + + t.Logf("rawData: %s", rawData) + + state2 := &objects.DkgState{} + + err = json.Unmarshal(rawData, state2) + assert.Nil(t, err) + assert.Equal(t, state.TransportPrivateKey, state2.TransportPrivateKey) + assert.Equal(t, state.TransportPublicKey, state2.TransportPublicKey) +} diff --git a/docker/generate-bridge/Dockerfile b/docker/generate-bridge/Dockerfile index 8dda98d6..cbe9105f 100644 --- a/docker/generate-bridge/Dockerfile +++ b/docker/generate-bridge/Dockerfile @@ -1,7 +1,7 @@ # golang helper image used just to compile binaries from go source FROM golang:1.17.6-alpine3.15 AS go_deps RUN apk add --no-cache linux-headers=5.10.41-r0 build-base=0.5-r2 -RUN go install github.com/ethereum/go-ethereum/cmd/abigen@v1.10.8 +RUN go install github.com/ethereum/go-ethereum/cmd/abigen@v1.10.16 # final node image containing binaries compiled by helper image FROM node:16.14.0-alpine3.15 diff --git a/scripts/main.sh b/scripts/main.sh index 41a204d0..8b31aba5 100755 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -55,6 +55,7 @@ CLEAN_UP () { # Init mkdir ./scripts/generated mkdir ./scripts/generated/stateDBs + mkdir ./scripts/generated/monitorDBs mkdir ./scripts/generated/config mkdir ./scripts/generated/keystores mkdir ./scripts/generated/keystores/keys @@ -93,6 +94,7 @@ CREATE_CONFIGS () { sed -e 's/passcodes = .*/passcodes = \"scripts\/generated\/keystores\/passcodes.txt\"/' | sed -e 's/keystore = .*/keystore = \"scripts\/generated\/keystores\/keys\"/' | sed -e 's/stateDB = .*/stateDB = \"scripts\/generated\/stateDBs\/validator'"$l"'\/\"/' | + sed -e 's/monitorDB = .*/monitorDB = \"scripts\/generated\/monitorDBs\/validator'"$l"'\/\"/' | sed -e 's/privateKey = .*/privateKey = \"'"$PK"'\"/' > ./scripts/generated/config/validator$l.toml echo "$ADDRESS=abc123" >> ./scripts/generated/keystores/passcodes.txt mv ./keyfile.json ./scripts/generated/keystores/keys/$ADDRESS From 1c29ed00449ced4ef3c27c7190d2d61d50a41b73 Mon Sep 17 00:00:00 2001 From: Ricardo Pinto Date: Tue, 29 Mar 2022 18:54:43 +0100 Subject: [PATCH 2/8] Detected issue and POC fix inplace Co-authored-by: stuckDaemon --- blockchain/dkg/dkgevents/processors.go | 2 +- blockchain/dkg/dkgtasks/completion_task.go | 8 +++ blockchain/dkg/dkgtasks/dispute_gpkj_task.go | 8 +++ .../dkg/dkgtasks/dispute_missing_gpkj_task.go | 7 ++ .../dispute_missing_key_shares_task.go | 7 ++ .../dispute_missing_registration_task.go | 7 ++ ...dispute_missing_share_distribution_task.go | 7 ++ .../dispute_share_distribution_task.go | 7 ++ .../dkg/dkgtasks/gpkj_submission_task.go | 7 ++ .../dkg/dkgtasks/keyshare_submission_task.go | 7 ++ .../dkg/dkgtasks/mpk_submission_task.go | 7 ++ blockchain/dkg/dkgtasks/register_task.go | 37 +++++++--- .../dkg/dkgtasks/share_distribution_task.go | 12 +++- blockchain/monitor/monitor.go | 67 ++++++++++++++++--- blockchain/objects/dkg_state.go | 5 ++ blockchain/objects/scheduler.go | 29 +++++++- blockchain/objects/state.go | 4 ++ blockchain/tasks/task_manager.go | 6 +- 18 files changed, 210 insertions(+), 24 deletions(-) diff --git a/blockchain/dkg/dkgevents/processors.go b/blockchain/dkg/dkgevents/processors.go index b7a33d1c..6a5c6e82 100644 --- a/blockchain/dkg/dkgevents/processors.go +++ b/blockchain/dkg/dkgevents/processors.go @@ -187,7 +187,7 @@ func ProcessRegistrationComplete(eth interfaces.Ethereum, logger *logrus.Entry, logger.WithFields(logrus.Fields{ "PhaseStart": shareDistributionStart, "PhaseEnd": shareDistributionEnd, - }).Info("Scheduling NewShareDistributionTask") + }).Infof("Scheduling NewShareDistributionTask: %p %p\n", shareDistributionTask.State, state.EthDKG) state.Schedule.Schedule(shareDistributionStart, shareDistributionEnd, shareDistributionTask) diff --git a/blockchain/dkg/dkgtasks/completion_task.go b/blockchain/dkg/dkgtasks/completion_task.go index 6871fd20..1cf61a0f 100644 --- a/blockchain/dkg/dkgtasks/completion_task.go +++ b/blockchain/dkg/dkgtasks/completion_task.go @@ -38,6 +38,14 @@ func NewCompletionTask(state *objects.DkgState, start uint64, end uint64) *Compl // Initialize prepares for work to be done in the Completion phase func (t *CompletionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/dispute_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_gpkj_task.go index b1bf0fb8..c4556678 100644 --- a/blockchain/dkg/dkgtasks/dispute_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_gpkj_task.go @@ -39,6 +39,14 @@ func NewDisputeGPKjTask(state *objects.DkgState, start uint64, end uint64) *Disp // Initialize prepares for work to be done in the GPKjDispute phase. // Here, we determine if anyone submitted an invalid gpkj. func (t *DisputeGPKjTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go index 5bd771cc..4e1297e6 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go @@ -38,6 +38,13 @@ func NewDisputeMissingGPKjTask(state *objects.DkgState, start uint64, end uint64 func (t *DisputeMissingGPKjTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { logger.Info("Initializing DisputeMissingGPKjTask...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go index 0f28c20d..b94ddef3 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go @@ -36,6 +36,13 @@ func NewDisputeMissingKeySharesTask(state *objects.DkgState, start uint64, end u func (t *DisputeMissingKeySharesTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { logger.Info("Initializing DisputeMissingKeySharesTask...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go index b3d2fd30..22b109e3 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go @@ -37,6 +37,13 @@ func (t *DisputeMissingRegistrationTask) Initialize(ctx context.Context, logger logger.Info("DisputeMissingRegistrationTask Initializing...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go index 0148a77c..ce3de183 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go @@ -36,6 +36,13 @@ func (t *DisputeMissingShareDistributionTask) Initialize(ctx context.Context, lo logger.Info("DisputeMissingShareDistributionTask Initializing...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go index 59a30dfc..8b34dcf2 100644 --- a/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go @@ -40,6 +40,13 @@ func NewDisputeShareDistributionTask(state *objects.DkgState, start uint64, end // It determines if the shares previously distributed are valid. // If any are invalid, disputes will be issued. func (t *DisputeShareDistributionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/gpkj_submission_task.go b/blockchain/dkg/dkgtasks/gpkj_submission_task.go index 1f726c79..d40166d2 100644 --- a/blockchain/dkg/dkgtasks/gpkj_submission_task.go +++ b/blockchain/dkg/dkgtasks/gpkj_submission_task.go @@ -40,6 +40,13 @@ func NewGPKjSubmissionTask(state *objects.DkgState, start uint64, end uint64, ad // Here, we construct our gpkj and associated signature. // We will submit them in DoWork. func (t *GPKjSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/keyshare_submission_task.go b/blockchain/dkg/dkgtasks/keyshare_submission_task.go index c29ac7b9..5dc1ea74 100644 --- a/blockchain/dkg/dkgtasks/keyshare_submission_task.go +++ b/blockchain/dkg/dkgtasks/keyshare_submission_task.go @@ -35,6 +35,13 @@ func NewKeyshareSubmissionTask(state *objects.DkgState, start uint64, end uint64 // Here, the G1 key share, G1 proof, and G2 key share are constructed // and stored for submission. func (t *KeyshareSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/mpk_submission_task.go b/blockchain/dkg/dkgtasks/mpk_submission_task.go index f42e73cc..1e7cc915 100644 --- a/blockchain/dkg/dkgtasks/mpk_submission_task.go +++ b/blockchain/dkg/dkgtasks/mpk_submission_task.go @@ -41,6 +41,13 @@ func NewMPKSubmissionTask(state *objects.DkgState, start uint64, end uint64) *MP // Here we load all key shares and construct the master public key // to submit in DoWork. func (t *MPKSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/register_task.go b/blockchain/dkg/dkgtasks/register_task.go index 7b047b7b..d700b763 100644 --- a/blockchain/dkg/dkgtasks/register_task.go +++ b/blockchain/dkg/dkgtasks/register_task.go @@ -22,8 +22,8 @@ type RegisterTask struct { End uint64 State *objects.DkgState Success bool - TxOpts *bind.TransactOpts - TxHash common.Hash + TxOpts *bind.TransactOpts `json:"-"` + TxHash common.Hash `json:"-"` } // asserting that RegisterTask struct implements interface interfaces.Task @@ -46,17 +46,38 @@ func NewRegisterTask(state *objects.DkgState, start uint64, end uint64) *Registe // Also get the list of existing validators from the pool to assert accusation // in later phases func (t *RegisterTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() - logger.Info("RegisterTask Initialize()") + logger.Infof("RegisterTask Initialize() %p\n", t.State) - priv, pub, err := math.GenerateKeys() - if err != nil { - return err + if t.State.TransportPrivateKey == nil || + t.State.TransportPrivateKey.Cmp(big.NewInt(0)) == 0 { + + logger.Infof("RegisterTask Initialize(): generating private-public transport keys") + priv, pub, err := math.GenerateKeys() + if err != nil { + return err + } + t.State.TransportPrivateKey = priv + t.State.TransportPublicKey = pub + + logger.Infof("RegisterTask pre-save state\n") + dkgData.PersistStateCB() + logger.Infof("RegisterTask post-save state\n") + + } else { + logger.Infof("RegisterTask Initialize(): private-public transport keys already defined") } - t.State.TransportPrivateKey = priv - t.State.TransportPublicKey = pub + return nil } diff --git a/blockchain/dkg/dkgtasks/share_distribution_task.go b/blockchain/dkg/dkgtasks/share_distribution_task.go index 99b1d753..971295b1 100644 --- a/blockchain/dkg/dkgtasks/share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/share_distribution_task.go @@ -36,9 +36,19 @@ func NewShareDistributionTask(state *objects.DkgState, start uint64, end uint64) // We construct our commitments and encrypted shares before // submitting them to the associated smart contract. func (t *ShareDistributionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() + logger.Infof("ShareDistributionTask Initialize() %p\n", t.State) + if t.State.Phase != objects.ShareDistribution { return fmt.Errorf("%w because it's not in ShareDistribution phase", objects.ErrCanNotContinue) } @@ -51,7 +61,7 @@ func (t *ShareDistributionTask) Initialize(ctx context.Context, logger *logrus.E encryptedShares, privateCoefficients, commitments, err := math.GenerateShares( t.State.TransportPrivateKey, participants) if err != nil { - logger.Errorf("Failed to generate shares: %v", err) + logger.Errorf("Failed to generate shares: %v %#v", err, participants) return err } diff --git a/blockchain/monitor/monitor.go b/blockchain/monitor/monitor.go index cf6efd1d..378673d2 100644 --- a/blockchain/monitor/monitor.go +++ b/blockchain/monitor/monitor.go @@ -150,6 +150,12 @@ func (mon *monitor) LoadState() error { if err != nil { return err } + + // todo: fix task state pointers + // for taskUUID, block := range mon.State.Schedule.Ranges { + // block.Task. + // } + return nil }); err != nil { return err @@ -161,7 +167,9 @@ func (mon *monitor) LoadState() error { func (mon *monitor) PersistState() error { + fmt.Println("mon.PersistState() pre-lock") mon.Lock() + fmt.Println("mon.PersistState() post-lock") defer mon.Unlock() rawData, err := json.Marshal(mon) @@ -169,6 +177,9 @@ func (mon *monitor) PersistState() error { return err } + // todo: delete this + //fmt.Printf("persisted monitor: %s\n", rawData) + err = mon.db.Update(func(txn *badger.Txn) error { keyLabel := fmt.Sprintf("%x", getStateKey()) mon.logger.WithField("Key", keyLabel).Infof("Saving state") @@ -219,6 +230,9 @@ func (mon *monitor) Start() error { mon.State.HighestBlockProcessed = startingBlock } + // todo: delete this + logger.Infof("loaded monitor.state.dkgState: %##v\n", mon.State.EthDKG) + if startingBlock > mon.State.HighestBlockProcessed { logger.WithFields(logrus.Fields{ "StartingBlock": startingBlock, @@ -280,7 +294,13 @@ func (mon *monitor) eventLoop(wg *sync.WaitGroup, logger *logrus.Entry, cancelCh oldMonitorState := mon.State.Clone() - if err := MonitorTick(ctx, cf, wg, mon.eth, mon.State, mon.logger, mon.eventMap, mon.adminHandler, mon.batchSize); err != nil { + persistMonitorCB := func() { + logger.Infof("persistMonitorCB is calling") + mon.PersistState() + logger.Infof("persistMonitorCB was called") + } + + if err := MonitorTick(ctx, cf, wg, mon.eth, mon.State, mon.logger, mon.eventMap, mon.adminHandler, mon.batchSize, persistMonitorCB); err != nil { logger.Errorf("Failed MonitorTick(...): %v", err) } @@ -324,7 +344,7 @@ func (m *monitor) UnmarshalJSON(raw []byte) error { // MonitorTick using existing monitorState and incrementally updates it based on current State of Ethereum endpoint func MonitorTick(ctx context.Context, cf context.CancelFunc, wg *sync.WaitGroup, eth interfaces.Ethereum, monitorState *objects.MonitorState, logger *logrus.Entry, - eventMap *objects.EventMap, adminHandler interfaces.AdminHandler, batchSize uint64) error { + eventMap *objects.EventMap, adminHandler interfaces.AdminHandler, batchSize uint64, persistMonitorCB func()) error { defer cf() logger = logger.WithFields(logrus.Fields{ @@ -415,19 +435,46 @@ func MonitorTick(ctx context.Context, cf context.CancelFunc, wg *sync.WaitGroup, // Check if any tasks are scheduled logEntry.Debug("Looking for scheduled task") + logger.Infof("monitor.State.DkgState: %p\n", monitorState.EthDKG) uuid, err := monitorState.Schedule.Find(currentBlock) if err == nil { - task, _ := monitorState.Schedule.Retrieve(uuid) + isRunning, err := monitorState.Schedule.IsRunning(uuid) + if err != nil { + return err + } - taskName, _ := objects.GetNameType(task) + if !isRunning { - log := logEntry.WithFields(logrus.Fields{ - "TaskID": uuid.String(), - "TaskName": taskName}) + task, err := monitorState.Schedule.Retrieve(uuid) + if err != nil { + return err + } - tasks.StartTask(log, wg, eth, task, nil) + taskName, _ := objects.GetNameType(task) + + log := logEntry.WithFields(logrus.Fields{ + "TaskID": uuid.String(), + "TaskName": taskName}) + + onFinishCB := func() { + monitorState.Schedule.SetRunning(uuid, false) + monitorState.Schedule.Remove(uuid) + } + dkgData := objects.ETHDKGTaskData{ + PersistStateCB: persistMonitorCB, + State: monitorState.EthDKG, + } + err = tasks.StartTask(log, wg, eth, task, dkgData, &onFinishCB) + if err != nil { + return err + } + err = monitorState.Schedule.SetRunning(uuid, true) + if err != nil { + return err + } + } - monitorState.Schedule.Remove(uuid) + //monitorState.Schedule.Remove(uuid) } else if err == objects.ErrNothingScheduled { logEntry.Debug("No tasks scheduled") } else { @@ -478,7 +525,7 @@ func PersistSnapshot(ctx context.Context, wg *sync.WaitGroup, eth interfaces.Eth task := tasks.NewSnapshotTask(eth.GetDefaultAccount()) task.BlockHeader = bh - tasks.StartTask(logger, wg, eth, task, nil) + tasks.StartTask(logger, wg, eth, task, nil, nil) return nil } diff --git a/blockchain/objects/dkg_state.go b/blockchain/objects/dkg_state.go index 63a502eb..ea2c03f8 100644 --- a/blockchain/objects/dkg_state.go +++ b/blockchain/objects/dkg_state.go @@ -304,3 +304,8 @@ func (pl ParticipantList) Less(i, j int) bool { func (pl ParticipantList) Swap(i, j int) { pl[i], pl[j] = pl[j], pl[i] } + +type ETHDKGTaskData struct { + PersistStateCB func() + State *DkgState +} diff --git a/blockchain/objects/scheduler.go b/blockchain/objects/scheduler.go index 12f24921..9c346400 100644 --- a/blockchain/objects/scheduler.go +++ b/blockchain/objects/scheduler.go @@ -3,6 +3,7 @@ package objects import ( "encoding/json" "errors" + "fmt" "reflect" "github.com/MadBase/MadNet/blockchain/interfaces" @@ -17,9 +18,10 @@ var ( ) type Block struct { - Start uint64 `json:"start"` - End uint64 `json:"end"` - Task interfaces.Task `json:"-"` + Start uint64 `json:"start"` + End uint64 `json:"end"` + Task interfaces.Task `json:"-"` + IsRunning bool `json:"isRunning"` } type innerBlock struct { @@ -76,6 +78,25 @@ func (s *SequentialSchedule) PurgePrior(now uint64) { } } +func (s *SequentialSchedule) SetRunning(taskId uuid.UUID, running bool) error { + block, present := s.Ranges[taskId.String()] + if !present { + return ErrNotScheduled + } + + block.IsRunning = running + return nil +} + +func (s *SequentialSchedule) IsRunning(taskId uuid.UUID) (bool, error) { + block, present := s.Ranges[taskId.String()] + if !present { + return false, ErrNotScheduled + } + + return block.IsRunning, nil +} + func (s *SequentialSchedule) Find(now uint64) (uuid.UUID, error) { for taskId, block := range s.Ranges { @@ -126,6 +147,7 @@ func (ss *SequentialSchedule) MarshalJSON() ([]byte, error) { for k, v := range ss.Ranges { wt, err := ss.marshaller.WrapInstance(v.Task) if err != nil { + fmt.Printf("error marshalling wrapinstance1: %v", err) return []byte{}, err } ws.Ranges[k] = &innerBlock{Start: v.Start, End: v.End, WrappedTask: wt} @@ -133,6 +155,7 @@ func (ss *SequentialSchedule) MarshalJSON() ([]byte, error) { raw, err := json.Marshal(&ws) if err != nil { + fmt.Printf("error marshalling wrapinstance2: %v", err) return []byte{}, err } diff --git a/blockchain/objects/state.go b/blockchain/objects/state.go index 7ec63bcb..d08cde84 100644 --- a/blockchain/objects/state.go +++ b/blockchain/objects/state.go @@ -108,6 +108,8 @@ func (s *MonitorState) Clone() *MonitorState { ns.LatestDepositSeen = s.LatestDepositSeen ns.PeerCount = s.PeerCount + // todo: clone DkgState + return ns } @@ -171,5 +173,7 @@ func (s *MonitorState) Diff(o *MonitorState) (string, bool) { d = append(d, fmt.Sprintf("LatestDepositSeen: %v -> %v", s.LatestDepositSeen, o.LatestDepositSeen)) } + // todo: check DkgState diff + return strings.Join(d, ", "), shouldWrite } diff --git a/blockchain/tasks/task_manager.go b/blockchain/tasks/task_manager.go index ede58e49..f7de3e2c 100644 --- a/blockchain/tasks/task_manager.go +++ b/blockchain/tasks/task_manager.go @@ -16,11 +16,14 @@ var ( ErrUnknownTaskType = errors.New("unkonwn task type") ) -func StartTask(logger *logrus.Entry, wg *sync.WaitGroup, eth interfaces.Ethereum, task interfaces.Task, state interface{}) error { +func StartTask(logger *logrus.Entry, wg *sync.WaitGroup, eth interfaces.Ethereum, task interfaces.Task, state interface{}, onFinishCB *func()) error { wg.Add(1) go func() { defer task.DoDone(logger.WithField("Method", "DoDone")) + if onFinishCB != nil { + defer (*onFinishCB)() + } defer wg.Done() retryCount := eth.RetryCount() @@ -41,6 +44,7 @@ func StartTask(logger *logrus.Entry, wg *sync.WaitGroup, eth interfaces.Ethereum initializationLogger := logger.WithField("Method", "Initialize") err = task.Initialize(ctx, initializationLogger, eth, state) + // todo: maybe force persistence for err != nil && count < retryCount { if errors.Is(err, objects.ErrCanNotContinue) { initializationLogger.Error(err) From 05b7077715a93e585dbfec126677c0120644278a Mon Sep 17 00:00:00 2001 From: Ricardo Pinto Date: Mon, 28 Mar 2022 13:40:47 +0100 Subject: [PATCH 3/8] Persisted DkgState --- .../dkg/dkgtasks/dispute_missing_gpkj_task.go | 2 +- .../dispute_missing_key_shares_task.go | 2 +- .../dispute_missing_registration_task.go | 2 +- ...dispute_missing_share_distribution_task.go | 2 +- blockchain/objects/dkg_state.go | 83 ++++++------ blockchain/objects/dkg_state_test.go | 118 ++++++++++++++++++ docker/generate-bridge/Dockerfile | 2 +- scripts/main.sh | 2 + 8 files changed, 165 insertions(+), 48 deletions(-) diff --git a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go index f2a46307..5787df6a 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go @@ -161,7 +161,7 @@ func (t *DisputeMissingGPKjTask) getAccusableParticipants(ctx context.Context, e for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != uint8(objects.GPKJSubmission) || + p.Phase != objects.GPKJSubmission || (p.GPKj[0].Cmp(big.NewInt(0)) == 0 && p.GPKj[1].Cmp(big.NewInt(0)) == 0 && p.GPKj[2].Cmp(big.NewInt(0)) == 0 && diff --git a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go index 7a9851eb..9679eb1c 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go @@ -159,7 +159,7 @@ func (t *DisputeMissingKeySharesTask) getAccusableParticipants(ctx context.Conte for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != uint8(objects.KeyShareSubmission) || + p.Phase != objects.KeyShareSubmission || (p.KeyShareG1s[0].Cmp(big.NewInt(0)) == 0 && p.KeyShareG1s[1].Cmp(big.NewInt(0)) == 0) || (p.KeyShareG1CorrectnessProofs[0].Cmp(big.NewInt(0)) == 0 && diff --git a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go index cdb08123..0f3c005f 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go @@ -164,7 +164,7 @@ func (t *DisputeMissingRegistrationTask) getAccusableParticipants(ctx context.Co if isValidator && (!ok || participant.Nonce != t.State.Nonce || - participant.Phase != uint8(objects.RegistrationOpen) || + participant.Phase != objects.RegistrationOpen || (participant.PublicKey[0].Cmp(big.NewInt(0)) == 0 && participant.PublicKey[1].Cmp(big.NewInt(0)) == 0)) { diff --git a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go index 929203a3..bd9a98fa 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go @@ -161,7 +161,7 @@ func (t *DisputeMissingShareDistributionTask) getAccusableParticipants(ctx conte for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != uint8(objects.ShareDistribution) || + p.Phase != objects.ShareDistribution || p.DistributedSharesHash == emptySharesHash) { // did not distribute shares accusableParticipants = append(accusableParticipants, p.Address) diff --git a/blockchain/objects/dkg_state.go b/blockchain/objects/dkg_state.go index c6b06e9e..63a502eb 100644 --- a/blockchain/objects/dkg_state.go +++ b/blockchain/objects/dkg_state.go @@ -19,79 +19,77 @@ var ( // DkgState is used to track the state of the ETHDKG type DkgState struct { - sync.RWMutex + sync.RWMutex `json:"-"` - IsValidator bool - Phase EthDKGPhase - PhaseLength uint64 - ConfirmationLength uint64 - PhaseStart uint64 - MPKSetAtBlock uint64 - CompletionAtBlock uint64 + IsValidator bool `json:"isValidator"` + Phase EthDKGPhase `json:"phase"` + PhaseLength uint64 `json:"phaseLength"` + ConfirmationLength uint64 `json:"confirmationLength"` + PhaseStart uint64 `json:"phaseStart"` // Local validator info //////////////////////////////////////////////////////////////////////////// // Account is the Ethereum account corresponding to the Ethereum Public Key // of the local Validator - Account accounts.Account + Account accounts.Account `json:"account"` // Index is the Base-1 index of the local Validator which is used // during the Share Distribution phase for verifiable secret sharing. // REPEAT: THIS IS BASE-1 - Index int + Index int `json:"index"` // ValidatorAddresses stores all validator addresses at the beginning of ETHDKG - ValidatorAddresses []common.Address + ValidatorAddresses []common.Address `json:"validatorAddresses"` // NumberOfValidators is equal to len(ValidatorAddresses) - NumberOfValidators int + NumberOfValidators int `json:"numberOfValidators"` // ETHDKG nonce - Nonce uint64 + Nonce uint64 `json:"nonce"` // ValidatorThreshold is the threshold number of validators for the system. // If n = NumberOfValidators and t = threshold, then // t+1 > 2*n/3 - ValidatorThreshold int + ValidatorThreshold int `json:"validatorThreshold"` // TransportPrivateKey is the private key corresponding to TransportPublicKey. - TransportPrivateKey *big.Int + TransportPrivateKey *big.Int `json:"transportPrivateKey"` // TransportPublicKey is the public key used in EthDKG. // This public key is used for secret communication over the open channel // of Ethereum. - TransportPublicKey [2]*big.Int + TransportPublicKey [2]*big.Int `json:"transportPublicKey"` // SecretValue is the secret value which is to be shared during // the verifiable secret sharing. // The sum of all the secret values of all the participants // is the master secret key, the secret key of the master public key // (MasterPublicKey) - SecretValue *big.Int + SecretValue *big.Int `json:"secretValue"` // PrivateCoefficients is the private polynomial which is used to share // the shared secret. This is performed via Shamir Secret Sharing. - PrivateCoefficients []*big.Int + PrivateCoefficients []*big.Int `json:"privateCoefficients"` // MasterPublicKey is the public key for the entire group. // As mentioned above, the secret key called the master secret key // and is the sum of all the shared secrets of all the participants. - MasterPublicKey [4]*big.Int + MasterPublicKey [4]*big.Int `json:"masterPublicKey"` // GroupPrivateKey is the local Validator's portion of the master secret key. // This is also denoted gskj. - GroupPrivateKey *big.Int + GroupPrivateKey *big.Int `json:"groupPrivateKey"` // Remote validator info //////////////////////////////////////////////////////////////////////////// // Participants is the list of Validators - Participants map[common.Address]*Participant // Index, Address & PublicKey + Participants map[common.Address]*Participant `json:"participants"` // Share Dispute Phase ////////////////////////////////////////////////// // These are the participants with bad shares - BadShares map[common.Address]*Participant + BadShares map[common.Address]*Participant `json:"badShares"` // Group Public Key (GPKj) Accusation Phase ////////////////////////////////////////////////// // DishonestValidatorsIndices stores the list indices of dishonest // validators - DishonestValidators ParticipantList // Calculated for group accusation + DishonestValidators ParticipantList `json:"dishonestValidators"` // HonestValidatorsIndices stores the list indices of honest // validators - HonestValidators ParticipantList // " + HonestValidators ParticipantList `json:"honestValidators"` // Inverse stores the multiplicative inverses // of elements. This may be used in GPKJGroupAccusation logic. - Inverse []*big.Int // " + Inverse []*big.Int `json:"inverse"` } // GetSortedParticipants returns the participant list sorted by Index field @@ -120,7 +118,7 @@ func (state *DkgState) OnAddressRegistered(account common.Address, index int, no Address: account, Index: index, PublicKey: publicKey, - Phase: uint8(RegistrationOpen), + Phase: RegistrationOpen, Nonce: nonce, } @@ -144,7 +142,7 @@ func (state *DkgState) OnSharesDistributed(logger *logrus.Entry, account common. return dkg.LogReturnErrorf(logger, "ProcessShareDistribution: error calculating distributed shares hash: %v", err) } - state.Participants[account].Phase = uint8(ShareDistribution) + state.Participants[account].Phase = ShareDistribution state.Participants[account].DistributedSharesHash = distributedSharesHash state.Participants[account].Commitments = commitments state.Participants[account].EncryptedShares = encryptedShares @@ -171,7 +169,6 @@ func (state *DkgState) OnKeyShareSubmissionComplete(mpkSubmissionStartBlock uint func (state *DkgState) OnMPKSet(gpkjSubmissionStartBlock uint64) { state.Phase = GPKJSubmission state.PhaseStart = gpkjSubmissionStartBlock - state.MPKSetAtBlock = gpkjSubmissionStartBlock } // OnGPKJSubmissionComplete processes data from GPKJSubmissionComplete event @@ -184,7 +181,7 @@ func (state *DkgState) OnGPKJSubmissionComplete(disputeGPKjStartBlock uint64) { func (state *DkgState) OnKeyShareSubmitted(account common.Address, keyShareG1 [2]*big.Int, keyShareG1CorrectnessProof [2]*big.Int, keyShareG2 [4]*big.Int) { state.Phase = KeyShareSubmission - state.Participants[account].Phase = uint8(KeyShareSubmission) + state.Participants[account].Phase = KeyShareSubmission state.Participants[account].KeyShareG1s = keyShareG1 state.Participants[account].KeyShareG1CorrectnessProofs = keyShareG1CorrectnessProof state.Participants[account].KeyShareG2s = keyShareG2 @@ -193,7 +190,7 @@ func (state *DkgState) OnKeyShareSubmitted(account common.Address, keyShareG1 [2 // OnGPKjSubmitted processes data from GPKjSubmitted event func (state *DkgState) OnGPKjSubmitted(account common.Address, gpkj [4]*big.Int) { state.Participants[account].GPKj = gpkj - state.Participants[account].Phase = uint8(GPKJSubmission) + state.Participants[account].Phase = GPKJSubmission } // OnCompletion processes data from ValidatorSetCompleted event @@ -214,16 +211,16 @@ func NewDkgState(account accounts.Account) *DkgState { type Participant struct { // Address is the Ethereum address corresponding to the Ethereum Public Key // for the Participant. - Address common.Address + Address common.Address `json:"address"` // Index is the Base-1 index of the participant. // This is used during the Share Distribution phase to perform // verifyiable secret sharing. // REPEAT: THIS IS BASE-1 - Index int + Index int `json:"index"` // PublicKey is the TransportPublicKey of Participant. - PublicKey [2]*big.Int - Nonce uint64 - Phase uint8 + PublicKey [2]*big.Int `json:"publicKey"` + Nonce uint64 `json:"nonce"` + Phase EthDKGPhase `json:"phase"` // Share Distribution Phase ////////////////////////////////////////////////// @@ -232,33 +229,33 @@ type Participant struct { // in Shamir Secret Sharing protocol. // The first coefficient (constant term) is the public commitment // corresponding to the secret share (SecretValue). - Commitments [][2]*big.Int + Commitments [][2]*big.Int `json:"commitments"` // EncryptedShares are the encrypted secret shares // in the Shamir Secret Sharing protocol. - EncryptedShares []*big.Int - DistributedSharesHash [32]byte + EncryptedShares []*big.Int `json:"encryptedShares"` + DistributedSharesHash [32]byte `json:"distributedSharesHash"` - CommitmentsFirstCoefficient [2]*big.Int + CommitmentsFirstCoefficient [2]*big.Int `json:"commitmentsFirstCoefficient"` // Key Share Submission Phase ////////////////////////////////////////////////// // KeyShareG1s stores the key shares of G1 element // for each participant - KeyShareG1s [2]*big.Int + KeyShareG1s [2]*big.Int `json:"keyShareG1s"` // KeyShareG1CorrectnessProofs stores the proofs of each // G1 element for each participant. - KeyShareG1CorrectnessProofs [2]*big.Int + KeyShareG1CorrectnessProofs [2]*big.Int `json:"keyShareG1CorrectnessProofs"` // KeyShareG2s stores the key shares of G2 element // for each participant. // Adding all the G2 shares together produces the // master public key (MasterPublicKey). - KeyShareG2s [4]*big.Int + KeyShareG2s [4]*big.Int `json:"keyShareG2s"` // GPKj is the local Validator's portion of the master public key. // This is also denoted GroupPublicKey. - GPKj [4]*big.Int + GPKj [4]*big.Int `json:"gpkj"` } // ParticipantList is a required type alias since the Sort interface is awful diff --git a/blockchain/objects/dkg_state_test.go b/blockchain/objects/dkg_state_test.go index a3d72c7c..1ba4b2e0 100644 --- a/blockchain/objects/dkg_state_test.go +++ b/blockchain/objects/dkg_state_test.go @@ -2,10 +2,15 @@ package objects_test import ( "bytes" + "encoding/json" "math/big" "testing" + "github.com/MadBase/MadNet/blockchain/dkg/math" "github.com/MadBase/MadNet/blockchain/objects" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" ) func TestParticipantCopy(t *testing.T) { @@ -59,3 +64,116 @@ func TestParticipantListExtractIndices(t *testing.T) { } } } + +func TestMarshalAndUnmarshalBigInt(t *testing.T) { + + // generate transport keys + priv, pub, err := math.GenerateKeys() + assert.Nil(t, err) + + // marshal privkey + rawPrivData, err := json.Marshal(priv) + assert.Nil(t, err) + rawPubData, err := json.Marshal(pub) + assert.Nil(t, err) + + priv2 := &big.Int{} + pub2 := [2]*big.Int{} + + err = json.Unmarshal(rawPrivData, priv2) + assert.Nil(t, err) + err = json.Unmarshal(rawPubData, &pub2) + assert.Nil(t, err) + + assert.Equal(t, priv, priv2) + assert.Equal(t, pub, pub2) +} + +func TestMarshalAndUnmarshalAccount(t *testing.T) { + addr := common.Address{} + addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + + // create a DkgState obj + acct := accounts.Account{ + Address: addr, + URL: accounts.URL{ + Scheme: "http", + Path: "", + }, + } + + // marshal acct + rawData, err := json.Marshal(acct) + assert.Nil(t, err) + + acct2 := &accounts.Account{} + + err = json.Unmarshal(rawData, acct2) + assert.Nil(t, err) + + assert.Equal(t, acct, *acct2) +} + +func TestMarshalAndUnmarshalParticipant(t *testing.T) { + addr := common.Address{} + addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + + // generate transport keys + _, pub, err := math.GenerateKeys() + assert.Nil(t, err) + + // create a Participant obj + participant := objects.Participant{ + Address: addr, + Index: 1, + PublicKey: pub, + Nonce: 1, + Phase: objects.RegistrationOpen, + } + + // marshal + rawData, err := json.Marshal(participant) + assert.Nil(t, err) + + t.Logf("rawData: %s", rawData) + + participant2 := &objects.Participant{} + + err = json.Unmarshal(rawData, participant2) + assert.Nil(t, err) + assert.Equal(t, participant.PublicKey, participant2.PublicKey) + +} + +func TestMarshalAndUnmarshalDkgState(t *testing.T) { + addr := common.Address{} + addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + + // create a DkgState obj + state := objects.NewDkgState(accounts.Account{ + Address: addr, + URL: accounts.URL{ + Scheme: "file", + Path: "", + }, + }) + + // generate transport keys + priv, pub, err := math.GenerateKeys() + assert.Nil(t, err) + state.TransportPrivateKey = priv + state.TransportPublicKey = pub + + // marshal + rawData, err := json.Marshal(state) + assert.Nil(t, err) + + t.Logf("rawData: %s", rawData) + + state2 := &objects.DkgState{} + + err = json.Unmarshal(rawData, state2) + assert.Nil(t, err) + assert.Equal(t, state.TransportPrivateKey, state2.TransportPrivateKey) + assert.Equal(t, state.TransportPublicKey, state2.TransportPublicKey) +} diff --git a/docker/generate-bridge/Dockerfile b/docker/generate-bridge/Dockerfile index da8b6de0..08538716 100644 --- a/docker/generate-bridge/Dockerfile +++ b/docker/generate-bridge/Dockerfile @@ -1,7 +1,7 @@ # golang helper image used just to compile binaries from go source FROM golang:1.17.6-alpine3.15 AS go_deps RUN apk add --no-cache linux-headers=5.10.41-r0 build-base=0.5-r2 -RUN go install github.com/ethereum/go-ethereum/cmd/abigen@v1.10.8 +RUN go install github.com/ethereum/go-ethereum/cmd/abigen@v1.10.16 # final node image containing binaries compiled by helper image FROM node:16.14.0-alpine3.15 diff --git a/scripts/main.sh b/scripts/main.sh index 48d81fb3..a1b934fa 100755 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -36,6 +36,7 @@ CLEAN_UP () { # Init mkdir ./scripts/generated mkdir ./scripts/generated/stateDBs + mkdir ./scripts/generated/monitorDBs mkdir ./scripts/generated/config mkdir ./scripts/generated/keystores mkdir ./scripts/generated/keystores/keys @@ -74,6 +75,7 @@ CREATE_CONFIGS () { sed -e 's/passcodes = .*/passcodes = \"scripts\/generated\/keystores\/passcodes.txt\"/' | sed -e 's/keystore = .*/keystore = \"scripts\/generated\/keystores\/keys\"/' | sed -e 's/stateDB = .*/stateDB = \"scripts\/generated\/stateDBs\/validator'"$l"'\/\"/' | + sed -e 's/monitorDB = .*/monitorDB = \"scripts\/generated\/monitorDBs\/validator'"$l"'\/\"/' | sed -e 's/privateKey = .*/privateKey = \"'"$PK"'\"/' > ./scripts/generated/config/validator$l.toml echo "$ADDRESS=abc123" >> ./scripts/generated/keystores/passcodes.txt mv ./keyfile.json ./scripts/generated/keystores/keys/$ADDRESS From 094d1e9ac18ef2c755f223f9c288bb72bc200508 Mon Sep 17 00:00:00 2001 From: Ricardo Pinto Date: Tue, 29 Mar 2022 18:54:43 +0100 Subject: [PATCH 4/8] Detected issue and POC fix inplace Co-authored-by: stuckDaemon --- blockchain/dkg/dkgevents/processors.go | 2 +- blockchain/dkg/dkgtasks/completion_task.go | 8 +++ blockchain/dkg/dkgtasks/dispute_gpkj_task.go | 8 +++ .../dkg/dkgtasks/dispute_missing_gpkj_task.go | 7 ++ .../dispute_missing_key_shares_task.go | 7 ++ .../dispute_missing_registration_task.go | 7 ++ ...dispute_missing_share_distribution_task.go | 7 ++ .../dispute_share_distribution_task.go | 7 ++ .../dkg/dkgtasks/gpkj_submission_task.go | 7 ++ .../dkg/dkgtasks/keyshare_submission_task.go | 7 ++ .../dkg/dkgtasks/mpk_submission_task.go | 7 ++ .../dkg/dkgtasks/share_distribution_task.go | 12 +++- blockchain/monitor/monitor.go | 67 ++++++++++++++++--- blockchain/objects/dkg_state.go | 5 ++ blockchain/objects/scheduler.go | 29 +++++++- blockchain/objects/state.go | 4 ++ 16 files changed, 176 insertions(+), 15 deletions(-) diff --git a/blockchain/dkg/dkgevents/processors.go b/blockchain/dkg/dkgevents/processors.go index b7a33d1c..6a5c6e82 100644 --- a/blockchain/dkg/dkgevents/processors.go +++ b/blockchain/dkg/dkgevents/processors.go @@ -187,7 +187,7 @@ func ProcessRegistrationComplete(eth interfaces.Ethereum, logger *logrus.Entry, logger.WithFields(logrus.Fields{ "PhaseStart": shareDistributionStart, "PhaseEnd": shareDistributionEnd, - }).Info("Scheduling NewShareDistributionTask") + }).Infof("Scheduling NewShareDistributionTask: %p %p\n", shareDistributionTask.State, state.EthDKG) state.Schedule.Schedule(shareDistributionStart, shareDistributionEnd, shareDistributionTask) diff --git a/blockchain/dkg/dkgtasks/completion_task.go b/blockchain/dkg/dkgtasks/completion_task.go index 5fed5866..35b7273c 100644 --- a/blockchain/dkg/dkgtasks/completion_task.go +++ b/blockchain/dkg/dkgtasks/completion_task.go @@ -29,6 +29,14 @@ func NewCompletionTask(state *objects.DkgState, start uint64, end uint64) *Compl // Initialize prepares for work to be done in the Completion phase func (t *CompletionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/dispute_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_gpkj_task.go index ca7f1ac3..1076581d 100644 --- a/blockchain/dkg/dkgtasks/dispute_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_gpkj_task.go @@ -32,6 +32,14 @@ func NewDisputeGPKjTask(state *objects.DkgState, start uint64, end uint64) *Disp // Initialize prepares for work to be done in the GPKjDispute phase. // Here, we determine if anyone submitted an invalid gpkj. func (t *DisputeGPKjTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go index 5787df6a..3c655a78 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go @@ -31,6 +31,13 @@ func NewDisputeMissingGPKjTask(state *objects.DkgState, start uint64, end uint64 func (t *DisputeMissingGPKjTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { logger.Info("Initializing DisputeMissingGPKjTask...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go index 9679eb1c..44443e91 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go @@ -29,6 +29,13 @@ func NewDisputeMissingKeySharesTask(state *objects.DkgState, start uint64, end u func (t *DisputeMissingKeySharesTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { logger.Info("Initializing DisputeMissingKeySharesTask...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go index 0f3c005f..873e90ea 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go @@ -30,6 +30,13 @@ func (t *DisputeMissingRegistrationTask) Initialize(ctx context.Context, logger logger.Info("DisputeMissingRegistrationTask Initializing...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go index bd9a98fa..5f26061a 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go @@ -30,6 +30,13 @@ func (t *DisputeMissingShareDistributionTask) Initialize(ctx context.Context, lo logger.Info("DisputeMissingShareDistributionTask Initializing...") + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + return nil } diff --git a/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go index e591ab11..32ed8f35 100644 --- a/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go @@ -34,6 +34,13 @@ func NewDisputeShareDistributionTask(state *objects.DkgState, start uint64, end // It determines if the shares previously distributed are valid. // If any are invalid, disputes will be issued. func (t *DisputeShareDistributionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/gpkj_submission_task.go b/blockchain/dkg/dkgtasks/gpkj_submission_task.go index fc667f67..eeed5d7f 100644 --- a/blockchain/dkg/dkgtasks/gpkj_submission_task.go +++ b/blockchain/dkg/dkgtasks/gpkj_submission_task.go @@ -33,6 +33,13 @@ func NewGPKjSubmissionTask(state *objects.DkgState, start uint64, end uint64, ad // Here, we construct our gpkj and associated signature. // We will submit them in DoWork. func (t *GPKjSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/keyshare_submission_task.go b/blockchain/dkg/dkgtasks/keyshare_submission_task.go index 81239fa5..2957766e 100644 --- a/blockchain/dkg/dkgtasks/keyshare_submission_task.go +++ b/blockchain/dkg/dkgtasks/keyshare_submission_task.go @@ -29,6 +29,13 @@ func NewKeyshareSubmissionTask(state *objects.DkgState, start uint64, end uint64 // Here, the G1 key share, G1 proof, and G2 key share are constructed // and stored for submission. func (t *KeyshareSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/mpk_submission_task.go b/blockchain/dkg/dkgtasks/mpk_submission_task.go index d306819f..35ec989e 100644 --- a/blockchain/dkg/dkgtasks/mpk_submission_task.go +++ b/blockchain/dkg/dkgtasks/mpk_submission_task.go @@ -32,6 +32,13 @@ func NewMPKSubmissionTask(state *objects.DkgState, start uint64, end uint64) *MP // Here we load all key shares and construct the master public key // to submit in DoWork. func (t *MPKSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/share_distribution_task.go b/blockchain/dkg/dkgtasks/share_distribution_task.go index 5020f308..63cccbb3 100644 --- a/blockchain/dkg/dkgtasks/share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/share_distribution_task.go @@ -30,9 +30,19 @@ func NewShareDistributionTask(state *objects.DkgState, start uint64, end uint64) // We construct our commitments and encrypted shares before // submitting them to the associated smart contract. func (t *ShareDistributionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { + + dkgData, ok := state.(objects.ETHDKGTaskData) + if !ok { + return objects.ErrCanNotContinue + } + + t.State = dkgData.State + t.State.Lock() defer t.State.Unlock() + logger.Infof("ShareDistributionTask Initialize() %p\n", t.State) + if t.State.Phase != objects.ShareDistribution { return fmt.Errorf("%w because it's not in ShareDistribution phase", objects.ErrCanNotContinue) } @@ -45,7 +55,7 @@ func (t *ShareDistributionTask) Initialize(ctx context.Context, logger *logrus.E encryptedShares, privateCoefficients, commitments, err := math.GenerateShares( t.State.TransportPrivateKey, participants) if err != nil { - logger.Errorf("Failed to generate shares: %v", err) + logger.Errorf("Failed to generate shares: %v %#v", err, participants) return err } diff --git a/blockchain/monitor/monitor.go b/blockchain/monitor/monitor.go index dddb8ae8..347e6566 100644 --- a/blockchain/monitor/monitor.go +++ b/blockchain/monitor/monitor.go @@ -150,6 +150,12 @@ func (mon *monitor) LoadState() error { if err != nil { return err } + + // todo: fix task state pointers + // for taskUUID, block := range mon.State.Schedule.Ranges { + // block.Task. + // } + return nil }); err != nil { return err @@ -161,7 +167,9 @@ func (mon *monitor) LoadState() error { func (mon *monitor) PersistState() error { + fmt.Println("mon.PersistState() pre-lock") mon.Lock() + fmt.Println("mon.PersistState() post-lock") defer mon.Unlock() rawData, err := json.Marshal(mon) @@ -169,6 +177,9 @@ func (mon *monitor) PersistState() error { return err } + // todo: delete this + //fmt.Printf("persisted monitor: %s\n", rawData) + err = mon.db.Update(func(txn *badger.Txn) error { keyLabel := fmt.Sprintf("%x", getStateKey()) mon.logger.WithField("Key", keyLabel).Infof("Saving state") @@ -219,6 +230,9 @@ func (mon *monitor) Start() error { mon.State.HighestBlockProcessed = startingBlock } + // todo: delete this + logger.Infof("loaded monitor.state.dkgState: %##v\n", mon.State.EthDKG) + if startingBlock > mon.State.HighestBlockProcessed { logger.WithFields(logrus.Fields{ "StartingBlock": startingBlock, @@ -280,7 +294,13 @@ func (mon *monitor) eventLoop(wg *sync.WaitGroup, logger *logrus.Entry, cancelCh oldMonitorState := mon.State.Clone() - if err := MonitorTick(ctx, cf, wg, mon.eth, mon.State, mon.logger, mon.eventMap, mon.adminHandler, mon.batchSize); err != nil { + persistMonitorCB := func() { + logger.Infof("persistMonitorCB is calling") + mon.PersistState() + logger.Infof("persistMonitorCB was called") + } + + if err := MonitorTick(ctx, cf, wg, mon.eth, mon.State, mon.logger, mon.eventMap, mon.adminHandler, mon.batchSize, persistMonitorCB); err != nil { logger.Errorf("Failed MonitorTick(...): %v", err) } @@ -324,7 +344,7 @@ func (m *monitor) UnmarshalJSON(raw []byte) error { // MonitorTick using existing monitorState and incrementally updates it based on current State of Ethereum endpoint func MonitorTick(ctx context.Context, cf context.CancelFunc, wg *sync.WaitGroup, eth interfaces.Ethereum, monitorState *objects.MonitorState, logger *logrus.Entry, - eventMap *objects.EventMap, adminHandler interfaces.AdminHandler, batchSize uint64) error { + eventMap *objects.EventMap, adminHandler interfaces.AdminHandler, batchSize uint64, persistMonitorCB func()) error { defer cf() logger = logger.WithFields(logrus.Fields{ @@ -415,19 +435,46 @@ func MonitorTick(ctx context.Context, cf context.CancelFunc, wg *sync.WaitGroup, // Check if any tasks are scheduled logEntry.Debug("Looking for scheduled task") + logger.Infof("monitor.State.DkgState: %p\n", monitorState.EthDKG) uuid, err := monitorState.Schedule.Find(currentBlock) if err == nil { - task, _ := monitorState.Schedule.Retrieve(uuid) + isRunning, err := monitorState.Schedule.IsRunning(uuid) + if err != nil { + return err + } - taskName, _ := objects.GetNameType(task) + if !isRunning { - log := logEntry.WithFields(logrus.Fields{ - "TaskID": uuid.String(), - "TaskName": taskName}) + task, err := monitorState.Schedule.Retrieve(uuid) + if err != nil { + return err + } - tasks.StartTask(log, wg, eth, task, nil) + taskName, _ := objects.GetNameType(task) + + log := logEntry.WithFields(logrus.Fields{ + "TaskID": uuid.String(), + "TaskName": taskName}) + + onFinishCB := func() { + monitorState.Schedule.SetRunning(uuid, false) + monitorState.Schedule.Remove(uuid) + } + dkgData := objects.ETHDKGTaskData{ + PersistStateCB: persistMonitorCB, + State: monitorState.EthDKG, + } + err = tasks.StartTask(log, wg, eth, task, dkgData, &onFinishCB) + if err != nil { + return err + } + err = monitorState.Schedule.SetRunning(uuid, true) + if err != nil { + return err + } + } - monitorState.Schedule.Remove(uuid) + //monitorState.Schedule.Remove(uuid) } else if err == objects.ErrNothingScheduled { logEntry.Debug("No tasks scheduled") } else { @@ -478,7 +525,7 @@ func PersistSnapshot(ctx context.Context, wg *sync.WaitGroup, eth interfaces.Eth task := tasks.NewSnapshotTask(eth.GetDefaultAccount()) task.BlockHeader = bh - tasks.StartTask(logger, wg, eth, task, nil) + tasks.StartTask(logger, wg, eth, task, nil, nil) return nil } diff --git a/blockchain/objects/dkg_state.go b/blockchain/objects/dkg_state.go index 63a502eb..ea2c03f8 100644 --- a/blockchain/objects/dkg_state.go +++ b/blockchain/objects/dkg_state.go @@ -304,3 +304,8 @@ func (pl ParticipantList) Less(i, j int) bool { func (pl ParticipantList) Swap(i, j int) { pl[i], pl[j] = pl[j], pl[i] } + +type ETHDKGTaskData struct { + PersistStateCB func() + State *DkgState +} diff --git a/blockchain/objects/scheduler.go b/blockchain/objects/scheduler.go index 12f24921..9c346400 100644 --- a/blockchain/objects/scheduler.go +++ b/blockchain/objects/scheduler.go @@ -3,6 +3,7 @@ package objects import ( "encoding/json" "errors" + "fmt" "reflect" "github.com/MadBase/MadNet/blockchain/interfaces" @@ -17,9 +18,10 @@ var ( ) type Block struct { - Start uint64 `json:"start"` - End uint64 `json:"end"` - Task interfaces.Task `json:"-"` + Start uint64 `json:"start"` + End uint64 `json:"end"` + Task interfaces.Task `json:"-"` + IsRunning bool `json:"isRunning"` } type innerBlock struct { @@ -76,6 +78,25 @@ func (s *SequentialSchedule) PurgePrior(now uint64) { } } +func (s *SequentialSchedule) SetRunning(taskId uuid.UUID, running bool) error { + block, present := s.Ranges[taskId.String()] + if !present { + return ErrNotScheduled + } + + block.IsRunning = running + return nil +} + +func (s *SequentialSchedule) IsRunning(taskId uuid.UUID) (bool, error) { + block, present := s.Ranges[taskId.String()] + if !present { + return false, ErrNotScheduled + } + + return block.IsRunning, nil +} + func (s *SequentialSchedule) Find(now uint64) (uuid.UUID, error) { for taskId, block := range s.Ranges { @@ -126,6 +147,7 @@ func (ss *SequentialSchedule) MarshalJSON() ([]byte, error) { for k, v := range ss.Ranges { wt, err := ss.marshaller.WrapInstance(v.Task) if err != nil { + fmt.Printf("error marshalling wrapinstance1: %v", err) return []byte{}, err } ws.Ranges[k] = &innerBlock{Start: v.Start, End: v.End, WrappedTask: wt} @@ -133,6 +155,7 @@ func (ss *SequentialSchedule) MarshalJSON() ([]byte, error) { raw, err := json.Marshal(&ws) if err != nil { + fmt.Printf("error marshalling wrapinstance2: %v", err) return []byte{}, err } diff --git a/blockchain/objects/state.go b/blockchain/objects/state.go index 7ec63bcb..d08cde84 100644 --- a/blockchain/objects/state.go +++ b/blockchain/objects/state.go @@ -108,6 +108,8 @@ func (s *MonitorState) Clone() *MonitorState { ns.LatestDepositSeen = s.LatestDepositSeen ns.PeerCount = s.PeerCount + // todo: clone DkgState + return ns } @@ -171,5 +173,7 @@ func (s *MonitorState) Diff(o *MonitorState) (string, bool) { d = append(d, fmt.Sprintf("LatestDepositSeen: %v -> %v", s.LatestDepositSeen, o.LatestDepositSeen)) } + // todo: check DkgState diff + return strings.Join(d, ", "), shouldWrite } From 0119f4ff7893f1cf12044ea04d3a88a57bad37c5 Mon Sep 17 00:00:00 2001 From: stuckDaemon Date: Wed, 20 Apr 2022 19:27:10 +0200 Subject: [PATCH 5/8] Small typo Added slow return test Modified error log Added TestNewEthereumEndpoint --- blockchain/cancellation_test.go | 45 ++++++++++++- blockchain/ethereum.go | 2 +- blockchain/ethereum_test.go | 113 ++++++++++++++++++++++++++++++++ scripts/base-scripts/deploy.sh | 2 +- 4 files changed, 158 insertions(+), 4 deletions(-) diff --git a/blockchain/cancellation_test.go b/blockchain/cancellation_test.go index ce5fed5e..def61d82 100644 --- a/blockchain/cancellation_test.go +++ b/blockchain/cancellation_test.go @@ -32,7 +32,7 @@ func TestSleepWithContextComplete(t *testing.T) { assert.True(t, completed) } -func TestSleepWithContextInterupted(t *testing.T) { +func TestSleepWithContextInterrupted(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) completed := false @@ -48,10 +48,51 @@ func TestSleepWithContextInterupted(t *testing.T) { } wg.Done() }() - cancel() wg.Wait() assert.False(t, completed) } + +func TestSlowReturn(t *testing.T) { + ctx, _ := context.WithCancel(context.Background()) + + type args struct { + ctx context.Context + delay time.Duration + value bool + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "Test slow Return success", + args: args{ + ctx: ctx, + delay: 5000 * time.Millisecond, + value: true, + }, + want: true, + }, + { + name: "Test slow Return quicker delay", + args: args{ + ctx: ctx, + delay: 500 * time.Millisecond, + value: false, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + start := time.Now() + assert.Equalf(t, tt.want, blockchain.SlowReturn(tt.args.ctx, tt.args.delay, tt.args.value), "SlowReturn(%v, %v, %v)", tt.args.ctx, tt.args.delay, tt.args.value) + elapsed := time.Since(start) + assert.GreaterOrEqual(t, elapsed, tt.args.delay, "Delay time has not been respected") + }) + } +} diff --git a/blockchain/ethereum.go b/blockchain/ethereum.go index 0d96a5a3..87668e1e 100644 --- a/blockchain/ethereum.go +++ b/blockchain/ethereum.go @@ -308,7 +308,7 @@ func NewEthereumEndpoint( defer cancel() rpcClient, rpcErr := rpc.DialContext(ctx, endpoint) if rpcErr != nil { - logger.Errorf("Error in NewEthereumEndpoint at rpc.DialContext: %v", err) + logger.Errorf("Error in NewEthereumEndpoint at rpc.DialContext: %v", rpcErr) return nil, rpcErr } ethClient := ethclient.NewClient(rpcClient) diff --git a/blockchain/ethereum_test.go b/blockchain/ethereum_test.go index 6a3b33c3..49fb78f8 100644 --- a/blockchain/ethereum_test.go +++ b/blockchain/ethereum_test.go @@ -2,8 +2,12 @@ package blockchain_test import ( "context" + "errors" + "fmt" + "io/fs" "math" "math/big" + "net" "testing" "time" @@ -92,3 +96,112 @@ func TestHardhatNode(t *testing.T) { t.Logf("done testing") } + +func TestNewEthereumEndpoint(t *testing.T) { + + eth := setupEthereum(t, 4) + defer eth.Close() + + type args struct { + endpoint string + pathKeystore string + pathPasscodes string + defaultAccount string + timeout time.Duration + retryCount int + retryDelay time.Duration + finalityDelay int + txFeePercentageToIncrease int + txMaxFeeThresholdInGwei uint64 + txCheckFrequency time.Duration + txTimeoutForReplacement time.Duration + } + tests := []struct { + name string + args args + want bool + wantErr assert.ErrorAssertionFunc + }{ + + { + name: "Create new ethereum endpoint failing with passcode file not found", + args: args{"", "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}, + want: false, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + _, ok := err.(*fs.PathError) + if !ok { + t.Errorf("Failing test with an unexpected error") + } + return ok + }, + }, + { + name: "Create new ethereum endpoint failing with specified account not found", + args: args{"", "", "../assets/test/passcodes.txt", "", 0, 0, 0, 0, 0, 0, 0, 0}, + want: false, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + if !errors.Is(err, blockchain.ErrAccountNotFound) { + t.Errorf("Failing test with an unexpected error") + } + return true + }, + }, + { + name: "Create new ethereum endpoint failing on Dial Context", + args: args{ + eth.GetEndpoint(), + "../assets/test/keys", + "../assets/test/passcodes.txt", + eth.GetDefaultAccount().Address.String(), + eth.Timeout(), + eth.RetryCount(), + eth.RetryDelay(), + int(eth.GetFinalityDelay()), + eth.GetTxFeePercentageToIncrease(), + eth.GetTxMaxFeeThresholdInGwei(), + eth.GetTxCheckFrequency(), + eth.GetTxTimeoutForReplacement(), + }, + want: false, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + _, ok := err.(*net.OpError) + if !ok { + t.Errorf("Failing test with an unexpected error") + } + return ok + }, + }, + { + name: "Create new ethereum endpoint returning EthereumDetails", + args: args{ + "http://localhost:8545", + "../assets/test/keys", + "../assets/test/passcodes.txt", + eth.GetDefaultAccount().Address.String(), + eth.Timeout(), + eth.RetryCount(), + eth.RetryDelay(), + int(eth.GetFinalityDelay()), + eth.GetTxFeePercentageToIncrease(), + eth.GetTxMaxFeeThresholdInGwei(), + eth.GetTxCheckFrequency(), + eth.GetTxTimeoutForReplacement(), + }, + want: true, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + return true + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := blockchain.NewEthereumEndpoint(tt.args.endpoint, tt.args.pathKeystore, tt.args.pathPasscodes, tt.args.defaultAccount, tt.args.timeout, tt.args.retryCount, tt.args.retryDelay, tt.args.finalityDelay, tt.args.txFeePercentageToIncrease, tt.args.txMaxFeeThresholdInGwei, tt.args.txCheckFrequency, tt.args.txTimeoutForReplacement) + if !tt.wantErr(t, err, fmt.Sprintf("NewEthereumEndpoint(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v)", tt.args.endpoint, tt.args.pathKeystore, tt.args.pathPasscodes, tt.args.defaultAccount, tt.args.timeout, tt.args.retryCount, tt.args.retryDelay, tt.args.finalityDelay, tt.args.txFeePercentageToIncrease, tt.args.txMaxFeeThresholdInGwei, tt.args.txCheckFrequency, tt.args.txTimeoutForReplacement)) { + return + } + if tt.want { + assert.NotNilf(t, got, "Ethereum Details must not be nil") + } + }) + } +} diff --git a/scripts/base-scripts/deploy.sh b/scripts/base-scripts/deploy.sh index 23357436..6eebc6f9 100755 --- a/scripts/base-scripts/deploy.sh +++ b/scripts/base-scripts/deploy.sh @@ -16,7 +16,7 @@ npx hardhat --network "$NETWORK" deployLegacyTokenAndUpdateDeploymentArgs cp ../scripts/base-files/deploymentList ../scripts/generated/deploymentList npx hardhat --network "$NETWORK" --show-stack-traces deployContracts --input-folder ../scripts/generated -addr="$(grep -zo "\[$NETWORK\]\ndefaultFactoryAddress = \".*\"\n" ../scripts/generated/factoryState | grep -a "defaultFactoryAddress = .*" | awk '{print $NF}')" +addr="$(grep -Pzo "\[$NETWORK\]\ndefaultFactoryAddress = \".*\"\n" ../scripts/generated/factoryState | grep -a "defaultFactoryAddress = .*" | awk '{print $NF}')" export FACTORY_ADDRESS=$addr for filePath in $(ls ../scripts/generated/config | xargs); do sed -e "s/registryAddress = .*/registryAddress = $FACTORY_ADDRESS/" "../scripts/generated/config/$filePath" > "../scripts/generated/config/$filePath".bk &&\ From c2ec60eca121dc856fb2162da9f9a3a8dca0d95d Mon Sep 17 00:00:00 2001 From: stuckDaemon Date: Wed, 27 Apr 2022 12:34:26 +0200 Subject: [PATCH 6/8] Removed deposit, ethdkgempty, staking and validators test. All of these were testing old or no logic. --- blockchain/deposit_test.go | 84 --------- blockchain/ethdkg_test.go | 10 -- blockchain/staking_test.go | 162 ----------------- blockchain/validators_test.go | 329 ---------------------------------- 4 files changed, 585 deletions(-) delete mode 100644 blockchain/deposit_test.go delete mode 100644 blockchain/ethdkg_test.go delete mode 100644 blockchain/staking_test.go delete mode 100644 blockchain/validators_test.go diff --git a/blockchain/deposit_test.go b/blockchain/deposit_test.go deleted file mode 100644 index 5d0f8db5..00000000 --- a/blockchain/deposit_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package blockchain_test - -/* -import ( - "context" - "math/big" - "testing" - - "github.com/MadBase/MadNet/blockchain/interfaces" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type DepositTestSuite struct { - suite.Suite - eth interfaces.Ethereum - callOpts *bind.CallOpts - txnOpts *bind.TransactOpts -} - -func (s *DepositTestSuite) SetupTest() { - t := s.T() - eth, err := setupEthereum(t, 4) - assert.Nil(t, err) - c := eth.Contracts() - - s.eth = eth - ctx := context.TODO() - - testAcct := eth.GetDefaultAccount() - - err = eth.UnlockAccount(testAcct) - if err != nil { - panic(err) - } - - bal, _ := eth.GetBalance(testAcct.Address) - t.Logf("ether balance of %v is %v", testAcct.Address.Hex(), bal) - - // Deployer starts with tokens, so has to transfer - txnOpts, _ := eth.GetTransactionOpts(ctx, testAcct) - _, err = c.UtilityToken().Transfer(txnOpts, testAcct.Address, InitialAllowance) - assert.Nil(t, err) - eth.Commit() - - assert.Nilf(t, err, "Initial transfer of %v to %v failed: %v", InitialAllowance, testAcct.Address.Hex(), err) - if err == nil { - t.Logf("Initial transfer of %v tokens to %v succeeded.", InitialAllowance, testAcct.Address.Hex()) - } - - s.callOpts = eth.GetCallOpts(ctx, eth.GetDefaultAccount()) - s.txnOpts, err = eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err, "Failed to build txnOpts") -} - -func (s *DepositTestSuite) TestDepositEvent() { - t := s.T() - eth := s.eth - c := eth.Contracts() - - bal, _ := c.UtilityToken().BalanceOf(s.callOpts, eth.GetDefaultAccount().Address) - t.Logf("utility token balance of %v is %v", eth.GetDefaultAccount().Address.Hex(), bal) - - bal, _ = eth.GetBalance(eth.GetDefaultAccount().Address) - t.Logf("ether balance of %v is %v", eth.GetDefaultAccount().Address.Hex(), bal) - - // Approve deposit contract to withdrawh.GetDefaultAccount()) - txn, err := c.UtilityToken().Approve(s.txnOpts, c.DepositAddress(), big.NewInt(10000)) - assert.Nilf(t, err, "Approve failed by %v to %v", eth.GetDefaultAccount().Address.Hex(), c.DepositAddress().Hex()) - assert.NotNil(t, txn, "Approve failed: transaction is nil") - s.eth.Commit() - - // Tell deposit contract to withdraw - txn, err = c.Deposit().Deposit(s.txnOpts, big.NewInt(1000)) - assert.Nil(t, err, "Deposit failed") - assert.NotNilf(t, txn, "Deposit failed: transaction is nil") - s.eth.Commit() -} - -func TestDepositTestSuite(t *testing.T) { - suite.Run(t, new(DepositTestSuite)) -} -*/ diff --git a/blockchain/ethdkg_test.go b/blockchain/ethdkg_test.go deleted file mode 100644 index d82e4ba4..00000000 --- a/blockchain/ethdkg_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package blockchain_test - -import ( - "testing" -) - -func TestAccuse(t *testing.T) { - // eth, commit, err := setupEthereum() - -} diff --git a/blockchain/staking_test.go b/blockchain/staking_test.go deleted file mode 100644 index e4621d73..00000000 --- a/blockchain/staking_test.go +++ /dev/null @@ -1,162 +0,0 @@ -package blockchain_test - -/* -import ( - "context" - "math/big" - "testing" - - "github.com/MadBase/MadNet/blockchain/interfaces" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -type StakingTestSuite struct { - suite.Suite - eth interfaces.Ethereum - callOpts *bind.CallOpts - txnOpts *bind.TransactOpts -} - -var InitialAllowance = big.NewInt(1000000000000000000) - -func (s *StakingTestSuite) SetupTest() { - t := s.T() - var err error - s.eth, err = setupEthereum(t, 4) - assert.Nil(t, err) - eth := s.eth - c := s.eth.Contracts() - ctx := context.TODO() - - acct := eth.GetDefaultAccount() - txnOpts, _ := eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) - _, err = c.StakingToken().Transfer(txnOpts, acct.Address, InitialAllowance) - assert.Nilf(t, err, "Initial transfer of %v to %v failed: %v", InitialAllowance, acct.Address.Hex(), err) - - // Tester needs to approve those for Staking - s.txnOpts, err = eth.GetTransactionOpts(ctx, acct) - assert.Nil(t, err, "Can't build txnOpts") - - _, err = c.StakingToken().Approve(s.txnOpts, c.ValidatorsAddress(), InitialAllowance) - assert.Nilf(t, err, "Initial approval of %v to %v failed: %v", InitialAllowance, c.ValidatorsAddress().Hex(), err) - s.eth.Commit() - - s.callOpts = eth.GetCallOpts(ctx, acct) - - // Tell staking we're in the 1st epoch - _, err = c.Snapshots().SetEpoch(txnOpts, big.NewInt(1)) // Must be deploy account - assert.Nil(t, err) - s.eth.Commit() -} - -func (s *StakingTestSuite) TestStakeEvent() { - t := s.T() - - eth := s.eth - c := eth.Contracts() - - balance, err := c.Staking().BalanceStake(s.callOpts) - assert.Truef(t, err == nil, "Failed to check balance:%v", err) - assert.Truef(t, big.NewInt(10).Cmp(balance) > 0, "Allowance %v insufficient", balance) - - stakeAmount := big.NewInt(1000000) - txn, err := c.Staking().LockStake(s.txnOpts, stakeAmount) - assert.Nil(t, err, "Failed to post stake") - assert.NotNil(t, txn, "Staking transaction is nil") - s.eth.Commit() - - rcpt, err := eth.Queue().QueueAndWait(context.Background(), txn) - assert.True(t, err == nil, "Couldn't parse event log:%v", err) - - events := rcpt.Logs - assert.Equal(t, 2, len(events), "Should be 2 events.") - - foundStakeEvent := false - for _, event := range events { - stakeEvent, err := c.Staking().ParseLockedStake(*event) - if err == nil { - foundStakeEvent = true - assert.Equal(t, stakeAmount, stakeEvent.Amount, "Stake amount incorrect") - } - } - assert.True(t, foundStakeEvent) -} - -func (s *StakingTestSuite) TestUnlocked() { - stakeAmount := big.NewInt(1000000) - - t := s.T() - eth := s.eth - c := eth.Contracts() - ctx := context.TODO() - - // Start by making sure unlocked balance and stake are both 0 - unlocked, err := c.Staking().BalanceUnlocked(s.callOpts) - assert.Truef(t, err == nil, "Failed to get unlocked balance: %v", err) - assert.Truef(t, big.NewInt(0).Cmp(unlocked) == 0, "Initial unlocked balance should be 0 but is %v", unlocked) - s.eth.Commit() - - staked, err := c.Staking().BalanceStake(s.callOpts) - assert.Truef(t, err == nil, "Failed to get stake balance: %v", err) - assert.Truef(t, big.NewInt(0).Cmp(staked) == 0, "Initial stake should be 0 but is %v", staked) - s.eth.Commit() - - // Now we lock some - this pulls from token balance based on approvals - _, err = c.Staking().LockStake(s.txnOpts, stakeAmount) - assert.True(t, err == nil, "Failed to post stake:%v", err) - s.eth.Commit() - - // Make sure stake shows the increase and unlocked balance has no change - staked, err = c.Staking().BalanceStake(s.callOpts) - assert.Truef(t, err == nil, "Failed to get stake balance: %v", err) - assert.Truef(t, stakeAmount.Cmp(staked) == 0, "Stake should be %v but is %v", stakeAmount, staked) - t.Logf("staked balance is %v", staked) - - unlocked, err = c.Staking().BalanceUnlocked(s.callOpts) - assert.Truef(t, err == nil, "Failed to get unlocked balance: %v", err) - assert.Truef(t, big.NewInt(0).Cmp(unlocked) == 0, "Unlocked balance should be 0 but is %v", unlocked) - t.Logf("unlocked balance is %v", unlocked) - - // Request stake be unlockable - _, err = c.Staking().RequestUnlockStake(s.txnOpts) - assert.Truef(t, err == nil, "Failed to request unlock of stake: %v", err) - s.eth.Commit() - - // Set clock ahead - requires privileged account (contract owner/operator) - ownerAuth, _ := eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) - _, err = c.Snapshots().SetEpoch(ownerAuth, big.NewInt(5)) - assert.Truef(t, err == nil, "Failed to set clock forward: %v", err) - s.eth.Commit() - - // Now we can actually unlock stake - txn, err := c.Staking().UnlockStake(s.txnOpts, stakeAmount) - assert.Truef(t, err == nil, "Failed to unlock stake: %v", err) - s.eth.Commit() - - // Just making sure the unlock completes - _, err = eth.Queue().QueueAndWait(context.Background(), txn) - if err != nil { - t.Fatal(err) - } - // Now unlocked balance contains what was formerly staked - unlocked, err = c.Staking().BalanceUnlocked(s.callOpts) - assert.Truef(t, err == nil, "Failed to get stake balance: %v", err) - assert.Truef(t, stakeAmount.Cmp(unlocked) == 0, "Unlocked balance should be %v but is %v", stakeAmount, unlocked) -} - -func (s *StakingTestSuite) TestBalanceUnlockedFor() { - t := s.T() - eth := s.eth - c := eth.Contracts() - - balance, err := c.Staking().BalanceUnlockedFor(s.callOpts, c.ValidatorsAddress()) - assert.Nilf(t, err, "Failed: balanceUnlockedFor()") - assert.Truef(t, big.NewInt(0).Cmp(balance) == 0, "Allowance initially should be %v but is %v", InitialAllowance, balance) -} - -func TestStakingTestSuite(t *testing.T) { - suite.Run(t, new(StakingTestSuite)) -} -*/ diff --git a/blockchain/validators_test.go b/blockchain/validators_test.go deleted file mode 100644 index c3f1386d..00000000 --- a/blockchain/validators_test.go +++ /dev/null @@ -1,329 +0,0 @@ -package blockchain_test - -/* -import ( - "bufio" - "context" - "encoding/hex" - "fmt" - "os" - "testing" - - "github.com/MadBase/MadNet/consensus/objs" - "github.com/MadBase/MadNet/crypto" - "github.com/MadBase/MadNet/crypto/bn256" - "github.com/MadBase/MadNet/crypto/bn256/cloudflare" - "github.com/stretchr/testify/assert" -) - -const SnapshotTakenSelector string = "0x6d438b6b835d16cdae6efdc0259fdfba17e6aa32dae81863a2467866f85f724a" - -func TestSnapshot(t *testing.T) { - rawBlockHeaderString := "" + - "000000000000030008000000010004005900000002060000b500000002000000" + - "2a000000004000000d0000000201000019000000020100002500000002010000" + - "31000000020100007e06a605256de00205be97e3db46a7179d10baa270991a68" + - "82adff2b3ca99d37c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b" + - "7bfad8045d85a470000000000000000000000000000000000000000000000000" + - "00000000000000007682aa2f2a0cacceb6abbb88b081b76481dd2704ceb42194" + - "bb4d7aa8e41759110a1673b5fb0848a5fea6fb60aa3d013df90d1797f8b5511c" + - "242f1c4060cbf32512443fa842e474f906eb7aedbff7a2a20818b277ef9e9fed" + - "bae4d4012cdd476021b1d4a7f125e9199e945f602942928ccebfe5f76822bce2" + - "c25b05da413cf9431097b5fc8ed39f381362375f1de1680cdd0525c59a76959b" + - "b91deac7590ecdd12686f605b19f284323f20d30a2b1aa5333f7471acc3787a1" + - "c9b24fed41717ba612f6f612c92fdee07fd6636ed067a0262971ace406b1242a" + - "7c41397d34b642ed" - - // Just make sure it unmarshals as expected - rawBlockHeader, err := hex.DecodeString(rawBlockHeaderString) - assert.Nil(t, err) - assert.Equal(t, 392, len(rawBlockHeader)) - - t.Logf("rawBlockHeader: %x", rawBlockHeader) - - blockHeader := &objs.BlockHeader{} - err = blockHeader.UnmarshalBinary(rawBlockHeader) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, uint32(42), blockHeader.BClaims.ChainID) - assert.Equal(t, uint32(16384), blockHeader.BClaims.Height) - assert.Equal(t, uint32(0), blockHeader.BClaims.TxCount) - - // pull out the block claims - bclaims := blockHeader.BClaims - rawBclaims, err := bclaims.MarshalBinary() - assert.Nil(t, err) - t.Logf("rawBclaims: %x", rawBclaims) - - // pull out the sig - rawSigGroup := blockHeader.SigGroup - assert.Equal(t, rawSigGroup, rawSigGroup) - - publicKeyG2, signatureG1, err := cloudflare.UnmarshalSignature(rawSigGroup) - assert.Nil(t, err) - - publicKey, err := bn256.G2ToBigIntArray(publicKeyG2) - assert.Nil(t, err) - - for idx := 0; idx < 4; idx++ { - t.Logf("publicKey[%d]: %x", idx, publicKey[idx]) - } - - signature, err := bn256.G1ToBigIntArray(signatureG1) - assert.Nil(t, err) - - for idx := 0; idx < 2; idx++ { - t.Logf("signature[%d]: %x", idx, signature[idx]) - } - - fmt.Printf("rawBclaims: %x\n", rawBclaims) - bhsh := crypto.Hasher(rawBclaims) - // fmt.Printf("blockHash: %x", ) - assert.Nil(t, err) - - ok, err := cloudflare.Verify(bhsh, signatureG1, publicKeyG2, cloudflare.HashToG1) - assert.Nil(t, err) - assert.True(t, ok) - - // Check validity with Crypto - eth, err := setupEthereum(t, 4) - assert.Nil(t, err) - - c := eth.Contracts() - ctx := context.TODO() - acct := eth.GetDefaultAccount() - callOpts := eth.GetCallOpts(ctx, acct) - txnOpts, err := eth.GetTransactionOpts(ctx, acct) - assert.Nil(t, err) - - good, err := c.Crypto().Verify(callOpts, bhsh, signature, publicKey) - assert.Nil(t, err) - assert.True(t, good) - - txn, err := c.Validators().Snapshot(txnOpts, rawSigGroup, rawBclaims) - assert.Nil(t, err) - assert.NotNil(t, txn) - eth.Commit() - - rcpt, err := eth.Queue().QueueAndWait(context.Background(), txn) - assert.Nil(t, err) - assert.Equal(t, uint64(1), rcpt.Status) - - // Look for the snapshot taken event - foundIt := false - for _, log := range rcpt.Logs { - if log.Topics[0].String() == SnapshotTakenSelector { - snapshotTaken, err := c.Validators().ParseSnapshotTaken(*log) - assert.Nil(t, err) - assert.Equal(t, uint64(1), snapshotTaken.Epoch.Uint64()) - foundIt = true - - // Now see if I can reconstruct the header from what we have - rawEventBclaims, err := c.Validators().GetRawBlockClaimsSnapshot(callOpts, snapshotTaken.Epoch) - assert.Nil(t, err) - - rawEventSigGroup, err := c.Validators().GetRawSignatureSnapshot(callOpts, snapshotTaken.Epoch) - assert.Nil(t, err) - - assert.Equal(t, rawBclaims, rawEventBclaims) - assert.Equal(t, rawSigGroup, rawEventSigGroup) - - bclaims := &objs.BClaims{} - err = bclaims.UnmarshalBinary(rawEventBclaims) - if err != nil { - t.Fatal(err) - } - header := &objs.BlockHeader{} - header.BClaims = bclaims - header.SigGroup = rawEventSigGroup - - assert.Equal(t, uint32(42), header.BClaims.ChainID) - assert.Equal(t, uint32(16384), header.BClaims.Height) - assert.Equal(t, uint32(0), header.BClaims.TxCount) - } - } - assert.True(t, foundIt, "Should have received SnapshotTaken event") -} - -func TestBlockHeaderParsing(t *testing.T) { - rawBlockHeaderString := "" + - "000000000000030008000000010004005900000002060000b500000002000000" + - "2a000000004000000d0000000201000019000000020100002500000002010000" + - "31000000020100007e06a605256de00205be97e3db46a7179d10baa270991a68" + - "82adff2b3ca99d37c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b" + - "7bfad8045d85a470000000000000000000000000000000000000000000000000" + - "00000000000000007682aa2f2a0cacceb6abbb88b081b76481dd2704ceb42194" + - "bb4d7aa8e41759110a1673b5fb0848a5fea6fb60aa3d013df90d1797f8b5511c" + - "242f1c4060cbf32512443fa842e474f906eb7aedbff7a2a20818b277ef9e9fed" + - "bae4d4012cdd476021b1d4a7f125e9199e945f602942928ccebfe5f76822bce2" + - "c25b05da413cf9431097b5fc8ed39f381362375f1de1680cdd0525c59a76959b" + - "b91deac7590ecdd12686f605b19f284323f20d30a2b1aa5333f7471acc3787a1" + - "c9b24fed41717ba612f6f612c92fdee07fd6636ed067a0262971ace406b1242a" + - "7c41397d34b642ed" - - // Convert the string to binary and make a copy for comparison later - rawBlockHeader, err := hex.DecodeString(rawBlockHeaderString) - assert.Nil(t, err) - - clonedRawBlockHeader := make([]byte, len(rawBlockHeader)) - copy(clonedRawBlockHeader, rawBlockHeader) - - // Just make sure it unmarshals as expected - blockHeader := &objs.BlockHeader{} - err = blockHeader.UnmarshalBinary(rawBlockHeader) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, uint32(42), blockHeader.BClaims.ChainID) - assert.Equal(t, uint32(16384), blockHeader.BClaims.Height) - assert.Equal(t, uint32(0), blockHeader.BClaims.TxCount) - - // Make sure unmarshal->marshal is identical - bh, err := blockHeader.MarshalBinary() - assert.Nil(t, err) - for idx := 0; idx < 392; idx++ { - assert.Equal(t, rawBlockHeader[idx], bh[idx]) - } - - // see what changes - blockHeader.BClaims.ChainID = 42 - // blockHeader.BClaims.Height = 0x12345678 - // blockHeader.BClaims.TxCount = 0 - - bh, err = blockHeader.MarshalBinary() - assert.Nil(t, err) - - // what changed? - differences := make(map[int]string) - - for idx := 0; idx < 392; idx++ { - a := clonedRawBlockHeader[idx] - b := bh[idx] - if a != b { - differences[idx] = fmt.Sprintf("{0x%02x -> 0x%02x}", a, b) - } - } - t.Logf("Change count: %v", len(differences)) - t.Logf(" Changes: %v", differences) -} - -func TestBulkProcessBlockHeaders(t *testing.T) { - file, err := os.Open("../assets/test/blockheaders.txt") - assert.Nil(t, err) - - defer file.Close() - - scanner := bufio.NewScanner(file) - - for scanner.Scan() { - - hexText := scanner.Text() - rawBlockHeader, err := hex.DecodeString(hexText) - assert.Nil(t, err) - - processBlockHeader(t, rawBlockHeader) - } -} - -func processBlockHeader(t *testing.T, rawBlockHeader []byte) { - - blockHeader := &objs.BlockHeader{} - err := blockHeader.UnmarshalBinary(rawBlockHeader) - assert.Nil(t, err) - - // pull out the block claims - bclaims := blockHeader.BClaims - rawBclaims, err := bclaims.MarshalBinary() - assert.Nil(t, err) - bclaimsHash := crypto.Hasher(rawBclaims) - - // pull out the sig - rawSigGroup := blockHeader.SigGroup - - publicKeyG2, signatureG1, err := cloudflare.UnmarshalSignature(rawSigGroup) - assert.Nil(t, err) - - ok, err := cloudflare.Verify(bclaimsHash, signatureG1, publicKeyG2, cloudflare.HashToG1) - assert.Nil(t, err) - assert.True(t, ok, "verify should return true") - - // Check validity with Crypto - assert.Nil(t, err) - - eth, err := setupEthereum(t, 5) - assert.Nil(t, err) - c := eth.Contracts() - ctx := context.TODO() - acct := eth.GetDefaultAccount() - callOpts := eth.GetCallOpts(ctx, acct) - txnOpts, err := eth.GetTransactionOpts(ctx, acct) - assert.Nil(t, err) - - // Convert from G1/G2 into []*big.Int's - publicKey, err := bn256.G2ToBigIntArray(publicKeyG2) - assert.Nil(t, err) - - signature, err := bn256.G1ToBigIntArray(signatureG1) - assert.Nil(t, err) - - good, err := c.Crypto().Verify(callOpts, bclaimsHash, signature, publicKey) - assert.Nil(t, err) - assert.True(t, good) - - t.Logf("rawBclaims: 0x%x", rawBclaims) - - txn, err := c.Validators().Snapshot(txnOpts, rawSigGroup, rawBclaims) - assert.Nil(t, err) - assert.NotNil(t, txn) - eth.Commit() - - rcpt, err := eth.Queue().QueueAndWait(context.Background(), txn) - assert.Nil(t, err) - assert.Equal(t, uint64(1), rcpt.Status) - - // Look for the snapshot taken event - foundIt := false - for _, log := range rcpt.Logs { - if log.Topics[0].String() == SnapshotTakenSelector { - snapshotTaken, err := c.Validators().ParseSnapshotTaken(*log) - assert.Nil(t, err) - assert.Equal(t, uint64(1), snapshotTaken.Epoch.Uint64()) - foundIt = true - - // Now see if I can reconstruct the header from what we have - rawEventBclaims, err := c.Validators().GetRawBlockClaimsSnapshot(callOpts, snapshotTaken.Epoch) - assert.Nil(t, err) - - rawEventSigGroup, err := c.Validators().GetRawSignatureSnapshot(callOpts, snapshotTaken.Epoch) - assert.Nil(t, err) - - chainId, err := c.Validators().GetChainIdFromSnapshot(callOpts, snapshotTaken.Epoch) - assert.Nil(t, err) - - height, err := c.Validators().GetMadHeightFromSnapshot(callOpts, snapshotTaken.Epoch) - assert.Nil(t, err) - - assert.Equal(t, rawBclaims, rawEventBclaims) - assert.Equal(t, rawSigGroup, rawEventSigGroup) - - bclaims := &objs.BClaims{} - err = bclaims.UnmarshalBinary(rawEventBclaims) - assert.Nil(t, err) - - header := &objs.BlockHeader{} - header.BClaims = bclaims - header.SigGroup = rawEventSigGroup - - t.Logf("ChainID:%v Height:%v TxCount:%v", bclaims.ChainID, bclaims.Height, bclaims.TxCount) - - assert.Equal(t, blockHeader.BClaims.ChainID, chainId, "ChainID isn't as expected") - assert.Equal(t, blockHeader.BClaims.Height, height, "Height isn't as expected") - assert.Equal(t, blockHeader.BClaims.ChainID, header.BClaims.ChainID) - assert.Equal(t, blockHeader.BClaims.Height, header.BClaims.Height) - assert.Equal(t, blockHeader.BClaims.TxCount, header.BClaims.TxCount) - } - } - assert.True(t, foundIt, "Should have received SnapshotTaken event") -} -*/ From 5ae527030803bd43edf8aebf925f8f87422c4bac Mon Sep 17 00:00:00 2001 From: stuckDaemon Date: Wed, 27 Apr 2022 12:52:35 +0200 Subject: [PATCH 7/8] Including blockchain package in CI workflow --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3720c186..b694fdb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -144,4 +144,4 @@ jobs: - name: Run tests run: | set -euo pipefail - go test -json -v $(go list ./... | grep -Ev '/blockchain|/badgerTrie|/consensus|/transport|/testutils') 2>&1 | tee /tmp/gotest.log | gotestfmt + go test -json -v $(go list ./... | grep -Ev '/badgerTrie|/consensus|/transport|/testutils') 2>&1 | tee /tmp/gotest.log | gotestfmt From c5b9c2fe9360e99606ed2e87695b71d541f97478 Mon Sep 17 00:00:00 2001 From: stuckDaemon Date: Wed, 27 Apr 2022 13:34:29 +0200 Subject: [PATCH 8/8] Merging the latest candidate branch --- blockchain/dkg/dkgevents/processors.go | 2 +- blockchain/dkg/dkgtasks/completion_task.go | 8 -- blockchain/dkg/dkgtasks/dispute_gpkj_task.go | 8 -- .../dkg/dkgtasks/dispute_missing_gpkj_task.go | 9 +- .../dispute_missing_key_shares_task.go | 9 +- .../dispute_missing_registration_task.go | 9 +- ...dispute_missing_share_distribution_task.go | 9 +- .../dispute_share_distribution_task.go | 7 -- .../dkg/dkgtasks/gpkj_submission_task.go | 7 -- .../dkg/dkgtasks/keyshare_submission_task.go | 7 -- .../dkg/dkgtasks/mpk_submission_task.go | 7 -- .../dkg/dkgtasks/share_distribution_task.go | 12 +-- blockchain/monitor/monitor.go | 67 +++----------- blockchain/objects/dkg_state.go | 88 +++++++++---------- blockchain/objects/dkg_state_test.go | 2 +- blockchain/objects/scheduler.go | 29 +----- blockchain/objects/state.go | 4 - docker/generate-bridge/Dockerfile | 4 +- scripts/main.sh | 2 - 19 files changed, 65 insertions(+), 225 deletions(-) diff --git a/blockchain/dkg/dkgevents/processors.go b/blockchain/dkg/dkgevents/processors.go index 6a5c6e82..b7a33d1c 100644 --- a/blockchain/dkg/dkgevents/processors.go +++ b/blockchain/dkg/dkgevents/processors.go @@ -187,7 +187,7 @@ func ProcessRegistrationComplete(eth interfaces.Ethereum, logger *logrus.Entry, logger.WithFields(logrus.Fields{ "PhaseStart": shareDistributionStart, "PhaseEnd": shareDistributionEnd, - }).Infof("Scheduling NewShareDistributionTask: %p %p\n", shareDistributionTask.State, state.EthDKG) + }).Info("Scheduling NewShareDistributionTask") state.Schedule.Schedule(shareDistributionStart, shareDistributionEnd, shareDistributionTask) diff --git a/blockchain/dkg/dkgtasks/completion_task.go b/blockchain/dkg/dkgtasks/completion_task.go index 35b7273c..5fed5866 100644 --- a/blockchain/dkg/dkgtasks/completion_task.go +++ b/blockchain/dkg/dkgtasks/completion_task.go @@ -29,14 +29,6 @@ func NewCompletionTask(state *objects.DkgState, start uint64, end uint64) *Compl // Initialize prepares for work to be done in the Completion phase func (t *CompletionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/dispute_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_gpkj_task.go index 1076581d..ca7f1ac3 100644 --- a/blockchain/dkg/dkgtasks/dispute_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_gpkj_task.go @@ -32,14 +32,6 @@ func NewDisputeGPKjTask(state *objects.DkgState, start uint64, end uint64) *Disp // Initialize prepares for work to be done in the GPKjDispute phase. // Here, we determine if anyone submitted an invalid gpkj. func (t *DisputeGPKjTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go index 3c655a78..f2a46307 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_gpkj_task.go @@ -31,13 +31,6 @@ func NewDisputeMissingGPKjTask(state *objects.DkgState, start uint64, end uint64 func (t *DisputeMissingGPKjTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { logger.Info("Initializing DisputeMissingGPKjTask...") - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - return nil } @@ -168,7 +161,7 @@ func (t *DisputeMissingGPKjTask) getAccusableParticipants(ctx context.Context, e for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != objects.GPKJSubmission || + p.Phase != uint8(objects.GPKJSubmission) || (p.GPKj[0].Cmp(big.NewInt(0)) == 0 && p.GPKj[1].Cmp(big.NewInt(0)) == 0 && p.GPKj[2].Cmp(big.NewInt(0)) == 0 && diff --git a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go index 44443e91..7a9851eb 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_key_shares_task.go @@ -29,13 +29,6 @@ func NewDisputeMissingKeySharesTask(state *objects.DkgState, start uint64, end u func (t *DisputeMissingKeySharesTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { logger.Info("Initializing DisputeMissingKeySharesTask...") - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - return nil } @@ -166,7 +159,7 @@ func (t *DisputeMissingKeySharesTask) getAccusableParticipants(ctx context.Conte for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != objects.KeyShareSubmission || + p.Phase != uint8(objects.KeyShareSubmission) || (p.KeyShareG1s[0].Cmp(big.NewInt(0)) == 0 && p.KeyShareG1s[1].Cmp(big.NewInt(0)) == 0) || (p.KeyShareG1CorrectnessProofs[0].Cmp(big.NewInt(0)) == 0 && diff --git a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go index 873e90ea..cdb08123 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_registration_task.go @@ -30,13 +30,6 @@ func (t *DisputeMissingRegistrationTask) Initialize(ctx context.Context, logger logger.Info("DisputeMissingRegistrationTask Initializing...") - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - return nil } @@ -171,7 +164,7 @@ func (t *DisputeMissingRegistrationTask) getAccusableParticipants(ctx context.Co if isValidator && (!ok || participant.Nonce != t.State.Nonce || - participant.Phase != objects.RegistrationOpen || + participant.Phase != uint8(objects.RegistrationOpen) || (participant.PublicKey[0].Cmp(big.NewInt(0)) == 0 && participant.PublicKey[1].Cmp(big.NewInt(0)) == 0)) { diff --git a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go index 5f26061a..929203a3 100644 --- a/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_missing_share_distribution_task.go @@ -30,13 +30,6 @@ func (t *DisputeMissingShareDistributionTask) Initialize(ctx context.Context, lo logger.Info("DisputeMissingShareDistributionTask Initializing...") - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - return nil } @@ -168,7 +161,7 @@ func (t *DisputeMissingShareDistributionTask) getAccusableParticipants(ctx conte for _, p := range t.State.Participants { _, isValidator := validatorsMap[p.Address] if isValidator && (p.Nonce != t.State.Nonce || - p.Phase != objects.ShareDistribution || + p.Phase != uint8(objects.ShareDistribution) || p.DistributedSharesHash == emptySharesHash) { // did not distribute shares accusableParticipants = append(accusableParticipants, p.Address) diff --git a/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go b/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go index 32ed8f35..e591ab11 100644 --- a/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/dispute_share_distribution_task.go @@ -34,13 +34,6 @@ func NewDisputeShareDistributionTask(state *objects.DkgState, start uint64, end // It determines if the shares previously distributed are valid. // If any are invalid, disputes will be issued. func (t *DisputeShareDistributionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/gpkj_submission_task.go b/blockchain/dkg/dkgtasks/gpkj_submission_task.go index eeed5d7f..fc667f67 100644 --- a/blockchain/dkg/dkgtasks/gpkj_submission_task.go +++ b/blockchain/dkg/dkgtasks/gpkj_submission_task.go @@ -33,13 +33,6 @@ func NewGPKjSubmissionTask(state *objects.DkgState, start uint64, end uint64, ad // Here, we construct our gpkj and associated signature. // We will submit them in DoWork. func (t *GPKjSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/keyshare_submission_task.go b/blockchain/dkg/dkgtasks/keyshare_submission_task.go index 2957766e..81239fa5 100644 --- a/blockchain/dkg/dkgtasks/keyshare_submission_task.go +++ b/blockchain/dkg/dkgtasks/keyshare_submission_task.go @@ -29,13 +29,6 @@ func NewKeyshareSubmissionTask(state *objects.DkgState, start uint64, end uint64 // Here, the G1 key share, G1 proof, and G2 key share are constructed // and stored for submission. func (t *KeyshareSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/mpk_submission_task.go b/blockchain/dkg/dkgtasks/mpk_submission_task.go index 35ec989e..d306819f 100644 --- a/blockchain/dkg/dkgtasks/mpk_submission_task.go +++ b/blockchain/dkg/dkgtasks/mpk_submission_task.go @@ -32,13 +32,6 @@ func NewMPKSubmissionTask(state *objects.DkgState, start uint64, end uint64) *MP // Here we load all key shares and construct the master public key // to submit in DoWork. func (t *MPKSubmissionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() diff --git a/blockchain/dkg/dkgtasks/share_distribution_task.go b/blockchain/dkg/dkgtasks/share_distribution_task.go index 63cccbb3..5020f308 100644 --- a/blockchain/dkg/dkgtasks/share_distribution_task.go +++ b/blockchain/dkg/dkgtasks/share_distribution_task.go @@ -30,19 +30,9 @@ func NewShareDistributionTask(state *objects.DkgState, start uint64, end uint64) // We construct our commitments and encrypted shares before // submitting them to the associated smart contract. func (t *ShareDistributionTask) Initialize(ctx context.Context, logger *logrus.Entry, eth interfaces.Ethereum, state interface{}) error { - - dkgData, ok := state.(objects.ETHDKGTaskData) - if !ok { - return objects.ErrCanNotContinue - } - - t.State = dkgData.State - t.State.Lock() defer t.State.Unlock() - logger.Infof("ShareDistributionTask Initialize() %p\n", t.State) - if t.State.Phase != objects.ShareDistribution { return fmt.Errorf("%w because it's not in ShareDistribution phase", objects.ErrCanNotContinue) } @@ -55,7 +45,7 @@ func (t *ShareDistributionTask) Initialize(ctx context.Context, logger *logrus.E encryptedShares, privateCoefficients, commitments, err := math.GenerateShares( t.State.TransportPrivateKey, participants) if err != nil { - logger.Errorf("Failed to generate shares: %v %#v", err, participants) + logger.Errorf("Failed to generate shares: %v", err) return err } diff --git a/blockchain/monitor/monitor.go b/blockchain/monitor/monitor.go index 347e6566..dddb8ae8 100644 --- a/blockchain/monitor/monitor.go +++ b/blockchain/monitor/monitor.go @@ -150,12 +150,6 @@ func (mon *monitor) LoadState() error { if err != nil { return err } - - // todo: fix task state pointers - // for taskUUID, block := range mon.State.Schedule.Ranges { - // block.Task. - // } - return nil }); err != nil { return err @@ -167,9 +161,7 @@ func (mon *monitor) LoadState() error { func (mon *monitor) PersistState() error { - fmt.Println("mon.PersistState() pre-lock") mon.Lock() - fmt.Println("mon.PersistState() post-lock") defer mon.Unlock() rawData, err := json.Marshal(mon) @@ -177,9 +169,6 @@ func (mon *monitor) PersistState() error { return err } - // todo: delete this - //fmt.Printf("persisted monitor: %s\n", rawData) - err = mon.db.Update(func(txn *badger.Txn) error { keyLabel := fmt.Sprintf("%x", getStateKey()) mon.logger.WithField("Key", keyLabel).Infof("Saving state") @@ -230,9 +219,6 @@ func (mon *monitor) Start() error { mon.State.HighestBlockProcessed = startingBlock } - // todo: delete this - logger.Infof("loaded monitor.state.dkgState: %##v\n", mon.State.EthDKG) - if startingBlock > mon.State.HighestBlockProcessed { logger.WithFields(logrus.Fields{ "StartingBlock": startingBlock, @@ -294,13 +280,7 @@ func (mon *monitor) eventLoop(wg *sync.WaitGroup, logger *logrus.Entry, cancelCh oldMonitorState := mon.State.Clone() - persistMonitorCB := func() { - logger.Infof("persistMonitorCB is calling") - mon.PersistState() - logger.Infof("persistMonitorCB was called") - } - - if err := MonitorTick(ctx, cf, wg, mon.eth, mon.State, mon.logger, mon.eventMap, mon.adminHandler, mon.batchSize, persistMonitorCB); err != nil { + if err := MonitorTick(ctx, cf, wg, mon.eth, mon.State, mon.logger, mon.eventMap, mon.adminHandler, mon.batchSize); err != nil { logger.Errorf("Failed MonitorTick(...): %v", err) } @@ -344,7 +324,7 @@ func (m *monitor) UnmarshalJSON(raw []byte) error { // MonitorTick using existing monitorState and incrementally updates it based on current State of Ethereum endpoint func MonitorTick(ctx context.Context, cf context.CancelFunc, wg *sync.WaitGroup, eth interfaces.Ethereum, monitorState *objects.MonitorState, logger *logrus.Entry, - eventMap *objects.EventMap, adminHandler interfaces.AdminHandler, batchSize uint64, persistMonitorCB func()) error { + eventMap *objects.EventMap, adminHandler interfaces.AdminHandler, batchSize uint64) error { defer cf() logger = logger.WithFields(logrus.Fields{ @@ -435,46 +415,19 @@ func MonitorTick(ctx context.Context, cf context.CancelFunc, wg *sync.WaitGroup, // Check if any tasks are scheduled logEntry.Debug("Looking for scheduled task") - logger.Infof("monitor.State.DkgState: %p\n", monitorState.EthDKG) uuid, err := monitorState.Schedule.Find(currentBlock) if err == nil { - isRunning, err := monitorState.Schedule.IsRunning(uuid) - if err != nil { - return err - } + task, _ := monitorState.Schedule.Retrieve(uuid) - if !isRunning { + taskName, _ := objects.GetNameType(task) - task, err := monitorState.Schedule.Retrieve(uuid) - if err != nil { - return err - } + log := logEntry.WithFields(logrus.Fields{ + "TaskID": uuid.String(), + "TaskName": taskName}) - taskName, _ := objects.GetNameType(task) - - log := logEntry.WithFields(logrus.Fields{ - "TaskID": uuid.String(), - "TaskName": taskName}) - - onFinishCB := func() { - monitorState.Schedule.SetRunning(uuid, false) - monitorState.Schedule.Remove(uuid) - } - dkgData := objects.ETHDKGTaskData{ - PersistStateCB: persistMonitorCB, - State: monitorState.EthDKG, - } - err = tasks.StartTask(log, wg, eth, task, dkgData, &onFinishCB) - if err != nil { - return err - } - err = monitorState.Schedule.SetRunning(uuid, true) - if err != nil { - return err - } - } + tasks.StartTask(log, wg, eth, task, nil) - //monitorState.Schedule.Remove(uuid) + monitorState.Schedule.Remove(uuid) } else if err == objects.ErrNothingScheduled { logEntry.Debug("No tasks scheduled") } else { @@ -525,7 +478,7 @@ func PersistSnapshot(ctx context.Context, wg *sync.WaitGroup, eth interfaces.Eth task := tasks.NewSnapshotTask(eth.GetDefaultAccount()) task.BlockHeader = bh - tasks.StartTask(logger, wg, eth, task, nil, nil) + tasks.StartTask(logger, wg, eth, task, nil) return nil } diff --git a/blockchain/objects/dkg_state.go b/blockchain/objects/dkg_state.go index ea2c03f8..c6b06e9e 100644 --- a/blockchain/objects/dkg_state.go +++ b/blockchain/objects/dkg_state.go @@ -19,77 +19,79 @@ var ( // DkgState is used to track the state of the ETHDKG type DkgState struct { - sync.RWMutex `json:"-"` + sync.RWMutex - IsValidator bool `json:"isValidator"` - Phase EthDKGPhase `json:"phase"` - PhaseLength uint64 `json:"phaseLength"` - ConfirmationLength uint64 `json:"confirmationLength"` - PhaseStart uint64 `json:"phaseStart"` + IsValidator bool + Phase EthDKGPhase + PhaseLength uint64 + ConfirmationLength uint64 + PhaseStart uint64 + MPKSetAtBlock uint64 + CompletionAtBlock uint64 // Local validator info //////////////////////////////////////////////////////////////////////////// // Account is the Ethereum account corresponding to the Ethereum Public Key // of the local Validator - Account accounts.Account `json:"account"` + Account accounts.Account // Index is the Base-1 index of the local Validator which is used // during the Share Distribution phase for verifiable secret sharing. // REPEAT: THIS IS BASE-1 - Index int `json:"index"` + Index int // ValidatorAddresses stores all validator addresses at the beginning of ETHDKG - ValidatorAddresses []common.Address `json:"validatorAddresses"` + ValidatorAddresses []common.Address // NumberOfValidators is equal to len(ValidatorAddresses) - NumberOfValidators int `json:"numberOfValidators"` + NumberOfValidators int // ETHDKG nonce - Nonce uint64 `json:"nonce"` + Nonce uint64 // ValidatorThreshold is the threshold number of validators for the system. // If n = NumberOfValidators and t = threshold, then // t+1 > 2*n/3 - ValidatorThreshold int `json:"validatorThreshold"` + ValidatorThreshold int // TransportPrivateKey is the private key corresponding to TransportPublicKey. - TransportPrivateKey *big.Int `json:"transportPrivateKey"` + TransportPrivateKey *big.Int // TransportPublicKey is the public key used in EthDKG. // This public key is used for secret communication over the open channel // of Ethereum. - TransportPublicKey [2]*big.Int `json:"transportPublicKey"` + TransportPublicKey [2]*big.Int // SecretValue is the secret value which is to be shared during // the verifiable secret sharing. // The sum of all the secret values of all the participants // is the master secret key, the secret key of the master public key // (MasterPublicKey) - SecretValue *big.Int `json:"secretValue"` + SecretValue *big.Int // PrivateCoefficients is the private polynomial which is used to share // the shared secret. This is performed via Shamir Secret Sharing. - PrivateCoefficients []*big.Int `json:"privateCoefficients"` + PrivateCoefficients []*big.Int // MasterPublicKey is the public key for the entire group. // As mentioned above, the secret key called the master secret key // and is the sum of all the shared secrets of all the participants. - MasterPublicKey [4]*big.Int `json:"masterPublicKey"` + MasterPublicKey [4]*big.Int // GroupPrivateKey is the local Validator's portion of the master secret key. // This is also denoted gskj. - GroupPrivateKey *big.Int `json:"groupPrivateKey"` + GroupPrivateKey *big.Int // Remote validator info //////////////////////////////////////////////////////////////////////////// // Participants is the list of Validators - Participants map[common.Address]*Participant `json:"participants"` + Participants map[common.Address]*Participant // Index, Address & PublicKey // Share Dispute Phase ////////////////////////////////////////////////// // These are the participants with bad shares - BadShares map[common.Address]*Participant `json:"badShares"` + BadShares map[common.Address]*Participant // Group Public Key (GPKj) Accusation Phase ////////////////////////////////////////////////// // DishonestValidatorsIndices stores the list indices of dishonest // validators - DishonestValidators ParticipantList `json:"dishonestValidators"` + DishonestValidators ParticipantList // Calculated for group accusation // HonestValidatorsIndices stores the list indices of honest // validators - HonestValidators ParticipantList `json:"honestValidators"` + HonestValidators ParticipantList // " // Inverse stores the multiplicative inverses // of elements. This may be used in GPKJGroupAccusation logic. - Inverse []*big.Int `json:"inverse"` + Inverse []*big.Int // " } // GetSortedParticipants returns the participant list sorted by Index field @@ -118,7 +120,7 @@ func (state *DkgState) OnAddressRegistered(account common.Address, index int, no Address: account, Index: index, PublicKey: publicKey, - Phase: RegistrationOpen, + Phase: uint8(RegistrationOpen), Nonce: nonce, } @@ -142,7 +144,7 @@ func (state *DkgState) OnSharesDistributed(logger *logrus.Entry, account common. return dkg.LogReturnErrorf(logger, "ProcessShareDistribution: error calculating distributed shares hash: %v", err) } - state.Participants[account].Phase = ShareDistribution + state.Participants[account].Phase = uint8(ShareDistribution) state.Participants[account].DistributedSharesHash = distributedSharesHash state.Participants[account].Commitments = commitments state.Participants[account].EncryptedShares = encryptedShares @@ -169,6 +171,7 @@ func (state *DkgState) OnKeyShareSubmissionComplete(mpkSubmissionStartBlock uint func (state *DkgState) OnMPKSet(gpkjSubmissionStartBlock uint64) { state.Phase = GPKJSubmission state.PhaseStart = gpkjSubmissionStartBlock + state.MPKSetAtBlock = gpkjSubmissionStartBlock } // OnGPKJSubmissionComplete processes data from GPKJSubmissionComplete event @@ -181,7 +184,7 @@ func (state *DkgState) OnGPKJSubmissionComplete(disputeGPKjStartBlock uint64) { func (state *DkgState) OnKeyShareSubmitted(account common.Address, keyShareG1 [2]*big.Int, keyShareG1CorrectnessProof [2]*big.Int, keyShareG2 [4]*big.Int) { state.Phase = KeyShareSubmission - state.Participants[account].Phase = KeyShareSubmission + state.Participants[account].Phase = uint8(KeyShareSubmission) state.Participants[account].KeyShareG1s = keyShareG1 state.Participants[account].KeyShareG1CorrectnessProofs = keyShareG1CorrectnessProof state.Participants[account].KeyShareG2s = keyShareG2 @@ -190,7 +193,7 @@ func (state *DkgState) OnKeyShareSubmitted(account common.Address, keyShareG1 [2 // OnGPKjSubmitted processes data from GPKjSubmitted event func (state *DkgState) OnGPKjSubmitted(account common.Address, gpkj [4]*big.Int) { state.Participants[account].GPKj = gpkj - state.Participants[account].Phase = GPKJSubmission + state.Participants[account].Phase = uint8(GPKJSubmission) } // OnCompletion processes data from ValidatorSetCompleted event @@ -211,16 +214,16 @@ func NewDkgState(account accounts.Account) *DkgState { type Participant struct { // Address is the Ethereum address corresponding to the Ethereum Public Key // for the Participant. - Address common.Address `json:"address"` + Address common.Address // Index is the Base-1 index of the participant. // This is used during the Share Distribution phase to perform // verifyiable secret sharing. // REPEAT: THIS IS BASE-1 - Index int `json:"index"` + Index int // PublicKey is the TransportPublicKey of Participant. - PublicKey [2]*big.Int `json:"publicKey"` - Nonce uint64 `json:"nonce"` - Phase EthDKGPhase `json:"phase"` + PublicKey [2]*big.Int + Nonce uint64 + Phase uint8 // Share Distribution Phase ////////////////////////////////////////////////// @@ -229,33 +232,33 @@ type Participant struct { // in Shamir Secret Sharing protocol. // The first coefficient (constant term) is the public commitment // corresponding to the secret share (SecretValue). - Commitments [][2]*big.Int `json:"commitments"` + Commitments [][2]*big.Int // EncryptedShares are the encrypted secret shares // in the Shamir Secret Sharing protocol. - EncryptedShares []*big.Int `json:"encryptedShares"` - DistributedSharesHash [32]byte `json:"distributedSharesHash"` + EncryptedShares []*big.Int + DistributedSharesHash [32]byte - CommitmentsFirstCoefficient [2]*big.Int `json:"commitmentsFirstCoefficient"` + CommitmentsFirstCoefficient [2]*big.Int // Key Share Submission Phase ////////////////////////////////////////////////// // KeyShareG1s stores the key shares of G1 element // for each participant - KeyShareG1s [2]*big.Int `json:"keyShareG1s"` + KeyShareG1s [2]*big.Int // KeyShareG1CorrectnessProofs stores the proofs of each // G1 element for each participant. - KeyShareG1CorrectnessProofs [2]*big.Int `json:"keyShareG1CorrectnessProofs"` + KeyShareG1CorrectnessProofs [2]*big.Int // KeyShareG2s stores the key shares of G2 element // for each participant. // Adding all the G2 shares together produces the // master public key (MasterPublicKey). - KeyShareG2s [4]*big.Int `json:"keyShareG2s"` + KeyShareG2s [4]*big.Int // GPKj is the local Validator's portion of the master public key. // This is also denoted GroupPublicKey. - GPKj [4]*big.Int `json:"gpkj"` + GPKj [4]*big.Int } // ParticipantList is a required type alias since the Sort interface is awful @@ -304,8 +307,3 @@ func (pl ParticipantList) Less(i, j int) bool { func (pl ParticipantList) Swap(i, j int) { pl[i], pl[j] = pl[j], pl[i] } - -type ETHDKGTaskData struct { - PersistStateCB func() - State *DkgState -} diff --git a/blockchain/objects/dkg_state_test.go b/blockchain/objects/dkg_state_test.go index 1ba4b2e0..0c871a01 100644 --- a/blockchain/objects/dkg_state_test.go +++ b/blockchain/objects/dkg_state_test.go @@ -128,7 +128,7 @@ func TestMarshalAndUnmarshalParticipant(t *testing.T) { Index: 1, PublicKey: pub, Nonce: 1, - Phase: objects.RegistrationOpen, + Phase: 0, } // marshal diff --git a/blockchain/objects/scheduler.go b/blockchain/objects/scheduler.go index 9c346400..12f24921 100644 --- a/blockchain/objects/scheduler.go +++ b/blockchain/objects/scheduler.go @@ -3,7 +3,6 @@ package objects import ( "encoding/json" "errors" - "fmt" "reflect" "github.com/MadBase/MadNet/blockchain/interfaces" @@ -18,10 +17,9 @@ var ( ) type Block struct { - Start uint64 `json:"start"` - End uint64 `json:"end"` - Task interfaces.Task `json:"-"` - IsRunning bool `json:"isRunning"` + Start uint64 `json:"start"` + End uint64 `json:"end"` + Task interfaces.Task `json:"-"` } type innerBlock struct { @@ -78,25 +76,6 @@ func (s *SequentialSchedule) PurgePrior(now uint64) { } } -func (s *SequentialSchedule) SetRunning(taskId uuid.UUID, running bool) error { - block, present := s.Ranges[taskId.String()] - if !present { - return ErrNotScheduled - } - - block.IsRunning = running - return nil -} - -func (s *SequentialSchedule) IsRunning(taskId uuid.UUID) (bool, error) { - block, present := s.Ranges[taskId.String()] - if !present { - return false, ErrNotScheduled - } - - return block.IsRunning, nil -} - func (s *SequentialSchedule) Find(now uint64) (uuid.UUID, error) { for taskId, block := range s.Ranges { @@ -147,7 +126,6 @@ func (ss *SequentialSchedule) MarshalJSON() ([]byte, error) { for k, v := range ss.Ranges { wt, err := ss.marshaller.WrapInstance(v.Task) if err != nil { - fmt.Printf("error marshalling wrapinstance1: %v", err) return []byte{}, err } ws.Ranges[k] = &innerBlock{Start: v.Start, End: v.End, WrappedTask: wt} @@ -155,7 +133,6 @@ func (ss *SequentialSchedule) MarshalJSON() ([]byte, error) { raw, err := json.Marshal(&ws) if err != nil { - fmt.Printf("error marshalling wrapinstance2: %v", err) return []byte{}, err } diff --git a/blockchain/objects/state.go b/blockchain/objects/state.go index d08cde84..7ec63bcb 100644 --- a/blockchain/objects/state.go +++ b/blockchain/objects/state.go @@ -108,8 +108,6 @@ func (s *MonitorState) Clone() *MonitorState { ns.LatestDepositSeen = s.LatestDepositSeen ns.PeerCount = s.PeerCount - // todo: clone DkgState - return ns } @@ -173,7 +171,5 @@ func (s *MonitorState) Diff(o *MonitorState) (string, bool) { d = append(d, fmt.Sprintf("LatestDepositSeen: %v -> %v", s.LatestDepositSeen, o.LatestDepositSeen)) } - // todo: check DkgState diff - return strings.Join(d, ", "), shouldWrite } diff --git a/docker/generate-bridge/Dockerfile b/docker/generate-bridge/Dockerfile index 08538716..3dc5409f 100644 --- a/docker/generate-bridge/Dockerfile +++ b/docker/generate-bridge/Dockerfile @@ -1,7 +1,7 @@ # golang helper image used just to compile binaries from go source FROM golang:1.17.6-alpine3.15 AS go_deps RUN apk add --no-cache linux-headers=5.10.41-r0 build-base=0.5-r2 -RUN go install github.com/ethereum/go-ethereum/cmd/abigen@v1.10.16 +RUN go install github.com/ethereum/go-ethereum/cmd/abigen@v1.10.8 # final node image containing binaries compiled by helper image FROM node:16.14.0-alpine3.15 @@ -22,4 +22,4 @@ ADD --chown=$BUILDER_UID bridge/package.json bridge/package-lock.json /app/ RUN npm ci COPY --from=go_deps /go/bin/ /usr/local/bin/ -CMD npm run build \ No newline at end of file +CMD npm run build diff --git a/scripts/main.sh b/scripts/main.sh index a1b934fa..48d81fb3 100755 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -36,7 +36,6 @@ CLEAN_UP () { # Init mkdir ./scripts/generated mkdir ./scripts/generated/stateDBs - mkdir ./scripts/generated/monitorDBs mkdir ./scripts/generated/config mkdir ./scripts/generated/keystores mkdir ./scripts/generated/keystores/keys @@ -75,7 +74,6 @@ CREATE_CONFIGS () { sed -e 's/passcodes = .*/passcodes = \"scripts\/generated\/keystores\/passcodes.txt\"/' | sed -e 's/keystore = .*/keystore = \"scripts\/generated\/keystores\/keys\"/' | sed -e 's/stateDB = .*/stateDB = \"scripts\/generated\/stateDBs\/validator'"$l"'\/\"/' | - sed -e 's/monitorDB = .*/monitorDB = \"scripts\/generated\/monitorDBs\/validator'"$l"'\/\"/' | sed -e 's/privateKey = .*/privateKey = \"'"$PK"'\"/' > ./scripts/generated/config/validator$l.toml echo "$ADDRESS=abc123" >> ./scripts/generated/keystores/passcodes.txt mv ./keyfile.json ./scripts/generated/keystores/keys/$ADDRESS