-
Notifications
You must be signed in to change notification settings - Fork 5
/
helpers.go
134 lines (122 loc) · 4.42 KB
/
helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package util
import (
"context"
"encoding/binary"
"testing"
"github.com/pkg/errors"
"github.com/theQRL/qrysm/v4/beacon-chain/core/helpers"
"github.com/theQRL/qrysm/v4/beacon-chain/core/signing"
"github.com/theQRL/qrysm/v4/beacon-chain/core/time"
"github.com/theQRL/qrysm/v4/beacon-chain/core/transition"
"github.com/theQRL/qrysm/v4/beacon-chain/state"
"github.com/theQRL/qrysm/v4/config/params"
"github.com/theQRL/qrysm/v4/consensus-types/blocks"
"github.com/theQRL/qrysm/v4/consensus-types/interfaces"
"github.com/theQRL/qrysm/v4/consensus-types/primitives"
"github.com/theQRL/qrysm/v4/crypto/bls"
"github.com/theQRL/qrysm/v4/crypto/rand"
zondpb "github.com/theQRL/qrysm/v4/proto/prysm/v1alpha1"
)
// RandaoReveal returns a signature of the requested epoch using the beacon proposer private key.
func RandaoReveal(beaconState state.ReadOnlyBeaconState, epoch primitives.Epoch, privKeys []bls.SecretKey) ([]byte, error) {
// We fetch the proposer's index as that is whom the RANDAO will be verified against.
proposerIdx, err := helpers.BeaconProposerIndex(context.Background(), beaconState)
if err != nil {
return []byte{}, errors.Wrap(err, "could not get beacon proposer index")
}
buf := make([]byte, 32)
binary.LittleEndian.PutUint64(buf, uint64(epoch))
// We make the previous validator's index sign the message instead of the proposer.
sszEpoch := primitives.SSZUint64(epoch)
return signing.ComputeDomainAndSign(beaconState, epoch, &sszEpoch, params.BeaconConfig().DomainRandao, privKeys[proposerIdx])
}
// BlockSignature calculates the post-state root of the block and returns the signature.
func BlockSignature(
bState state.BeaconState,
block interface{},
privKeys []bls.SecretKey,
) (bls.Signature, error) {
var wsb interfaces.ReadOnlySignedBeaconBlock
var err error
// copy the state since we need to process slots
bState = bState.Copy()
switch b := block.(type) {
case *zondpb.BeaconBlock:
wsb, err = blocks.NewSignedBeaconBlock(&zondpb.SignedBeaconBlock{Block: b})
case *zondpb.BeaconBlockAltair:
wsb, err = blocks.NewSignedBeaconBlock(&zondpb.SignedBeaconBlockAltair{Block: b})
case *zondpb.BeaconBlockBellatrix:
wsb, err = blocks.NewSignedBeaconBlock(&zondpb.SignedBeaconBlockBellatrix{Block: b})
case *zondpb.BeaconBlockCapella:
wsb, err = blocks.NewSignedBeaconBlock(&zondpb.SignedBeaconBlockCapella{Block: b})
default:
return nil, errors.New("unsupported block type")
}
if err != nil {
return nil, errors.Wrap(err, "could not wrap block")
}
s, err := transition.CalculateStateRoot(context.Background(), bState, wsb)
if err != nil {
return nil, errors.Wrap(err, "could not calculate state root")
}
switch b := block.(type) {
case *zondpb.BeaconBlock:
b.StateRoot = s[:]
case *zondpb.BeaconBlockAltair:
b.StateRoot = s[:]
case *zondpb.BeaconBlockBellatrix:
b.StateRoot = s[:]
case *zondpb.BeaconBlockCapella:
b.StateRoot = s[:]
}
// Temporarily increasing the beacon state slot here since BeaconProposerIndex is a
// function deterministic on beacon state slot.
var blockSlot primitives.Slot
switch b := block.(type) {
case *zondpb.BeaconBlock:
blockSlot = b.Slot
case *zondpb.BeaconBlockAltair:
blockSlot = b.Slot
case *zondpb.BeaconBlockBellatrix:
blockSlot = b.Slot
case *zondpb.BeaconBlockCapella:
blockSlot = b.Slot
}
// process slots to get the right fork
bState, err = transition.ProcessSlots(context.Background(), bState, blockSlot)
if err != nil {
return nil, err
}
domain, err := signing.Domain(bState.Fork(), time.CurrentEpoch(bState), params.BeaconConfig().DomainBeaconProposer, bState.GenesisValidatorsRoot())
if err != nil {
return nil, err
}
var blockRoot [32]byte
switch b := block.(type) {
case *zondpb.BeaconBlock:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
case *zondpb.BeaconBlockAltair:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
case *zondpb.BeaconBlockBellatrix:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
case *zondpb.BeaconBlockCapella:
blockRoot, err = signing.ComputeSigningRoot(b, domain)
}
if err != nil {
return nil, err
}
proposerIdx, err := helpers.BeaconProposerIndex(context.Background(), bState)
if err != nil {
return nil, err
}
return privKeys[proposerIdx].Sign(blockRoot[:]), nil
}
// Random32Bytes generates a random 32 byte slice.
func Random32Bytes(t *testing.T) []byte {
b := make([]byte, 32)
_, err := rand.NewDeterministicGenerator().Read(b)
if err != nil {
t.Fatal(err)
}
return b
}