diff --git a/.github/workflows/check-pr.yaml b/.github/workflows/check-pr.yaml index 6fc8704af4..1c26684e1e 100644 --- a/.github/workflows/check-pr.yaml +++ b/.github/workflows/check-pr.yaml @@ -5,7 +5,7 @@ on: jobs: check-pr: name: Check PR - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml new file mode 100644 index 0000000000..ecf996bc27 --- /dev/null +++ b/.github/workflows/publish-docker-image.yml @@ -0,0 +1,62 @@ +name: Publish Docker image + +on: + workflow_dispatch: + inputs: + dockerTag: + description: 'Docker tag' + required: true + type: string + baseImage: + description: 'Base image' + required: true + default: 'eclipse-temurin:11-jre-noble' + type: string + +env: + IMAGE_NAME: ghcr.io/${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + cache: 'sbt' + - run: sbt --mem 4096 --batch buildTarballsForDocker + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/setup-buildx-action@v3 + - uses: docker/metadata-action@v5 + id: meta + with: + images: ${{ env.IMAGE_NAME }} + flavor: latest=false + tags: type=raw,value=${{ inputs.dockerTag }} + labels: | + org.opencontainers.image.source=https://github.com/${{ github.repository }} + org.opencontainers.image.licenses=MIT + org.opencontainers.image.description="Waves Node" + - uses: docker/build-push-action@v5 + id: push + with: + context: ./docker + platforms: linux/amd64,linux/arm64 + push: true + pull: true + build-args: baseImage=${{ inputs.baseImage }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/publish-node-sbt-builder.yml b/.github/workflows/publish-node-sbt-builder.yml deleted file mode 100644 index aea743f29e..0000000000 --- a/.github/workflows/publish-node-sbt-builder.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Build SBT docker builder for node - -on: - release: - types: [published] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - id: extract-versions - run: | - echo "waves-version=$(cut -d\" -f2 version.sbt)" >> $GITHUB_OUTPUT - echo "sbt-version=$(cut -d= -f2 project/build.properties)" >> $GITHUB_OUTPUT - - uses: docker/setup-buildx-action@v3 - - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USER }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - uses: docker/build-push-action@v5 - with: - context: ./docker - file: ./docker/node-sbt-builder.Dockerfile - push: true - pull: true - tags: wavesplatform/node-sbt-builder:${{ steps.extract-versions.outputs.waves-version }} - build-args: | - WAVES_VERSION=${{ steps.extract-versions.outputs.waves-version }} - SBT_VERSION=${{ steps.extract-versions.outputs.sbt-version }} diff --git a/.github/workflows/publish-release-jars.yaml b/.github/workflows/publish-release-jars.yaml deleted file mode 100644 index 7aa7d79e72..0000000000 --- a/.github/workflows/publish-release-jars.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Publish node and lang jars to Maven Central - -on: - release: - types: [published] - -jobs: - publish-release: - name: Publish jars - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - id: sbt-version - run: | - sbt_version=$(cut -d\" -f2 version.sbt) - echo "sbt_version=$sbt_version" >> "$GITHUB_OUTPUT" - - if: ${{ format('v{0}', steps.sbt-version.outputs.sbt_version) != github.ref_name }} - env: - SBT_VERSION: ${{ steps.sbt-version.outputs.sbt_version }} - RELEASE_VERSION: ${{ github.ref_name }} - run: | - echo "::error::Release version $RELEASE_VERSION does not match SBT version $SBT_VERSION" - exit 1 - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '11' - cache: 'sbt' - gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} - gpg-passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} - - name: Publish release jars - env: - SONATYPE_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} - SONATYPE_USERNAME: ${{ secrets.OSSRH_USERNAME }} - PGP_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }} - run: | - sbt --mem 4096 --batch ";publishSigned;sonatypeBundleRelease" diff --git a/.github/workflows/publish-docker-node.yaml b/.github/workflows/publish-release.yml similarity index 53% rename from .github/workflows/publish-docker-node.yaml rename to .github/workflows/publish-release.yml index 30938ad106..4db33b70be 100644 --- a/.github/workflows/publish-docker-node.yaml +++ b/.github/workflows/publish-release.yml @@ -1,12 +1,13 @@ -name: Build docker images for node +name: Publish Release on: release: types: [published] jobs: - build: - runs-on: ubuntu-latest + publish-node-image: + name: Publish node image + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -88,3 +89,59 @@ jobs: push: true pull: true tags: ${{ steps.meta-ride-runner.outputs.tags }} + + publish-node-sbt-builder-image: + name: Publish node SBT builder image + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - id: extract-versions + run: | + echo "waves-version=$(cut -d\" -f2 version.sbt)" >> $GITHUB_OUTPUT + echo "sbt-version=$(cut -d= -f2 project/build.properties)" >> $GITHUB_OUTPUT + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + - uses: docker/build-push-action@v5 + with: + context: ./docker + file: ./docker/node-sbt-builder.Dockerfile + push: true + pull: true + tags: wavesplatform/node-sbt-builder:${{ steps.extract-versions.outputs.waves-version }} + build-args: | + WAVES_VERSION=${{ steps.extract-versions.outputs.waves-version }} + SBT_VERSION=${{ steps.extract-versions.outputs.sbt-version }} + + publish-release-jars: + name: Publish jars to Sonatype + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - id: sbt-version + run: | + sbt_version=$(cut -d\" -f2 version.sbt) + echo "sbt_version=$sbt_version" >> "$GITHUB_OUTPUT" + - if: ${{ format('v{0}', steps.sbt-version.outputs.sbt_version) != github.ref_name }} + env: + SBT_VERSION: ${{ steps.sbt-version.outputs.sbt_version }} + RELEASE_VERSION: ${{ github.ref_name }} + run: | + echo "::error::Release version $RELEASE_VERSION does not match SBT version $SBT_VERSION" + exit 1 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + cache: 'sbt' + gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} + gpg-passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} + - name: Publish release jars + env: + SONATYPE_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.OSSRH_USERNAME }} + PGP_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }} + run: | + sbt --mem 4096 --batch ";publishSigned;sonatypeBundleRelease" diff --git a/.github/workflows/push-default-branch.yml b/.github/workflows/push-default-branch.yml index b02db3d3ab..e8b7a810ff 100644 --- a/.github/workflows/push-default-branch.yml +++ b/.github/workflows/push-default-branch.yml @@ -8,7 +8,7 @@ on: jobs: update-graph: name: Update Dependency Graph - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: scalacenter/sbt-dependency-submission@v3 @@ -16,7 +16,7 @@ jobs: configs-ignore: test compile-internal provided publish-snapshot: name: Publish Snapshots to Sonatype - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 diff --git a/docker/Dockerfile b/docker/Dockerfile index 9c1f4a7dbb..1ffdf2a56a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,5 @@ -FROM eclipse-temurin:11-jre-noble +ARG baseImage=eclipse-temurin:11-jre-noble +FROM $baseImage ENV WAVES_LOG_LEVEL=INFO ENV WAVES_HEAP_SIZE=2g diff --git a/node/src/main/scala/com/wavesplatform/Application.scala b/node/src/main/scala/com/wavesplatform/Application.scala index a954f7385f..ab767812d5 100644 --- a/node/src/main/scala/com/wavesplatform/Application.scala +++ b/node/src/main/scala/com/wavesplatform/Application.scala @@ -643,7 +643,8 @@ object Application extends ScorexLogging { case "import" => Importer.main(args.tail) case "explore" => Explorer.main(args.tail) case "util" => UtilApp.main(args.tail) - case "help" | "--help" | "-h" => println("Usage: waves | export | import | explore | util") + case "gengen" => GenesisBlockGenerator.main(args.tail) + case "help" | "--help" | "-h" => println("Usage: waves | export | import | explore | util | gengen") case _ => startNode(args.headOption) } } diff --git a/node/src/main/scala/com/wavesplatform/utils/UtilApp.scala b/node/src/main/scala/com/wavesplatform/utils/UtilApp.scala index 6e07b9cd05..8e4a0802a1 100644 --- a/node/src/main/scala/com/wavesplatform/utils/UtilApp.scala +++ b/node/src/main/scala/com/wavesplatform/utils/UtilApp.scala @@ -7,7 +7,7 @@ import com.wavesplatform.common.state.ByteStr import com.wavesplatform.common.utils.{Base58, Base64, FastBase58} import com.wavesplatform.features.EstimatorProvider.* import com.wavesplatform.lang.script.{Script, ScriptReader} -import com.wavesplatform.settings.WavesSettings +import com.wavesplatform.settings.{WalletSettings, WavesSettings} import com.wavesplatform.transaction.TxValidationError.GenericError import com.wavesplatform.transaction.smart.script.ScriptCompiler import com.wavesplatform.transaction.{Transaction, TransactionFactory, TransactionSignOps, TransactionType} @@ -42,6 +42,7 @@ object UtilApp { case class VerifyOptions(publicKey: PublicKey = null, signature: ByteStr = ByteStr.empty, checkWeakPk: Boolean = false) case class HashOptions(mode: String = "fast") case class SignTxOptions(signerAddress: String = "") + case class KeyPairOptions(seedType: String = "account", nonce: Int = 0) sealed trait Input object Input { @@ -50,6 +51,8 @@ object UtilApp { final case class Str(str: String) extends Input } + sealed trait SeedType + case class Command( mode: Command.Mode = null, configFile: Option[String] = None, @@ -61,14 +64,15 @@ object UtilApp { signOptions: SignOptions = SignOptions(), verifyOptions: VerifyOptions = VerifyOptions(), hashOptions: HashOptions = HashOptions(), - signTxOptions: SignTxOptions = SignTxOptions() + signTxOptions: SignTxOptions = SignTxOptions(), + keyPairOptions: KeyPairOptions = KeyPairOptions() ) def main(args: Array[String]): Unit = { OParser.parse(commandParser, args, Command()) match { case Some(cmd) => val settings = Application.loadApplicationConfig(cmd.configFile.map(new File(_))) - val inBytes = IO.readInput(cmd) + val inBytes = IO.readInput(cmd) val result = { val doAction = cmd.mode match { case Command.CompileScript => Actions.doCompile(settings) _ @@ -183,6 +187,16 @@ object UtilApp { cmd("create-keys") .text("Generate key pair from seed") .action((_, c) => c.copy(mode = Command.CreateKeyPair)) + .children( + opt[String]("seed-type") + .validate { + case "account" | "wallet" => success + case _ => failure("Invalid seed format") + } + .action((t, c) => c.copy(keyPairOptions = c.keyPairOptions.copy(seedType = t))), + opt[Int]("nonce") + .action((n, c) => c.copy(keyPairOptions = c.keyPairOptions.copy(nonce = n))) + ) ), cmd("transaction").children( cmd("serialize") @@ -251,12 +265,29 @@ object UtilApp { "Invalid signature" ) - def doCreateKeyPair(c: Command, data: Array[Byte]): ActionResult = - KeyPair - .fromSeed(new String(data)) - .left + def doCreateKeyPair(c: Command, data: Array[Byte]): ActionResult = { + import com.wavesplatform.utils.byteStrFormat + (c.keyPairOptions.seedType match { + case "account" => + KeyPair.fromSeed(new String(data)) + case "wallet" => + Wallet(WalletSettings(None, Some("123"), Some(ByteStr(data)))) + .generateNewAccount(c.keyPairOptions.nonce) + .toRight("Could not generate account") + }).left .map(_.toString) - .map(kp => Json.toBytes(Json.toJson(kp))) + .map(kp => + Json.toBytes( + Json.obj( + "publicKey" -> kp.publicKey, + "privateKey" -> kp.privateKey, + "address" -> kp.publicKey.toAddress, + "walletSeed" -> ByteStr(data), + "nonce" -> c.keyPairOptions.nonce + ) + ) + ) + } def doHash(c: Command, data: Array[Byte]): ActionResult = c.hashOptions.mode match { case "fast" => Right(com.wavesplatform.crypto.fastHash(data))