mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-26 13:18:57 +00:00
263 lines
7.2 KiB
Go
263 lines
7.2 KiB
Go
package casper
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/params"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/utils"
|
|
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
|
b "github.com/prysmaticlabs/prysm/shared/bytes"
|
|
)
|
|
|
|
func TestTallyVoteBalances(t *testing.T) {
|
|
|
|
var validators []*pb.ValidatorRecord
|
|
var blockHash [32]byte
|
|
|
|
blockVoteCache := utils.NewBlockVoteCache()
|
|
initialBalance := uint64(1e9)
|
|
for i := 0; i < 1000; i++ {
|
|
validator := &pb.ValidatorRecord{
|
|
WithdrawalShard: 0,
|
|
Balance: initialBalance}
|
|
|
|
validators = append(validators, validator)
|
|
}
|
|
|
|
validators[20].Status = uint64(params.Active)
|
|
validators[10].Status = uint64(params.Active)
|
|
|
|
blockVote := &utils.BlockVote{
|
|
VoterIndices: []uint32{20, 10},
|
|
VoteTotalDeposit: 300,
|
|
}
|
|
copy(blockHash[:], []byte{'t', 'e', 's', 't', 'i', 'n', 'g'})
|
|
|
|
blockVoteCache[blockHash] = blockVote
|
|
|
|
zeroBalance, _ := TallyVoteBalances([32]byte{}, 10, blockVoteCache, validators, 2)
|
|
|
|
if zeroBalance != 0 {
|
|
t.Fatalf("votes have been calculated despite blockhash not existing in cache")
|
|
}
|
|
|
|
voteBalance, newValidators := TallyVoteBalances(blockHash, 10, blockVoteCache, validators, 2)
|
|
if voteBalance != 300 {
|
|
t.Fatalf("vote balances is not the amount expected %d", voteBalance)
|
|
}
|
|
|
|
if newValidators[1].Balance != initialBalance {
|
|
t.Fatalf("validator balance changed %d ", newValidators[1].Balance)
|
|
}
|
|
|
|
if newValidators[20].Balance == initialBalance {
|
|
t.Fatalf("validator balance not changed %d ", newValidators[20].Balance)
|
|
}
|
|
|
|
if newValidators[10].Balance == initialBalance {
|
|
t.Errorf("validator balance not changed %d ", newValidators[10].Balance)
|
|
}
|
|
}
|
|
|
|
func TestFinalizeAndJustifySlots(t *testing.T) {
|
|
slot := uint64(10)
|
|
justifiedSlot := uint64(8)
|
|
finalizedSlot := uint64(6)
|
|
justifiedStreak := uint64(2)
|
|
blockVoteBalance := uint64(2e9)
|
|
totalDeposit := uint64(4e9)
|
|
|
|
justifiedSlot, finalizedSlot, justifiedStreak = FinalizeAndJustifySlots(slot, justifiedSlot, finalizedSlot,
|
|
justifiedStreak, blockVoteBalance, totalDeposit)
|
|
|
|
if justifiedSlot != 8 {
|
|
t.Fatalf("justified slot has been updated %d", justifiedSlot)
|
|
}
|
|
|
|
if justifiedStreak != 0 {
|
|
t.Fatalf("justified streak not updated %d", justifiedStreak)
|
|
}
|
|
|
|
if finalizedSlot != 6 {
|
|
t.Fatalf("finalized slot changed when it was not supposed to %d", finalizedSlot)
|
|
}
|
|
|
|
blockVoteBalance = uint64(3e9)
|
|
|
|
justifiedSlot, finalizedSlot, justifiedStreak = FinalizeAndJustifySlots(slot, justifiedSlot, finalizedSlot,
|
|
justifiedStreak, blockVoteBalance, totalDeposit)
|
|
|
|
if justifiedSlot != 10 {
|
|
t.Fatalf("justified slot has not been updated %d", justifiedSlot)
|
|
}
|
|
|
|
if justifiedStreak != 1 {
|
|
t.Fatalf("justified streak not updated %d", justifiedStreak)
|
|
}
|
|
|
|
if finalizedSlot != 6 {
|
|
t.Fatalf("finalized slot changed when it was not supposed to %d", finalizedSlot)
|
|
}
|
|
|
|
slot = 100
|
|
justifiedStreak = 70
|
|
|
|
justifiedSlot, finalizedSlot, justifiedStreak = FinalizeAndJustifySlots(slot, justifiedSlot, finalizedSlot,
|
|
justifiedStreak, blockVoteBalance, totalDeposit)
|
|
|
|
if justifiedSlot != 100 {
|
|
t.Fatalf("justified slot has not been updated %d", justifiedSlot)
|
|
}
|
|
|
|
if justifiedStreak != 71 {
|
|
t.Fatalf("justified streak not updated %d", justifiedStreak)
|
|
}
|
|
|
|
if finalizedSlot == 6 {
|
|
t.Fatalf("finalized slot not updated when it was supposed to %d", finalizedSlot)
|
|
}
|
|
|
|
}
|
|
|
|
func TestApplyCrosslinkRewardsAndPenalties(t *testing.T) {
|
|
var validators []*pb.ValidatorRecord
|
|
initialBalance := uint64(1e9)
|
|
totalBalance := uint64(5e9)
|
|
voteBalance := uint64(4e9)
|
|
indices := []uint32{20, 10}
|
|
|
|
for i := 0; i < 1000; i++ {
|
|
validator := &pb.ValidatorRecord{
|
|
WithdrawalShard: 0,
|
|
Balance: initialBalance}
|
|
|
|
validators = append(validators, validator)
|
|
}
|
|
|
|
validators[20].Status = uint64(params.Active)
|
|
validators[10].Status = uint64(params.Active)
|
|
|
|
crossLinks := []*pb.CrosslinkRecord{
|
|
{
|
|
RecentlyChanged: false,
|
|
ShardBlockHash: []byte{'A'},
|
|
Slot: 10,
|
|
},
|
|
{
|
|
RecentlyChanged: false,
|
|
ShardBlockHash: []byte{'B'},
|
|
Slot: 10,
|
|
},
|
|
{
|
|
RecentlyChanged: false,
|
|
ShardBlockHash: []byte{'C'},
|
|
Slot: 10,
|
|
},
|
|
{
|
|
RecentlyChanged: false,
|
|
ShardBlockHash: []byte{'D'},
|
|
Slot: 10,
|
|
},
|
|
}
|
|
|
|
attestation := &pb.AggregatedAttestation{
|
|
Slot: 10,
|
|
Shard: 1,
|
|
AttesterBitfield: []byte{100, 128, 8},
|
|
}
|
|
|
|
ApplyCrosslinkRewardsAndPenalties(crossLinks, 12, indices, attestation, validators, totalBalance, voteBalance)
|
|
|
|
if validators[20].Balance <= initialBalance {
|
|
t.Fatalf("validator balance has not been updated %d", validators[20].Balance)
|
|
}
|
|
|
|
if validators[10].Balance >= initialBalance {
|
|
t.Fatalf("validator balance has not been updated %d", validators[10].Balance)
|
|
}
|
|
|
|
if validators[1].Balance != initialBalance {
|
|
t.Fatalf("validator balance updated when it was not supposed to %d", validators[1].Balance)
|
|
}
|
|
|
|
}
|
|
|
|
func TestCrosslinks(t *testing.T) {
|
|
totalBalance := uint64(5e9)
|
|
voteBalance := uint64(4e9)
|
|
|
|
crossLinks := []*pb.CrosslinkRecord{
|
|
{
|
|
RecentlyChanged: false,
|
|
ShardBlockHash: []byte{'A'},
|
|
Slot: 10,
|
|
},
|
|
{
|
|
RecentlyChanged: true,
|
|
ShardBlockHash: []byte{'A'},
|
|
Slot: 10,
|
|
},
|
|
}
|
|
|
|
attestation := &pb.AggregatedAttestation{
|
|
Slot: 10,
|
|
Shard: 1,
|
|
ShardBlockHash: []byte{'B'},
|
|
AttesterBitfield: []byte{100, 128, 8},
|
|
}
|
|
|
|
crossLinks = ProcessCrosslink(10, voteBalance, totalBalance, attestation, crossLinks)
|
|
|
|
if bytes.Equal(crossLinks[1].GetShardBlockHash(), []byte{'B'}) {
|
|
t.Fatal("crosslink updated when it was not supposed to")
|
|
}
|
|
|
|
crossLinks[1].RecentlyChanged = false
|
|
|
|
crossLinks = ProcessCrosslink(10, voteBalance, totalBalance, attestation, crossLinks)
|
|
|
|
if !bytes.Equal(crossLinks[1].GetShardBlockHash(), []byte{'B'}) {
|
|
t.Errorf("shard blockhash not saved in crosslink record %v", crossLinks[1].GetShardBlockHash())
|
|
}
|
|
|
|
}
|
|
|
|
func TestProcessSpecialRecords(t *testing.T) {
|
|
|
|
specialRecords := []*pb.SpecialRecord{
|
|
{Kind: uint32(params.Logout), Data: [][]byte{b.Bytes8(4)}}, // Validator 4
|
|
{Kind: uint32(params.Logout), Data: [][]byte{b.Bytes8(5)}}, // Validator 5
|
|
{Kind: uint32(params.RandaoChange), Data: [][]byte{b.Bytes8(6), {byte('A')}}}, // Validator 6
|
|
{Kind: uint32(params.RandaoChange), Data: [][]byte{b.Bytes8(7), {byte('B')}}}, // Validator 7
|
|
}
|
|
|
|
validators := make([]*pb.ValidatorRecord, 10)
|
|
for i := 0; i < len(validators); i++ {
|
|
validators[i] = &pb.ValidatorRecord{Status: uint64(params.Active)}
|
|
}
|
|
|
|
newValidators, err := ProcessSpecialRecords(99, validators, specialRecords)
|
|
if err != nil {
|
|
t.Fatalf("Failed to call process special records %v", err)
|
|
}
|
|
if newValidators[4].Status != uint64(params.PendingExit) {
|
|
t.Error("Validator 4 status is not PendingExit")
|
|
}
|
|
if newValidators[4].ExitSlot != 99 {
|
|
t.Error("Validator 4 exit slot is not 99")
|
|
}
|
|
if newValidators[5].Status != uint64(params.PendingExit) {
|
|
t.Error("Validator 5 status is not PendingExit")
|
|
}
|
|
if newValidators[5].ExitSlot != 99 {
|
|
t.Error("Validator 5 exit slot is not 99")
|
|
}
|
|
if !(bytes.Equal(newValidators[6].RandaoCommitment, []byte{'A'})) {
|
|
t.Error("Failed to set validator 7's randao reveal")
|
|
}
|
|
if !(bytes.Equal(newValidators[7].RandaoCommitment, []byte{'B'})) {
|
|
t.Error("Failed to set validator 8's randao reveal")
|
|
}
|
|
}
|