Skip to content

Commit

Permalink
Test bad justification (#332)
Browse files Browse the repository at this point in the history
- Invalid bitfield
- Participant without power
  • Loading branch information
Stebalien authored Jul 11, 2024
1 parent d1b048a commit e03bdb0
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 10 deletions.
58 changes: 48 additions & 10 deletions sim/adversary/decide.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,39 @@ import (

var _ Receiver = (*ImmediateDecide)(nil)

type ImmediateDecideOption func(*ImmediateDecide)

func ImmediateDecideWithNthParticipant(n uint64) ImmediateDecideOption {
return func(i *ImmediateDecide) {
i.additionalParticipant = &n
}
}

// / An "adversary" that immediately sends a DECIDE message, justified by its own COMMIT.
type ImmediateDecide struct {
id gpbft.ActorID
host Host
value gpbft.ECChain

additionalParticipant *uint64
}

func NewImmediateDecide(id gpbft.ActorID, host Host, value gpbft.ECChain) *ImmediateDecide {
return &ImmediateDecide{
func NewImmediateDecide(id gpbft.ActorID, host Host, value gpbft.ECChain, opts ...ImmediateDecideOption) *ImmediateDecide {
i := &ImmediateDecide{
id: id,
host: host,
value: value,
}
for _, opt := range opts {
opt(i)
}
return i
}

func NewImmediateDecideGenerator(value gpbft.ECChain, power *gpbft.StoragePower) Generator {
func NewImmediateDecideGenerator(value gpbft.ECChain, power *gpbft.StoragePower, opts ...ImmediateDecideOption) Generator {
return func(id gpbft.ActorID, host Host) *Adversary {
return &Adversary{
Receiver: NewImmediateDecide(id, host, value),
Receiver: NewImmediateDecide(id, host, value, opts...),
Power: power,
}
}
Expand All @@ -55,15 +69,39 @@ func (i *ImmediateDecide) StartInstanceAt(instance uint64, _when time.Time) erro
SupplementalData: *supplementalData,
}
sigPayload := i.host.MarshalPayloadForSigning(i.host.NetworkName(), &justificationPayload)
_, pubkey := powertable.Get(i.id)
sig, err := i.host.Sign(context.Background(), pubkey, sigPayload)
if err != nil {
signers := bitfield.New()

signers.Set(uint64(powertable.Lookup[i.id]))

if i.additionalParticipant != nil {
signers.Set(*i.additionalParticipant)
}

var (
pubkeys []gpbft.PubKey
sigs [][]byte
)

if err := signers.ForEach(func(j uint64) error {
pubkey := gpbft.PubKey("fake pubkey")
sig := []byte("fake sig")
if j < uint64(len(powertable.Entries)) {
pubkey = powertable.Entries[j].PubKey
var err error
sig, err = i.host.Sign(context.Background(), pubkey, sigPayload)
if err != nil {
return err
}
}

pubkeys = append(pubkeys, pubkey)
sigs = append(sigs, sig)
return nil
}); err != nil {
panic(err)
}

signers := bitfield.New()
signers.Set(uint64(powertable.Lookup[i.id]))
aggregatedSig, err := i.host.Aggregate([]gpbft.PubKey{pubkey}, [][]byte{sig})
aggregatedSig, err := i.host.Aggregate(pubkeys, sigs)
if err != nil {
panic(err)
}
Expand Down
46 changes: 46 additions & 0 deletions test/decide_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,49 @@ func FuzzImmediateDecideAdversary(f *testing.F) {
require.Equal(t, adversaryValue.Head(), decision.Head(), "honest node did not decide the right value")
})
}

func TestIllegalCommittee_OutOfRange(t *testing.T) {
const seed = 98562314
t.Parallel()
rng := rand.New(rand.NewSource(int64(seed)))
tsg := sim.NewTipSetGenerator(tipSetGeneratorSeed)
baseChain := generateECChain(t, tsg)
adversaryValue := baseChain.Extend(tsg.Sample())
sm, err := sim.NewSimulation(
asyncOptions(rng.Int(),
sim.AddHonestParticipants(
1,
sim.NewUniformECChainGenerator(rng.Uint64(), 1, 5),
uniformOneStoragePower),
sim.WithBaseChain(&baseChain),
// Add the adversary to the simulation with 3/4 of total power.
sim.WithAdversary(adversary.NewImmediateDecideGenerator(adversaryValue, gpbft.NewStoragePower(3), adversary.ImmediateDecideWithNthParticipant(100))),
)...)
require.NoError(t, err)

err = sm.Run(1, maxRounds)
require.ErrorContains(t, err, "invalid signer index")
}

func TestIllegalCommittee_NoPower(t *testing.T) {
const seed = 98562314
t.Parallel()
rng := rand.New(rand.NewSource(int64(seed)))
tsg := sim.NewTipSetGenerator(tipSetGeneratorSeed)
baseChain := generateECChain(t, tsg)
adversaryValue := baseChain.Extend(tsg.Sample())
sm, err := sim.NewSimulation(
asyncOptions(rng.Int(),
sim.AddHonestParticipants(
1,
sim.NewUniformECChainGenerator(rng.Uint64(), 1, 5),
sim.UniformStoragePower(gpbft.NewStoragePower(1))),
sim.WithBaseChain(&baseChain),
// Add the adversary to the simulation with 3/4 of total power.
sim.WithAdversary(adversary.NewImmediateDecideGenerator(adversaryValue, gpbft.NewStoragePower(0xffff), adversary.ImmediateDecideWithNthParticipant(1))),
)...)
require.NoError(t, err)

err = sm.Run(1, maxRounds)
require.ErrorContains(t, err, "signer with ID 0 has no power")
}

0 comments on commit e03bdb0

Please sign in to comment.