Skip to content

Commit

Permalink
Reject additional authorities for lite accounts [#3607]
Browse files Browse the repository at this point in the history
  • Loading branch information
firelizzard18 committed Jun 17, 2024
1 parent 27f3572 commit a05043a
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 20 deletions.
41 changes: 21 additions & 20 deletions internal/core/execute/v2/block/sig_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,10 @@ func init() {
protocol.SignatureTypeETH,
)

// RSA signatures (enabled with Vandenberg)
// Vandenberg: RSA and ECDSA signatures
registerConditionalExec[UserSignature](&signatureExecutors,
func(ctx *SignatureContext) bool { return ctx.GetActiveGlobals().ExecutorVersion.V2VandenbergEnabled() },
protocol.SignatureTypeRsaSha256,
)

// PKI signatures (enabled with Vandenberg)
registerConditionalExec[UserSignature](&signatureExecutors,
func(ctx *SignatureContext) bool { return ctx.GetActiveGlobals().ExecutorVersion.V2VandenbergEnabled() },
protocol.SignatureTypeEcdsaSha256,
)
}
Expand Down Expand Up @@ -138,6 +133,14 @@ func (x UserSignature) check(batch *database.Batch, ctx *userSigContext) error {
return errors.UnknownError.Wrap(err)
}

// A lite identity may not require additional authorities
if ctx.GetActiveGlobals().ExecutorVersion.V2VandenbergEnabled() &&
ctx.signer.Type() == protocol.AccountTypeLiteIdentity &&
len(ctx.transaction.Header.Authorities) > 0 &&
ctx.isInitiator {
return errors.BadRequest.WithFormat("a transaction initiated by a lite identity cannot require additional authorities")
}

return nil
}

Expand Down Expand Up @@ -437,25 +440,23 @@ func (UserSignature) process(batch *database.Batch, ctx *userSigContext) error {
// sendSignatureRequests sends signature requests so that the transaction
// will appear on the appropriate pending lists.
func (UserSignature) sendSignatureRequests(batch *database.Batch, ctx *userSigContext) error {
// If the signer is a lite identity, do not send a signature request
if _, ok := ctx.signer.(*protocol.LiteIdentity); ok &&
ctx.GetActiveGlobals().ExecutorVersion.V2VandenbergEnabled() {
return nil
}

// If this is the initiator signature
if !ctx.isInitiator {
return nil
}

// Send a notice to the principal
msg := new(messaging.SignatureRequest)
msg.Authority = ctx.transaction.Header.Principal
msg.Cause = ctx.message.ID()
msg.TxID = ctx.transaction.ID()
err := ctx.didProduce(batch, msg.Authority, msg)
if err != nil {
return errors.UnknownError.Wrap(err)
// Send a notice to the principal, unless principal is a lite identity
_, err := protocol.ParseLiteAddress(ctx.transaction.Header.Principal)
isLite := err == nil && ctx.GetActiveGlobals().ExecutorVersion.V2VandenbergEnabled()
if !isLite {
msg := new(messaging.SignatureRequest)
msg.Authority = ctx.transaction.Header.Principal
msg.Cause = ctx.message.ID()
msg.TxID = ctx.transaction.ID()
err := ctx.didProduce(batch, msg.Authority, msg)
if err != nil {
return errors.UnknownError.Wrap(err)
}
}

// If transaction requests additional authorities, send out signature requests
Expand Down
58 changes: 58 additions & 0 deletions test/e2e/sig_general_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,43 @@ func TestSignatureErrors(t *testing.T) {
require.ErrorContains(t, err, "insufficient credits: have 0.00, want 0.01")
}

// Verifies that ADI accounts do produce signature requests.
func TestAdiAccountSignatureRequests(t *testing.T) {
alice := build.
Identity("alice").Create("book").
Tokens("tokens").Create("ACME").Add(1e9).Identity().
Book("book").Page(1).Create().AddCredits(1e9).Book().Identity()
aliceKey := alice.Book("book").Page(1).
GenerateKey(SignatureTypeED25519)

// Initialize
sim := NewSim(t,
simulator.SimpleNetwork(t.Name(), 1, 1),
simulator.Genesis(GenesisTime).With(alice),
)

// Execute a transaction
st := sim.BuildAndSubmitSuccessfully(
build.Transaction().For(alice, "tokens").
AddCredits().Spend(10).To(alice, "book", "1").WithOracle(InitialAcmeOracle).
SignWith(alice, "book", "1").Version(1).Timestamp(1).PrivateKey(aliceKey))

sim.StepUntil(
Txn(st[0].TxID).Completes())

// Verify that the signature did not produce any signature requests
r := sim.QuerySignature(st[1].TxID, nil)
var ok bool
for _, r := range r.Produced.Records {
r := sim.QueryMessage(r.Value, nil)
_, x := r.Message.(*messaging.SignatureRequest)
if x {
ok = true
}
}
require.True(t, ok, "A signature request is produced")
}

// Verifies that lite accounts do not produce signature requests.
func TestLiteAccountSignatureRequests(t *testing.T) {
lite := build.LiteIdentity().Generate(t).AddCredits(1000).
Expand Down Expand Up @@ -491,3 +528,24 @@ func TestLiteAccountSignatureRequests(t *testing.T) {
require.False(t, ok, "A signature request is not produced")
}
}

func TestLiteAdditionalAuthorities(t *testing.T) {
lite := build.LiteIdentity().Generate(t).AddCredits(1000).
Tokens("ACME").Create().Add(1000).Identity()

// Initialize
sim := NewSim(t,
simulator.SimpleNetwork(t.Name(), 1, 1),
simulator.Genesis(GenesisTime).With(lite),
)

// Execute a transaction with additional authorities
st := sim.BuildAndSubmit(
build.Transaction().For(lite, "ACME").
AdditionalAuthority("alice.acme/book/1").
AddCredits().Spend(10).To(lite).WithOracle(InitialAcmeOracle).
SignWith(lite).Version(1).Timestamp(1).PrivateKey(lite.Key))

require.Error(t, st[1].AsError())
require.ErrorContains(t, st[1].Error, "a transaction initiated by a lite identity cannot require additional authorities")
}

0 comments on commit a05043a

Please sign in to comment.