diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 25a58ac..609c77f 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -20,3 +20,4 @@ jobs: uses: golangci/golangci-lint-action@v6 with: version: v1.64 + args: --timeout=5m diff --git a/go.mod b/go.mod index d23248a..59381f6 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,11 @@ module github.com/gnolang/supernova -go 1.23 +go 1.23.0 + +toolchain go1.24.1 require ( - github.com/gnolang/gno v0.0.0-20250129165357-b392287f0d2c + github.com/gnolang/gno v0.0.0-20250826105341-fba926958b6b github.com/peterbourgon/ff/v3 v3.4.0 github.com/schollz/progressbar/v3 v3.18.0 github.com/stretchr/testify v1.10.0 @@ -11,30 +13,54 @@ require ( require ( dario.cat/mergo v1.0.1 // indirect + github.com/DataDog/zstd v1.4.5 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/btcsuite/btcd/btcutil v1.1.6 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.5 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/gofrs/flock v0.12.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/onsi/gomega v1.31.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.15.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/rs/cors v1.11.1 // indirect github.com/rs/xid v1.6.0 // indirect github.com/sig-0/insertion-queue v0.0.0-20241004125609-6b3ca841346b // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect go.etcd.io/bbolt v1.3.11 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.34.0 // indirect @@ -46,14 +72,15 @@ require ( go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.40.0 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/mod v0.26.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/term v0.33.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/tools v0.35.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect google.golang.org/grpc v1.69.4 // indirect diff --git a/go.sum b/go.sum index 447c34a..60f31ad 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= @@ -30,12 +34,29 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/cosmos/ledger-cosmos-go v0.14.0 h1:WfCHricT3rPbkPSVKRH+L4fQGKYHuGOK9Edpel8TYpE= github.com/cosmos/ledger-cosmos-go v0.14.0/go.mod h1:E07xCWSBl3mTGofZ2QnL4cIUzMbbGVyik84QYKbX3RA= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -53,14 +74,23 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/gnolang/gno v0.0.0-20250129165357-b392287f0d2c h1:9XalLZCqb6vfNUXojzVj4WXgpQEAONsyeoAH+DTbT1E= -github.com/gnolang/gno v0.0.0-20250129165357-b392287f0d2c/go.mod h1:9UN8hxUrbTQzq5oqXdx39seAtRBhUyONGw0voV4lMBs= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/gnolang/gno v0.0.0-20250826105341-fba926958b6b h1:z0iw3ObgSnibeOpORPzRZjnx6v5eeSbQ35zgdoZndjE= +github.com/gnolang/gno v0.0.0-20250826105341-fba926958b6b/go.mod h1:j9wKq29meqwktEj2ReqPbSkeYUwoisfxHHVeV20lhtw= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -89,7 +119,11 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -100,6 +134,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -120,12 +156,24 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc= github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= +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/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +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.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= @@ -147,6 +195,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= @@ -175,23 +227,33 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -201,17 +263,25 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= +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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA= diff --git a/internal/client/client.go b/internal/client/client.go index ac771ae..1e08c70 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -12,7 +12,10 @@ import ( "github.com/gnolang/supernova/internal/common" ) -const simulatePath = ".app/simulate" +const ( + simulatePath = ".app/simulate" + gaspricePath = "auth/gasprice" +) type Client struct { conn *client.RPCClient @@ -170,3 +173,20 @@ func (h *Client) EstimateGas(tx *std.Tx) (int64, error) { // for executing the transaction return deliverTx.GasUsed, nil } + +func (h *Client) FetchGasPrice() (std.GasPrice, error) { + // Perform auth/gasprice + gp := std.GasPrice{} + + qres, err := h.conn.ABCIQuery(gaspricePath, []byte{}) + if err != nil { + return gp, err + } + + err = amino.UnmarshalJSON(qres.Response.Data, &gp) + if err != nil { + return gp, err + } + + return gp, nil +} diff --git a/internal/distributor/distributor.go b/internal/distributor/distributor.go index d42de88..c278b2f 100644 --- a/internal/distributor/distributor.go +++ b/internal/distributor/distributor.go @@ -20,6 +20,7 @@ type Client interface { GetAccount(address string) (*gnoland.GnoAccount, error) BroadcastTransaction(tx *std.Tx) error EstimateGas(tx *std.Tx) (int64, error) + FetchGasPrice() (std.GasPrice, error) } // Distributor is the process @@ -42,41 +43,20 @@ func NewDistributor( func (d *Distributor) Distribute( distributor crypto.PrivKey, accounts []crypto.Address, - transactions uint64, chainID string, + gasPrice std.GasPrice, + calculatedRuntimeCost std.Coin, ) ([]std.Account, error) { fmt.Printf("\n💸 Starting Fund Distribution 💸\n\n") - // Calculate the base fees - subAccountCost := calculateRuntimeCosts(int64(transactions)) fmt.Printf( "Calculated sub-account cost as %d %s\n", - subAccountCost.Amount, - subAccountCost.Denom, + calculatedRuntimeCost.Amount, + calculatedRuntimeCost.Denom, ) // Fund the accounts - return d.fundAccounts(distributor, accounts, subAccountCost, chainID) -} - -// calculateRuntimeCosts calculates the amount of funds -// each account needs to have in order to participate in the -// stress test run -func calculateRuntimeCosts(totalTx int64) std.Coin { - // Cost of a single run transaction for the sub-account - // NOTE: Since there is no gas estimation support yet, this value - // is fixed, but it will change in the future once pricing estimations - // are added - baseTxCost := common.CalculateFeeInRatio(1_000_000, common.DefaultGasPrice) - - // Each account should have enough funds - // to execute the entire run - subAccountCost := std.Coin{ - Denom: common.Denomination, - Amount: totalTx * baseTxCost.GasFee.Amount, - } - - return subAccountCost + return d.fundAccounts(distributor, accounts, calculatedRuntimeCost, chainID, gasPrice) } // fundAccounts attempts to fund accounts that have missing funds, @@ -86,6 +66,7 @@ func (d *Distributor) fundAccounts( accounts []crypto.Address, singleRunCost std.Coin, chainID string, + gasPrice std.GasPrice, ) ([]std.Account, error) { type shortAccount struct { missingFunds std.Coin @@ -150,7 +131,7 @@ func (d *Distributor) fundAccounts( var ( distributorBalance = distributor.Coins fundableIndex = 0 - defaultFee = common.CalculateFeeInRatio(100_000, common.DefaultGasPrice) + defaultFee = common.CalculateFeeInRatio(100_000, gasPrice) ) for _, account := range shortAccounts { diff --git a/internal/distributor/distributor_test.go b/internal/distributor/distributor_test.go index 33ce5f4..c3ae019 100644 --- a/internal/distributor/distributor_test.go +++ b/internal/distributor/distributor_test.go @@ -17,7 +17,10 @@ func TestDistributor_Distribute(t *testing.T) { var ( numTx = uint64(1000) - singleCost = calculateRuntimeCosts(int64(numTx)) + singleCost = std.Coin{ + Denom: common.Denomination, + Amount: int64(numTx) * 100_00, + } ) getAccount := func(address string, accounts []crypto.PrivKey) crypto.PrivKey { @@ -66,7 +69,7 @@ func TestDistributor_Distribute(t *testing.T) { addresses = append(addresses, account.PubKey().Address()) } - readyAccounts, err := d.Distribute(accounts[0], addresses, numTx, "dummy") + readyAccounts, err := d.Distribute(accounts[0], addresses, "dummy", common.DefaultGasPrice, singleCost) if err != nil { t.Fatalf("unable to distribute funds, %v", err) } @@ -122,7 +125,7 @@ func TestDistributor_Distribute(t *testing.T) { addresses = append(addresses, account.PubKey().Address()) } - readyAccounts, err := d.Distribute(accounts[0], addresses, numTx, "dummy") + readyAccounts, err := d.Distribute(accounts[0], addresses, "dummy", common.DefaultGasPrice, singleCost) assert.Nil(t, readyAccounts) assert.ErrorIs(t, err, errInsufficientFunds) @@ -192,7 +195,7 @@ func TestDistributor_Distribute(t *testing.T) { addresses = append(addresses, account.PubKey().Address()) } - readyAccounts, err := d.Distribute(accounts[0], addresses, numTx, "dummy") + readyAccounts, err := d.Distribute(accounts[0], addresses, "dummy", common.DefaultGasPrice, singleCost) if err != nil { t.Fatalf("unable to distribute funds, %v", err) } diff --git a/internal/distributor/mock_test.go b/internal/distributor/mock_test.go index bd9cd1b..5d30456 100644 --- a/internal/distributor/mock_test.go +++ b/internal/distributor/mock_test.go @@ -9,12 +9,14 @@ type ( broadcastTransactionDelegate func(*std.Tx) error getAccountDelegate func(string) (*gnoland.GnoAccount, error) estimateGasDelegate func(*std.Tx) (int64, error) + fetchGasPriceDelegate func() (std.GasPrice, error) ) type mockClient struct { broadcastTransactionFn broadcastTransactionDelegate getAccountFn getAccountDelegate estimateGasFn estimateGasDelegate + fetchGasPriceFn fetchGasPriceDelegate } func (m *mockClient) BroadcastTransaction(tx *std.Tx) error { @@ -40,3 +42,11 @@ func (m *mockClient) EstimateGas(tx *std.Tx) (int64, error) { return 0, nil } + +func (m *mockClient) FetchGasPrice() (std.GasPrice, error) { + if m.fetchGasPriceFn != nil { + return m.fetchGasPriceFn() + } + + return std.GasPrice{}, nil +} diff --git a/internal/pipeline.go b/internal/pipeline.go index f76d047..9a278ce 100644 --- a/internal/pipeline.go +++ b/internal/pipeline.go @@ -6,6 +6,7 @@ import ( "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/crypto/bip39" + "github.com/gnolang/gno/tm2/pkg/std" "github.com/gnolang/supernova/internal/batcher" "github.com/gnolang/supernova/internal/client" "github.com/gnolang/supernova/internal/collector" @@ -65,14 +66,32 @@ func (p *Pipeline) Execute() error { // Initialize the accounts for the runtime accounts := p.initializeAccounts() + gasPrice, err := p.cli.FetchGasPrice() + if err != nil { + return err + } + + lastBlock, err := p.cli.GetLatestBlockHeight() + if err != nil { + return fmt.Errorf("unable to get last block, %w", err) + } + + maxGas, err := p.cli.GetBlockGasLimit(lastBlock) + if err != nil { + return fmt.Errorf("unable to get block gas limit, %w", err) + } // Predeploy any pending transactions - if err := prepareRuntime( + estimatedGas, err := prepareRuntime( mode, accounts[0], p.cfg.ChainID, p.cli, txRuntime, - ); err != nil { + maxGas, + gasPrice, + p.cfg.Transactions, + ) + if err != nil { return err } @@ -86,8 +105,9 @@ func (p *Pipeline) Execute() error { runAccounts, err := distributor.NewDistributor(p.cli).Distribute( accounts[0], addresses, - p.cfg.Transactions, p.cfg.ChainID, + gasPrice, + estimatedGas, ) if err != nil { return fmt.Errorf("unable to distribute funds, %w", err) @@ -109,6 +129,8 @@ func (p *Pipeline) Execute() error { runKeys, runAccounts, p.cfg.Transactions, + maxGas, + gasPrice, p.cfg.ChainID, p.cli.EstimateGas, ) @@ -192,28 +214,34 @@ func prepareRuntime( chainID string, cli pipelineClient, txRuntime runtime.Runtime, -) error { - if mode != runtime.RealmCall { - return nil - } - - fmt.Printf("\n✨ Starting Predeployment Procedure ✨\n\n") - + currentMaxGas int64, + gasPrice std.GasPrice, + transactions uint64, +) (std.Coin, error) { // Get the deployer account deployer, err := cli.GetAccount(deployerKey.PubKey().Address().String()) if err != nil { - return fmt.Errorf("unable to fetch deployer account, %w", err) + return std.Coin{}, fmt.Errorf("unable to fetch deployer account, %w", err) } + signCB := runtime.SignTransactionsCb(chainID, deployer, deployerKey) + + if mode != runtime.RealmCall { + return txRuntime.CalculateRuntimeCosts(deployer, cli.EstimateGas, signCB, currentMaxGas, gasPrice, transactions) + } + + fmt.Printf("\n✨ Starting Predeployment Procedure ✨\n\n") + // Get the predeploy transactions predeployTxs, err := txRuntime.Initialize( deployer, - deployerKey, - chainID, + signCB, cli.EstimateGas, + currentMaxGas, + gasPrice, ) if err != nil { - return fmt.Errorf("unable to initialize runtime, %w", err) + return std.Coin{}, fmt.Errorf("unable to initialize runtime, %w", err) } bar := progressbar.Default(int64(len(predeployTxs)), "predeployed txs") @@ -221,7 +249,7 @@ func prepareRuntime( // Execute the predeploy transactions for _, tx := range predeployTxs { if err := cli.BroadcastTransaction(tx); err != nil { - return fmt.Errorf("unable to broadcast predeploy tx, %w", err) + return std.Coin{}, fmt.Errorf("unable to broadcast predeploy tx, %w", err) } _ = bar.Add(1) //nolint:errcheck // No need to check @@ -229,5 +257,5 @@ func prepareRuntime( fmt.Printf("✅ Successfully predeployed %d transactions\n", len(predeployTxs)) - return nil + return txRuntime.CalculateRuntimeCosts(deployer, cli.EstimateGas, signCB, currentMaxGas, gasPrice, transactions) } diff --git a/internal/runtime/helper.go b/internal/runtime/helper.go index cc93bd2..7c791df 100644 --- a/internal/runtime/helper.go +++ b/internal/runtime/helper.go @@ -21,6 +21,8 @@ func constructTransactions( keys []crypto.PrivKey, accounts []std.Account, transactions uint64, + maxGas int64, + gasPrice std.GasPrice, chainID string, getMsg msgFn, estimateFn EstimateGasFn, @@ -37,9 +39,10 @@ func constructTransactions( fmt.Printf("\n⏳ Estimating Gas ⏳\n") // Estimate the fee for the transaction batch + // passing in the maximum block gas, this is just a simulation txFee := common.CalculateFeeInRatio( - 1_000_000, - common.DefaultGasPrice, + maxGas, + gasPrice, ) // Construct the first tx @@ -74,7 +77,7 @@ func constructTransactions( clear(tx.Signatures) // Use the estimated gas limit - txFee = common.CalculateFeeInRatio(gasWanted+gasBuffer, common.DefaultGasPrice) // 10k gas buffer + txFee = common.CalculateFeeInRatio(gasWanted+gasBuffer, gasPrice) // 10k gas buffer if err = signer.SignTx(tx, creatorKey, cfg); err != nil { return nil, fmt.Errorf("unable to sign transaction, %w", err) @@ -128,3 +131,55 @@ func constructTransactions( return txs, nil } + +func calculateRuntimeCosts( + account std.Account, + transactions uint64, + maxBlockMaxGas int64, + gasPrice std.GasPrice, + getMsg msgFn, + signFn SignFn, + estimateFn EstimateGasFn, +) (std.Coin, error) { + fmt.Printf("\n⏳ Estimating Gas ⏳\n") + + // Estimate the fee for the transaction batch + // passing in the maximum block gas, this is just a simulation + txFee := common.CalculateFeeInRatio( + maxBlockMaxGas, + gasPrice, + ) + + tx := &std.Tx{ + Msgs: []std.Msg{getMsg(account, 0)}, + Fee: txFee, + } + + err := signFn(tx) + if err != nil { + return std.Coin{}, fmt.Errorf("unable to sign transaction, %w", err) + } + + estimatedGas, err := estimateFn(tx) + if err != nil { + return std.Coin{}, fmt.Errorf("unable to estimate gas, %w", err) + } + + return std.Coin{ + Denom: common.Denomination, + Amount: int64(transactions) * estimatedGas, + }, nil +} + +func SignTransactionsCb(chainID string, account std.Account, key crypto.PrivKey) SignFn { + // Sign the transaction + cfg := signer.SignCfg{ + ChainID: chainID, + AccountNumber: account.GetAccountNumber(), + Sequence: account.GetSequence(), + } + + return func(tx *std.Tx) error { + return signer.SignTx(tx, key, cfg) + } +} diff --git a/internal/runtime/helper_test.go b/internal/runtime/helper_test.go index a12006a..6e4ad13 100644 --- a/internal/runtime/helper_test.go +++ b/internal/runtime/helper_test.go @@ -54,6 +54,8 @@ func TestHelper_ConstructTransactions(t *testing.T) { accountKeys, accounts, transactions, + 1_000_000, + common.DefaultGasPrice, "dummy", getMsgFn, func(_ *std.Tx) (int64, error) { diff --git a/internal/runtime/package_deployment.go b/internal/runtime/package_deployment.go index 62cb52e..330dbf4 100644 --- a/internal/runtime/package_deployment.go +++ b/internal/runtime/package_deployment.go @@ -5,7 +5,6 @@ import ( "time" "github.com/gnolang/gno/gno.land/pkg/sdk/vm" - "github.com/gnolang/gno/gnovm" "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/std" ) @@ -18,55 +17,81 @@ func newPackageDeployment() *packageDeployment { func (c *packageDeployment) Initialize( _ std.Account, - _ crypto.PrivKey, - _ string, + _ SignFn, _ EstimateGasFn, + _ int64, + _ std.GasPrice, ) ([]*std.Tx, error) { // No extra setup needed for this runtime type return nil, nil } +func (c *packageDeployment) CalculateRuntimeCosts( + account std.Account, + estimateFn EstimateGasFn, + signFn SignFn, + currentMaxGas int64, + gasPrice std.GasPrice, + transactions uint64, +) (std.Coin, error) { + return calculateRuntimeCosts( + account, + transactions, + currentMaxGas, + gasPrice, + c.getMsgFn, + signFn, + estimateFn, + ) +} + func (c *packageDeployment) ConstructTransactions( keys []crypto.PrivKey, accounts []std.Account, transactions uint64, + maxGas int64, + gasPrice std.GasPrice, chainID string, estimateFn EstimateGasFn, ) ([]*std.Tx, error) { - var ( - timestamp = time.Now().Unix() - - getMsgFn = func(creator std.Account, index int) std.Msg { - memPkg := &gnovm.MemPackage{ - Name: packageName, - Path: fmt.Sprintf( - "%s/%s/stress_%d_%d", - packagePathPrefix, - creator.GetAddress().String(), - timestamp, - index, - ), - Files: []*gnovm.MemFile{ - { - Name: packageFileName, - Body: packageBody, - }, - }, - } - - return vm.MsgAddPackage{ - Creator: creator.GetAddress(), - Package: memPkg, - } - } - ) - return constructTransactions( keys, accounts, transactions, + maxGas, + gasPrice, chainID, - getMsgFn, + c.getMsgFn, estimateFn, ) } + +func (c *packageDeployment) getMsgFn(creator std.Account, index int) std.Msg { + timestamp := time.Now().Unix() + + memPkg := &std.MemPackage{ + Name: packageName, + Path: fmt.Sprintf( + "%s/%s/stress_%d_%d", + packagePathPrefix, + creator.GetAddress().String(), + timestamp, + index, + ), + Files: []*std.MemFile{ + { + Name: gnomodFileName, + Body: gnomodBody, + }, + { + Name: packageFileName, + Body: packageBody, + }, + }, + } + + return vm.MsgAddPackage{ + Creator: creator.GetAddress(), + Package: memPkg, + } +} diff --git a/internal/runtime/realm_call.go b/internal/runtime/realm_call.go index 157785d..aa3cc0e 100644 --- a/internal/runtime/realm_call.go +++ b/internal/runtime/realm_call.go @@ -5,11 +5,9 @@ import ( "time" "github.com/gnolang/gno/gno.land/pkg/sdk/vm" - "github.com/gnolang/gno/gnovm" "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/std" "github.com/gnolang/supernova/internal/common" - "github.com/gnolang/supernova/internal/signer" ) const methodName = "SayHello" @@ -24,9 +22,10 @@ func newRealmCall() *realmCall { func (r *realmCall) Initialize( account std.Account, - key crypto.PrivKey, - chainID string, + signFn SignFn, estimateFn EstimateGasFn, + currentMaxGas int64, + gasPrice std.GasPrice, ) ([]*std.Tx, error) { // The Realm needs to be deployed before // it can be interacted with @@ -40,10 +39,14 @@ func (r *realmCall) Initialize( // Construct the transaction msg := vm.MsgAddPackage{ Creator: account.GetAddress(), - Package: &gnovm.MemPackage{ + Package: &std.MemPackage{ Name: packageName, Path: r.realmPath, - Files: []*gnovm.MemFile{ + Files: []*std.MemFile{ + { + Name: gnomodFileName, + Body: gnomodBody, + }, { Name: realmFileName, Body: realmBody, @@ -54,17 +57,12 @@ func (r *realmCall) Initialize( tx := &std.Tx{ Msgs: []std.Msg{msg}, - Fee: common.CalculateFeeInRatio(1_000_000, common.DefaultGasPrice), + // passing in the maximum block gas, this is just a simulation + Fee: common.CalculateFeeInRatio(currentMaxGas, gasPrice), } - // Sign it - cfg := signer.SignCfg{ - ChainID: chainID, - AccountNumber: account.GetAccountNumber(), - Sequence: account.GetSequence(), - } - - if err := signer.SignTx(tx, key, cfg); err != nil { + err := signFn(tx) + if err != nil { return nil, fmt.Errorf("unable to sign initialize transaction, %w", err) } @@ -76,39 +74,62 @@ func (r *realmCall) Initialize( // Wipe the signatures, because we will change the fee, // and cause the previous ones to be invalid - clear(tx.Signatures) + tx.Signatures = make([]std.Signature, 0) + tx.Fee = common.CalculateFeeInRatio(gasWanted+gasBuffer, gasPrice) // buffer with 10k gas - tx.Fee = common.CalculateFeeInRatio(gasWanted+gasBuffer, common.DefaultGasPrice) // buffer with 10k gas - - if err = signer.SignTx(tx, key, cfg); err != nil { + err = signFn(tx) + if err != nil { return nil, fmt.Errorf("unable to sign initialize transaction, %w", err) } return []*std.Tx{tx}, nil } +func (r *realmCall) CalculateRuntimeCosts( + account std.Account, + estimateFn EstimateGasFn, + signFn SignFn, + currentMaxGas int64, + gasPrice std.GasPrice, + transactions uint64, +) (std.Coin, error) { + return calculateRuntimeCosts( + account, + transactions, + currentMaxGas, + gasPrice, + r.getMsgFn, + signFn, + estimateFn, + ) +} + func (r *realmCall) ConstructTransactions( keys []crypto.PrivKey, accounts []std.Account, transactions uint64, + maxGas int64, + gasPrice std.GasPrice, chainID string, estimateFn EstimateGasFn, ) ([]*std.Tx, error) { - getMsgFn := func(creator std.Account, index int) std.Msg { - return vm.MsgCall{ - Caller: creator.GetAddress(), - PkgPath: r.realmPath, - Func: methodName, - Args: []string{fmt.Sprintf("Account-%d", index)}, - } - } - return constructTransactions( keys, accounts, transactions, + maxGas, + gasPrice, chainID, - getMsgFn, + r.getMsgFn, estimateFn, ) } + +func (r *realmCall) getMsgFn(creator std.Account, index int) std.Msg { + return vm.MsgCall{ + Caller: creator.GetAddress(), + PkgPath: r.realmPath, + Func: methodName, + Args: []string{fmt.Sprintf("Account-%d", index)}, + } +} diff --git a/internal/runtime/realm_deployment.go b/internal/runtime/realm_deployment.go index 064477f..daa54d5 100644 --- a/internal/runtime/realm_deployment.go +++ b/internal/runtime/realm_deployment.go @@ -5,7 +5,6 @@ import ( "time" "github.com/gnolang/gno/gno.land/pkg/sdk/vm" - "github.com/gnolang/gno/gnovm" "github.com/gnolang/gno/tm2/pkg/crypto" "github.com/gnolang/gno/tm2/pkg/std" ) @@ -18,55 +17,80 @@ func newRealmDeployment() *realmDeployment { func (c *realmDeployment) Initialize( _ std.Account, - _ crypto.PrivKey, - _ string, + _ SignFn, _ EstimateGasFn, + _ int64, + _ std.GasPrice, ) ([]*std.Tx, error) { // No extra setup needed for this runtime type return nil, nil } +func (c *realmDeployment) CalculateRuntimeCosts( + account std.Account, + estimateFn EstimateGasFn, + signFn SignFn, + currentMaxGas int64, + gasPrice std.GasPrice, + transactions uint64, +) (std.Coin, error) { + return calculateRuntimeCosts( + account, + transactions, + currentMaxGas, + gasPrice, + c.getMsgFn, + signFn, + estimateFn, + ) +} + +func (c *realmDeployment) getMsgFn(creator std.Account, index int) std.Msg { + timestamp := time.Now().Unix() + memPkg := &std.MemPackage{ + Name: packageName, + Path: fmt.Sprintf( + "%s/%s/stress_%d_%d", + realmPathPrefix, + creator.GetAddress().String(), + timestamp, + index, + ), + Files: []*std.MemFile{ + { + Name: gnomodFileName, + Body: gnomodBody, + }, + { + Name: realmFileName, + Body: realmBody, + }, + }, + } + + return vm.MsgAddPackage{ + Creator: creator.GetAddress(), + Package: memPkg, + } +} + func (c *realmDeployment) ConstructTransactions( keys []crypto.PrivKey, accounts []std.Account, transactions uint64, + maxGas int64, + gasPrice std.GasPrice, chainID string, estimateFn EstimateGasFn, ) ([]*std.Tx, error) { - var ( - timestamp = time.Now().Unix() - - getMsgFn = func(creator std.Account, index int) std.Msg { - memPkg := &gnovm.MemPackage{ - Name: packageName, - Path: fmt.Sprintf( - "%s/%s/stress_%d_%d", - realmPathPrefix, - creator.GetAddress().String(), - timestamp, - index, - ), - Files: []*gnovm.MemFile{ - { - Name: realmFileName, - Body: realmBody, - }, - }, - } - - return vm.MsgAddPackage{ - Creator: creator.GetAddress(), - Package: memPkg, - } - } - ) - return constructTransactions( keys, accounts, transactions, + maxGas, + gasPrice, chainID, - getMsgFn, + c.getMsgFn, estimateFn, ) } diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index 8915a7e..219d1b6 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -13,6 +13,9 @@ const ( // EstimateGasFn is the gas estimation callback type EstimateGasFn func(tx *std.Tx) (int64, error) +// SignFn is the tx signing callback +type SignFn func(tx *std.Tx) error + // Runtime is the base interface for all runtime // implementations. // @@ -23,10 +26,22 @@ type Runtime interface { // to be executed before the stress test runs, if any Initialize( account std.Account, - key crypto.PrivKey, - chainID string, + signFn SignFn, estimateFn EstimateGasFn, + currentMaxGas int64, + gasPrice std.GasPrice, ) ([]*std.Tx, error) + // CalculateRuntimeCosts calculates the amount of funds + // each account needs to have in order to participate in the + // stress test run + CalculateRuntimeCosts( + account std.Account, + estimateFn EstimateGasFn, + signFn SignFn, + currentMaxGas int64, + gasPrice std.GasPrice, + transactions uint64, + ) (std.Coin, error) // ConstructTransactions generates and signs the required transactions // that will be used in the stress test @@ -34,6 +49,8 @@ type Runtime interface { keys []crypto.PrivKey, accounts []std.Account, transactions uint64, + maxGas int64, + gasPrice std.GasPrice, chainID string, estimateFn EstimateGasFn, ) ([]*std.Tx, error) diff --git a/internal/runtime/runtime_test.go b/internal/runtime/runtime_test.go index 4769fe5..f3ac770 100644 --- a/internal/runtime/runtime_test.go +++ b/internal/runtime/runtime_test.go @@ -27,9 +27,9 @@ func verifyDeployTxCommon(t *testing.T, tx *std.Tx, expectedPrefix string) { // Make sure the deploy params are valid assert.Contains(t, vmMsg.Package.Path, expectedPrefix) - assert.Len(t, vmMsg.Package.Files, 1) + assert.Len(t, vmMsg.Package.Files, 2) assert.NotNil(t, vmMsg.Creator) - assert.Nil(t, vmMsg.Deposit) + assert.Nil(t, vmMsg.Send) // Make sure the fee is valid assert.Equal( @@ -75,11 +75,14 @@ func TestRuntime_CommonDeployment(t *testing.T) { // Make sure there is no initialization logic initialTxs, err := r.Initialize( accounts[0], - accountKeys[0], - "dummy", + func(_ *std.Tx) error { + return nil + }, func(_ *std.Tx) (int64, error) { return 1_000_000, nil }, + 1_000_000, + common.DefaultGasPrice, ) assert.Nil(t, initialTxs) @@ -90,6 +93,8 @@ func TestRuntime_CommonDeployment(t *testing.T) { accountKeys, accounts, transactions, + 1_000_000, + common.DefaultGasPrice, "dummy", func(_ *std.Tx) (int64, error) { return 1_000_000, nil @@ -126,11 +131,14 @@ func TestRuntime_RealmCall(t *testing.T) { // Make sure the initialization logic is present initialTxs, err := r.Initialize( accounts[0], - accountKeys[0], - "dummy", + func(_ *std.Tx) error { + return nil + }, func(_ *std.Tx) (int64, error) { return 1_000_000, nil }, + 1_000_000, + common.DefaultGasPrice, ) if err != nil { t.Fatalf("unable to generate init transactions, %v", err) @@ -149,6 +157,8 @@ func TestRuntime_RealmCall(t *testing.T) { accountKeys[1:], accounts[1:], transactions, + 1_000_000, + common.DefaultGasPrice, "dummy", func(_ *std.Tx) (int64, error) { return 1_000_000, nil diff --git a/internal/runtime/source.go b/internal/runtime/source.go index 7baa117..c936470 100644 --- a/internal/runtime/source.go +++ b/internal/runtime/source.go @@ -11,7 +11,7 @@ func init() { // SayHello says hello to the specified name, using // the saved greeting -func SayHello(name string) string { +func SayHello(cur realm, name string) string { return greeting + " " + name + "!" } ` @@ -48,6 +48,10 @@ func GetGreeting(language Language) string { return "Hello" } } +` + gnomodBody = ` +module = "gno.land/r/demo/runtime" +gno = "0.9" ` ) @@ -55,4 +59,5 @@ const ( packageName = "runtime" realmFileName = "realm.gno" packageFileName = "package.gno" + gnomodFileName = "gnomod.toml" )