@ -3,7 +3,8 @@ package chain
import (
import (
"math/big"
"math/big"
"sort"
"sort"
"sync"
"github.com/harmony-one/harmony/shard/committee"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rlp"
@ -220,90 +221,71 @@ func AccumulateRewards(
return err
return err
}
}
w := sync . WaitGroup { }
type slotPayable struct {
type slotPayable struct {
effective numeric . Dec
effective numeric . Dec
payee common . Address
payee common . Address
bucket int
bucket int
index int
index int
oops error
}
}
payable := make ( chan slotPayable )
allPayables := [ ] slotPayable { }
slotError := func ( err error , receive chan slotPayable ) {
s := slotPayable { }
s . oops = err
go func ( ) {
receive <- s
} ( )
}
for i := range crossLinks {
for i := range crossLinks {
w . Add ( 1 )
go func ( i int ) {
defer w . Done ( )
cxLink := crossLinks [ i ]
subCommittee := shard . State { }
if err := rlp . DecodeBytes (
cxLink . ChainHeader . ShardState ( ) , & subCommittee ,
) ; err != nil {
slotError ( err , payable )
return
}
subComm := subCommittee . FindCommitteeByID ( cxLink . ShardID ( ) )
cxLink := crossLinks [ i ]
// _ are the missing signers, later for slashing
payableSigners , _ , err := blockSigners ( cxLink . Header ( ) , subComm )
votingPower := votepower . Compute ( subComm . Slots )
if err != nil {
shardState , err := bc . ReadShardState ( cxLink . ChainHeader . Epoch ( ) )
slotError ( err , payable )
if ! bc . Config ( ) . IsStaking ( cxLink . Header ( ) . Epoch ( ) ) {
return
shardState , err = committee . WithStakingEnabled . Compute ( cxLink . ChainHeader . Epoch ( ) , bc )
}
}
if err != nil {
// TEMP HACK: IGNORE THE ERROR as THERE IS NO WAY TO VERIFY THE SIG OF FIRST BLOCK OF SHARD FIRST TIME ENTERING STAKING, NO WAY TO FIND THE LAST COMMITEE AS THERE IS GAP
// TODO: FIX THIS WITH NEW CROSSLINK FORMAT
continue
}
for member := range payableSigners {
subComm := shardState . FindCommitteeByID ( cxLink . ShardID ( ) )
voter := votingPower . Voters [ payableSigners [ member ] . BlsPublicKey ]
// _ are the missing signers, later for slashing
if ! voter . IsHarmonyNode {
payableSigners , _ , err := blockSigners ( cxLink . Header ( ) , subComm )
due := defaultReward . Mul (
voter . EffectivePercent . Quo ( votepower . StakersShare ) ,
if err != nil {
)
// TEMP HACK: IGNORE THE ERROR as THERE IS NO WAY TO VERIFY THE SIG OF FIRST BLOCK OF SHARD FIRST TIME ENTERING STAKING, NO WAY TO FIND THE LAST COMMITEE AS THERE IS GAP
to := voter . EarningAccount
// TODO: FIX THIS WITH NEW CROSSLINK FORMAT
go func ( signersDue numeric . Dec , addr common . Address , j int ) {
continue
payable <- slotPayable {
}
effective : signersDue ,
payee : addr ,
votingPower := votepower . Compute ( payableSigners )
bucket : i ,
for j := range payableSigners {
index : j ,
voter := votingPower . Voters [ payableSigners [ j ] . BlsPublicKey ]
oops : nil ,
if ! voter . IsHarmonyNode && ! voter . EffectivePercent . IsZero ( ) {
}
due := defaultReward . Mul (
} ( due , to , member )
voter . EffectivePercent . Quo ( votepower . StakersShare ) ,
}
)
to := voter . EarningAccount
allPayables = append ( allPayables , slotPayable {
effective : due ,
payee : to ,
bucket : i ,
index : j ,
} )
}
}
} ( i )
}
}
}
w . Wait ( )
resultsHandle := make ( [ ] [ ] slotPayable , len ( crossLinks ) )
resultsHandle := make ( [ ] [ ] slotPayable , len ( crossLinks ) )
for i := range resultsHandle {
for i := range resultsHandle {
resultsHandle [ i ] = [ ] slotPayable { }
resultsHandle [ i ] = [ ] slotPayable { }
}
}
for payThem := range payable {
for _ , payThem := range allPayables {
bucket := payThem . bucket
bucket := payThem . bucket
resultsHandle [ bucket ] = append ( resultsHandle [ bucket ] , payThem )
resultsHandle [ bucket ] = append ( resultsHandle [ bucket ] , payThem )
}
}
// Check if any errors and sort each bucket to enforce order
// Check if any errors and sort each bucket to enforce order
for bucket := range resultsHandle {
for bucket := range resultsHandle {
for payThem := range resultsHandle [ bucket ] {
if err := resultsHandle [ bucket ] [ payThem ] . oops ; err != nil {
return err
}
}
sort . SliceStable ( resultsHandle [ bucket ] ,
sort . SliceStable ( resultsHandle [ bucket ] ,
func ( i , j int ) bool {
func ( i , j int ) bool {
return resultsHandle [ bucket ] [ i ] . index < resultsHandle [ bucket ] [ j ] . index
return resultsHandle [ bucket ] [ i ] . index < resultsHandle [ bucket ] [ j ] . index