From 27434166ef4a263ffb1121c76a05bc582ac1e06b Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 2 Aug 2024 23:27:55 +0530 Subject: [PATCH] new execution api changes --- go.mod | 21 ++-- go.sum | 23 ++++ grpc/execution/server.go | 90 +++++++++++--- grpc/execution/server_test.go | 45 +++++-- grpc/execution/validation.go | 190 ++++++++++++++++++++---------- grpc/execution/validation_test.go | 110 ++++++++++++++++- 6 files changed, 381 insertions(+), 98 deletions(-) diff --git a/go.mod b/go.mod index 42b49387f..882c354e5 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/ethereum/go-ethereum go 1.21 require ( - buf.build/gen/go/astria/execution-apis/grpc/go v1.4.0-20240627184145-202c666b5a8a.1 - buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-20240627184145-202c666b5a8a.2 - buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.2-20240626163506-691883836b9e.2 - buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.2-20240627184145-00f432997496.2 + buf.build/gen/go/astria/execution-apis/grpc/go v1.5.1-00000000000000-cdc3a35f6a0c.1 + buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-20240801092317-cdc3a35f6a0c.2 + buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.2-20240801092317-1af140bbf6af.2 + buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.2-20240801092317-547455022126.2 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 github.com/Microsoft/go-winio v0.6.1 github.com/VictoriaMetrics/fastcache v1.12.1 @@ -72,19 +72,20 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 github.com/urfave/cli/v2 v2.25.7 go.uber.org/automaxprocs v1.5.2 - golang.org/x/crypto v0.22.0 + golang.org/x/crypto v0.24.0 golang.org/x/sync v0.7.0 - golang.org/x/sys v0.19.0 - golang.org/x/text v0.14.0 + golang.org/x/sys v0.21.0 + golang.org/x/text v0.16.0 golang.org/x/time v0.5.0 - golang.org/x/tools v0.20.0 - google.golang.org/grpc v1.64.0 + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d + google.golang.org/grpc v1.64.1 google.golang.org/protobuf v1.34.2 gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/yaml.v3 v3.0.1 ) require ( + buf.build/gen/go/astria/composer-apis/protocolbuffers/go v1.34.2-00000000000000-b8b0a7e37fa2.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect github.com/DataDog/zstd v1.4.5 // indirect @@ -149,7 +150,7 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 054ae7bd4..af7d1592b 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,28 @@ +buf.build/gen/go/astria/composer-apis/protocolbuffers/go v1.34.2-00000000000000-b8b0a7e37fa2.2 h1:2ektaygWFz5FIEHtkAxsiUZk3TZPWoZAqDjFI8V7vL4= +buf.build/gen/go/astria/composer-apis/protocolbuffers/go v1.34.2-00000000000000-b8b0a7e37fa2.2/go.mod h1:vrjomDuiv4T+/yZ/iqIjT6E5NXrBmSCR1yKMRZ8iwlU= buf.build/gen/go/astria/execution-apis/grpc/go v1.4.0-20240627184145-202c666b5a8a.1 h1:hYCnNcMBgnEa6XLAMgGD0cZXoulA1Dmn5xi6cERVqZA= buf.build/gen/go/astria/execution-apis/grpc/go v1.4.0-20240627184145-202c666b5a8a.1/go.mod h1:SFzpkHZaY4sEyrJ5vSwZU6XdPo1ntBDKXtt75T26dac= +buf.build/gen/go/astria/execution-apis/grpc/go v1.5.1-00000000000000-cdc3a35f6a0c.1 h1:/9SoFuKGYYb3XtPxTsPsn3vPY3WkpiIn6UisZF3TJMQ= +buf.build/gen/go/astria/execution-apis/grpc/go v1.5.1-00000000000000-cdc3a35f6a0c.1/go.mod h1:pXISQNa1zGM905/v0nXCPkMZwrEIk+5AmgEs+cTPFCQ= buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.1-20240627184145-202c666b5a8a.1/go.mod h1:lBkx3jiHbz6XM0FAkbQEmUFNifgc4x7oi9LuOK/HDbg= +buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-00000000000000-cdc3a35f6a0c.2 h1:B48z/K8rQFpvSCnA9/2GrpK+ide/mIjcmuoEZ9yZ0jM= +buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-00000000000000-cdc3a35f6a0c.2/go.mod h1:KVuELHO13ERiTsogomrb9+O4lb8s8QlLcix1nArjdrI= buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-20240627184145-202c666b5a8a.2 h1:IYFQwWxQXFovUY/kMnXWaQJ8KJ5uuLOBE0ks2II254c= buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-20240627184145-202c666b5a8a.2/go.mod h1:czHASkeeVmYV4IC0uo9qWDQ0dmEJeC6LfgYWBwSSREI= +buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-20240801092317-cdc3a35f6a0c.2 h1:/4vRNkmKQ6mfzbQpjX5gsAy+jX/Sa95XTvoz3Cr05KA= +buf.build/gen/go/astria/execution-apis/protocolbuffers/go v1.34.2-20240801092317-cdc3a35f6a0c.2/go.mod h1:KVuELHO13ERiTsogomrb9+O4lb8s8QlLcix1nArjdrI= buf.build/gen/go/astria/primitives/grpc/go v1.4.0-20240626163506-691883836b9e.1/go.mod h1:VU1xcDnHOU7++vCZHJzilQGWAd4m1SWTBYKuo4qx/cg= buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.1-20240626163506-691883836b9e.1/go.mod h1:pkz/GfhAgZSnDxyZ5bmGUzk6iQNAvyW72pYPkqb7Pbk= buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.2-20240626163506-691883836b9e.2 h1:bCHvCYyvhCPWGc3tpl164ONADbH+nKPSc6KhOWb9tfk= buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.2-20240626163506-691883836b9e.2/go.mod h1:J0Tk7JAHcrhzWNEf1lbePSfFZ1Kp78eAlnO8Cs2ELKg= +buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.2-20240801092317-1af140bbf6af.2 h1:jVRnwdYnEuCMZVT8WE4MF6j8cdmMzjLO2N1FBrGVv5E= +buf.build/gen/go/astria/primitives/protocolbuffers/go v1.34.2-20240801092317-1af140bbf6af.2/go.mod h1:J0Tk7JAHcrhzWNEf1lbePSfFZ1Kp78eAlnO8Cs2ELKg= buf.build/gen/go/astria/sequencerblock-apis/grpc/go v1.4.0-20240627184145-00f432997496.1/go.mod h1:viF0ZoRvyO5qpIZb1wB3aBBt9WWKOg5x5t6AFKKuKQU= buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.1-20240627184145-00f432997496.1/go.mod h1:KkZ92tBsbbl5HTuN/AbQLkW2ALXsaV5MsEU9PPy/n9c= buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.2-20240627184145-00f432997496.2 h1:s349kECGqPwCKQ1q09lqBR6782/0zDqDez+FEM5PT0s= buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.2-20240627184145-00f432997496.2/go.mod h1:NEZbII2+dhqPXaQqMYN8ziELoYQgp7hbDFv5Oc45EZU= +buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.2-20240801092317-547455022126.2 h1:QKl4FPcbNiGmnWDeG/bIAOzmb93rydMA2Cl1motkgAw= +buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go v1.34.2-20240801092317-547455022126.2/go.mod h1:mohUSyi2UmALXDaJlA1CqHwhaJ84bZHnt09ydfnDsHs= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -1880,6 +1892,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2018,6 +2032,8 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2185,6 +2201,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2224,6 +2242,8 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2303,6 +2323,7 @@ golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2636,6 +2657,8 @@ google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9Y google.golang.org/grpc v1.61.2/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 15a6e58b1..f58f7af8b 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -5,6 +5,8 @@ package execution import ( + composerv1alpha1 "buf.build/gen/go/astria/composer-apis/protocolbuffers/go/astria/composer/v1alpha1" + sequencerblockv1alpha1 "buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go/astria/sequencerblock/v1alpha1" "context" "crypto/sha256" "errors" @@ -160,7 +162,7 @@ func (s *ExecutionServiceServerV1Alpha2) GetGenesisInfo(ctx context.Context, req rollupId := sha256.Sum256([]byte(s.bc.Config().AstriaRollupName)) res := &astriaPb.GenesisInfo{ - RollupId: rollupId[:], + RollupId: &primitivev1.RollupId{Inner: rollupId[:]}, SequencerGenesisBlockHeight: s.bc.Config().AstriaSequencerInitialHeight, CelestiaBlockVariance: s.bc.Config().AstriaCelestiaHeightVariance, } @@ -221,9 +223,34 @@ func protoU128ToBigInt(u128 *primitivev1.Uint128) *big.Int { return lo.Add(lo, hi) } +func unbundleBuilderBundlePacket( + builderBundlePacket *composerv1alpha1.BuilderBundlePacket, + height uint64, + bridgeAddresses map[string]*params.AstriaBridgeAddressConfig, + bridgeAllowedAssets map[string]struct{}, + bridgeSenderAddress common.Address, +) (types.Transactions, error) { + // TODO - add builder packet validation + if builderBundlePacket == nil { + return types.Transactions{}, nil + } + + ethTxs := types.Transactions{} + for _, tx := range builderBundlePacket.GetBundle().GetTransactions() { + ethTx, err := validateAndUnmarshalTx(height, tx, bridgeAddresses, bridgeAllowedAssets, bridgeSenderAddress) + if err != nil { + return nil, err + } + + ethTxs = append(ethTxs, ethTx) + } + + return ethTxs, nil +} + // ExecuteBlock drives deterministic derivation of a rollup block from sequencer // block data -func (s *ExecutionServiceServerV1Alpha2) ExecuteBlock(ctx context.Context, req *astriaPb.ExecuteBlockRequest) (*astriaPb.Block, error) { +func (s *ExecutionServiceServerV1Alpha2) ExecuteBlock(ctx context.Context, req *astriaPb.ExecuteBlockRequest) (*astriaPb.ExecuteBlockResponse, error) { log.Debug("ExecuteBlock called", "prevBlockHash", common.BytesToHash(req.PrevBlockHash), "tx_count", len(req.Transactions), "timestamp", req.Timestamp) executeBlockRequestCount.Inc(1) @@ -247,18 +274,26 @@ func (s *ExecutionServiceServerV1Alpha2) ExecuteBlock(ctx context.Context, req * // the height that this block will be at height := s.bc.CurrentBlock().Number.Uint64() + 1 - txsToProcess := types.Transactions{} - for _, tx := range req.Transactions { - unmarshalledTx, err := validateAndUnmarshalSequencerTx(height, tx, s.bridgeAddresses, s.bridgeAllowedAssets, s.bridgeSenderAddress) + builderBundlePacket, ethTxs, err := extractBuilderBundleAndTxs(req.Transactions, height, s.bridgeAddresses, s.bridgeAllowedAssets, s.bridgeSenderAddress) + if err != nil { + log.Error("failed to extract builder bundle and txs", "err", err) + return nil, status.Error(codes.InvalidArgument, "Could not extract builder bundle and txs") + } + if req.GetSimulateOnly() && builderBundlePacket != nil { + return nil, status.Error(codes.InvalidArgument, "bundle simulation is not supported for builder bundle packets") + } + + tobTxs := types.Transactions{} + if builderBundlePacket != nil { + tobTxs, err = unbundleBuilderBundlePacket(builderBundlePacket, height, s.bridgeAddresses, s.bridgeAllowedAssets, s.bridgeSenderAddress) if err != nil { - log.Debug("failed to validate sequencer tx, ignoring", "tx", tx, "err", err) - continue + log.Error("failed to unbundle builder bundle packet", "err", err) + return nil, status.Error(codes.InvalidArgument, "Could not unbundle builder bundle packet") } - txsToProcess = append(txsToProcess, unmarshalledTx) } - // This set of ordered TXs on the TxPool is has been configured to be used by - // the Miner when building a payload. + txsToProcess := append(tobTxs, ethTxs...) + s.eth.TxPool().SetAstriaOrdered(txsToProcess) // Build a payload to add to the chain @@ -281,16 +316,32 @@ func (s *ExecutionServiceServerV1Alpha2) ExecuteBlock(ctx context.Context, req * log.Error("failed to convert executable data to block", err) return nil, status.Error(codes.Internal, "failed to execute block") } - err = s.bc.InsertBlockWithoutSetHead(block) - if err != nil { - log.Error("failed to insert block to chain", "hash", block.Hash(), "prevHash", req.PrevBlockHash, "err", err) - return nil, status.Error(codes.Internal, "failed to insert block to chain") + + includedTransactions := make([]*sequencerblockv1alpha1.RollupData, 0, len(block.Transactions())) + for _, tx := range block.Transactions() { + marshalledTx, err := tx.MarshalBinary() + if err != nil { + log.Error("failed to marshal transaction", "err", err) + return nil, status.Error(codes.Internal, "failed to marshal transaction") + } + includedTransactions = append(includedTransactions, &sequencerblockv1alpha1.RollupData{ + Value: &sequencerblockv1alpha1.RollupData_SequencedData{SequencedData: marshalledTx}, + }) + } + + // we do not insert the block to the chain if we just want to simulate the transactions + if !req.GetSimulateOnly() { + err = s.bc.InsertBlockWithoutSetHead(block) + if err != nil { + log.Error("failed to insert block to chain", "hash", block.Hash(), "prevHash", req.PrevBlockHash, "err", err) + return nil, status.Error(codes.Internal, "failed to insert block to chain") + } } // remove txs from original mempool s.eth.TxPool().ClearAstriaOrdered() - res := &astriaPb.Block{ + finalBlock := &astriaPb.Block{ Number: uint32(block.NumberU64()), Hash: block.Hash().Bytes(), ParentBlockHash: block.ParentHash().Bytes(), @@ -299,11 +350,16 @@ func (s *ExecutionServiceServerV1Alpha2) ExecuteBlock(ctx context.Context, req * }, } - if next, ok := s.bc.Config().AstriaFeeCollectors[res.Number+1]; ok { + if next, ok := s.bc.Config().AstriaFeeCollectors[finalBlock.Number+1]; ok { s.nextFeeRecipient = next } - log.Info("ExecuteBlock completed", "block_num", res.Number, "timestamp", res.Timestamp) + res := &astriaPb.ExecuteBlockResponse{ + Block: finalBlock, + IncludedTransactions: includedTransactions, + } + + log.Info("ExecuteBlock completed", "block_num", res.GetBlock().Number, "timestamp", res.GetBlock().Timestamp) totalExecutedTxCount.Inc(int64(len(block.Transactions()))) executeBlockSuccessCount.Inc(1) return res, nil diff --git a/grpc/execution/server_test.go b/grpc/execution/server_test.go index 5727c3cb9..03fa96bde 100644 --- a/grpc/execution/server_test.go +++ b/grpc/execution/server_test.go @@ -28,7 +28,7 @@ func TestExecutionService_GetGenesisInfo(t *testing.T) { hashedRollupId := sha256.Sum256([]byte(ethservice.BlockChain().Config().AstriaRollupName)) - require.True(t, bytes.Equal(genesisInfo.RollupId, hashedRollupId[:]), "RollupId is not correct") + require.True(t, bytes.Equal(genesisInfo.RollupId.Inner, hashedRollupId[:]), "RollupId is not correct") require.Equal(t, genesisInfo.GetSequencerGenesisBlockHeight(), ethservice.BlockChain().Config().AstriaSequencerInitialHeight, "SequencerInitialHeight is not correct") require.Equal(t, genesisInfo.GetCelestiaBlockVariance(), ethservice.BlockChain().Config().AstriaCelestiaHeightVariance, "CelestiaHeightVariance is not correct") require.True(t, serviceV1Alpha1.genesisInfoCalled, "GetGenesisInfo should be called") @@ -206,6 +206,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { prevBlockHash []byte timestamp uint64 depositTxAmount *big.Int // if this is non zero then we send a deposit tx + simulateOnly bool expectedReturnCode codes.Code }{ { @@ -215,6 +216,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { prevBlockHash: ethservice.BlockChain().GetBlockByNumber(2).Hash().Bytes(), timestamp: ethservice.BlockChain().GetBlockByNumber(2).Time() + 2, depositTxAmount: big.NewInt(0), + simulateOnly: false, expectedReturnCode: codes.PermissionDenied, }, { @@ -224,6 +226,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { prevBlockHash: ethservice.BlockChain().CurrentSafeBlock().Hash().Bytes(), timestamp: ethservice.BlockChain().CurrentSafeBlock().Time + 2, depositTxAmount: big.NewInt(0), + simulateOnly: false, expectedReturnCode: 0, }, { @@ -233,6 +236,17 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { prevBlockHash: ethservice.BlockChain().CurrentSafeBlock().Hash().Bytes(), timestamp: ethservice.BlockChain().CurrentSafeBlock().Time + 2, depositTxAmount: big.NewInt(1000000000000000000), + simulateOnly: false, + expectedReturnCode: 0, + }, + { + description: "ExecuteBlock with 5 txs and no deposit tx in simulate only mode", + callGenesisInfoAndGetCommitmentState: true, + numberOfTxs: 5, + prevBlockHash: ethservice.BlockChain().CurrentSafeBlock().Hash().Bytes(), + timestamp: ethservice.BlockChain().CurrentSafeBlock().Time + 2, + depositTxAmount: big.NewInt(0), + simulateOnly: true, expectedReturnCode: 0, }, { @@ -242,6 +256,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { prevBlockHash: ethservice.BlockChain().GetBlockByNumber(2).Hash().Bytes(), timestamp: ethservice.BlockChain().GetBlockByNumber(2).Time() + 2, depositTxAmount: big.NewInt(0), + simulateOnly: false, expectedReturnCode: codes.FailedPrecondition, }, } @@ -300,7 +315,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { }, Asset: bridgeAssetDenom, Amount: depositAmount, - RollupId: &primitivev1.RollupId{Inner: genesisInfo.RollupId}, + RollupId: &primitivev1.RollupId{Inner: genesisInfo.RollupId.Inner}, DestinationChainAddress: chainDestinationAddress.String(), }}} @@ -313,6 +328,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { Seconds: int64(tt.timestamp), }, Transactions: marshalledTxs, + SimulateOnly: tt.simulateOnly, } executeBlockRes, err := serviceV1Alpha1.ExecuteBlock(context.Background(), executeBlockReq) @@ -321,6 +337,13 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlock(t *testing.T) { require.Equal(t, tt.expectedReturnCode, status.Code(err), "ExecuteBlock failed") } if err == nil { + block := ethservice.BlockChain().GetBlockByHash(common.BytesToHash(executeBlockRes.Block.Hash)) + if tt.simulateOnly { + require.Nil(t, block, "Block should not be found in blockchain") + } else { + require.NotNil(t, block, "Block not found in blockchain") + } + require.NotNil(t, executeBlockRes, "ExecuteBlock response is nil") astriaOrdered := ethservice.TxPool().AstriaOrdered() @@ -393,7 +416,7 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlockAndUpdateCommitment(t *testi }, Asset: bridgeAssetDenom, Amount: depositAmount, - RollupId: &primitivev1.RollupId{Inner: genesisInfo.RollupId}, + RollupId: &primitivev1.RollupId{Inner: genesisInfo.RollupId.Inner}, DestinationChainAddress: chainDestinationAddress.String(), }}} @@ -420,16 +443,16 @@ func TestExecutionServiceServerV1Alpha2_ExecuteBlockAndUpdateCommitment(t *testi updateCommitmentStateReq := &astriaPb.UpdateCommitmentStateRequest{ CommitmentState: &astriaPb.CommitmentState{ Soft: &astriaPb.Block{ - Hash: executeBlockRes.Hash, - ParentBlockHash: executeBlockRes.ParentBlockHash, - Number: executeBlockRes.Number, - Timestamp: executeBlockRes.Timestamp, + Hash: executeBlockRes.GetBlock().Hash, + ParentBlockHash: executeBlockRes.GetBlock().ParentBlockHash, + Number: executeBlockRes.GetBlock().Number, + Timestamp: executeBlockRes.GetBlock().Timestamp, }, Firm: &astriaPb.Block{ - Hash: executeBlockRes.Hash, - ParentBlockHash: executeBlockRes.ParentBlockHash, - Number: executeBlockRes.Number, - Timestamp: executeBlockRes.Timestamp, + Hash: executeBlockRes.GetBlock().Hash, + ParentBlockHash: executeBlockRes.GetBlock().ParentBlockHash, + Number: executeBlockRes.GetBlock().Number, + Timestamp: executeBlockRes.GetBlock().Timestamp, }, BaseCelestiaHeight: commitmentState.BaseCelestiaHeight + 1, }, diff --git a/grpc/execution/validation.go b/grpc/execution/validation.go index dd31c2872..4348eeb60 100644 --- a/grpc/execution/validation.go +++ b/grpc/execution/validation.go @@ -1,6 +1,7 @@ package execution import ( + composerv1alpha1 "buf.build/gen/go/astria/composer-apis/protocolbuffers/go/astria/composer/v1alpha1" sequencerblockv1alpha1 "buf.build/gen/go/astria/sequencerblock-apis/protocolbuffers/go/astria/sequencerblock/v1alpha1" "crypto/sha256" "fmt" @@ -9,14 +10,15 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" + "github.com/golang/protobuf/proto" "math/big" ) -// `validateAndUnmarshalSequencerTx` validates and unmarshals the given rollup sequencer transaction. +// `validateAndUnmarshalTx` validates and unmarshals the given rollup sequencer transaction. // If the sequencer transaction is a deposit tx, we ensure that the asset ID is allowed and the bridge address is known. // If the sequencer transaction is not a deposit tx, we unmarshal the sequenced data into an Ethereum transaction. We ensure that the // tx is not a blob tx or a deposit tx. -func validateAndUnmarshalSequencerTx( +func validateAndUnmarshalTx( height uint64, tx *sequencerblockv1alpha1.RollupData, bridgeAddresses map[string]*params.AstriaBridgeAddressConfig, @@ -24,80 +26,150 @@ func validateAndUnmarshalSequencerTx( bridgeSenderAddress common.Address, ) (*types.Transaction, error) { if deposit := tx.GetDeposit(); deposit != nil { - bridgeAddress := deposit.BridgeAddress.GetBech32M() - bac, ok := bridgeAddresses[bridgeAddress] - if !ok { - return nil, fmt.Errorf("unknown bridge address: %s", bridgeAddress) - } + return validateAndUnmarshallDepositTx(height, tx, bridgeAddresses, bridgeAllowedAssets, bridgeSenderAddress) + } else { + return validateAndUnmarshallSequenceTx(tx) + } +} + +func validateAndUnmarshallDepositTx( + height uint64, + tx *sequencerblockv1alpha1.RollupData, + bridgeAddresses map[string]*params.AstriaBridgeAddressConfig, + bridgeAllowedAssets map[string]struct{}, + bridgeSenderAddress common.Address, +) (*types.Transaction, error) { + deposit := tx.GetDeposit() + bridgeAddress := deposit.BridgeAddress.GetBech32M() + bac, ok := bridgeAddresses[bridgeAddress] + if !ok { + return nil, fmt.Errorf("unknown bridge address: %s", bridgeAddress) + } + + if height < uint64(bac.StartHeight) { + return nil, fmt.Errorf("bridging asset %s from bridge %s not allowed before height %d", bac.AssetDenom, bridgeAddress, bac.StartHeight) + } - if height < uint64(bac.StartHeight) { - return nil, fmt.Errorf("bridging asset %s from bridge %s not allowed before height %d", bac.AssetDenom, bridgeAddress, bac.StartHeight) + if _, ok := bridgeAllowedAssets[deposit.Asset]; !ok { + return nil, fmt.Errorf("disallowed asset %s in deposit tx", deposit.Asset) + } + + if deposit.Asset != bac.AssetDenom { + return nil, fmt.Errorf("asset %s does not match bridge address %s asset", deposit.Asset, bridgeAddress) + } + + recipient := common.HexToAddress(deposit.DestinationChainAddress) + amount := bac.ScaledDepositAmount(protoU128ToBigInt(deposit.Amount)) + + if bac.Erc20Asset != nil { + log.Debug("creating deposit tx to mint ERC20 asset", "token", bac.AssetDenom, "erc20Address", bac.Erc20Asset.ContractAddress) + abi, err := contracts.AstriaBridgeableERC20MetaData.GetAbi() + if err != nil { + // this should never happen, as the abi is hardcoded in the contract bindings + return nil, fmt.Errorf("failed to get abi for erc20 contract for asset %s: %w", bac.AssetDenom, err) } - if _, ok := bridgeAllowedAssets[deposit.Asset]; !ok { - return nil, fmt.Errorf("disallowed asset %s in deposit tx", deposit.Asset) + // pack arguments for calling the `mint` function on the ERC20 contract + args := []interface{}{recipient, amount} + calldata, err := abi.Pack("mint", args...) + if err != nil { + return nil, err } - if deposit.Asset != bac.AssetDenom { - return nil, fmt.Errorf("asset %s does not match bridge address %s asset", deposit.Asset, bridgeAddress) + txdata := types.DepositTx{ + From: bridgeSenderAddress, + Value: new(big.Int), // don't need to set this, as we aren't minting the native asset + // mints cost ~14k gas, however this can vary based on existing storage, so we add a little extra as buffer. + // + // the fees are spent from the "bridge account" which is not actually a real account, but is instead some + // address defined by consensus, so the gas cost is not actually deducted from any account. + Gas: 16000, + To: &bac.Erc20Asset.ContractAddress, + Data: calldata, } - recipient := common.HexToAddress(deposit.DestinationChainAddress) - amount := bac.ScaledDepositAmount(protoU128ToBigInt(deposit.Amount)) + tx := types.NewTx(&txdata) + return tx, nil + } - if bac.Erc20Asset != nil { - log.Debug("creating deposit tx to mint ERC20 asset", "token", bac.AssetDenom, "erc20Address", bac.Erc20Asset.ContractAddress) - abi, err := contracts.AstriaBridgeableERC20MetaData.GetAbi() - if err != nil { - // this should never happen, as the abi is hardcoded in the contract bindings - return nil, fmt.Errorf("failed to get abi for erc20 contract for asset %s: %w", bac.AssetDenom, err) - } + txdata := types.DepositTx{ + From: bridgeSenderAddress, + To: &recipient, + Value: amount, + Gas: 0, + } + return types.NewTx(&txdata), nil +} + +func validateAndUnmarshallSequenceTx( + tx *sequencerblockv1alpha1.RollupData, +) (*types.Transaction, error) { + ethTx := new(types.Transaction) + err := ethTx.UnmarshalBinary(tx.GetSequencedData()) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal sequenced data into transaction: %w. tx hash: %s", err, sha256.Sum256(tx.GetSequencedData())) + } + + if ethTx.Type() == types.DepositTxType { + return nil, fmt.Errorf("deposit tx not allowed in sequenced data. tx hash: %s", sha256.Sum256(tx.GetSequencedData())) + } - // pack arguments for calling the `mint` function on the ERC20 contract - args := []interface{}{recipient, amount} - calldata, err := abi.Pack("mint", args...) + if ethTx.Type() == types.BlobTxType { + return nil, fmt.Errorf("blob tx not allowed in sequenced data. tx hash: %s", sha256.Sum256(tx.GetSequencedData())) + } + + return ethTx, nil +} + +func extractBuilderBundleAndTxs(txs []*sequencerblockv1alpha1.RollupData, height uint64, + bridgeAddresses map[string]*params.AstriaBridgeAddressConfig, + bridgeAllowedAssets map[string]struct{}, + bridgeSenderAddress common.Address) (*composerv1alpha1.BuilderBundlePacket, types.Transactions, error) { + // Extract the builder bundle from the sequencer txs + var builderBundle *composerv1alpha1.BuilderBundlePacket + ethTxs := types.Transactions{} + for _, tx := range txs { + if deposit := tx.GetDeposit(); deposit != nil { + tx, err := validateAndUnmarshallDepositTx(height, tx, bridgeAddresses, bridgeAllowedAssets, bridgeSenderAddress) if err != nil { - return nil, err + return nil, nil, err } + ethTxs = append(ethTxs, tx) + } else { + // check if we can unmarshall the sequence data to a BuilderBundlePacket + tempBuilderBundle := &composerv1alpha1.BuilderBundlePacket{} + err := proto.Unmarshal(tx.GetSequencedData(), tempBuilderBundle) + if err == nil { + // we found a builder bundle, we first check if we got a duplicate builder bundle. if we did + // we throw an error + if builderBundle != nil { + return nil, nil, fmt.Errorf("duplicate builder bundle found in sequencer txs") + } - txdata := types.DepositTx{ - From: bridgeSenderAddress, - Value: new(big.Int), // don't need to set this, as we aren't minting the native asset - // mints cost ~14k gas, however this can vary based on existing storage, so we add a little extra as buffer. - // - // the fees are spent from the "bridge account" which is not actually a real account, but is instead some - // address defined by consensus, so the gas cost is not actually deducted from any account. - Gas: 16000, - To: &bac.Erc20Asset.ContractAddress, - Data: calldata, - } + // duplicate builder bundle not found, we set the builder bundle to the temp builder bundle + builderBundle = tempBuilderBundle - tx := types.NewTx(&txdata) - return tx, nil - } + } else { + // if its not a builder bundle, then it should be a regular eth tx + ethTx, err := validateAndUnmarshallSequenceTx(tx) + if err != nil { + return nil, nil, err + } - txdata := types.DepositTx{ - From: bridgeSenderAddress, - To: &recipient, - Value: amount, - Gas: 0, - } - return types.NewTx(&txdata), nil - } else { - ethTx := new(types.Transaction) - err := ethTx.UnmarshalBinary(tx.GetSequencedData()) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal sequenced data into transaction: %w. tx hash: %s", err, sha256.Sum256(tx.GetSequencedData())) - } + ethTxs = append(ethTxs, ethTx) + } - if ethTx.Type() == types.DepositTxType { - return nil, fmt.Errorf("deposit tx not allowed in sequenced data. tx hash: %s", sha256.Sum256(tx.GetSequencedData())) } - if ethTx.Type() == types.BlobTxType { - return nil, fmt.Errorf("blob tx not allowed in sequenced data. tx hash: %s", sha256.Sum256(tx.GetSequencedData())) - } + } - return ethTx, nil + if builderBundle == nil { + builderBundle = &composerv1alpha1.BuilderBundlePacket{ + Bundle: &composerv1alpha1.BuilderBundle{ + Transactions: []*sequencerblockv1alpha1.RollupData{}, + }, + } } + + return builderBundle, ethTxs, nil } diff --git a/grpc/execution/validation_test.go b/grpc/execution/validation_test.go index b715041b4..ebb8e013b 100644 --- a/grpc/execution/validation_test.go +++ b/grpc/execution/validation_test.go @@ -1,6 +1,8 @@ package execution import ( + composerv1alpha1 "buf.build/gen/go/astria/composer-apis/protocolbuffers/go/astria/composer/v1alpha1" + "github.com/golang/protobuf/proto" "math/big" "testing" @@ -52,6 +54,112 @@ func generateBech32MAddress() string { return bech32m } +func TestExtractBuilderBundleAndTxs(t *testing.T) { + // we need to consider the following cases + // 1: empty list of transactions + // 2. list of transactions without builderBundlePacket + // 3. list of transactions with builderBundlePacket + // 4. one transaction with builderBundlePacket + + ethservice, serviceV1Alpha1 := setupExecutionService(t, 10) + + //chainDestinationKey, err := crypto.GenerateKey() + //require.Nil(t, err, "failed to generate chain destination key: %v", err) + //chainDestinationAddress := crypto.PubkeyToAddress(chainDestinationKey.PublicKey) + // + //bridgeAssetDenom := ethservice.BlockChain().Config().AstriaBridgeAddressConfigs[0].AssetDenom + //invalidBridgeAssetDenom := "invalid-asset-denom" + + invalidHeightBridgeAssetDenom := "invalid-height-asset-denom" + invalidHeightBridgeAddressBech32m := generateBech32MAddress() + serviceV1Alpha1.bridgeAddresses[invalidHeightBridgeAddressBech32m] = ¶ms.AstriaBridgeAddressConfig{ + AssetDenom: invalidHeightBridgeAssetDenom, + StartHeight: 100, + } + + tests := []struct { + description string + noOfTxsInBuilderBundle int + noOfOtherTxs int + }{ + { + description: "empty list of transactions", + noOfTxsInBuilderBundle: 0, + noOfOtherTxs: 0, + }, + { + description: "list of transactions without builderBundlePacket", + noOfTxsInBuilderBundle: 0, + noOfOtherTxs: 5, + }, + { + description: "list of transactions with builderBundlePacket", + noOfTxsInBuilderBundle: 5, + noOfOtherTxs: 5, + }, + { + description: "one transaction with builderBundlePacket", + noOfTxsInBuilderBundle: 5, + noOfOtherTxs: 0, + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + marshalledTxs := []*sequencerblockv1alpha1.RollupData{} + + // create the other txs + nonce := 0 + for i := nonce; i < test.noOfOtherTxs; i++ { + unsignedTx := types.NewTransaction(uint64(i), testToAddress, big.NewInt(1), params.TxGas, big.NewInt(params.InitialBaseFee*2), nil) + tx, err := types.SignTx(unsignedTx, types.LatestSigner(ethservice.BlockChain().Config()), testKey) + require.Nil(t, err, "Failed to sign tx") + + marshalledTx, err := tx.MarshalBinary() + require.Nil(t, err, "Failed to marshal tx") + marshalledTxs = append(marshalledTxs, &sequencerblockv1alpha1.RollupData{ + Value: &sequencerblockv1alpha1.RollupData_SequencedData{SequencedData: marshalledTx}, + }) + } + + // create the BuilderBundlePacket + builderBundle := &composerv1alpha1.BuilderBundlePacket{ + Bundle: &composerv1alpha1.BuilderBundle{ + Transactions: []*sequencerblockv1alpha1.RollupData{}, + ParentHash: nil, + }, + } + if test.noOfTxsInBuilderBundle > 0 { + // create noOfTxsInBuilderBundle txs + for i := nonce; i < nonce+test.noOfTxsInBuilderBundle; i++ { + unsignedTx := types.NewTransaction(uint64(i), testToAddress, big.NewInt(1), params.TxGas, big.NewInt(params.InitialBaseFee*2), nil) + tx, err := types.SignTx(unsignedTx, types.LatestSigner(ethservice.BlockChain().Config()), testKey) + require.Nil(t, err, "Failed to sign tx") + + marshalledTx, err := tx.MarshalBinary() + require.Nil(t, err, "Failed to marshal tx") + builderBundle.Bundle.Transactions = append(builderBundle.Bundle.Transactions, &sequencerblockv1alpha1.RollupData{ + Value: &sequencerblockv1alpha1.RollupData_SequencedData{SequencedData: marshalledTx}, + }) + } + + // add the builderBundle to the list of transactions + marshalledProto, err := proto.Marshal(builderBundle) + require.Nil(t, err, "Failed to marshal builder bundle") + marshalledTxs = append(marshalledTxs, &sequencerblockv1alpha1.RollupData{ + Value: &sequencerblockv1alpha1.RollupData_SequencedData{SequencedData: marshalledProto}, + }) + } + + builderBundlePacket, otherTxs, err := extractBuilderBundleAndTxs(marshalledTxs, 2, serviceV1Alpha1.bridgeAddresses, serviceV1Alpha1.bridgeAllowedAssets, common.Address{}) + require.Nil(t, err, "Failed to extract builder bundle and txs") + require.Equal(t, test.noOfTxsInBuilderBundle, len(builderBundlePacket.GetBundle().GetTransactions()), "Incorrect number of txs in builder bundle") + require.Equal(t, test.noOfOtherTxs, len(otherTxs), "Incorrect number of other txs") + }) + } + +} + func TestSequenceTxValidation(t *testing.T) { ethservice, serviceV1Alpha1 := setupExecutionService(t, 10) @@ -180,7 +288,7 @@ func TestSequenceTxValidation(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { - _, err := validateAndUnmarshalSequencerTx(2, test.sequencerTx, serviceV1Alpha1.bridgeAddresses, serviceV1Alpha1.bridgeAllowedAssets, common.Address{}) + _, err := validateAndUnmarshalTx(2, test.sequencerTx, serviceV1Alpha1.bridgeAddresses, serviceV1Alpha1.bridgeAllowedAssets, common.Address{}) if test.wantErr == "" && err == nil { return }