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

Fix distribution with RewardBase #3086

Merged
merged 32 commits into from
Dec 15, 2024
Merged

Fix distribution with RewardBase #3086

merged 32 commits into from
Dec 15, 2024

Conversation

OnedgeLee
Copy link
Contributor

@OnedgeLee OnedgeLee commented Dec 12, 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의 보상정보가 아래쪽 인덱스에 더해져야 하는 것이 아니라 위쪽 인덱스에 더해져야 하는 것을 의미함

Related PRs

s2quake and others added 28 commits December 12, 2024 22:11
Copy link

cloudflare-workers-and-pages bot commented Dec 12, 2024

Deploying lib9c with  Cloudflare Pages  Cloudflare Pages

Latest commit: 86b8103
Status: ✅  Deploy successful!
Preview URL: https://f3f9347a.lib9c.pages.dev
Branch Preview URL: https://fix-distribution.lib9c.pages.dev

View logs

@OnedgeLee OnedgeLee marked this pull request as ready for review December 12, 2024 13:12
@OnedgeLee OnedgeLee changed the title Fix/distribution Fix distribution with RewardBase Dec 12, 2024
@OnedgeLee OnedgeLee self-assigned this Dec 12, 2024
@OnedgeLee
Copy link
Contributor Author

lint / check-items-without-docs-increased (pull_request)
요 액션은 무엇을 체크해서 터지는건지 잘 모르겠네요. 알려주시면 반영해서 고치겠습니다.

@eugene-doobu
Copy link
Member

eugene-doobu commented Dec 13, 2024

@OnedgeLee 새로 추가된 public 요소들에 xml 주석 첨부가 필요합니다
현재 pr에서 31개의 추가 xml주석 관련 요소가 필요한 것으로 보입니다
정확한 기준은 아래 두 문서에 대한 경고 내용입니다

  env:
    BASE_COUNT: 9197
    HEAD_COUNT: 9228

https://learn.microsoft.com/ko-kr/dotnet/csharp/misc/cs1573
https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/compiler-messages/cs1591

@OnedgeLee
Copy link
Contributor Author

사실 PoS관련 클래스들에 도큐먼트 제대로 안붙은 부분이 많은데, 연말에 찬찬히 채워넣겠습니다. 일단은 신규 변경건에 대해서만 추가하였습니다.

Copy link
Member

@ipdae ipdae left a comment

Choose a reason for hiding this comment

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

PR크기가 커서 설명을 봐도 컨텍스트를 따라가기가 쉽지않네요. 제 어프루브보다는 @riemannulus 님의 승인을 받고 머지하시는게 좋을것같습니다.

Lib9c/Delegation/Delegatee.cs Show resolved Hide resolved
@OnedgeLee OnedgeLee merged commit 702c387 into release/1.21.0 Dec 15, 2024
26 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.

5 participants