diff --git a/internal/core/execute/v2/block/sig_user.go b/internal/core/execute/v2/block/sig_user.go index 0cd68a756..78c741643 100644 --- a/internal/core/execute/v2/block/sig_user.go +++ b/internal/core/execute/v2/block/sig_user.go @@ -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, ) } @@ -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 } @@ -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 diff --git a/test/e2e/sig_general_test.go b/test/e2e/sig_general_test.go index 29c7be34f..33ea6b302 100644 --- a/test/e2e/sig_general_test.go +++ b/test/e2e/sig_general_test.go @@ -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). @@ -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") +}