diff --git a/interchain/witness/interface.go b/interchain/witness/interface.go index 0e7134c..4ac8292 100644 --- a/interchain/witness/interface.go +++ b/interchain/witness/interface.go @@ -14,5 +14,6 @@ type ChainWitness interface { Wait() GetMainchainBlockHeight() (*big.Int, error) GetValidatorSetByDynasty(dynasty *big.Int) (*score.ValidatorSet, error) + GetSubchainRegistrationHeight() (*big.Int, error) GetInterChainEventCache() *siu.InterChainEventCache } diff --git a/interchain/witness/metachain_witness.go b/interchain/witness/metachain_witness.go index 44c3015..35f9cff 100644 --- a/interchain/witness/metachain_witness.go +++ b/interchain/witness/metachain_witness.go @@ -574,36 +574,38 @@ func (mw *MetachainWitness) updateValidatorSetCache(dynasty *big.Int) (*score.Va // queryBlockHeight = big.NewInt(0).Add(queryBlockHeight, big.NewInt(1)) // increment by one to make sure the query block height falls into the dynasty // vs, err := mw.chainRegistrarOnMainchain.GetValidatorSet(nil, mw.subchainID, queryBlockHeight) - adjustedDynasty := dynasty - registrationMainchainHeight, ok, err := mw.chainRegistrarOnMainchain.GetSubchainRegistrationHeight(nil, mw.subchainID) - if !ok { - errMsg := fmt.Sprintf("subchain with ID %v does not exist", mw.subchainID) - logger.Warnf("updateValidatorSetCache: %v", errMsg) - return nil, fmt.Errorf(errMsg) - } - - if err != nil { - logger.Warnf("updateValidatorSetCache: %v", err) - return nil, err - } - - registrationDynasty := scom.CalculateDynasty(registrationMainchainHeight) - if adjustedDynasty.Cmp(registrationDynasty) == 0 { - // Special handling for the initial dynasty query on the **Mainchain**: - // The initial set of validators hardcoded in the genesis snapshot should be - // in charge during the initial dyansty. However, if we directly query the - // initial dynasty, we would obtain an empty set since the validators registered - // on the mainchain takes charge only when the next dynasty begins. Hence, for - // the initial dyansty, we query the next dynasty instead, which should return - // a validator set that matches with the validator set hardcoded in the - // genesis snapshot. - adjustedDynasty = big.NewInt(0).Add(adjustedDynasty, big.NewInt(1)) - - logger.Debugf("Subchain %v registration main chain height: %v, registration dynasty: %v, dynasty: %v, adjustedDynasty: %v", - mw.subchainID, registrationMainchainHeight, registrationDynasty, dynasty, adjustedDynasty) - } - - vs, err := mw.chainRegistrarOnMainchain.GetValidatorSet(nil, mw.subchainID, adjustedDynasty) + // adjustedDynasty := dynasty + // registrationMainchainHeight, ok, err := mw.chainRegistrarOnMainchain.GetSubchainRegistrationHeight(nil, mw.subchainID) + // if !ok { + // errMsg := fmt.Sprintf("subchain with ID %v does not exist", mw.subchainID) + // logger.Warnf("updateValidatorSetCache: %v", errMsg) + // return nil, fmt.Errorf(errMsg) + // } + + // if err != nil { + // logger.Warnf("updateValidatorSetCache: %v", err) + // return nil, err + // } + + // registrationDynasty := scom.CalculateDynasty(registrationMainchainHeight) + // if adjustedDynasty.Cmp(registrationDynasty) == 0 { + // // Special handling for the initial dynasty query on the **Mainchain**: + // // The initial set of validators hardcoded in the genesis snapshot should be + // // in charge during the initial dyansty. However, if we directly query the + // // initial dynasty, we would obtain an empty set since the validators registered + // // on the mainchain takes charge only when the next dynasty begins. Hence, for + // // the initial dyansty, we query the next dynasty instead, which should return + // // a validator set that matches with the validator set hardcoded in the + // // genesis snapshot. + // adjustedDynasty = big.NewInt(0).Add(adjustedDynasty, big.NewInt(1)) + + // logger.Debugf("Subchain %v registration main chain height: %v, registration dynasty: %v, dynasty: %v, adjustedDynasty: %v", + // mw.subchainID, registrationMainchainHeight, registrationDynasty, dynasty, adjustedDynasty) + // } + + // vs, err := mw.chainRegistrarOnMainchain.GetValidatorSet(nil, mw.subchainID, adjustedDynasty) + + vs, err := mw.chainRegistrarOnMainchain.GetValidatorSet(nil, mw.subchainID, dynasty) validatorAddrs := vs.Validators validatorStakes := vs.ShareAmounts @@ -631,3 +633,19 @@ func (mw *MetachainWitness) updateValidatorSetCache(dynasty *big.Int) (*score.Va func (mw *MetachainWitness) GetInterChainEventCache() *siu.InterChainEventCache { return mw.interChainEventCache } + +func (mw *MetachainWitness) GetSubchainRegistrationHeight() (*big.Int, error) { + registrationMainchainHeight, ok, err := mw.chainRegistrarOnMainchain.GetSubchainRegistrationHeight(nil, mw.subchainID) + if !ok { + errMsg := fmt.Sprintf("subchain with ID %v does not exist", mw.subchainID) + logger.Warnf("GetSubchainRegistrationHeight: %v", errMsg) + return nil, fmt.Errorf(errMsg) + } + + if err != nil { + logger.Warnf("GetSubchainRegistrationHeight: %v", err) + return nil, err + } + + return registrationMainchainHeight, nil +} diff --git a/ledger/ledger.go b/ledger/ledger.go index fb1ae2a..466c608 100644 --- a/ledger/ledger.go +++ b/ledger/ledger.go @@ -666,6 +666,19 @@ func (ledger *Ledger) getNewDynastyAndValidatorSet(view *slst.StoreView) (enteri return false, nil, nil } + registrationMainchainHeight, err := ledger.metachainWitness.GetSubchainRegistrationHeight() + if err != nil { + logger.Warnf("Failed to get subchain registration height: %v", err) + return false, nil, nil + } + + registrationDynasty := scom.CalculateDynasty(registrationMainchainHeight) + if currentDynasty.Cmp(registrationDynasty) == 0 { + // For the initial dynasty, i.e. the dynasty during which the subchain was registered, instead of querying + // the validator set from the main chain, we trust the validator set in the snapshot + return false, nil, nil + } + witnessedDynasty := scom.CalculateDynasty(mainchainBlockHeight) witnessedValidatorSet, err := ledger.metachainWitness.GetValidatorSetByDynasty(witnessedDynasty) if err != nil {