From 08d3bd4d32293b79788f9f72205a072a323211a2 Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Wed, 31 Jan 2024 11:00:38 -0800 Subject: [PATCH 1/9] Add state migratio for emulator state --- go.mod | 23 +- go.sum | 34 +-- storage/sqlite/migration.go | 293 +++++++++++++++++++++++ storage/sqlite/migration_test.go | 18 ++ storage/sqlite/test-data/emulator.sqlite | Bin 0 -> 962560 bytes 5 files changed, 344 insertions(+), 24 deletions(-) create mode 100644 storage/sqlite/migration.go create mode 100644 storage/sqlite/migration_test.go create mode 100644 storage/sqlite/test-data/emulator.sqlite diff --git a/go.mod b/go.mod index 8c24b330..e353e791 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c - github.com/glebarez/go-sqlite v1.21.1 + github.com/glebarez/go-sqlite v1.22.0 github.com/go-redis/redis/v8 v8.11.5 github.com/golang/mock v1.6.0 github.com/google/go-dap v0.11.0 @@ -16,7 +16,7 @@ require ( github.com/onflow/cadence v1.0.0-M4 github.com/onflow/crypto v0.25.0 github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d - github.com/onflow/flow-go v0.33.2-0.20240126002816-f0770a716d61 + github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f github.com/onflow/flow-go-sdk v1.0.0-M1 github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231213135419-ae911cc351a2 @@ -79,7 +79,7 @@ require ( github.com/golang/glog v1.1.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2 // indirect @@ -117,10 +117,11 @@ require ( github.com/logrusorgru/aurora/v4 v4.0.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect @@ -151,6 +152,7 @@ require ( github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/cors v1.8.0 // indirect + github.com/schollz/progressbar/v3 v3.13.1 // indirect github.com/sethvargo/go-retry v0.2.3 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/slok/go-http-metrics v0.10.0 // indirect @@ -189,10 +191,11 @@ require ( golang.org/x/net v0.19.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + golang.org/x/tools v0.16.1 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect @@ -202,10 +205,10 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect - modernc.org/libc v1.22.3 // indirect - modernc.org/mathutil v1.5.0 // indirect - modernc.org/memory v1.5.0 // indirect - modernc.org/sqlite v1.21.1 // indirect + modernc.org/libc v1.37.6 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.2 // indirect + modernc.org/sqlite v1.28.0 // indirect nhooyr.io/websocket v1.8.7 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index b9b1f440..245a1ee9 100644 --- a/go.sum +++ b/go.sum @@ -1311,8 +1311,8 @@ github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/ github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= -github.com/glebarez/go-sqlite v1.21.1 h1:7MZyUPh2XTrHS7xNEHQbrhfMZuPSzhkm2A1qgg0y5NY= -github.com/glebarez/go-sqlite v1.21.1/go.mod h1:ISs8MF6yk5cL4n/43rSOmVMGJJjHYr7L2MbZZ5Q4E2E= +github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= +github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= @@ -1529,8 +1529,9 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -1858,8 +1859,9 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -1984,8 +1986,8 @@ github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229- github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d/go.mod h1:MZ2j5YVTQiSE0B99zuaYhxvGG5GcvimWpQK1Fw/1QBg= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01 h1:8iKk5RuFvhe7NQyAO3c+xiVvv38RB/yopHdWxp4AbL8= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= -github.com/onflow/flow-go v0.33.2-0.20240126002816-f0770a716d61 h1:Xq40zbxw9mDS1+Zz1p6DCzAxDYQwbHWLJ5B9HOp9Fk8= -github.com/onflow/flow-go v0.33.2-0.20240126002816-f0770a716d61/go.mod h1:xdzERQeTalqsU0rHGSZgqQuE5krMfBQ4BA/4bgrLndY= +github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f h1:F1y95CpteZn0i4v0FDGjKiqI13Xlir3hX4x0C1xMRoc= +github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f/go.mod h1:9q+c+fuTpc/emueM/2bI/Ih2jw3V+9WS3Eu+pWBuLW0= github.com/onflow/flow-go-sdk v1.0.0-M1 h1:mke/ebYwNRRWPZqcwCV56Alx0A8psew43ZbSEUQ4TL8= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad h1:I6LD9BOsilGbiqhGjP86FIIXJe0YdUz75d/oWdHFzDI= @@ -2881,8 +2883,9 @@ golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= 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= @@ -2890,8 +2893,9 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -3341,25 +3345,27 @@ modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= -modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY= -modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw= +modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= +modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= -modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU= -modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= +modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= +modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= diff --git a/storage/sqlite/migration.go b/storage/sqlite/migration.go new file mode 100644 index 00000000..4890f8ea --- /dev/null +++ b/storage/sqlite/migration.go @@ -0,0 +1,293 @@ +package sqlite + +import ( + "context" + "database/sql" + "encoding/binary" + "encoding/hex" + "fmt" + "os" + "strconv" + "strings" + + "github.com/rs/zerolog" + + "github.com/onflow/flow-emulator/storage" + + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/interpreter" + + "github.com/onflow/flow-go/cmd/util/ledger/migrations" + "github.com/onflow/flow-go/cmd/util/ledger/reporters" + "github.com/onflow/flow-go/ledger" + "github.com/onflow/flow-go/ledger/common/convert" + "github.com/onflow/flow-go/model/flow" +) + +func Migrate(db *sql.DB) error { + payloads, payloadInfo, accounts, err := payloadsAndAccountsFromSnapshot(db) + if err != nil { + return err + } + + rwf := &ReportWriterFactory{} + capabilityIDs := map[interpreter.AddressPath]interpreter.UInt64Value{} + logger := newConsoleLogger() + + payloads, err = migrateLinkValues(rwf, logger, capabilityIDs, accounts, payloads) + if err != nil { + return err + } + + payloads, err = migrateCadenceValues(rwf, logger, capabilityIDs, accounts, payloads) + if err != nil { + return err + } + + return writePayloadsToSnapshot(db, payloads, payloadInfo) +} + +func migrateLinkValues( + rwf *ReportWriterFactory, + logger zerolog.Logger, + capabilityIDs map[interpreter.AddressPath]interpreter.UInt64Value, + accounts []common.Address, + payloads []*ledger.Payload, +) ([]*ledger.Payload, error) { + + linkValueMigration := migrations.NewCadenceLinkValueMigrator(rwf, capabilityIDs) + + err := linkValueMigration.InitMigration(logger, nil, 0) + if err != nil { + return nil, err + } + + for _, account := range accounts { + ctx := context.Background() + payloads, err = linkValueMigration.MigrateAccount(ctx, account, payloads) + if err != nil { + return nil, err + } + } + return payloads, nil +} + +func migrateCadenceValues( + rwf *ReportWriterFactory, + logger zerolog.Logger, + capabilityIDs map[interpreter.AddressPath]interpreter.UInt64Value, + accounts []common.Address, + payloads []*ledger.Payload, +) ([]*ledger.Payload, error) { + + valueMigration := migrations.NewCadenceValueMigrator( + rwf, + capabilityIDs, + func(staticType *interpreter.CompositeStaticType) interpreter.StaticType { + return nil + }, + func(staticType *interpreter.InterfaceStaticType) interpreter.StaticType { + return nil + }, + ) + + err := valueMigration.InitMigration(logger, nil, 0) + if err != nil { + return nil, err + } + + for _, account := range accounts { + ctx := context.Background() + payloads, err = valueMigration.MigrateAccount(ctx, account, payloads) + if err != nil { + return nil, err + } + } + + return payloads, nil +} + +func newConsoleLogger() zerolog.Logger { + writer := zerolog.ConsoleWriter{ + Out: os.Stdout, + } + + return zerolog.New(writer). + With(). + Timestamp(). + Logger(). + Level(zerolog.InfoLevel) +} + +func writePayloadsToSnapshot( + db *sql.DB, + payloads []*ledger.Payload, + payloadInfoSet map[flow.RegisterID]payloadMetaInfo, +) error { + + for _, payload := range payloads { + key, err := payload.Key() + if err != nil { + return err + } + + registerId, err := convert.LedgerKeyToRegisterID(key) + if err != nil { + return err + } + + registerIdBytes := []byte(registerId.String()) + + value := payload.Value() + + payloadInfo, ok := payloadInfoSet[registerId] + if !ok { + // Should be unreachable. + // Assumption is that registers can get modified/updated in-place, + // but no new registers are added or no exiting registers are removed during the migration. + // TODO: Verify if ^this is the case + return fmt.Errorf("cannot find payload meta info for register %s", registerId) + } + + _, err = db.Exec( + fmt.Sprintf( + "INSERT INTO %s (key, version, value, height) VALUES (?, ?, ?, ?) ON CONFLICT(key, version, height) DO UPDATE SET value=excluded.value", + storage.LedgerStoreName, + ), + hex.EncodeToString(registerIdBytes), + payloadInfo.version, + hex.EncodeToString(value), + payloadInfo.height, + ) + + if err != nil { + return err + } + } + + return nil +} + +func payloadsAndAccountsFromSnapshot(db *sql.DB) ( + []*ledger.Payload, + map[flow.RegisterID]payloadMetaInfo, + []common.Address, + error, +) { + rows, err := db.Query("SELECT key, value, version, height FROM ledger") + if err != nil { + return nil, nil, nil, err + } + + var payloads []*ledger.Payload + var accounts []common.Address + accountsSet := make(map[common.Address]struct{}) + + payloadSet := make(map[flow.RegisterID]payloadMetaInfo) + + for rows.Next() { + var hexKey, hexValue string + var height, version int + + err := rows.Scan(&hexKey, &hexValue, &height, &version) + if err != nil { + return nil, nil, nil, err + } + + key, err := hex.DecodeString(hexKey) + if err != nil { + return nil, nil, nil, err + } + + value, err := hex.DecodeString(hexValue) + if err != nil { + return nil, nil, nil, err + } + + registerId, address := registerIDKeyFromString(string(key)) + + if _, contains := accountsSet[address]; !contains { + accountsSet[address] = struct{}{} + accounts = append(accounts, address) + } + + ledgerKey := convert.RegisterIDToLedgerKey(registerId) + + payload := ledger.NewPayload( + ledgerKey, + value, + ) + + payloads = append(payloads, payload) + payloadSet[registerId] = payloadMetaInfo{ + height: height, + version: version, + } + } + + return payloads, payloadSet, accounts, nil +} + +// registerIDKeyFromString is the inverse of `flow.RegisterID.String()` method. +func registerIDKeyFromString(s string) (flow.RegisterID, common.Address) { + parts := strings.SplitN(s, "/", 2) + + owner := parts[0] + key := parts[1] + + address, err := common.HexToAddress(owner) + if err != nil { + panic(err) + } + + var decodedKey string + + switch key[0] { + case '$': + b := make([]byte, 9) + b[0] = '$' + + int64Value, err := strconv.ParseInt(key[1:], 10, 64) + if err != nil { + panic(err) + } + + binary.BigEndian.PutUint64(b[1:], uint64(int64Value)) + + decodedKey = string(b) + case '#': + decoded, err := hex.DecodeString(key[1:]) + if err != nil { + panic(err) + } + decodedKey = string(decoded) + default: + panic("Invalid register key") + } + + return flow.RegisterID{ + Owner: string(address.Bytes()), + Key: decodedKey, + }, + address +} + +type payloadMetaInfo struct { + height, version int +} + +type ReportWriterFactory struct{} + +func (_m *ReportWriterFactory) ReportWriter(_ string) reporters.ReportWriter { + return &NOOPWriter{} +} + +type NOOPWriter struct{} + +var _ reporters.ReportWriter = &NOOPWriter{} + +func (r *NOOPWriter) Write(_ any) { + // NO-OP +} + +func (r *NOOPWriter) Close() {} diff --git a/storage/sqlite/migration_test.go b/storage/sqlite/migration_test.go new file mode 100644 index 00000000..b6c21243 --- /dev/null +++ b/storage/sqlite/migration_test.go @@ -0,0 +1,18 @@ +package sqlite + +import ( + "database/sql" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestStateMigration(t *testing.T) { + path := "test-data/emulator.sqlite" + + db, err := sql.Open("sqlite", path) + require.NoError(t, err) + + err = Migrate(db) + require.NoError(t, err) +} diff --git a/storage/sqlite/test-data/emulator.sqlite b/storage/sqlite/test-data/emulator.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..12da50890e5260090dfd8c420b0b2e96b79f7a8c GIT binary patch literal 962560 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

`aI& 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%0A!bK_T6XV|9=hmE_+5l2Hq*NU*q-X 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 TtQo9m>t-zU_oC4NtLOg%doxxn literal 0 HcmV?d00001 From 74ea4157a6244e9def1828f8726279d88b3a0baf Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Thu, 1 Feb 2024 12:49:29 -0800 Subject: [PATCH 2/9] Improve migration. Update cadence version --- go.mod | 4 +- go.sum | 7 ++-- storage/sqlite/migration.go | 51 +++++++++++++---------- storage/sqlite/migration_test.go | 31 ++++++++++++-- storage/sqlite/test-data/emulator.sqlite | Bin 962560 -> 962560 bytes 5 files changed, 63 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index e353e791..c4e6b2a6 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/improbable-eng/grpc-web v0.15.0 github.com/logrusorgru/aurora v2.0.3+incompatible - github.com/onflow/cadence v1.0.0-M4 + github.com/onflow/cadence v1.0.0-preview.2.0.20240201184233-a301a4152f6b github.com/onflow/crypto v0.25.0 github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f @@ -118,7 +118,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect diff --git a/go.sum b/go.sum index 245a1ee9..11e0f82f 100644 --- a/go.sum +++ b/go.sum @@ -1867,8 +1867,9 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -1976,8 +1977,8 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f h1:Z8/PgTqOgOg02MTRpTBYO2k16FE6z4wEOtaC2WBR9Xo= github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= github.com/onflow/cadence v1.0.0-M3/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8= -github.com/onflow/cadence v1.0.0-M4 h1:/nt3j7vpYDxuI0ghIgAJrb2R01ijvJYZLAkKt+zbpTY= -github.com/onflow/cadence v1.0.0-M4/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8= +github.com/onflow/cadence v1.0.0-preview.2.0.20240201184233-a301a4152f6b h1:OLKpe4tZo/fpqxJK/WwpcIUgYYYSVcfxiGi92XnFVeU= +github.com/onflow/cadence v1.0.0-preview.2.0.20240201184233-a301a4152f6b/go.mod h1:a4mccDU90hmuxCLUFzs9J/ANG/rYbFa36h4Z0bBAqNU= github.com/onflow/crypto v0.25.0 h1:BeWbLsh3ZD13Ej+Uky6kg1PL1ZIVBDVX+2MVBNwqddg= github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.1-0.20240125214229-b7a95136dd0d h1:Afcfk/9jAQZ1v5PLGdP68FG/0yPPM60fn9Eq8ChBGS0= diff --git a/storage/sqlite/migration.go b/storage/sqlite/migration.go index 4890f8ea..acb09c16 100644 --- a/storage/sqlite/migration.go +++ b/storage/sqlite/migration.go @@ -24,8 +24,13 @@ import ( "github.com/onflow/flow-go/model/flow" ) -func Migrate(db *sql.DB) error { - payloads, payloadInfo, accounts, err := payloadsAndAccountsFromSnapshot(db) +func Migrate(url string) error { + store, err := New(url) + if err != nil { + return err + } + + payloads, payloadInfo, accounts, err := payloadsAndAccountsFromSnapshot(store.db) if err != nil { return err } @@ -44,7 +49,7 @@ func Migrate(db *sql.DB) error { return err } - return writePayloadsToSnapshot(db, payloads, payloadInfo) + return writePayloadsToSnapshot(store, payloads, payloadInfo) } func migrateLinkValues( @@ -120,11 +125,13 @@ func newConsoleLogger() zerolog.Logger { } func writePayloadsToSnapshot( - db *sql.DB, + store *Store, payloads []*ledger.Payload, payloadInfoSet map[flow.RegisterID]payloadMetaInfo, ) error { + const storeName = storage.LedgerStoreName + for _, payload := range payloads { key, err := payload.Key() if err != nil { @@ -141,25 +148,27 @@ func writePayloadsToSnapshot( value := payload.Value() payloadInfo, ok := payloadInfoSet[registerId] - if !ok { - // Should be unreachable. - // Assumption is that registers can get modified/updated in-place, - // but no new registers are added or no exiting registers are removed during the migration. - // TODO: Verify if ^this is the case - return fmt.Errorf("cannot find payload meta info for register %s", registerId) + if ok { + _, err = store.db.Exec( + fmt.Sprintf( + "INSERT INTO %s (key, version, value, height) VALUES (?, ?, ?, ?) ON CONFLICT(key, version, height) DO UPDATE SET value=excluded.value", + storeName, + ), + hex.EncodeToString(registerIdBytes), + payloadInfo.version, + hex.EncodeToString(value), + payloadInfo.height, + ) + } else { + // if this is a new payload, use the current block height + err = store.SetBytes( + nil, + storeName, + registerIdBytes, + value, + ) } - _, err = db.Exec( - fmt.Sprintf( - "INSERT INTO %s (key, version, value, height) VALUES (?, ?, ?, ?) ON CONFLICT(key, version, height) DO UPDATE SET value=excluded.value", - storage.LedgerStoreName, - ), - hex.EncodeToString(registerIdBytes), - payloadInfo.version, - hex.EncodeToString(value), - payloadInfo.height, - ) - if err != nil { return err } diff --git a/storage/sqlite/migration_test.go b/storage/sqlite/migration_test.go index b6c21243..e0753a43 100644 --- a/storage/sqlite/migration_test.go +++ b/storage/sqlite/migration_test.go @@ -1,18 +1,41 @@ package sqlite import ( - "database/sql" + "os" "testing" "github.com/stretchr/testify/require" ) func TestStateMigration(t *testing.T) { - path := "test-data/emulator.sqlite" + const emulatorStateFile = "test-data/emulator.sqlite" - db, err := sql.Open("sqlite", path) + // Work on a temp copy of the state, + // since the migration will be updating the state. + tempEmulatorState, err := os.CreateTemp("test-data", "tmp-emulator.state") require.NoError(t, err) - err = Migrate(db) + tempEmulatorStatePath := tempEmulatorState.Name() + + defer func() { + err := tempEmulatorState.Close() + require.NoError(t, err) + }() + + defer func() { + err := os.Remove(tempEmulatorStatePath) + require.NoError(t, err) + }() + + content, err := os.ReadFile(emulatorStateFile) + require.NoError(t, err) + + _, err = tempEmulatorState.Write(content) require.NoError(t, err) + + // Migrate + + err = Migrate(tempEmulatorStatePath) + require.NoError(t, err) + } diff --git a/storage/sqlite/test-data/emulator.sqlite b/storage/sqlite/test-data/emulator.sqlite index 12da50890e5260090dfd8c420b0b2e96b79f7a8c..198d0f9a8a114ca424267fb755f489d2830f3c78 100644 GIT binary patch delta 61 zcmV~$IT3&`006-W|8D@4q{YZd3B~o`00&g~hysYWRywfm*swbzy1}$ delta 61 zcmV~$IT3&`006-W|8D@4q{YZd3B~o`00&g~Nr?=0Q;sRea}D3M?cqC+Acd4tNiB`E P(n&9aj55jmvfR%P$wn3N From 374fd54b38e3fe5e48b7c22f922a31e9570f1cfe Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Thu, 1 Feb 2024 13:04:00 -0800 Subject: [PATCH 3/9] Move migrations to a separate directory --- .../cadence_values_migration.go} | 52 +++++++++------ .../cadence_values_migration_test.go | 63 ++++++++++++++++++ storage/migration/test-data/README.md | 3 + .../test-data/emulator_state_cadence_v0.42.6} | Bin storage/sqlite/migration_test.go | 41 ------------ storage/sqlite/store.go | 27 ++++++++ 6 files changed, 125 insertions(+), 61 deletions(-) rename storage/{sqlite/migration.go => migration/cadence_values_migration.go} (84%) create mode 100644 storage/migration/cadence_values_migration_test.go create mode 100644 storage/migration/test-data/README.md rename storage/{sqlite/test-data/emulator.sqlite => migration/test-data/emulator_state_cadence_v0.42.6} (100%) delete mode 100644 storage/sqlite/migration_test.go diff --git a/storage/sqlite/migration.go b/storage/migration/cadence_values_migration.go similarity index 84% rename from storage/sqlite/migration.go rename to storage/migration/cadence_values_migration.go index acb09c16..e04e198e 100644 --- a/storage/sqlite/migration.go +++ b/storage/migration/cadence_values_migration.go @@ -1,11 +1,28 @@ -package sqlite +/* + * Flow Emulator + * + * Copyright 2024 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package migration import ( "context" "database/sql" "encoding/binary" "encoding/hex" - "fmt" "os" "strconv" "strings" @@ -13,6 +30,7 @@ import ( "github.com/rs/zerolog" "github.com/onflow/flow-emulator/storage" + "github.com/onflow/flow-emulator/storage/sqlite" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" @@ -24,13 +42,8 @@ import ( "github.com/onflow/flow-go/model/flow" ) -func Migrate(url string) error { - store, err := New(url) - if err != nil { - return err - } - - payloads, payloadInfo, accounts, err := payloadsAndAccountsFromSnapshot(store.db) +func MigrateCadenceValues(store *sqlite.Store) error { + payloads, payloadInfo, accounts, err := payloadsAndAccountsFromSnapshot(store.DB()) if err != nil { return err } @@ -125,7 +138,7 @@ func newConsoleLogger() zerolog.Logger { } func writePayloadsToSnapshot( - store *Store, + store *sqlite.Store, payloads []*ledger.Payload, payloadInfoSet map[flow.RegisterID]payloadMetaInfo, ) error { @@ -149,18 +162,17 @@ func writePayloadsToSnapshot( payloadInfo, ok := payloadInfoSet[registerId] if ok { - _, err = store.db.Exec( - fmt.Sprintf( - "INSERT INTO %s (key, version, value, height) VALUES (?, ?, ?, ?) ON CONFLICT(key, version, height) DO UPDATE SET value=excluded.value", - storeName, - ), - hex.EncodeToString(registerIdBytes), + // Insert the values back with the existing height and version. + err = store.SetBytesWithVersionAndHeight( + nil, + storeName, + registerIdBytes, + value, payloadInfo.version, - hex.EncodeToString(value), payloadInfo.height, ) } else { - // if this is a new payload, use the current block height + // If this is a new payload, use the current block height, and default version. err = store.SetBytes( nil, storeName, @@ -196,7 +208,7 @@ func payloadsAndAccountsFromSnapshot(db *sql.DB) ( for rows.Next() { var hexKey, hexValue string - var height, version int + var height, version uint64 err := rows.Scan(&hexKey, &hexValue, &height, &version) if err != nil { @@ -282,7 +294,7 @@ func registerIDKeyFromString(s string) (flow.RegisterID, common.Address) { } type payloadMetaInfo struct { - height, version int + height, version uint64 } type ReportWriterFactory struct{} diff --git a/storage/migration/cadence_values_migration_test.go b/storage/migration/cadence_values_migration_test.go new file mode 100644 index 00000000..0ac093d3 --- /dev/null +++ b/storage/migration/cadence_values_migration_test.go @@ -0,0 +1,63 @@ +/* + * Flow Emulator + * + * Copyright 2024 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package migration + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onflow/flow-emulator/storage/sqlite" +) + +func TestStateMigration(t *testing.T) { + const emulatorStateFile = "test-data/emulator_state_cadence_v0.42.6" + + // Work on a temp copy of the state, + // since the migration will be updating the state. + tempEmulatorState, err := os.CreateTemp("test-data", "temp_emulator_state") + require.NoError(t, err) + + tempEmulatorStatePath := tempEmulatorState.Name() + + defer func() { + err := tempEmulatorState.Close() + require.NoError(t, err) + }() + + defer func() { + err := os.Remove(tempEmulatorStatePath) + require.NoError(t, err) + }() + + content, err := os.ReadFile(emulatorStateFile) + require.NoError(t, err) + + _, err = tempEmulatorState.Write(content) + require.NoError(t, err) + + // Migrate + + store, err := sqlite.New(tempEmulatorStatePath) + require.NoError(t, err) + + err = MigrateCadenceValues(store) + require.NoError(t, err) +} diff --git a/storage/migration/test-data/README.md b/storage/migration/test-data/README.md new file mode 100644 index 00000000..3c3688d4 --- /dev/null +++ b/storage/migration/test-data/README.md @@ -0,0 +1,3 @@ +This is the same emulator state used in https://github.com/onflow/flow-go/tree/feature/stable-cadence/cmd/util/ledger/migrations/test-data/cadence_values_migration + +Follow the instruction there to generate a new state, if needed. \ No newline at end of file diff --git a/storage/sqlite/test-data/emulator.sqlite b/storage/migration/test-data/emulator_state_cadence_v0.42.6 similarity index 100% rename from storage/sqlite/test-data/emulator.sqlite rename to storage/migration/test-data/emulator_state_cadence_v0.42.6 diff --git a/storage/sqlite/migration_test.go b/storage/sqlite/migration_test.go deleted file mode 100644 index e0753a43..00000000 --- a/storage/sqlite/migration_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package sqlite - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestStateMigration(t *testing.T) { - const emulatorStateFile = "test-data/emulator.sqlite" - - // Work on a temp copy of the state, - // since the migration will be updating the state. - tempEmulatorState, err := os.CreateTemp("test-data", "tmp-emulator.state") - require.NoError(t, err) - - tempEmulatorStatePath := tempEmulatorState.Name() - - defer func() { - err := tempEmulatorState.Close() - require.NoError(t, err) - }() - - defer func() { - err := os.Remove(tempEmulatorStatePath) - require.NoError(t, err) - }() - - content, err := os.ReadFile(emulatorStateFile) - require.NoError(t, err) - - _, err = tempEmulatorState.Write(content) - require.NoError(t, err) - - // Migrate - - err = Migrate(tempEmulatorStatePath) - require.NoError(t, err) - -} diff --git a/storage/sqlite/store.go b/storage/sqlite/store.go index 72dd1b1c..7e259318 100644 --- a/storage/sqlite/store.go +++ b/storage/sqlite/store.go @@ -339,3 +339,30 @@ func (s *Store) Close() error { return nil } + +// Below are needed for the state migrations only. + +func (s *Store) DB() *sql.DB { + return s.db +} + +func (s *Store) SetBytesWithVersionAndHeight(_ context.Context, store string, key []byte, value []byte, version, height uint64) error { + s.mu.Lock() + defer s.mu.Unlock() + + _, err := s.db.Exec( + fmt.Sprintf( + "INSERT INTO %s (key, version, value, height) VALUES (?, ?, ?, ?) ON CONFLICT(key, version, height) DO UPDATE SET value=excluded.value", + store, + ), + hex.EncodeToString(key), + version, + hex.EncodeToString(value), + height, + ) + if err != nil { + return err + } + + return nil +} From be384771ad7f792583874a350686c44bf676b8ce Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Thu, 1 Feb 2024 16:40:42 -0800 Subject: [PATCH 4/9] Add system contracts migration --- go.mod | 2 +- go.sum | 4 +- storage/migration/cadence_values_migration.go | 206 +----------------- ...es_migration_test.go => migration_test.go} | 16 +- .../migration/system_contracts_migration.go | 82 +++++++ storage/migration/utils.go | 117 ++++++++++ 6 files changed, 213 insertions(+), 214 deletions(-) rename storage/migration/{cadence_values_migration_test.go => migration_test.go} (87%) create mode 100644 storage/migration/system_contracts_migration.go create mode 100644 storage/migration/utils.go diff --git a/go.mod b/go.mod index c4e6b2a6..d917e845 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/onflow/cadence v1.0.0-preview.2.0.20240201184233-a301a4152f6b github.com/onflow/crypto v0.25.0 github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d - github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f + github.com/onflow/flow-go v0.33.2-0.20240202003043-efb29d915946 github.com/onflow/flow-go-sdk v1.0.0-M1 github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231213135419-ae911cc351a2 diff --git a/go.sum b/go.sum index 11e0f82f..48aca8fb 100644 --- a/go.sum +++ b/go.sum @@ -1987,8 +1987,8 @@ github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229- github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d/go.mod h1:MZ2j5YVTQiSE0B99zuaYhxvGG5GcvimWpQK1Fw/1QBg= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01 h1:8iKk5RuFvhe7NQyAO3c+xiVvv38RB/yopHdWxp4AbL8= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= -github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f h1:F1y95CpteZn0i4v0FDGjKiqI13Xlir3hX4x0C1xMRoc= -github.com/onflow/flow-go v0.33.2-0.20240126211806-97279f96695f/go.mod h1:9q+c+fuTpc/emueM/2bI/Ih2jw3V+9WS3Eu+pWBuLW0= +github.com/onflow/flow-go v0.33.2-0.20240202003043-efb29d915946 h1:YhEktpKe9wHOZDyzIMqVTuROWEGU9QFVmJ+s5u3M8Os= +github.com/onflow/flow-go v0.33.2-0.20240202003043-efb29d915946/go.mod h1:9q+c+fuTpc/emueM/2bI/Ih2jw3V+9WS3Eu+pWBuLW0= github.com/onflow/flow-go-sdk v1.0.0-M1 h1:mke/ebYwNRRWPZqcwCV56Alx0A8psew43ZbSEUQ4TL8= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad h1:I6LD9BOsilGbiqhGjP86FIIXJe0YdUz75d/oWdHFzDI= diff --git a/storage/migration/cadence_values_migration.go b/storage/migration/cadence_values_migration.go index e04e198e..b9a4a77a 100644 --- a/storage/migration/cadence_values_migration.go +++ b/storage/migration/cadence_values_migration.go @@ -20,37 +20,27 @@ package migration import ( "context" - "database/sql" - "encoding/binary" - "encoding/hex" - "os" - "strconv" - "strings" - "github.com/rs/zerolog" - "github.com/onflow/flow-emulator/storage" "github.com/onflow/flow-emulator/storage/sqlite" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/flow-go/cmd/util/ledger/migrations" - "github.com/onflow/flow-go/cmd/util/ledger/reporters" + "github.com/onflow/flow-go/cmd/util/ledger/util" "github.com/onflow/flow-go/ledger" - "github.com/onflow/flow-go/ledger/common/convert" - "github.com/onflow/flow-go/model/flow" ) func MigrateCadenceValues(store *sqlite.Store) error { - payloads, payloadInfo, accounts, err := payloadsAndAccountsFromSnapshot(store.DB()) + payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) if err != nil { return err } rwf := &ReportWriterFactory{} capabilityIDs := map[interpreter.AddressPath]interpreter.UInt64Value{} - logger := newConsoleLogger() + logger := NewConsoleLogger() payloads, err = migrateLinkValues(rwf, logger, capabilityIDs, accounts, payloads) if err != nil { @@ -62,7 +52,7 @@ func MigrateCadenceValues(store *sqlite.Store) error { return err } - return writePayloadsToSnapshot(store, payloads, payloadInfo) + return WritePayloadsToSnapshot(store, payloads, payloadInfo) } func migrateLinkValues( @@ -124,191 +114,3 @@ func migrateCadenceValues( return payloads, nil } - -func newConsoleLogger() zerolog.Logger { - writer := zerolog.ConsoleWriter{ - Out: os.Stdout, - } - - return zerolog.New(writer). - With(). - Timestamp(). - Logger(). - Level(zerolog.InfoLevel) -} - -func writePayloadsToSnapshot( - store *sqlite.Store, - payloads []*ledger.Payload, - payloadInfoSet map[flow.RegisterID]payloadMetaInfo, -) error { - - const storeName = storage.LedgerStoreName - - for _, payload := range payloads { - key, err := payload.Key() - if err != nil { - return err - } - - registerId, err := convert.LedgerKeyToRegisterID(key) - if err != nil { - return err - } - - registerIdBytes := []byte(registerId.String()) - - value := payload.Value() - - payloadInfo, ok := payloadInfoSet[registerId] - if ok { - // Insert the values back with the existing height and version. - err = store.SetBytesWithVersionAndHeight( - nil, - storeName, - registerIdBytes, - value, - payloadInfo.version, - payloadInfo.height, - ) - } else { - // If this is a new payload, use the current block height, and default version. - err = store.SetBytes( - nil, - storeName, - registerIdBytes, - value, - ) - } - - if err != nil { - return err - } - } - - return nil -} - -func payloadsAndAccountsFromSnapshot(db *sql.DB) ( - []*ledger.Payload, - map[flow.RegisterID]payloadMetaInfo, - []common.Address, - error, -) { - rows, err := db.Query("SELECT key, value, version, height FROM ledger") - if err != nil { - return nil, nil, nil, err - } - - var payloads []*ledger.Payload - var accounts []common.Address - accountsSet := make(map[common.Address]struct{}) - - payloadSet := make(map[flow.RegisterID]payloadMetaInfo) - - for rows.Next() { - var hexKey, hexValue string - var height, version uint64 - - err := rows.Scan(&hexKey, &hexValue, &height, &version) - if err != nil { - return nil, nil, nil, err - } - - key, err := hex.DecodeString(hexKey) - if err != nil { - return nil, nil, nil, err - } - - value, err := hex.DecodeString(hexValue) - if err != nil { - return nil, nil, nil, err - } - - registerId, address := registerIDKeyFromString(string(key)) - - if _, contains := accountsSet[address]; !contains { - accountsSet[address] = struct{}{} - accounts = append(accounts, address) - } - - ledgerKey := convert.RegisterIDToLedgerKey(registerId) - - payload := ledger.NewPayload( - ledgerKey, - value, - ) - - payloads = append(payloads, payload) - payloadSet[registerId] = payloadMetaInfo{ - height: height, - version: version, - } - } - - return payloads, payloadSet, accounts, nil -} - -// registerIDKeyFromString is the inverse of `flow.RegisterID.String()` method. -func registerIDKeyFromString(s string) (flow.RegisterID, common.Address) { - parts := strings.SplitN(s, "/", 2) - - owner := parts[0] - key := parts[1] - - address, err := common.HexToAddress(owner) - if err != nil { - panic(err) - } - - var decodedKey string - - switch key[0] { - case '$': - b := make([]byte, 9) - b[0] = '$' - - int64Value, err := strconv.ParseInt(key[1:], 10, 64) - if err != nil { - panic(err) - } - - binary.BigEndian.PutUint64(b[1:], uint64(int64Value)) - - decodedKey = string(b) - case '#': - decoded, err := hex.DecodeString(key[1:]) - if err != nil { - panic(err) - } - decodedKey = string(decoded) - default: - panic("Invalid register key") - } - - return flow.RegisterID{ - Owner: string(address.Bytes()), - Key: decodedKey, - }, - address -} - -type payloadMetaInfo struct { - height, version uint64 -} - -type ReportWriterFactory struct{} - -func (_m *ReportWriterFactory) ReportWriter(_ string) reporters.ReportWriter { - return &NOOPWriter{} -} - -type NOOPWriter struct{} - -var _ reporters.ReportWriter = &NOOPWriter{} - -func (r *NOOPWriter) Write(_ any) { - // NO-OP -} - -func (r *NOOPWriter) Close() {} diff --git a/storage/migration/cadence_values_migration_test.go b/storage/migration/migration_test.go similarity index 87% rename from storage/migration/cadence_values_migration_test.go rename to storage/migration/migration_test.go index 0ac093d3..c70a5235 100644 --- a/storage/migration/cadence_values_migration_test.go +++ b/storage/migration/migration_test.go @@ -37,15 +37,8 @@ func TestStateMigration(t *testing.T) { tempEmulatorStatePath := tempEmulatorState.Name() - defer func() { - err := tempEmulatorState.Close() - require.NoError(t, err) - }() - - defer func() { - err := os.Remove(tempEmulatorStatePath) - require.NoError(t, err) - }() + defer tempEmulatorState.Close() + defer os.Remove(tempEmulatorStatePath) content, err := os.ReadFile(emulatorStateFile) require.NoError(t, err) @@ -58,6 +51,11 @@ func TestStateMigration(t *testing.T) { store, err := sqlite.New(tempEmulatorStatePath) require.NoError(t, err) + // First migrate the system contracts + err = MigrateSystemContracts(store) + require.NoError(t, err) + + // Then migrate the values. err = MigrateCadenceValues(store) require.NoError(t, err) } diff --git a/storage/migration/system_contracts_migration.go b/storage/migration/system_contracts_migration.go new file mode 100644 index 00000000..b9a07630 --- /dev/null +++ b/storage/migration/system_contracts_migration.go @@ -0,0 +1,82 @@ +/* + * Flow Emulator + * + * Copyright 2024 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package migration + +import ( + "context" + "github.com/rs/zerolog" + + "github.com/onflow/flow-emulator/storage/sqlite" + + "github.com/onflow/cadence/runtime/common" + + "github.com/onflow/flow-go/cmd/util/ledger/migrations" + "github.com/onflow/flow-go/cmd/util/ledger/util" + "github.com/onflow/flow-go/ledger" + "github.com/onflow/flow-go/model/flow" +) + +func MigrateSystemContracts(store *sqlite.Store) error { + payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) + if err != nil { + return err + } + + logger := NewConsoleLogger() + + payloads, err = migrateSystemContracts(logger, accounts, payloads) + if err != nil { + return err + } + + return WritePayloadsToSnapshot(store, payloads, payloadInfo) +} + +func migrateSystemContracts( + logger zerolog.Logger, + accounts []common.Address, + payloads []*ledger.Payload, +) ([]*ledger.Payload, error) { + + migration := migrations.ChangeContractCodeMigration{} + + systemContractChanges := migrations.SystemContractChanges(flow.Emulator) + + for _, contractChange := range systemContractChanges { + migration.RegisterContractChange( + contractChange.Address, + contractChange.ContractName, + contractChange.NewContractCode, + ) + } + + err := migration.InitMigration(logger, nil, 0) + if err != nil { + return nil, err + } + + for _, account := range accounts { + ctx := context.Background() + payloads, err = migration.MigrateAccount(ctx, account, payloads) + if err != nil { + return nil, err + } + } + return payloads, nil +} diff --git a/storage/migration/utils.go b/storage/migration/utils.go new file mode 100644 index 00000000..a2651787 --- /dev/null +++ b/storage/migration/utils.go @@ -0,0 +1,117 @@ +/* + * Flow Emulator + * + * Copyright 2024 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package migration + +import ( + "context" + "os" + + "github.com/rs/zerolog" + + "github.com/onflow/flow-emulator/storage" + "github.com/onflow/flow-emulator/storage/sqlite" + + "github.com/onflow/flow-go/cmd/util/ledger/reporters" + "github.com/onflow/flow-go/cmd/util/ledger/util" + "github.com/onflow/flow-go/ledger" + "github.com/onflow/flow-go/ledger/common/convert" + "github.com/onflow/flow-go/model/flow" +) + +func WritePayloadsToSnapshot( + store *sqlite.Store, + payloads []*ledger.Payload, + payloadInfoSet map[flow.RegisterID]util.PayloadMetaInfo, +) error { + + const storeName = storage.LedgerStoreName + + ctx := context.TODO() + + for _, payload := range payloads { + key, err := payload.Key() + if err != nil { + return err + } + + registerId, err := convert.LedgerKeyToRegisterID(key) + if err != nil { + return err + } + + registerIdBytes := []byte(registerId.String()) + + value := payload.Value() + + payloadInfo, ok := payloadInfoSet[registerId] + if ok { + // Insert the values back with the existing height and version. + err = store.SetBytesWithVersionAndHeight( + ctx, + storeName, + registerIdBytes, + value, + payloadInfo.Version, + payloadInfo.Height, + ) + } else { + // If this is a new payload, use the current block height, and default version. + err = store.SetBytes( + ctx, + storeName, + registerIdBytes, + value, + ) + } + + if err != nil { + return err + } + } + + return nil +} + +func NewConsoleLogger() zerolog.Logger { + writer := zerolog.ConsoleWriter{ + Out: os.Stdout, + } + + return zerolog.New(writer). + With(). + Timestamp(). + Logger(). + Level(zerolog.InfoLevel) +} + +type ReportWriterFactory struct{} + +func (_m *ReportWriterFactory) ReportWriter(_ string) reporters.ReportWriter { + return &NOOPWriter{} +} + +type NOOPWriter struct{} + +var _ reporters.ReportWriter = &NOOPWriter{} + +func (r *NOOPWriter) Write(_ any) { + // NO-OP +} + +func (r *NOOPWriter) Close() {} From eac41889360620bd8d7075a66e98cabe430175df Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Fri, 2 Feb 2024 07:58:34 -0800 Subject: [PATCH 5/9] Add Burner contract to payloads --- go.mod | 2 +- go.sum | 4 ++-- storage/migration/system_contracts_migration.go | 10 +++++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index d917e845..54e54987 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/onflow/cadence v1.0.0-preview.2.0.20240201184233-a301a4152f6b github.com/onflow/crypto v0.25.0 github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d - github.com/onflow/flow-go v0.33.2-0.20240202003043-efb29d915946 + github.com/onflow/flow-go v0.33.2-0.20240202154538-408cb8872bc9 github.com/onflow/flow-go-sdk v1.0.0-M1 github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231213135419-ae911cc351a2 diff --git a/go.sum b/go.sum index 48aca8fb..78fd0bc2 100644 --- a/go.sum +++ b/go.sum @@ -1987,8 +1987,8 @@ github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229- github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d/go.mod h1:MZ2j5YVTQiSE0B99zuaYhxvGG5GcvimWpQK1Fw/1QBg= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01 h1:8iKk5RuFvhe7NQyAO3c+xiVvv38RB/yopHdWxp4AbL8= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= -github.com/onflow/flow-go v0.33.2-0.20240202003043-efb29d915946 h1:YhEktpKe9wHOZDyzIMqVTuROWEGU9QFVmJ+s5u3M8Os= -github.com/onflow/flow-go v0.33.2-0.20240202003043-efb29d915946/go.mod h1:9q+c+fuTpc/emueM/2bI/Ih2jw3V+9WS3Eu+pWBuLW0= +github.com/onflow/flow-go v0.33.2-0.20240202154538-408cb8872bc9 h1:QTAyUmeTu2N4mGG+mBjR78d8Etlr49AxMyHwcNjle7M= +github.com/onflow/flow-go v0.33.2-0.20240202154538-408cb8872bc9/go.mod h1:9q+c+fuTpc/emueM/2bI/Ih2jw3V+9WS3Eu+pWBuLW0= github.com/onflow/flow-go-sdk v1.0.0-M1 h1:mke/ebYwNRRWPZqcwCV56Alx0A8psew43ZbSEUQ4TL8= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad h1:I6LD9BOsilGbiqhGjP86FIIXJe0YdUz75d/oWdHFzDI= diff --git a/storage/migration/system_contracts_migration.go b/storage/migration/system_contracts_migration.go index b9a07630..6863a66b 100644 --- a/storage/migration/system_contracts_migration.go +++ b/storage/migration/system_contracts_migration.go @@ -20,6 +20,7 @@ package migration import ( "context" + "github.com/rs/zerolog" "github.com/onflow/flow-emulator/storage/sqlite" @@ -32,6 +33,8 @@ import ( "github.com/onflow/flow-go/model/flow" ) +const chain = flow.Emulator + func MigrateSystemContracts(store *sqlite.Store) error { payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) if err != nil { @@ -56,7 +59,7 @@ func migrateSystemContracts( migration := migrations.ChangeContractCodeMigration{} - systemContractChanges := migrations.SystemContractChanges(flow.Emulator) + systemContractChanges := migrations.SystemContractChanges(chain) for _, contractChange := range systemContractChanges { migration.RegisterContractChange( @@ -78,5 +81,10 @@ func migrateSystemContracts( return nil, err } } + + // Add new contracts + newlyIntroducedContracts := migrations.NewlyAddedSystemContracts(chain) + payloads = append(payloads, newlyIntroducedContracts...) + return payloads, nil } From 4bf481b79234e04d0d4f74d9ce17448a3f5f4e95 Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Fri, 2 Feb 2024 08:24:31 -0800 Subject: [PATCH 6/9] Improve tests --- storage/migration/cadence_values_migration.go | 14 +++++--- storage/migration/migration_test.go | 34 +++++++++++++++++-- .../migration/system_contracts_migration.go | 7 ++-- storage/migration/utils.go | 6 ++-- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/storage/migration/cadence_values_migration.go b/storage/migration/cadence_values_migration.go index b9a4a77a..5edababe 100644 --- a/storage/migration/cadence_values_migration.go +++ b/storage/migration/cadence_values_migration.go @@ -20,6 +20,7 @@ package migration import ( "context" + "github.com/rs/zerolog" "github.com/onflow/flow-emulator/storage/sqlite" @@ -28,19 +29,22 @@ import ( "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/flow-go/cmd/util/ledger/migrations" + "github.com/onflow/flow-go/cmd/util/ledger/reporters" "github.com/onflow/flow-go/cmd/util/ledger/util" "github.com/onflow/flow-go/ledger" ) -func MigrateCadenceValues(store *sqlite.Store) error { +func MigrateCadenceValues( + store *sqlite.Store, + rwf reporters.ReportWriterFactory, + logger zerolog.Logger, +) error { payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) if err != nil { return err } - rwf := &ReportWriterFactory{} capabilityIDs := map[interpreter.AddressPath]interpreter.UInt64Value{} - logger := NewConsoleLogger() payloads, err = migrateLinkValues(rwf, logger, capabilityIDs, accounts, payloads) if err != nil { @@ -56,7 +60,7 @@ func MigrateCadenceValues(store *sqlite.Store) error { } func migrateLinkValues( - rwf *ReportWriterFactory, + rwf reporters.ReportWriterFactory, logger zerolog.Logger, capabilityIDs map[interpreter.AddressPath]interpreter.UInt64Value, accounts []common.Address, @@ -81,7 +85,7 @@ func migrateLinkValues( } func migrateCadenceValues( - rwf *ReportWriterFactory, + rwf reporters.ReportWriterFactory, logger zerolog.Logger, capabilityIDs map[interpreter.AddressPath]interpreter.UInt64Value, accounts []common.Address, diff --git a/storage/migration/migration_test.go b/storage/migration/migration_test.go index c70a5235..60a3a569 100644 --- a/storage/migration/migration_test.go +++ b/storage/migration/migration_test.go @@ -19,9 +19,13 @@ package migration import ( + "io" "os" "testing" + "github.com/rs/zerolog" + + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/onflow/flow-emulator/storage/sqlite" @@ -51,11 +55,37 @@ func TestStateMigration(t *testing.T) { store, err := sqlite.New(tempEmulatorStatePath) require.NoError(t, err) + logWriter := &writer{} + logger := zerolog.New(logWriter).Level(zerolog.ErrorLevel) + // First migrate the system contracts - err = MigrateSystemContracts(store) + err = MigrateSystemContracts(store, logger) require.NoError(t, err) // Then migrate the values. - err = MigrateCadenceValues(store) + rwf := &NOOPReportWriterFactory{} + err = MigrateCadenceValues(store, rwf, logger) require.NoError(t, err) + + logs := logWriter.logs + require.Len(t, logs, 9) + + // TODO: see why + assert.Contains(t, logs[0], "failed to load type: A.f8d6e0586b0a20c7.MetadataViews.Resolver") + assert.Contains(t, logs[1], "failed to load type: A.f8d6e0586b0a20c7.MetadataViews.Resolver") + + for _, log := range logs[2:] { + assert.Contains(t, log, "cannot convert deprecated type") + } +} + +type writer struct { + logs []string +} + +var _ io.Writer = &writer{} + +func (w *writer) Write(p []byte) (n int, err error) { + w.logs = append(w.logs, string(p)) + return len(p), nil } diff --git a/storage/migration/system_contracts_migration.go b/storage/migration/system_contracts_migration.go index 6863a66b..67a19f08 100644 --- a/storage/migration/system_contracts_migration.go +++ b/storage/migration/system_contracts_migration.go @@ -35,14 +35,15 @@ import ( const chain = flow.Emulator -func MigrateSystemContracts(store *sqlite.Store) error { +func MigrateSystemContracts( + store *sqlite.Store, + logger zerolog.Logger, +) error { payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) if err != nil { return err } - logger := NewConsoleLogger() - payloads, err = migrateSystemContracts(logger, accounts, payloads) if err != nil { return err diff --git a/storage/migration/utils.go b/storage/migration/utils.go index a2651787..47687059 100644 --- a/storage/migration/utils.go +++ b/storage/migration/utils.go @@ -100,9 +100,9 @@ func NewConsoleLogger() zerolog.Logger { Level(zerolog.InfoLevel) } -type ReportWriterFactory struct{} +type NOOPReportWriterFactory struct{} -func (_m *ReportWriterFactory) ReportWriter(_ string) reporters.ReportWriter { +func (*NOOPReportWriterFactory) ReportWriter(_ string) reporters.ReportWriter { return &NOOPWriter{} } @@ -110,7 +110,7 @@ type NOOPWriter struct{} var _ reporters.ReportWriter = &NOOPWriter{} -func (r *NOOPWriter) Write(_ any) { +func (*NOOPWriter) Write(_ any) { // NO-OP } From b8362d65f277a02531934206ee4756bce154ec16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 2 Feb 2024 15:12:24 -0800 Subject: [PATCH 7/9] go mod tidy --- go.sum | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/go.sum b/go.sum index 92587d08..5e6aa7eb 100644 --- a/go.sum +++ b/go.sum @@ -1977,18 +1977,29 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f h1:Z8/PgTqOgOg02MTRpTBYO2k16FE6z4wEOtaC2WBR9Xo= github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs95K7IYdIYRnNcYQGf4nbF/uuJ0tHf4DRuM= github.com/onflow/cadence v1.0.0-M3/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8= +github.com/onflow/cadence v1.0.0-M5 h1:vNG7x2KLLrt2yfVr1HtEXUlUi4GdNo+rkXnPkhSzsFA= github.com/onflow/cadence v1.0.0-M5/go.mod h1:a4mccDU90hmuxCLUFzs9J/ANG/rYbFa36h4Z0bBAqNU= +github.com/onflow/crypto v0.25.0 h1:BeWbLsh3ZD13Ej+Uky6kg1PL1ZIVBDVX+2MVBNwqddg= github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= +github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.1-0.20240125214229-b7a95136dd0d h1:Afcfk/9jAQZ1v5PLGdP68FG/0yPPM60fn9Eq8ChBGS0= github.com/onflow/flow-core-contracts/lib/go/contracts v0.15.1-0.20240125214229-b7a95136dd0d/go.mod h1:Ts/HN+N0RaYJ6oPCqR1JPaMVFiVaMdKTSUH4OdSjjs0= +github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d h1:IQJpP3VLLjT4R8ItBpr+Mmp0IOnC/8iBcM0/67JNB9c= github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d/go.mod h1:MZ2j5YVTQiSE0B99zuaYhxvGG5GcvimWpQK1Fw/1QBg= +github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01 h1:8iKk5RuFvhe7NQyAO3c+xiVvv38RB/yopHdWxp4AbL8= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= +github.com/onflow/flow-go v0.33.2-0.20240202213228-22b58f760758 h1:TJj5MG39Pwt/lm/K0kc55uSfi5LTHfwtNZ8SKwbUauE= github.com/onflow/flow-go v0.33.2-0.20240202213228-22b58f760758/go.mod h1:G8POtilqh3X5X9tlbm6MbuP7ZT0laub3hmwj3vBz9p0= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= +github.com/onflow/flow-go-sdk v1.0.0-M2 h1:YWeXTo112RF8s6swiOU5oW8JWbOOz392FCeAbGnm+W4= github.com/onflow/flow-go-sdk v1.0.0-M2/go.mod h1:mllhNw5WAEug59EWvW3TudcrtPmB5VfLA3iUx7mAA4s= +github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad h1:I6LD9BOsilGbiqhGjP86FIIXJe0YdUz75d/oWdHFzDI= github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad/go.mod h1:2gpbza+uzs1k7x31hkpBPlggIRkI53Suo0n2AyA2HcE= github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231121210617-52ee94b830c2/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= +github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231213135419-ae911cc351a2 h1:+rT+UsfTR39JZO8ht2+4fkaWfHw74SCj1fyz1lWuX8A= github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231213135419-ae911cc351a2/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= +github.com/onflow/sdks v0.5.1-0.20230912225508-b35402f12bba h1:rIehuhO6bj4FkwE4VzwEjX7MoAlOhUJENBJLqDqVxAo= github.com/onflow/sdks v0.5.1-0.20230912225508-b35402f12bba/go.mod h1:F0dj0EyHC55kknLkeD10js4mo14yTdMotnWMslPirrU= +github.com/onflow/wal v0.0.0-20230529184820-bc9f8244608d h1:gAEqYPn3DS83rHIKEpsajnppVD1+zwuYPFyeDVFaQvg= github.com/onflow/wal v0.0.0-20230529184820-bc9f8244608d/go.mod h1:iMC8gkLqu4nkbkAla5HkSBb+FGyQOZiWz3DYm2wSXCk= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1996,15 +2007,20 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -2013,9 +2029,11 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= @@ -2026,20 +2044,24 @@ github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= @@ -2051,6 +2073,7 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -2060,6 +2083,7 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -2071,6 +2095,7 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8 github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -2081,16 +2106,25 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= +github.com/psiemens/graceland v1.0.0 h1:L580AVV4Q2XLcPpmvxJRH9UpEAYr/eu2jBKmMglhvM8= github.com/psiemens/graceland v1.0.0/go.mod h1:1Tof+vt1LbmcZFE0lzgdwMN0QBymAChG3FRgDx8XisU= +github.com/psiemens/sconfig v0.1.0 h1:xfWqW+TRpih7mXZIqKYTmpRhlZLQ1kbxV8EjllPv76s= github.com/psiemens/sconfig v0.1.0/go.mod h1:+MLKqdledP/8G3rOBpknbLh0IclCf4WneJUtS26JB2U= +github.com/quic-go/qtls-go1-19 v0.3.2 h1:tFxjCFcTQzK+oMxG6Zcvp4Dq8dx4yD3dDiIiyc86Z5U= +github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -2098,12 +2132,15 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -2114,6 +2151,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE= github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -2122,40 +2160,51 @@ github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfP github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sethvargo/go-retry v0.2.3 h1:oYlgvIvsju3jNbottWABtbnoLC+GDtLdBHxKWxQm/iU= github.com/sethvargo/go-retry v0.2.3/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slok/go-http-metrics v0.10.0 h1:rh0LaYEKza5eaYRGDXujKrOln57nHBi4TtVhmNEpbgM= github.com/slok/go-http-metrics v0.10.0/go.mod h1:lFqdaS4kWMfUKCSukjC47PdCeTk+hXDUVm8kLHRqJ38= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= @@ -2165,6 +2214,7 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -2179,27 +2229,37 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c h1:HelZ2kAFadG0La9d+4htN4HzQ68Bm2iM9qKMSMES6xg= github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c/go.mod h1:JlzghshsemAMDGZLytTFY8C1JQxQPhnatWqNwUXjggo= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d h1:5JInRQbk5UBX8JfUvKh2oYTLMVwj3p6n+wapDDm7hko= github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d/go.mod h1:Nlx5Y115XQvNcIdIy7dZXaNSUpzwBSge4/Ivk93/Yog= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= @@ -2212,10 +2272,14 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0cd26cZoE= github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= @@ -2236,8 +2300,11 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -2252,33 +2319,45 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -2286,6 +2365,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -2319,6 +2399,7 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 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= @@ -2340,6 +2421,7 @@ golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -2390,6 +2472,7 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2477,6 +2560,7 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -2511,6 +2595,7 @@ golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4 golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= +golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2532,6 +2617,7 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2664,6 +2750,7 @@ golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.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= @@ -2681,6 +2768,7 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2702,6 +2790,7 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2711,6 +2800,7 @@ golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2796,6 +2886,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.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= 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= @@ -2805,6 +2896,7 @@ golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= @@ -2813,6 +2905,7 @@ gonum.org/v1/gonum v0.6.1/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -2887,6 +2980,7 @@ google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvy google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk= google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/api v0.151.0 h1:FhfXLO/NFdJIzQtCqjpysWwqKk8AzGWBUhMIx67cVDU= google.golang.org/api v0.151.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2895,6 +2989,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -3051,6 +3146,7 @@ google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0t google.golang.org/genproto v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:CCviP9RmpZ1mxVr8MUjCnSiY09IbAXZxhLE6EhHIdPU= google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= +google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= @@ -3066,9 +3162,11 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go. google.golang.org/genproto/googleapis/api v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:RdyHbowztCGQySiCvQPgWQWgWhGnouTdCflKoDBt32U= google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:SUBoKXbI1Efip18FClrQVGjWcyd0QZd8KkvdP34t7ww= +google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405 h1:o4S3HvTUEXgRsNSUQsALDVog0O9F/U1JJlHmmUN8Uas= google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= @@ -3085,6 +3183,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik= google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= google.golang.org/grpc v0.0.0-20170208002647-2a6bf6142e96/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -3141,6 +3240,7 @@ google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpX google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= 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= @@ -3160,6 +3260,7 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -3167,6 +3268,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -3176,12 +3278,14 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8 gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -3192,12 +3296,15 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -3208,6 +3315,7 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= @@ -3239,10 +3347,12 @@ modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= +modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= @@ -3250,11 +3360,13 @@ modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= +modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= @@ -3265,12 +3377,15 @@ modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From a10dc74f905a94a780526e1077677d3f930b2504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 2 Feb 2024 15:14:06 -0800 Subject: [PATCH 8/9] update to latest flow-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 701247f3..0a291be3 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/onflow/cadence v1.0.0-M5 github.com/onflow/crypto v0.25.0 github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d - github.com/onflow/flow-go v0.33.2-0.20240202213228-22b58f760758 + github.com/onflow/flow-go v0.33.2-0.20240202225843-db8d63fef179 github.com/onflow/flow-go-sdk v1.0.0-M2 github.com/onflow/flow-nft/lib/go/contracts v1.1.1-0.20240125205553-d2b571fb3fad github.com/onflow/flow/protobuf/go/flow v0.3.2-0.20231213135419-ae911cc351a2 diff --git a/go.sum b/go.sum index 5e6aa7eb..188d7d1a 100644 --- a/go.sum +++ b/go.sum @@ -1987,8 +1987,8 @@ github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229- github.com/onflow/flow-core-contracts/lib/go/templates v0.15.1-0.20240125214229-b7a95136dd0d/go.mod h1:MZ2j5YVTQiSE0B99zuaYhxvGG5GcvimWpQK1Fw/1QBg= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01 h1:8iKk5RuFvhe7NQyAO3c+xiVvv38RB/yopHdWxp4AbL8= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20240125205519-2e80d9b4bd01/go.mod h1:PwsL8fC81cjnUnTfmyL/HOIyHnyaw/JA474Wfj2tl6A= -github.com/onflow/flow-go v0.33.2-0.20240202213228-22b58f760758 h1:TJj5MG39Pwt/lm/K0kc55uSfi5LTHfwtNZ8SKwbUauE= -github.com/onflow/flow-go v0.33.2-0.20240202213228-22b58f760758/go.mod h1:G8POtilqh3X5X9tlbm6MbuP7ZT0laub3hmwj3vBz9p0= +github.com/onflow/flow-go v0.33.2-0.20240202225843-db8d63fef179 h1:HcDYt9s4fNoQKz8m8OPzwU+WJxolmSOnloyjERVQrIA= +github.com/onflow/flow-go v0.33.2-0.20240202225843-db8d63fef179/go.mod h1:G8POtilqh3X5X9tlbm6MbuP7ZT0laub3hmwj3vBz9p0= github.com/onflow/flow-go-sdk v1.0.0-M1/go.mod h1:TDW0MNuCs4SvqYRUzkbRnRmHQL1h4X8wURsCw9P9beo= github.com/onflow/flow-go-sdk v1.0.0-M2 h1:YWeXTo112RF8s6swiOU5oW8JWbOOz392FCeAbGnm+W4= github.com/onflow/flow-go-sdk v1.0.0-M2/go.mod h1:mllhNw5WAEug59EWvW3TudcrtPmB5VfLA3iUx7mAA4s= From 02211c0cbbef4c2bf3234a9ffeb071bd0cc09281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 8 Feb 2024 10:29:32 -0800 Subject: [PATCH 9/9] use Cadence 1.0 migration pipeline from flow-go --- storage/migration/cadence1.go | 69 ++++++++++ .../{migration_test.go => cadence1_test.go} | 20 +-- storage/migration/cadence_values_migration.go | 120 ------------------ .../migration/system_contracts_migration.go | 91 ------------- 4 files changed, 72 insertions(+), 228 deletions(-) create mode 100644 storage/migration/cadence1.go rename storage/migration/{migration_test.go => cadence1_test.go} (75%) delete mode 100644 storage/migration/cadence_values_migration.go delete mode 100644 storage/migration/system_contracts_migration.go diff --git a/storage/migration/cadence1.go b/storage/migration/cadence1.go new file mode 100644 index 00000000..2e367b14 --- /dev/null +++ b/storage/migration/cadence1.go @@ -0,0 +1,69 @@ +/* + * Flow Emulator + * + * Copyright 2024 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package migration + +import ( + "github.com/onflow/flow-go/cmd/util/ledger/migrations" + "github.com/onflow/flow-go/model/flow" + "github.com/rs/zerolog" + + "github.com/onflow/flow-emulator/storage/sqlite" + + "github.com/onflow/flow-go/cmd/util/ledger/reporters" + "github.com/onflow/flow-go/cmd/util/ledger/util" +) + +func MigrateCadence1( + store *sqlite.Store, + rwf reporters.ReportWriterFactory, + logger zerolog.Logger, +) error { + payloads, payloadInfo, _, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) + if err != nil { + return err + } + + // TODO: >1 breaks atree storage map iteration + // and requires LinkValueMigration.LinkValueMigration to be thread-safe + const nWorker = 1 + + // TODO: EVM contract is not deployed in snapshot yet, so can't update it + const evmContractChange = migrations.EVMContractChangeNone + + // TODO: + var stagedContracts []migrations.StagedContract + + cadence1Migrations := migrations.NewCadence1Migrations( + logger, + rwf, + nWorker, + flow.Emulator, + evmContractChange, + stagedContracts, + ) + + for _, migration := range cadence1Migrations { + payloads, err = migration(payloads) + if err != nil { + return err + } + } + + return WritePayloadsToSnapshot(store, payloads, payloadInfo) +} diff --git a/storage/migration/migration_test.go b/storage/migration/cadence1_test.go similarity index 75% rename from storage/migration/migration_test.go rename to storage/migration/cadence1_test.go index 60a3a569..0d8baf69 100644 --- a/storage/migration/migration_test.go +++ b/storage/migration/cadence1_test.go @@ -25,13 +25,12 @@ import ( "github.com/rs/zerolog" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/onflow/flow-emulator/storage/sqlite" ) -func TestStateMigration(t *testing.T) { +func TestCadence1Migration(t *testing.T) { const emulatorStateFile = "test-data/emulator_state_cadence_v0.42.6" // Work on a temp copy of the state, @@ -58,25 +57,12 @@ func TestStateMigration(t *testing.T) { logWriter := &writer{} logger := zerolog.New(logWriter).Level(zerolog.ErrorLevel) - // First migrate the system contracts - err = MigrateSystemContracts(store, logger) - require.NoError(t, err) - // Then migrate the values. rwf := &NOOPReportWriterFactory{} - err = MigrateCadenceValues(store, rwf, logger) + err = MigrateCadence1(store, rwf, logger) require.NoError(t, err) - logs := logWriter.logs - require.Len(t, logs, 9) - - // TODO: see why - assert.Contains(t, logs[0], "failed to load type: A.f8d6e0586b0a20c7.MetadataViews.Resolver") - assert.Contains(t, logs[1], "failed to load type: A.f8d6e0586b0a20c7.MetadataViews.Resolver") - - for _, log := range logs[2:] { - assert.Contains(t, log, "cannot convert deprecated type") - } + require.Empty(t, logWriter.logs) } type writer struct { diff --git a/storage/migration/cadence_values_migration.go b/storage/migration/cadence_values_migration.go deleted file mode 100644 index 5edababe..00000000 --- a/storage/migration/cadence_values_migration.go +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Flow Emulator - * - * Copyright 2024 Dapper Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package migration - -import ( - "context" - - "github.com/rs/zerolog" - - "github.com/onflow/flow-emulator/storage/sqlite" - - "github.com/onflow/cadence/runtime/common" - "github.com/onflow/cadence/runtime/interpreter" - - "github.com/onflow/flow-go/cmd/util/ledger/migrations" - "github.com/onflow/flow-go/cmd/util/ledger/reporters" - "github.com/onflow/flow-go/cmd/util/ledger/util" - "github.com/onflow/flow-go/ledger" -) - -func MigrateCadenceValues( - store *sqlite.Store, - rwf reporters.ReportWriterFactory, - logger zerolog.Logger, -) error { - payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) - if err != nil { - return err - } - - capabilityIDs := map[interpreter.AddressPath]interpreter.UInt64Value{} - - payloads, err = migrateLinkValues(rwf, logger, capabilityIDs, accounts, payloads) - if err != nil { - return err - } - - payloads, err = migrateCadenceValues(rwf, logger, capabilityIDs, accounts, payloads) - if err != nil { - return err - } - - return WritePayloadsToSnapshot(store, payloads, payloadInfo) -} - -func migrateLinkValues( - rwf reporters.ReportWriterFactory, - logger zerolog.Logger, - capabilityIDs map[interpreter.AddressPath]interpreter.UInt64Value, - accounts []common.Address, - payloads []*ledger.Payload, -) ([]*ledger.Payload, error) { - - linkValueMigration := migrations.NewCadenceLinkValueMigrator(rwf, capabilityIDs) - - err := linkValueMigration.InitMigration(logger, nil, 0) - if err != nil { - return nil, err - } - - for _, account := range accounts { - ctx := context.Background() - payloads, err = linkValueMigration.MigrateAccount(ctx, account, payloads) - if err != nil { - return nil, err - } - } - return payloads, nil -} - -func migrateCadenceValues( - rwf reporters.ReportWriterFactory, - logger zerolog.Logger, - capabilityIDs map[interpreter.AddressPath]interpreter.UInt64Value, - accounts []common.Address, - payloads []*ledger.Payload, -) ([]*ledger.Payload, error) { - - valueMigration := migrations.NewCadenceValueMigrator( - rwf, - capabilityIDs, - func(staticType *interpreter.CompositeStaticType) interpreter.StaticType { - return nil - }, - func(staticType *interpreter.InterfaceStaticType) interpreter.StaticType { - return nil - }, - ) - - err := valueMigration.InitMigration(logger, nil, 0) - if err != nil { - return nil, err - } - - for _, account := range accounts { - ctx := context.Background() - payloads, err = valueMigration.MigrateAccount(ctx, account, payloads) - if err != nil { - return nil, err - } - } - - return payloads, nil -} diff --git a/storage/migration/system_contracts_migration.go b/storage/migration/system_contracts_migration.go deleted file mode 100644 index 67a19f08..00000000 --- a/storage/migration/system_contracts_migration.go +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Flow Emulator - * - * Copyright 2024 Dapper Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package migration - -import ( - "context" - - "github.com/rs/zerolog" - - "github.com/onflow/flow-emulator/storage/sqlite" - - "github.com/onflow/cadence/runtime/common" - - "github.com/onflow/flow-go/cmd/util/ledger/migrations" - "github.com/onflow/flow-go/cmd/util/ledger/util" - "github.com/onflow/flow-go/ledger" - "github.com/onflow/flow-go/model/flow" -) - -const chain = flow.Emulator - -func MigrateSystemContracts( - store *sqlite.Store, - logger zerolog.Logger, -) error { - payloads, payloadInfo, accounts, err := util.PayloadsAndAccountsFromEmulatorSnapshot(store.DB()) - if err != nil { - return err - } - - payloads, err = migrateSystemContracts(logger, accounts, payloads) - if err != nil { - return err - } - - return WritePayloadsToSnapshot(store, payloads, payloadInfo) -} - -func migrateSystemContracts( - logger zerolog.Logger, - accounts []common.Address, - payloads []*ledger.Payload, -) ([]*ledger.Payload, error) { - - migration := migrations.ChangeContractCodeMigration{} - - systemContractChanges := migrations.SystemContractChanges(chain) - - for _, contractChange := range systemContractChanges { - migration.RegisterContractChange( - contractChange.Address, - contractChange.ContractName, - contractChange.NewContractCode, - ) - } - - err := migration.InitMigration(logger, nil, 0) - if err != nil { - return nil, err - } - - for _, account := range accounts { - ctx := context.Background() - payloads, err = migration.MigrateAccount(ctx, account, payloads) - if err != nil { - return nil, err - } - } - - // Add new contracts - newlyIntroducedContracts := migrations.NewlyAddedSystemContracts(chain) - payloads = append(payloads, newlyIntroducedContracts...) - - return payloads, nil -}