Commit 0b7a9f7f authored by protolambda's avatar protolambda Committed by GitHub

op-node: make p2p sequencer addr rollup runtime configurable (#4529)

* op-node: remove p2p sequencer addr rollup config value, load during startup from L1

* op-node: use trie.VerifyProof instead of trie.Trie.TryGet
Co-authored-by: default avatarMatthew Slipper <me@matthewslipper.com>
parent 8ef4058d
...@@ -51,6 +51,7 @@ github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxG ...@@ -51,6 +51,7 @@ github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxG
github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s=
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
...@@ -82,8 +83,11 @@ github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= ...@@ -82,8 +83,11 @@ github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625 h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625 h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4=
github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI=
github.com/c-bata/go-prompt v0.2.2 h1:uyKRz6Z6DUyj49QVijyM339UJV9yhbr70gESwbNU3e0= github.com/c-bata/go-prompt v0.2.2 h1:uyKRz6Z6DUyj49QVijyM339UJV9yhbr70gESwbNU3e0=
github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g= github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g=
...@@ -101,6 +105,7 @@ github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA= ...@@ -101,6 +105,7 @@ github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rnb5MREYqG8ixi5+WbeUsquF0c= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rnb5MREYqG8ixi5+WbeUsquF0c=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
...@@ -111,6 +116,7 @@ github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572 h1:+R8G1+Ftumd0 ...@@ -111,6 +116,7 @@ github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572 h1:+R8G1+Ftumd0
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d h1:t5Wuyh53qYyg9eqn4BbnlIT+vmhyww0TatL+zT3uWgI=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
...@@ -119,8 +125,10 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBt ...@@ -119,8 +125,10 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf h1:CAKfRE2YtTUIjjh1bkBt
github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7 h1:6IrxszG5G+O7zhtkWxq6+unVvnrm1fqV2Pe+T95DUzw= github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7 h1:6IrxszG5G+O7zhtkWxq6+unVvnrm1fqV2Pe+T95DUzw=
github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c h1:/ovYnF02fwL0kvspmy9AuyKg1JhdTRUgPw4nUxd9oZM= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c h1:/ovYnF02fwL0kvspmy9AuyKg1JhdTRUgPw4nUxd9oZM=
github.com/dave/jennifer v1.2.0 h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc= github.com/dave/jennifer v1.2.0 h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc=
github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8=
github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE=
github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
...@@ -139,6 +147,7 @@ github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t ...@@ -139,6 +147,7 @@ github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw=
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 h1:dulLQAYQFYtG5MTplgNGHWuV2D+OBD+Z8lmDBmbLg+s= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 h1:dulLQAYQFYtG5MTplgNGHWuV2D+OBD+Z8lmDBmbLg+s=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
...@@ -234,6 +243,7 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8 ...@@ -234,6 +243,7 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU=
github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc=
...@@ -284,8 +294,10 @@ github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+ ...@@ -284,8 +294,10 @@ github.com/iris-contrib/schema v0.0.1 h1:10g/WnoRR+U+XXHWKBHeNy/+tZmM2kcAVGLOsz+
github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc= github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1 h1:ujPKutqRlJtcfWk6toYVYagwra7HQHbXOaS171b4Tg8= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1 h1:ujPKutqRlJtcfWk6toYVYagwra7HQHbXOaS171b4Tg8=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jsternberg/zap-logfmt v1.0.0 h1:0Dz2s/eturmdUS34GM82JwNEdQ9hPoJgqptcEKcbpzY= github.com/jsternberg/zap-logfmt v1.0.0 h1:0Dz2s/eturmdUS34GM82JwNEdQ9hPoJgqptcEKcbpzY=
...@@ -301,6 +313,7 @@ github.com/kataras/pio v0.0.2 h1:6NAi+uPJ/Zuid6mrAKlgpbI11/zK/lV4B2rxWaJN98Y= ...@@ -301,6 +313,7 @@ github.com/kataras/pio v0.0.2 h1:6NAi+uPJ/Zuid6mrAKlgpbI11/zK/lV4B2rxWaJN98Y=
github.com/kataras/sitemap v0.0.5 h1:4HCONX5RLgVy6G4RkYOV3vKNcma9p236LdGOipJsaFE= github.com/kataras/sitemap v0.0.5 h1:4HCONX5RLgVy6G4RkYOV3vKNcma9p236LdGOipJsaFE=
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE=
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio=
...@@ -336,6 +349,7 @@ github.com/libp2p/go-libp2p-yamux v0.8.2 h1:6GKWntresp0TFxMP/oSoH96nV8XKJRdynXsd ...@@ -336,6 +349,7 @@ github.com/libp2p/go-libp2p-yamux v0.8.2 h1:6GKWntresp0TFxMP/oSoH96nV8XKJRdynXsd
github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE=
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
github.com/libp2p/go-reuseport-transport v0.1.0 h1:C3PHeHjmnz8m6f0uydObj02tMEoi7CyD1zuN7xQT8gc= github.com/libp2p/go-reuseport-transport v0.1.0 h1:C3PHeHjmnz8m6f0uydObj02tMEoi7CyD1zuN7xQT8gc=
github.com/libp2p/go-sockaddr v0.0.2 h1:tCuXfpA9rq7llM/v834RKc/Xvovy/AqM9kHvTV/jY/Q=
github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0= github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlTDj0=
github.com/libp2p/go-stream-muxer-multistream v0.4.0 h1:HsM/9OdtqnIzjVXcxTXjmqKrj3gJ8kacaOJwJS1ipaY= github.com/libp2p/go-stream-muxer-multistream v0.4.0 h1:HsM/9OdtqnIzjVXcxTXjmqKrj3gJ8kacaOJwJS1ipaY=
github.com/libp2p/go-tcp-transport v0.5.1 h1:edOOs688VLZAozWC7Kj5/6HHXKNwi9M6wgRmmLa8M6Q= github.com/libp2p/go-tcp-transport v0.5.1 h1:edOOs688VLZAozWC7Kj5/6HHXKNwi9M6wgRmmLa8M6Q=
...@@ -445,6 +459,7 @@ github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJ ...@@ -445,6 +459,7 @@ github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJ
github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y= github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52 h1:RnWNS9Hlm8BIkjr6wx8li5abe0fr73jljLycdfemTp0= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52 h1:RnWNS9Hlm8BIkjr6wx8li5abe0fr73jljLycdfemTp0=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng=
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU=
......
...@@ -313,7 +313,6 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHas ...@@ -313,7 +313,6 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHas
ChannelTimeout: d.ChannelTimeout, ChannelTimeout: d.ChannelTimeout,
L1ChainID: new(big.Int).SetUint64(d.L1ChainID), L1ChainID: new(big.Int).SetUint64(d.L1ChainID),
L2ChainID: new(big.Int).SetUint64(d.L2ChainID), L2ChainID: new(big.Int).SetUint64(d.L2ChainID),
P2PSequencerAddress: d.P2PSequencerAddress,
BatchInboxAddress: d.BatchInboxAddress, BatchInboxAddress: d.BatchInboxAddress,
DepositContractAddress: d.OptimismPortalProxy, DepositContractAddress: d.OptimismPortalProxy,
L1SystemConfigAddress: d.SystemConfigProxy, L1SystemConfigAddress: d.SystemConfigProxy,
......
...@@ -52,7 +52,7 @@ type L2API interface { ...@@ -52,7 +52,7 @@ type L2API interface {
L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error) L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error)
InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error)
// GetProof returns a proof of the account, it may return a nil result without error if the address was not found. // GetProof returns a proof of the account, it may return a nil result without error if the address was not found.
GetProof(ctx context.Context, address common.Address, blockTag string) (*eth.AccountResult, error) GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error)
} }
func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, eng L2API, cfg *rollup.Config) *L2Verifier { func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, eng L2API, cfg *rollup.Config) *L2Verifier {
......
...@@ -41,7 +41,7 @@ func CollectAddresses(sd *SetupData, dp *DeployParams) (out []common.Address) { ...@@ -41,7 +41,7 @@ func CollectAddresses(sd *SetupData, dp *DeployParams) (out []common.Address) {
out = append(out, out = append(out,
sd.L1Cfg.Coinbase, sd.L1Cfg.Coinbase,
sd.L2Cfg.Coinbase, sd.L2Cfg.Coinbase,
sd.RollupCfg.P2PSequencerAddress, dp.Addresses.SequencerP2P,
predeploys.SequencerFeeVaultAddr, predeploys.SequencerFeeVaultAddr,
sd.RollupCfg.BatchInboxAddress, sd.RollupCfg.BatchInboxAddress,
sd.RollupCfg.Genesis.SystemConfig.BatcherAddr, sd.RollupCfg.Genesis.SystemConfig.BatcherAddr,
......
...@@ -6,16 +6,17 @@ import ( ...@@ -6,16 +6,17 @@ import (
"path" "path"
"time" "time"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
) )
var testingJWTSecret = [32]byte{123} var testingJWTSecret = [32]byte{123}
...@@ -207,7 +208,6 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) * ...@@ -207,7 +208,6 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
ChannelTimeout: deployConf.ChannelTimeout, ChannelTimeout: deployConf.ChannelTimeout,
L1ChainID: new(big.Int).SetUint64(deployConf.L1ChainID), L1ChainID: new(big.Int).SetUint64(deployConf.L1ChainID),
L2ChainID: new(big.Int).SetUint64(deployConf.L2ChainID), L2ChainID: new(big.Int).SetUint64(deployConf.L2ChainID),
P2PSequencerAddress: deployConf.P2PSequencerAddress,
BatchInboxAddress: deployConf.BatchInboxAddress, BatchInboxAddress: deployConf.BatchInboxAddress,
DepositContractAddress: predeploys.DevOptimismPortalAddr, DepositContractAddress: predeploys.DevOptimismPortalAddr,
L1SystemConfigAddress: predeploys.DevSystemConfigAddr, L1SystemConfigAddress: predeploys.DevSystemConfigAddr,
......
...@@ -19,6 +19,12 @@ import ( ...@@ -19,6 +19,12 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-bindings/hardhat" "github.com/ethereum-optimism/optimism/op-bindings/hardhat"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration_action" "github.com/ethereum-optimism/optimism/op-chain-ops/genesis/migration_action"
...@@ -31,11 +37,6 @@ import ( ...@@ -31,11 +37,6 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-node/rollup/driver"
"github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-service/backoff" "github.com/ethereum-optimism/optimism/op-service/backoff"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"
) )
type migrationTestConfig struct { type migrationTestConfig struct {
...@@ -296,7 +297,6 @@ func TestMigration(t *testing.T) { ...@@ -296,7 +297,6 @@ func TestMigration(t *testing.T) {
ChannelTimeout: deployCfg.ChannelTimeout, ChannelTimeout: deployCfg.ChannelTimeout,
L1ChainID: new(big.Int).SetUint64(deployCfg.L1ChainID), L1ChainID: new(big.Int).SetUint64(deployCfg.L1ChainID),
L2ChainID: new(big.Int).SetUint64(deployCfg.L2ChainID), L2ChainID: new(big.Int).SetUint64(deployCfg.L2ChainID),
P2PSequencerAddress: deployCfg.P2PSequencerAddress,
BatchInboxAddress: deployCfg.BatchInboxAddress, BatchInboxAddress: deployCfg.BatchInboxAddress,
DepositContractAddress: portal.Address, DepositContractAddress: portal.Address,
L1SystemConfigAddress: sysConfig.Address, L1SystemConfigAddress: sysConfig.Address,
......
...@@ -303,7 +303,6 @@ func (cfg SystemConfig) Start() (*System, error) { ...@@ -303,7 +303,6 @@ func (cfg SystemConfig) Start() (*System, error) {
ChannelTimeout: cfg.DeployConfig.ChannelTimeout, ChannelTimeout: cfg.DeployConfig.ChannelTimeout,
L1ChainID: cfg.L1ChainIDBig(), L1ChainID: cfg.L1ChainIDBig(),
L2ChainID: cfg.L2ChainIDBig(), L2ChainID: cfg.L2ChainIDBig(),
P2PSequencerAddress: cfg.DeployConfig.P2PSequencerAddress,
BatchInboxAddress: cfg.DeployConfig.BatchInboxAddress, BatchInboxAddress: cfg.DeployConfig.BatchInboxAddress,
DepositContractAddress: predeploys.DevOptimismPortalAddr, DepositContractAddress: predeploys.DevOptimismPortalAddr,
L1SystemConfigAddress: predeploys.DevSystemConfigAddr, L1SystemConfigAddress: predeploys.DevSystemConfigAddr,
......
...@@ -4,9 +4,10 @@ import ( ...@@ -4,9 +4,10 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
) )
var Beta1 = rollup.Config{ var Beta1 = rollup.Config{
...@@ -33,7 +34,6 @@ var Beta1 = rollup.Config{ ...@@ -33,7 +34,6 @@ var Beta1 = rollup.Config{
ChannelTimeout: 30, ChannelTimeout: 30,
L1ChainID: big.NewInt(5), L1ChainID: big.NewInt(5),
L2ChainID: big.NewInt(902), L2ChainID: big.NewInt(902),
P2PSequencerAddress: common.HexToAddress("0x42415b1258908bb27f34585133368900ba668dce"),
BatchInboxAddress: common.HexToAddress("0xFb3aECf08940785D4fB3Ad87cDC6e1Ceb20e9aac"), BatchInboxAddress: common.HexToAddress("0xFb3aECf08940785D4fB3Ad87cDC6e1Ceb20e9aac"),
DepositContractAddress: common.HexToAddress("0xf91795564662DcC9a17de67463ec5BA9C6DC207b"), DepositContractAddress: common.HexToAddress("0xf91795564662DcC9a17de67463ec5BA9C6DC207b"),
L1SystemConfigAddress: common.HexToAddress("0x686df068eaa71af78dadc1c427e35600e0fadac5"), L1SystemConfigAddress: common.HexToAddress("0x686df068eaa71af78dadc1c427e35600e0fadac5"),
......
...@@ -13,6 +13,12 @@ import ( ...@@ -13,6 +13,12 @@ import (
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
type StorageProofEntry struct {
Key common.Hash `json:"key"`
Value hexutil.Bytes `json:"value"`
Proof []hexutil.Bytes `json:"proof"`
}
type AccountResult struct { type AccountResult struct {
AccountProof []hexutil.Bytes `json:"accountProof"` AccountProof []hexutil.Bytes `json:"accountProof"`
...@@ -21,40 +27,57 @@ type AccountResult struct { ...@@ -21,40 +27,57 @@ type AccountResult struct {
CodeHash common.Hash `json:"codeHash"` CodeHash common.Hash `json:"codeHash"`
Nonce hexutil.Uint64 `json:"nonce"` Nonce hexutil.Uint64 `json:"nonce"`
StorageHash common.Hash `json:"storageHash"` StorageHash common.Hash `json:"storageHash"`
// storageProof field is ignored, we only need to proof the account contents,
// we do not access any individual storage values. // Optional
StorageProof []StorageProofEntry `json:"storageProof,omitempty"`
} }
// Verify an account proof from the getProof RPC. See https://eips.ethereum.org/EIPS/eip-1186 // Verify an account (and optionally storage) proof from the getProof RPC. See https://eips.ethereum.org/EIPS/eip-1186
func (res *AccountResult) Verify(stateRoot common.Hash) error { func (res *AccountResult) Verify(stateRoot common.Hash) error {
// verify storage proof values, if any, against the storage trie root hash of the account
for i, entry := range res.StorageProof {
// load all MPT nodes into a DB
db := memorydb.New()
for j, encodedNode := range entry.Proof {
nodeKey := encodedNode
if len(encodedNode) >= 32 { // small MPT nodes are not hashed
nodeKey = crypto.Keccak256(encodedNode)
}
if err := db.Put(nodeKey, encodedNode); err != nil {
return fmt.Errorf("failed to load storage proof node %d of storage value %d into mem db: %w", j, i, err)
}
}
path := crypto.Keccak256(entry.Key[:])
val, err := trie.VerifyProof(res.StorageHash, path, db)
if err != nil {
return fmt.Errorf("failed to verify storage value %d with key %s (path %x) in storage trie %s: %w", i, entry.Key, path, res.StorageHash, err)
}
if !bytes.Equal(val, val) {
return fmt.Errorf("value %d in storage proof does not match proven value at key %s (path %x)", i, entry.Key, path)
}
}
accountClaimed := []any{uint64(res.Nonce), (*big.Int)(res.Balance).Bytes(), res.StorageHash, res.CodeHash} accountClaimed := []any{uint64(res.Nonce), (*big.Int)(res.Balance).Bytes(), res.StorageHash, res.CodeHash}
accountClaimedValue, err := rlp.EncodeToBytes(accountClaimed) accountClaimedValue, err := rlp.EncodeToBytes(accountClaimed)
if err != nil { if err != nil {
return fmt.Errorf("failed to encode account from retrieved values: %w", err) return fmt.Errorf("failed to encode account from retrieved values: %w", err)
} }
// create a db with all trie nodes // create a db with all account trie nodes
db := memorydb.New() db := memorydb.New()
for i, encodedNode := range res.AccountProof { for i, encodedNode := range res.AccountProof {
nodeKey := crypto.Keccak256(encodedNode) nodeKey := encodedNode
if len(encodedNode) >= 32 { // small MPT nodes are not hashed
nodeKey = crypto.Keccak256(encodedNode)
}
if err := db.Put(nodeKey, encodedNode); err != nil { if err := db.Put(nodeKey, encodedNode); err != nil {
return fmt.Errorf("failed to load proof value %d into mem db: %w", i, err) return fmt.Errorf("failed to load account proof node %d into mem db: %w", i, err)
} }
} }
path := crypto.Keccak256(res.Address[:])
key := crypto.Keccak256Hash(res.Address[:]) accountProofValue, err := trie.VerifyProof(stateRoot, path, db)
trieDB := trie.NewDatabase(db)
// wrap our DB of trie nodes with a Trie interface, and anchor it at the trusted state root
proofTrie, err := trie.New(trie.StateTrieID(stateRoot), trieDB)
if err != nil {
return fmt.Errorf("failed to load db wrapper around kv store")
}
// now get the full value from the account proof, and check that it matches the JSON contents
accountProofValue, err := proofTrie.TryGet(key[:])
if err != nil { if err != nil {
return fmt.Errorf("failed to retrieve account value: %w", err) return fmt.Errorf("failed to verify account value with key %s (path %x) in account trie %s: %w", res.Address, path, stateRoot, err)
} }
if !bytes.Equal(accountClaimedValue, accountProofValue) { if !bytes.Equal(accountClaimedValue, accountProofValue) {
......
package eth
import (
"encoding/json"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestAccountResult_Verify(t *testing.T) {
// Example account result: a SystemConfig storage read, to proof the value of slot 103 (0x67) equals some address,
// which would be RLP-encoded when retrieved as value from a trie node.
resultData := `
{
"accountProof": [
"0xf90211a03d0bbcace6414d254eb5ee34923da6dadda532025554251fccb0f3e401f97f64a00b0060669e7d8bee64b69cd327edd83aec3839bcdc2c51df61a87d26c06a6e6da0c0325f24cc335b26d107c0704a0c88d96aac42cb807f732d45196ba2b3ec6f4fa0be4d5280fb18316c250432acd5272e0558a850e2b17803e2262a0f12ec7293cda0584c838d31e2b8b7b1b61ea86ec96c14de6f8e48b5085ab88f26022e46c434f3a033ce2881dfbf590f36e88d999b52b5f88fa3e2845aa069f354fffc4657269db0a0bc0d89addbe9e9dd1b4570e6403b9540c631d4b018d6a30dee0d6b1416d79f7da0b208a7628b6e33e21638856ae0cf77f0245aab58300a3ea459b049fcbcf7c95aa01d16509886c5fef9deee332e82ca26739b35acfc192c4fd5f31310caf9996304a062a1114d555e0657a953a9e79156ecf6323629961afe756c846a1222c415999aa0e3ae9195242e45330d273187de63ccd74c2ab787dc50e0ff3edbc8ef47cd3b2da0c1b261a54efdfa3596cec84a23784ed051bc346b80dbf0694dc7d39356c212eea04512835bd07815d2bcc00f25ea70dee0f0a770b16d16250f7d5c884b0d440581a0ee25f14adcbd0dc55d15a2148deae12c3ab9c6a001c6e899e22d3e0890999083a01c0c47189ac3d6931aa05fbe3cd4140a1794f68b724b1804f46d2705435f08caa0d9a14e2b4e6778a2405bc7931934b5e97b8e3a2033eedb30409896420a2db44b80",
"0xf90211a0e65e35c2066e63b933bd300ad97883dbcf4e2d2df8a540aa3964f5354e2bb8dba0814e82409c1813007af146f3b47f0e0d6da4c2885de8f34f034826bcb4c4c9e7a07d726afe2a20f4928e8715d80bc5aff5fc30c05b1e953372d564cba93d3b45bda02fc8df4a480ea0402f48aa206047ef0acbedf1a7033153c60d5ec4dfb9ee30cca05ecda76647515fb8342434b5a36faec2f17fc729ea369edcf7a42cd235c51fa2a0ab51933d2bde083801bd7fedb17ec22ae5231e508c62d66e9dccbd598c1d98fda0e2af2dc4a1b87147a5e388388ee5d1aafb415498e1011e87df127cc8d57616eca00bb9b95cfda6476e321ca441f523f80cb13519e537679ad6139600b35c91b5b1a0e3aae75bdc65365e2f8bb9c8646a4118d302076e0d9de95fc4425e82680ed912a0124bb32fc404a8647d7192f438a2bca8c52877b02a921b014fe4a192982bcf9ea0da2df7e5f41d6e38cc48fd9d0ca91bc96ff6ffa336b75784b3e23cd8dfddc0b1a0f7fc4a6792cdf964423f705935f0338128d099c83a74c2b76c688ecda8f23ffea009b2347ed0222d713137ad280310fad2ca92f007b5fd3ed1b768a6b52b5040d6a07b5bfe1bbd07575f26d97b9a0e8c67cd11d251f3d8bc823ade462daee2309e4ba02d2e464a4ad06d6dca6cb54e31fb5aac85dc9c5bab420a2c7c1ca986991f4d1da0cd5f723720652dec2a8bbba3bad3f73fb16b83a31d28a707fd0e0f85370eae6380",
"0xf90151a04df2503da3b2491b68d13d2735005e451ca9cae77d336061df9250e0d3592e0ca01580374cce4fa8401d9fdeebb037e96c3f9c03873aec0637b43ba809fa8e53a9a0101d14d18ee6c9bf21f8292b155e40462605d15d315337e0f1098479d9ba6d1b80a0d0baf298792955a012fc458a97de8b3b2319911c3a82e427b5424fb544ac1ea080a09b2cc83f7e69b3c46bde63e4805d1aa9a064c0220532de547693122bba9b24458080a0a44850b8b25ced24d074182424ab7aa668b78acaa64e2da1854d04093332153b80a00b513b7944399ac7e2291ab7cdc1b99f0445256cc3f0c3b6b5c2d50eab4f9887a06b979f3c7a2a1d95af02c44d015ac42202cd0df8c19b629f6089a6a2a181d69aa0eb0216e118a1b797b90165cea439923e58bc672b81573ae44156cf38632fa36880a0e16e6a4603316f2fa41cd7d0a8fc9a8dca7ca36763abe39b99ef57b83adf501180",
"0xf8689f3b8dff764734b5790096e811fc30835b13a5bea290831c7c6722f325a5f818b846f8448080a0dd6d0b4dba95e79439c501e2109ded26989a53ca4641e1f48bf702e7361637e9a01f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35"
],
"address": "0x6900000000000000000000000000000000000009",
"balance": "0x0",
"codeHash": "0x1f958654ab06a152993e7a0ae7b6dbb0d4b19265cc9337b8789fe1353bd9dc35",
"nonce": "0x0",
"storageHash": "0xdd6d0b4dba95e79439c501e2109ded26989a53ca4641e1f48bf702e7361637e9",
"storageProof": [
{
"key": "0x0000000000000000000000000000000000000000000000000000000000000067",
"value": "0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc",
"proof": [
"0xf8f18080a04fc5f13ab2f9ba0c2da88b0151ab0e7cf4d85d08cca45ccd923c6ab76323eb2880a0f57febb7b16455e051f412a56e54016c676a3d4aa515d2e77a90520dfe36162ea0558f72e6d0e3b401856defa90b07dd0442282592b3ca718e2dc919ea53b8e69280a04f893abcf66ae78abb4ac986ddf78bdf95a7b15079be06cc5756f78d772271eba0c1529c7d0f249fd7060e930515ac4980103920979274f56b07419bf33be4d3d7a0a055722fdc9281d825dfc17c2ae775aba5b283954f5c484fc7e0e5a148131e2ea02833bc13e1f58010a678009d7d5982b892b3ba1432ca6b06f8a849b71491b51e808080808080",
"0xf7a03787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae95949965507d1a55bcc2695c58ba16fb37d819b0a4dc"
]
}
]
}
`
var result AccountResult
require.NoError(t, json.Unmarshal([]byte(resultData), &result))
require.NoError(t, result.Verify(common.HexToHash("0xb3a98a923c23cf25cbe04485f55243b37b29b7e12760bd24368ace23bf370e7a")), "verifies against good state root")
require.NotNil(t, result.Verify(common.HexToHash("0xb3a98a923c23cf25cbe04485f55243b37b29b7e12760bd24368ace23bf370e7b")), "does not verify against other state root")
}
...@@ -18,7 +18,8 @@ import ( ...@@ -18,7 +18,8 @@ import (
type l2EthClient interface { type l2EthClient interface {
InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error)
// GetProof returns a proof of the account, it may return a nil result without error if the address was not found. // GetProof returns a proof of the account, it may return a nil result without error if the address was not found.
GetProof(ctx context.Context, address common.Address, blockTag string) (*eth.AccountResult, error) // Optionally keys of the account storage trie can be specified to include with corresponding values in the proof.
GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error)
} }
type driverClient interface { type driverClient interface {
...@@ -85,7 +86,7 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et ...@@ -85,7 +86,7 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
return nil, ethereum.NotFound return nil, ethereum.NotFound
} }
proof, err := n.client.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, ref.Hash.String()) proof, err := n.client.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, []common.Hash{}, ref.Hash.String())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get contract proof at block %s: %w", ref, err) return nil, fmt.Errorf("failed to get contract proof at block %s: %w", ref, err)
} }
......
...@@ -2,6 +2,7 @@ package node ...@@ -2,6 +2,7 @@ package node
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"time" "time"
...@@ -36,6 +37,7 @@ type OpNode struct { ...@@ -36,6 +37,7 @@ type OpNode struct {
p2pNode *p2p.NodeP2P // P2P node functionality p2pNode *p2p.NodeP2P // P2P node functionality
p2pSigner p2p.Signer // p2p gogssip application messages will be signed with this signer p2pSigner p2p.Signer // p2p gogssip application messages will be signed with this signer
tracer Tracer // tracer to get events for testing/debugging tracer Tracer // tracer to get events for testing/debugging
runCfg *RuntimeConfig // runtime configurables
// some resources cannot be stopped directly, like the p2p gossipsub router (not our design), // some resources cannot be stopped directly, like the p2p gossipsub router (not our design),
// and depend on this ctx to be closed. // and depend on this ctx to be closed.
...@@ -78,6 +80,9 @@ func (n *OpNode) init(ctx context.Context, cfg *Config, snapshotLog log.Logger) ...@@ -78,6 +80,9 @@ func (n *OpNode) init(ctx context.Context, cfg *Config, snapshotLog log.Logger)
if err := n.initL1(ctx, cfg); err != nil { if err := n.initL1(ctx, cfg); err != nil {
return err return err
} }
if err := n.initRuntimeConfig(ctx, cfg); err != nil {
return err
}
if err := n.initL2(ctx, cfg, snapshotLog); err != nil { if err := n.initL2(ctx, cfg, snapshotLog); err != nil {
return err return err
} }
...@@ -143,6 +148,33 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { ...@@ -143,6 +148,33 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error {
return nil return nil
} }
func (n *OpNode) initRuntimeConfig(ctx context.Context, cfg *Config) error {
// attempt to load runtime config, repeat N times
n.runCfg = NewRuntimeConfig(n.log, n.l1Source, &cfg.Rollup)
for i := 0; i < 5; i++ {
fetchCtx, fetchCancel := context.WithTimeout(ctx, time.Second*10)
l1Head, err := n.l1Source.L1BlockRefByLabel(fetchCtx, eth.Unsafe)
fetchCancel()
if err != nil {
n.log.Error("failed to fetch L1 head for runtime config initialization", "err", err)
continue
}
fetchCtx, fetchCancel = context.WithTimeout(ctx, time.Second*10)
err = n.runCfg.Load(fetchCtx, l1Head)
fetchCancel()
if err != nil {
n.log.Error("failed to fetch runtime config data", "err", err)
continue
}
return nil
}
return errors.New("failed to load runtime configuration repeatedly")
}
func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger) error { func (n *OpNode) initL2(ctx context.Context, cfg *Config, snapshotLog log.Logger) error {
rpcClient, err := cfg.L2.Setup(ctx, n.log) rpcClient, err := cfg.L2.Setup(ctx, n.log)
if err != nil { if err != nil {
...@@ -197,7 +229,7 @@ func (n *OpNode) initMetricsServer(ctx context.Context, cfg *Config) error { ...@@ -197,7 +229,7 @@ func (n *OpNode) initMetricsServer(ctx context.Context, cfg *Config) error {
func (n *OpNode) initP2P(ctx context.Context, cfg *Config) error { func (n *OpNode) initP2P(ctx context.Context, cfg *Config) error {
if cfg.P2P != nil { if cfg.P2P != nil {
p2pNode, err := p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.metrics) p2pNode, err := p2p.NewNodeP2P(n.resourcesCtx, &cfg.Rollup, n.log, cfg.P2P, n, n.runCfg, n.metrics)
if err != nil || p2pNode == nil { if err != nil || p2pNode == nil {
return err return err
} }
......
package node
import (
"context"
"fmt"
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/p2p"
"github.com/ethereum-optimism/optimism/op-node/rollup"
)
var (
// UnsafeBlockSignerAddressSystemConfigStorageSlot is the storage slot identifier of the unsafeBlockSigner
// `address` storage value in the SystemConfig L1 contract.
UnsafeBlockSignerAddressSystemConfigStorageSlot = common.Hash{31: 103}
)
type RuntimeCfgL1Source interface {
ReadStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockHash common.Hash) (common.Hash, error)
}
// RuntimeConfig maintains runtime-configurable options.
// These options are loaded based on initial loading + updates for every subsequent L1 block.
// Only the *latest* values are maintained however, the runtime config has no concept of chain history,
// does not require any archive data, and may be out of sync with the rollup derivation process.
type RuntimeConfig struct {
mu sync.RWMutex
log log.Logger
l1Client RuntimeCfgL1Source
rollupCfg *rollup.Config
// l1Ref is the current source of the data,
// if this is invalidated with a reorg the data will have to be reloaded.
l1Ref eth.L1BlockRef
runtimeConfigData
}
// runtimeConfigData is a flat bundle of configurable data, easy and light to copy around.
type runtimeConfigData struct {
p2pBlockSignerAddr common.Address
}
var _ p2p.GossipRuntimeConfig = (*RuntimeConfig)(nil)
func NewRuntimeConfig(log log.Logger, l1Client RuntimeCfgL1Source, rollupCfg *rollup.Config) *RuntimeConfig {
return &RuntimeConfig{
log: log,
l1Client: l1Client,
rollupCfg: rollupCfg,
}
}
func (r *RuntimeConfig) P2PSequencerAddress() common.Address {
r.mu.RLock()
defer r.mu.RUnlock()
return r.p2pBlockSignerAddr
}
// Load resets the runtime configuration by fetching the latest config data from L1 at the given L1 block.
// Load is safe to call concurrently, but will lock the runtime configuration modifications only,
// and will thus not block other Load calls with possibly alternative L1 block views.
func (r *RuntimeConfig) Load(ctx context.Context, l1Ref eth.L1BlockRef) error {
val, err := r.l1Client.ReadStorageAt(ctx, r.rollupCfg.L1SystemConfigAddress, UnsafeBlockSignerAddressSystemConfigStorageSlot, l1Ref.Hash)
if err != nil {
return fmt.Errorf("failed to fetch unsafe block signing address from system config: %w", err)
}
r.mu.Lock()
defer r.mu.Unlock()
r.l1Ref = l1Ref
r.p2pBlockSignerAddr = common.BytesToAddress(val[:])
r.log.Info("loaded new runtime config values!", "p2p_seq_address", r.p2pBlockSignerAddr)
return nil
}
...@@ -104,7 +104,7 @@ func TestOutputAtBlock(t *testing.T) { ...@@ -104,7 +104,7 @@ func TestOutputAtBlock(t *testing.T) {
SequenceNumber: 0, SequenceNumber: 0,
} }
l2Client.ExpectInfoByHash(common.HexToHash("0x8512bee03061475e4b069171f7b406097184f16b22c3f5c97c0abfc49591c524"), info, nil) l2Client.ExpectInfoByHash(common.HexToHash("0x8512bee03061475e4b069171f7b406097184f16b22c3f5c97c0abfc49591c524"), info, nil)
l2Client.ExpectGetProof(predeploys.L2ToL1MessagePasserAddr, "0x8512bee03061475e4b069171f7b406097184f16b22c3f5c97c0abfc49591c524", &result, nil) l2Client.ExpectGetProof(predeploys.L2ToL1MessagePasserAddr, []common.Hash{}, "0x8512bee03061475e4b069171f7b406097184f16b22c3f5c97c0abfc49591c524", &result, nil)
drClient := &mockDriverClient{} drClient := &mockDriverClient{}
status := randomSyncStatus(rand.New(rand.NewSource(123))) status := randomSyncStatus(rand.New(rand.NewSource(123)))
......
...@@ -43,6 +43,10 @@ const ( ...@@ -43,6 +43,10 @@ const (
var MessageDomainInvalidSnappy = [4]byte{0, 0, 0, 0} var MessageDomainInvalidSnappy = [4]byte{0, 0, 0, 0}
var MessageDomainValidSnappy = [4]byte{1, 0, 0, 0} var MessageDomainValidSnappy = [4]byte{1, 0, 0, 0}
type GossipRuntimeConfig interface {
P2PSequencerAddress() common.Address
}
type GossipMetricer interface { type GossipMetricer interface {
RecordGossipEvent(evType int32) RecordGossipEvent(evType int32)
} }
...@@ -201,7 +205,7 @@ func (sb *seenBlocks) markSeen(h common.Hash) { ...@@ -201,7 +205,7 @@ func (sb *seenBlocks) markSeen(h common.Hash) {
sb.blockHashes = append(sb.blockHashes, h) sb.blockHashes = append(sb.blockHashes, h)
} }
func BuildBlocksValidator(log log.Logger, cfg *rollup.Config) pubsub.ValidatorEx { func BuildBlocksValidator(log log.Logger, cfg *rollup.Config, runCfg GossipRuntimeConfig) pubsub.ValidatorEx {
// Seen block hashes per block height // Seen block hashes per block height
// uint64 -> *seenBlocks // uint64 -> *seenBlocks
...@@ -252,9 +256,16 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config) pubsub.ValidatorEx ...@@ -252,9 +256,16 @@ func BuildBlocksValidator(log log.Logger, cfg *rollup.Config) pubsub.ValidatorEx
} }
addr := crypto.PubkeyToAddress(*pub) addr := crypto.PubkeyToAddress(*pub)
// TODO: in the future we can support multiple valid p2p addresses. // In the future we may load & validate block metadata before checking the signature.
if addr != cfg.P2PSequencerAddress { // And then check the signer based on the metadata, to support e.g. multiple p2p signers at the same time.
log.Warn("unexpected block author", "err", err, "peer", id) // For now we only have one signer at a time and thus check the address directly.
// This means we may drop old payloads upon key rotation,
// but this can be recovered from like any other missed unsafe payload.
if expected := runCfg.P2PSequencerAddress(); expected == (common.Address{}) {
log.Warn("no configured p2p sequencer address, ignoring gossiped block", "peer", id, "addr", addr)
return pubsub.ValidationIgnore
} else if addr != expected {
log.Warn("unexpected block author", "err", err, "peer", id, "addr", addr, "expected", expected)
return pubsub.ValidationReject return pubsub.ValidationReject
} }
...@@ -330,6 +341,7 @@ type publisher struct { ...@@ -330,6 +341,7 @@ type publisher struct {
log log.Logger log log.Logger
cfg *rollup.Config cfg *rollup.Config
blocksTopic *pubsub.Topic blocksTopic *pubsub.Topic
runCfg GossipRuntimeConfig
} }
var _ GossipOut = (*publisher)(nil) var _ GossipOut = (*publisher)(nil)
...@@ -369,8 +381,8 @@ func (p *publisher) Close() error { ...@@ -369,8 +381,8 @@ func (p *publisher) Close() error {
return p.blocksTopic.Close() return p.blocksTopic.Close()
} }
func JoinGossip(p2pCtx context.Context, self peer.ID, ps *pubsub.PubSub, log log.Logger, cfg *rollup.Config, gossipIn GossipIn) (GossipOut, error) { func JoinGossip(p2pCtx context.Context, self peer.ID, ps *pubsub.PubSub, log log.Logger, cfg *rollup.Config, runCfg GossipRuntimeConfig, gossipIn GossipIn) (GossipOut, error) {
val := guardGossipValidator(log, logValidationResult(self, "validated block", log, BuildBlocksValidator(log, cfg))) val := guardGossipValidator(log, logValidationResult(self, "validated block", log, BuildBlocksValidator(log, cfg, runCfg)))
blocksTopicName := blocksTopicV1(cfg) blocksTopicName := blocksTopicV1(cfg)
err := ps.RegisterTopicValidator(blocksTopicName, err := ps.RegisterTopicValidator(blocksTopicName,
val, val,
...@@ -403,7 +415,7 @@ func JoinGossip(p2pCtx context.Context, self peer.ID, ps *pubsub.PubSub, log log ...@@ -403,7 +415,7 @@ func JoinGossip(p2pCtx context.Context, self peer.ID, ps *pubsub.PubSub, log log
subscriber := MakeSubscriber(log, BlocksHandler(gossipIn.OnUnsafeL2Payload)) subscriber := MakeSubscriber(log, BlocksHandler(gossipIn.OnUnsafeL2Payload))
go subscriber(p2pCtx, subscription) go subscriber(p2pCtx, subscription)
return &publisher{log: log, cfg: cfg, blocksTopic: blocksTopic}, nil return &publisher{log: log, cfg: cfg, blocksTopic: blocksTopic, runCfg: runCfg}, nil
} }
type TopicSubscriber func(ctx context.Context, sub *pubsub.Subscription) type TopicSubscriber func(ctx context.Context, sub *pubsub.Subscription)
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/ethereum/go-ethereum/common"
ds "github.com/ipfs/go-datastore" ds "github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/sync" "github.com/ipfs/go-datastore/sync"
lconf "github.com/libp2p/go-libp2p/config" lconf "github.com/libp2p/go-libp2p/config"
...@@ -27,6 +28,7 @@ import ( ...@@ -27,6 +28,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
) )
func TestingConfig(t *testing.T) *Config { func TestingConfig(t *testing.T) *Config {
...@@ -131,8 +133,11 @@ func TestP2PFull(t *testing.T) { ...@@ -131,8 +133,11 @@ func TestP2PFull(t *testing.T) {
confB.Store = sync.MutexWrap(ds.NewMapDatastore()) confB.Store = sync.MutexWrap(ds.NewMapDatastore())
// TODO: maybe swap the order of sec/mux preferences, to test that negotiation works // TODO: maybe swap the order of sec/mux preferences, to test that negotiation works
runCfgA := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}}
runCfgB := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}}
logA := testlog.Logger(t, log.LvlError).New("host", "A") logA := testlog.Logger(t, log.LvlError).New("host", "A")
nodeA, err := NewNodeP2P(context.Background(), &rollup.Config{}, logA, &confA, &mockGossipIn{}, nil) nodeA, err := NewNodeP2P(context.Background(), &rollup.Config{}, logA, &confA, &mockGossipIn{}, runCfgA, nil)
require.NoError(t, err) require.NoError(t, err)
defer nodeA.Close() defer nodeA.Close()
...@@ -155,7 +160,7 @@ func TestP2PFull(t *testing.T) { ...@@ -155,7 +160,7 @@ func TestP2PFull(t *testing.T) {
logB := testlog.Logger(t, log.LvlError).New("host", "B") logB := testlog.Logger(t, log.LvlError).New("host", "B")
nodeB, err := NewNodeP2P(context.Background(), &rollup.Config{}, logB, &confB, &mockGossipIn{}, nil) nodeB, err := NewNodeP2P(context.Background(), &rollup.Config{}, logB, &confB, &mockGossipIn{}, runCfgB, nil)
require.NoError(t, err) require.NoError(t, err)
defer nodeB.Close() defer nodeB.Close()
hostB := nodeB.Host() hostB := nodeB.Host()
...@@ -286,10 +291,14 @@ func TestDiscovery(t *testing.T) { ...@@ -286,10 +291,14 @@ func TestDiscovery(t *testing.T) {
confB.Store = sync.MutexWrap(ds.NewMapDatastore()) confB.Store = sync.MutexWrap(ds.NewMapDatastore())
confB.DiscoveryDB = discDBB confB.DiscoveryDB = discDBB
runCfgA := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}}
runCfgB := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}}
runCfgC := &testutils.MockRuntimeConfig{P2PSeqAddress: common.Address{0x42}}
resourcesCtx, resourcesCancel := context.WithCancel(context.Background()) resourcesCtx, resourcesCancel := context.WithCancel(context.Background())
defer resourcesCancel() defer resourcesCancel()
nodeA, err := NewNodeP2P(context.Background(), rollupCfg, logA, &confA, &mockGossipIn{}, nil) nodeA, err := NewNodeP2P(context.Background(), rollupCfg, logA, &confA, &mockGossipIn{}, runCfgA, nil)
require.NoError(t, err) require.NoError(t, err)
defer nodeA.Close() defer nodeA.Close()
hostA := nodeA.Host() hostA := nodeA.Host()
...@@ -304,7 +313,7 @@ func TestDiscovery(t *testing.T) { ...@@ -304,7 +313,7 @@ func TestDiscovery(t *testing.T) {
confB.DiscoveryDB = discDBC confB.DiscoveryDB = discDBC
// Start B // Start B
nodeB, err := NewNodeP2P(context.Background(), rollupCfg, logB, &confB, &mockGossipIn{}, nil) nodeB, err := NewNodeP2P(context.Background(), rollupCfg, logB, &confB, &mockGossipIn{}, runCfgB, nil)
require.NoError(t, err) require.NoError(t, err)
defer nodeB.Close() defer nodeB.Close()
hostB := nodeB.Host() hostB := nodeB.Host()
...@@ -319,7 +328,7 @@ func TestDiscovery(t *testing.T) { ...@@ -319,7 +328,7 @@ func TestDiscovery(t *testing.T) {
}}) }})
// Start C // Start C
nodeC, err := NewNodeP2P(context.Background(), rollupCfg, logC, &confC, &mockGossipIn{}, nil) nodeC, err := NewNodeP2P(context.Background(), rollupCfg, logC, &confC, &mockGossipIn{}, runCfgC, nil)
require.NoError(t, err) require.NoError(t, err)
defer nodeC.Close() defer nodeC.Close()
hostC := nodeC.Host() hostC := nodeC.Host()
......
...@@ -34,12 +34,12 @@ type NodeP2P struct { ...@@ -34,12 +34,12 @@ type NodeP2P struct {
gsOut GossipOut // p2p gossip application interface for publishing gsOut GossipOut // p2p gossip application interface for publishing
} }
func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, metrics metrics.Metricer) (*NodeP2P, error) { func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, runCfg GossipRuntimeConfig, metrics metrics.Metricer) (*NodeP2P, error) {
if setup == nil { if setup == nil {
return nil, errors.New("p2p node cannot be created without setup") return nil, errors.New("p2p node cannot be created without setup")
} }
var n NodeP2P var n NodeP2P
if err := n.init(resourcesCtx, rollupCfg, log, setup, gossipIn, metrics); err != nil { if err := n.init(resourcesCtx, rollupCfg, log, setup, gossipIn, runCfg, metrics); err != nil {
closeErr := n.Close() closeErr := n.Close()
if closeErr != nil { if closeErr != nil {
log.Error("failed to close p2p after starting with err", "closeErr", closeErr, "err", err) log.Error("failed to close p2p after starting with err", "closeErr", closeErr, "err", err)
...@@ -52,7 +52,7 @@ func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log. ...@@ -52,7 +52,7 @@ func NewNodeP2P(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.
return &n, nil return &n, nil
} }
func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, metrics metrics.Metricer) error { func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, log log.Logger, setup SetupP2P, gossipIn GossipIn, runCfg GossipRuntimeConfig, metrics metrics.Metricer) error {
bwc := p2pmetrics.NewBandwidthCounter() bwc := p2pmetrics.NewBandwidthCounter()
var err error var err error
...@@ -80,7 +80,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l ...@@ -80,7 +80,7 @@ func (n *NodeP2P) init(resourcesCtx context.Context, rollupCfg *rollup.Config, l
return fmt.Errorf("failed to start gossipsub router: %w", err) return fmt.Errorf("failed to start gossipsub router: %w", err)
} }
n.gsOut, err = JoinGossip(resourcesCtx, n.host.ID(), n.gs, log, rollupCfg, gossipIn) n.gsOut, err = JoinGossip(resourcesCtx, n.host.ID(), n.gs, log, rollupCfg, runCfg, gossipIn)
if err != nil { if err != nil {
return fmt.Errorf("failed to join blocks gossip topic: %w", err) return fmt.Errorf("failed to join blocks gossip topic: %w", err)
} }
......
...@@ -15,9 +15,10 @@ import ( ...@@ -15,9 +15,10 @@ import (
) )
var ( var (
SystemConfigUpdateBatcher = common.Hash{31: 0} SystemConfigUpdateBatcher = common.Hash{31: 0}
SystemConfigUpdateGasConfig = common.Hash{31: 1} SystemConfigUpdateGasConfig = common.Hash{31: 1}
SystemConfigUpdateGasLimit = common.Hash{31: 2} SystemConfigUpdateGasLimit = common.Hash{31: 2}
SystemConfigUpdateUnsafeBlockSigner = common.Hash{31: 3}
) )
var ( var (
...@@ -113,6 +114,9 @@ func ProcessSystemConfigUpdateLogEvent(destSysCfg *eth.SystemConfig, ev *types.L ...@@ -113,6 +114,9 @@ func ProcessSystemConfigUpdateLogEvent(destSysCfg *eth.SystemConfig, ev *types.L
} }
destSysCfg.GasLimit = binary.BigEndian.Uint64(ev.Data[64+24:]) destSysCfg.GasLimit = binary.BigEndian.Uint64(ev.Data[64+24:])
return nil return nil
case SystemConfigUpdateUnsafeBlockSigner:
// Ignored in derivation. This configurable applies to runtime configuration outside of the derivation.
return nil
default: default:
return fmt.Errorf("unrecognized L1 sysCfg update type: %s", updateType) return fmt.Errorf("unrecognized L1 sysCfg update type: %s", updateType)
} }
......
...@@ -44,9 +44,6 @@ type Config struct { ...@@ -44,9 +44,6 @@ type Config struct {
// Required to identify the L2 network and create p2p signatures unique for this chain. // Required to identify the L2 network and create p2p signatures unique for this chain.
L2ChainID *big.Int `json:"l2_chain_id"` L2ChainID *big.Int `json:"l2_chain_id"`
// Address of the key the sequencer uses to sign blocks on the P2P layer
P2PSequencerAddress common.Address `json:"p2p_sequencer_address"`
// Note: below addresses are part of the block-derivation process, // Note: below addresses are part of the block-derivation process,
// and required to be the same network-wide to stay in consensus. // and required to be the same network-wide to stay in consensus.
...@@ -93,9 +90,6 @@ func (cfg *Config) Check() error { ...@@ -93,9 +90,6 @@ func (cfg *Config) Check() error {
if cfg.Genesis.SystemConfig.GasLimit == 0 { if cfg.Genesis.SystemConfig.GasLimit == 0 {
return errors.New("missing genesis system config gas limit") return errors.New("missing genesis system config gas limit")
} }
if cfg.P2PSequencerAddress == (common.Address{}) {
return errors.New("missing p2p sequencer address")
}
if cfg.BatchInboxAddress == (common.Address{}) { if cfg.BatchInboxAddress == (common.Address{}) {
return errors.New("missing batch inbox address") return errors.New("missing batch inbox address")
} }
......
...@@ -41,7 +41,6 @@ func randConfig() *Config { ...@@ -41,7 +41,6 @@ func randConfig() *Config {
ChannelTimeout: 123, ChannelTimeout: 123,
L1ChainID: big.NewInt(900), L1ChainID: big.NewInt(900),
L2ChainID: big.NewInt(901), L2ChainID: big.NewInt(901),
P2PSequencerAddress: randAddr(),
BatchInboxAddress: randAddr(), BatchInboxAddress: randAddr(),
DepositContractAddress: randAddr(), DepositContractAddress: randAddr(),
L1SystemConfigAddress: randAddr(), L1SystemConfigAddress: randAddr(),
......
...@@ -265,13 +265,58 @@ func (s *EthClient) FetchReceipts(ctx context.Context, blockHash common.Hash) (e ...@@ -265,13 +265,58 @@ func (s *EthClient) FetchReceipts(ctx context.Context, blockHash common.Hash) (e
return info, receipts, nil return info, receipts, nil
} }
func (s *EthClient) GetProof(ctx context.Context, address common.Address, blockTag string) (*eth.AccountResult, error) { // GetProof returns an account proof result, with any optional requested storage proofs.
// The retrieval does sanity-check that storage proofs for the expected keys are present in the response,
// but does not verify the result. Call accountResult.Verify(stateRoot) to verify the result.
func (s *EthClient) GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error) {
var getProofResponse *eth.AccountResult var getProofResponse *eth.AccountResult
err := s.client.CallContext(ctx, &getProofResponse, "eth_getProof", address, []common.Hash{}, blockTag) err := s.client.CallContext(ctx, &getProofResponse, "eth_getProof", address, storage, blockTag)
if err == nil && getProofResponse == nil { if err != nil {
err = ethereum.NotFound return nil, err
}
if getProofResponse == nil {
return nil, ethereum.NotFound
}
if len(getProofResponse.StorageProof) != len(storage) {
return nil, fmt.Errorf("missing storage proof data, got %d proof entries but requested %d storage keys", len(getProofResponse.StorageProof), len(storage))
}
for i, key := range storage {
if key != getProofResponse.StorageProof[i].Key {
return nil, fmt.Errorf("unexpected storage proof key difference for entry %d: got %s but requested %s", i, getProofResponse.StorageProof[i].Key, key)
}
}
return getProofResponse, nil
}
// GetStorageAt returns the storage value at the given address and storage slot, **without verifying the correctness of the result**.
// This should only ever be used as alternative to GetProof when the user opts in.
// E.g. Erigon L1 node users may have to use this, since Erigon does not support eth_getProof, see https://github.com/ledgerwatch/erigon/issues/1349
func (s *EthClient) GetStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockTag string) (common.Hash, error) {
var out common.Hash
err := s.client.CallContext(ctx, &out, "eth_getStorageAt", address, storageSlot, blockTag)
return out, err
}
// ReadStorageAt is a convenience method to read a single storage value at the given slot in the given account.
// The storage slot value is verified against the state-root of the given block if we do not trust the RPC provider, or directly retrieved without proof if we do trust the RPC.
func (s *EthClient) ReadStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockHash common.Hash) (common.Hash, error) {
if s.trustRPC {
return s.GetStorageAt(ctx, address, storageSlot, blockHash.String())
}
block, err := s.InfoByHash(ctx, blockHash)
if err != nil {
return common.Hash{}, fmt.Errorf("failed to retrieve state root of block %s: %w", blockHash, err)
}
result, err := s.GetProof(ctx, address, []common.Hash{storageSlot}, blockHash.String())
if err != nil {
return common.Hash{}, fmt.Errorf("failed to fetch proof of storage slot %s at block %s: %w", storageSlot, blockHash, err)
}
if err := result.Verify(block.Root()); err != nil {
return common.Hash{}, fmt.Errorf("failed to verify retrieved proof against state root: %w", err)
} }
return getProofResponse, err return common.BytesToHash(result.StorageProof[0].Value), nil
} }
func (s *EthClient) Close() { func (s *EthClient) Close() {
......
...@@ -10,13 +10,14 @@ import ( ...@@ -10,13 +10,14 @@ import (
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum-optimism/optimism/op-node/client"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
) )
type mockRPC struct { type mockRPC struct {
......
...@@ -105,10 +105,26 @@ func (m *MockEthClient) ExpectFetchReceipts(hash common.Hash, info eth.BlockInfo ...@@ -105,10 +105,26 @@ func (m *MockEthClient) ExpectFetchReceipts(hash common.Hash, info eth.BlockInfo
m.Mock.On("FetchReceipts", hash).Once().Return(&info, receipts, &err) m.Mock.On("FetchReceipts", hash).Once().Return(&info, receipts, &err)
} }
func (m *MockEthClient) GetProof(ctx context.Context, address common.Address, blockTag string) (*eth.AccountResult, error) { func (m *MockEthClient) GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error) {
return m.Mock.MethodCalled("GetProof", address, blockTag).Get(0).(*eth.AccountResult), nil return m.Mock.MethodCalled("GetProof", address, storage, blockTag).Get(0).(*eth.AccountResult), nil
} }
func (m *MockEthClient) ExpectGetProof(address common.Address, blockTag string, result *eth.AccountResult, err error) { func (m *MockEthClient) ExpectGetProof(address common.Address, storage []common.Hash, blockTag string, result *eth.AccountResult, err error) {
m.Mock.On("GetProof", address, blockTag).Once().Return(result, &err) m.Mock.On("GetProof", address, storage, blockTag).Once().Return(result, &err)
}
func (m *MockEthClient) GetStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockTag string) (common.Hash, error) {
return m.Mock.MethodCalled("GetStorageAt", address, storageSlot, blockTag).Get(0).(common.Hash), nil
}
func (m *MockEthClient) ExpectGetStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockTag string, result common.Hash, err error) {
m.Mock.On("GetStorageAt", address, storageSlot, blockTag).Once().Return(result, &err)
}
func (m *MockEthClient) ReadStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockHash common.Hash) (common.Hash, error) {
return m.Mock.MethodCalled("ReadStorageAt", address, storageSlot, blockHash).Get(0).(common.Hash), nil
}
func (m *MockEthClient) ExpectReadStorageAt(ctx context.Context, address common.Address, storageSlot common.Hash, blockHash common.Hash, result common.Hash, err error) {
m.Mock.On("ReadStorageAt", address, storageSlot, blockHash).Once().Return(result, &err)
} }
package testutils
import "github.com/ethereum/go-ethereum/common"
type MockRuntimeConfig struct {
P2PSeqAddress common.Address
}
func (m *MockRuntimeConfig) P2PSequencerAddress() common.Address {
return m.P2PSeqAddress
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment