Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce RewardBase #3065

Merged
merged 20 commits into from
Dec 12, 2024

Conversation

OnedgeLee
Copy link
Contributor

@OnedgeLee OnedgeLee commented Dec 4, 2024

AS-IS

LumpSumRewardsRecord를 통한 보상 분배

  • RewardPeriod마다, 1개의 LumpSumRewardsRecord를 유지, 해당 객체는 RewardPeriod동안 수집한 보상량 및 총 지분량을 저장
  • RewardPeriod는 지분량의 변화가 발생할 때 및 보상수령이 발생할 때마다 생성
  • 보상을 분배하게 될 때, 이전에 마지막으로 보상을 수령한 블록높이의 LumpSumRewardsRecord부터, 현재의 LumpSumRewardRecord까지를 순회하며, 보상분배대상의 지분량을 곱하고, LumpSumRewardRecord에 저장된 총 지분량으로 나누어 구한 해당 RewardPeriod의 보상량을 분배대상자에게 분배
  • 오딘 기준, 해당 순회량이 수천건에 해당하여, 액션이 지나치게 느려짐

TO-BE

RewardBase를 통한 보상 분배

  • RewardPeriod마다, 1개의 RewardBase를 유지, 해당 객체는 RewardPeriod동안 수집한 보상량 / 총 지분량(multiplier)의 누적치 및 유효숫자를 저장
  • RewardPeriod는 지분량의 변화가 발생할 때 및 보상수령이 발생할 때마다 생성
  • 보상을 분배하게 될 때, 현재의 RewardBase의 multiplier와 분배대상자의 지분을 곱한 값에서, 마지막으로 보상을 수령한 블록높이 RewardBase의 multiplier와 분배대상자의 지분을 곱한 값을 빼 줘, 기간동안의 총 보상량을 구하고, 이 값을 분배대상자에게 분배
  • 분배시 항상 두 건만 참조하면 되기에, 위의 순회에 따른 문제를 해결할 수 있음

TEST

  • 기존의 보상 테스트에서 기존과 똑같이 작동할 경우, 변경된 방식을 신뢰할 수 있음
  • 기존의 방식으로부터 현재 방식으로 마이그레이션하는 테스트를 통하여, 마이그레이션의 정합성을 신뢰할 수 있음

중점리뷰대상

  • RewardBase.cs
    • 신규 클래스
    • 기능 : 적절한 유효숫자를 유지하며, Portion += Reward/TotalShare를 수행, 저장
    • 테스트를 통하여, 기본동작에 큰 문제가 없음은 이미 확인됨, 유효숫자를 산출하는 방식에 있어, 신뢰할 만 하고 적절한지에 대한 리뷰 필요
    • StartHeight가 없을 경우, 아직 기록으로 활용되지 않는 CurrentRewardBase임을 의미함
  • Delegatee.cs
    • 기본적으로, 보상 관련 모든 로직에서 CurrentRewardBase가 존재하는지 여부를 플래그로, 존재할 경우 변경된 로직(RewardBase)을 타고, 존재하지 않을 경우 기존의 로직(LumpSumRewardsRecord)을 탐
    • Delegatee.DistributeReward()CurrentRewardBase와 이전에 마지막으로 보상수령자가 보상받은 높이에 존재하는 RewardBase를 수집, 이 두 값을 통해 Delegatee.TransferReward()를 이용하여 보상을 분배, 이 방식은 위에 설명되었듯, 보상 수령자의 지분량을 Portion정보에 곱한 뒤, 차분값을 얻는 방식
    • Delegatee.CollectReward()CurrentRewardBase에 값을 누적
    • Delegatee.StartNewRewardPeriod()AttachHeight()를 통하여 StartHeight를 부여하고 아카이빙, 그리고 이전의 RewardBase에 총 지분량을 업데이트하여 새로운 CurrentRewardBase를 생성
    • Delegatee.StartNewRewardPeriod()MigrateLumpSumRewardsRecords()를 통하여, 만약 CurrentLumpSumRewardsRecord가 존재할 경우, 이전의 모든 LumpSumRewardsRecord들을 수집하여, RewardBase로 마이그레이션 수행, 이 마이그레이션은 CurrentLumpSumRewardsRecord를 상태에서 제거하기 때문에, 단 한번만 수행됨
    • Delegatee.MigrateLumpSumRewardsRecords()LumpSumRewardRecord를 전부 가져온 뒤, 맨 아래에서부터 이터레이션을 돌며 RewardBase로 변환, 이 때, StartHeight가 한칸씩 뒤로 밀려야 함에 주의
      • 예) 기존 StartHeight = 5였던 LumpSumRewardsRecord와, StartHeight = 10LumpSumRewardsRecord가 순차적으로 존재한다고 가정할 경우, 전자는 StartHeight = 10RewardBase로 마이그레이션되어야 하며, 후자는 StartHeight = nullCurrentRewardBase로 마이그레이션되어야 함, 후자가 StartHeight를 가지게 되는 시점은 다음 CurrentRewardBase가 발견된 시점임
      • RewardBaseStartHeight를 선태깅할 경우, 정상적으로 작동할 수 없음, 이를테면 Height = 5StartHeight = 5RewardBase를 만든다고 가정할 경우, 이후 누적되는 보상정보들이 StartHeight = 5RewardBase에 쌓일 것, 이는 (StartHeight = 10 RewardBase) - (StartHeight = 5 RewardBase)로 계산이 불가능하게 만들기 때문에, 항상 CurrentRewardBase를 만들어, 여기에 차분값을 쌓도록 구현되었고, 이는 기존 LumpSumRewardRecord의 보상정보가 아래쪽 인덱스에 더해져야 하는 것이 아니라 위쪽 인덱스에 더해져야 하는 것을 의미함
    • 각 로직이 도는 타이밍의 정합성에 대한 리뷰 필요

@OnedgeLee OnedgeLee self-assigned this Dec 4, 2024
@OnedgeLee OnedgeLee force-pushed the feature/reward-base branch from 40eca7c to d80cf7a Compare December 4, 2024 16:31
@OnedgeLee OnedgeLee force-pushed the feature/reward-base branch 2 times, most recently from 7751e9e to 13c2fd0 Compare December 4, 2024 16:35
@OnedgeLee OnedgeLee marked this pull request as ready for review December 10, 2024 18:10
Lib9c/Delegation/RewardBase.cs Outdated Show resolved Hide resolved
Comment on lines +551 to +554
if (Repository.GetRewardBase(this, recordEach.StartHeight) is not null)
{
Repository.SetRewardBase(newRewardBase);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, is this migration running at the end of blocks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this migration is run on the delegation.
(Will be held on the Stake action)
So, I expect two staking take place for proper migration.

@OnedgeLee OnedgeLee requested a review from s2quake December 12, 2024 12:50
@OnedgeLee OnedgeLee merged commit eef7e54 into planetarium:fix/distribution Dec 12, 2024
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants