Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Adopt SmithyDafnyMakefile.mk, progress towards fixing nightly build #797

Merged
merged 42 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
e7a6e2e
Workflow and makefile changes
robin-aws Mar 7, 2024
bca6327
regenerate Dafny, fix client factory method return types
robin-aws Mar 7, 2024
890dd5c
More client type fixes
robin-aws Mar 7, 2024
f3e651f
Regenerate .net
robin-aws Mar 7, 2024
ae27d80
More client type fixes
robin-aws Mar 7, 2024
8b94d1d
Verification fixes
robin-aws Mar 8, 2024
ce19eca
Another fix
robin-aws Mar 8, 2024
c13f980
Regenerate Java
robin-aws Mar 8, 2024
38f6403
Check codegen of TestVectors too!
robin-aws Mar 8, 2024
2a85637
Manual edit -> patch file
robin-aws Mar 8, 2024
1a47d6d
Fussy patch alignment
robin-aws Mar 8, 2024
26ef683
Wrong mpl path
robin-aws Mar 8, 2024
ebc68c8
Change StructuredEncryption client in Config back to concrete type
robin-aws Mar 8, 2024
7505ffe
Necessary ensures
robin-aws Mar 8, 2024
3544cab
Different method for updating MPL
robin-aws Mar 8, 2024
def5032
Fix library path
robin-aws Mar 8, 2024
609d3c5
Whoops
robin-aws Mar 8, 2024
31168ab
Submodule init
robin-aws Mar 8, 2024
a2ef35c
More client changes
robin-aws Mar 8, 2024
a87c15e
Revert config change
robin-aws Mar 9, 2024
7628de5
Revert another config change
robin-aws Mar 9, 2024
369e31e
One more client cast fix
robin-aws Mar 9, 2024
280cc24
Another client fix, a little help with an expensive assertion
robin-aws Mar 9, 2024
4b3252c
Convert really expensive “test lemma” to test
robin-aws Mar 10, 2024
5f3aa61
Typo
robin-aws Mar 10, 2024
eaa8098
Merge checked-in and smithy-dafny generated properties
robin-aws Mar 21, 2024
8d0d273
Ordering
robin-aws Mar 21, 2024
70dbd8e
Use awk instead
robin-aws Mar 22, 2024
146d26e
Debugging
robin-aws Mar 22, 2024
280d6ad
Update smithy-dafny
robin-aws Mar 22, 2024
59ce0e5
Update smithy-dafny
robin-aws Mar 22, 2024
3deea78
update project.properties in MPL too
robin-aws Mar 25, 2024
89eb30e
Merge branch 'main' of github.com:aws/aws-database-encryption-sdk-dyn…
robin-aws Mar 26, 2024
8f4c453
Regenerate code after merge
robin-aws Mar 26, 2024
6ed4023
Missed merge conflict
robin-aws Mar 26, 2024
1118544
Only regenerate project properties files in nightly build
robin-aws Mar 26, 2024
3eaa6a8
Select DafnyRuntime version dynamically
robin-aws Mar 26, 2024
55514fc
Merge branch 'main' of github.com:aws/aws-database-encryption-sdk-dyn…
robin-aws Apr 17, 2024
c396dfb
Pull latest smithy-dafny, regenerate, undo client changes
robin-aws Apr 18, 2024
3329da4
Typo
robin-aws Apr 18, 2024
bedce38
two more
robin-aws Apr 18, 2024
2eaaa3e
formatting, complete incomplete .NET regeneration
robin-aws Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions .github/actions/polymorph_codegen/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#
# This local action serves two purposes:
#
# 1. For core workflows like pull.yml and push.yml,
# it is uses to check that the checked in copy of generated code
# matches what the current submodule version of smithy-dafny generates.
# This is important to ensure whenever someone changes the models
# or needs to regenerate to pick up smithy-dafny improvements,
# they don't have to deal with unpleasant surprises.
#
# 2. For workflows that check compatibility with other Dafny versions,
# such as nightly_dafny.yml, it is necessary to regenerate the code
# for that version of Dafny first.
# This is ultimately because some of the code smithy-dafny generates
# is tightly coupled to what code Dafny itself generates.
# A concrete example is that Dafny 4.3 added TypeDescriptors
# as parameters when constructing datatypes like Option and Result.
#
# This is why this is a composite action instead of a reusable workflow:
# the latter executes in a separate runner environment,
# but here we need to actually overwrite the generated code in place
# so that subsequent steps can work correctly.
#
# This action assumes that the given version of Dafny and .NET 6.0.x
# have already been set up, since they are used to format generated code.
#
# Note that recursively generating code doesn't currently work in this repo
# with the version of the mpl pinned by the submodule,
# because the SharedMakefileV2.mk in it doesn't work with newer versions of smithy-dafny.
# Therefore by default we don't recursively regenerate code
# (accomplished by setting the POLYMORPH_DEPENDENCIES environment variable to "").
# If `update-and-regenerate-mpl` is true, we first pull the latest mpl,
# which is necessary both for Makefile compatibility and so we can regenerate mpl code
# for compatibility with newer versions of Dafny.
#

name: "Polymorph code generation"
description: "Regenerates code using smithy-dafny, and optionally checks that the result matches the checked in state"
inputs:
dafny:
description: "The Dafny version to run"
required: true
type: string
library:
description: "Name of the library to regenerate code for"
required: true
type: string
diff-generated-code:
description: "Diff regenerated code against committed state"
required: true
type: boolean
update-and-regenerate-mpl:
description: "Locally update MPL to the tip of master and regenerate its code too"
required: false
default: false
type: boolean
runs:
using: "composite"
steps:
- name: Update MPL submodule locally if requested
if: inputs.update-and-regenerate-mpl == 'true'
working-directory: submodules/MaterialProviders
shell: bash
run: |
git checkout main
git pull
git submodule update --init --recursive

- name: Update top-level project.properties file in MPL
if: inputs.update-and-regenerate-mpl == 'true'
shell: bash
working-directory: submodules/MaterialProviders
run: |
make generate_properties_file

# Update the project.properties file so that we pick up the right runtimes etc.,
# in cases where inputs.dafny is different from the current value in that file.
- name: Generate smithy-dafny-project.properties file
if: inputs.update-and-regenerate-mpl == 'true'
env:
DAFNY_VERSION: ${{ inputs.dafny }}
shell: bash
run: |
make generate_properties_file

- name: Update top-level project.properties file
if: inputs.update-and-regenerate-mpl == 'true'
shell: bash
run: |
awk -F= '!a[$1]++' smithy-dafny-project.properties project.properties > merged.properties
mv merged.properties project.properties
cat project.properties

- name: Don't regenerate dependencies unless requested
id: dependencies
shell: bash
run: |
echo "PROJECT_DEPENDENCIES=${{ inputs.update-and-regenerate-mpl != 'true' && 'PROJECT_DEPENDENCIES=' || '' }}" >> $GITHUB_OUTPUT

- name: Regenerate Dafny code using smithy-dafny
# Unfortunately Dafny codegen doesn't work on Windows:
# https://github.com/smithy-lang/smithy-dafny/issues/317
if: runner.os != 'Windows'
working-directory: ./${{ inputs.library }}
shell: bash
run: |
make polymorph_dafny ${{ steps.dependencies.outputs.PROJECT_DEPENDENCIES }}

- name: Set up prettier in MPL
if: inputs.update-and-regenerate-mpl == 'true'
shell: bash
# Annoyingly, prettier has to be installed in each library individually.
# And this is only necessary or even possible if we've updated the mpl submodule.
run: |
make -C submodules/MaterialProviders/AwsCryptographyPrimitives setup_prettier
make -C submodules/MaterialProviders/AwsCryptographicMaterialProviders setup_prettier
make -C submodules/MaterialProviders/ComAmazonawsKms setup_prettier
make -C submodules/MaterialProviders/ComAmazonawsDynamodb setup_prettier

- name: Regenerate Java code using smithy-dafny
# npx seems to be unavailable on Windows GHA runners,
# so we don't regenerate Java code on them either.
if: runner.os != 'Windows'
working-directory: ./${{ inputs.library }}
shell: bash
# smithy-dafny also formats generated code itself now,
# so prettier is a necessary dependency.
run: |
make setup_prettier
make polymorph_java ${{ steps.dependencies.outputs.PROJECT_DEPENDENCIES }}

- name: Regenerate .NET code using smithy-dafny
working-directory: ./${{ inputs.library }}
shell: bash
run: |
make polymorph_dotnet ${{ steps.dependencies.outputs.PROJECT_DEPENDENCIES }}

- name: Check regenerated code against commited code
# Composite action inputs seem to not actually support booleans properly for some reason
if: inputs.diff-generated-code == 'true'
working-directory: ./${{ inputs.library }}
shell: bash
run: |
make check_polymorph_diff
56 changes: 56 additions & 0 deletions .github/workflows/ci_codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# This workflow regenerates code using smithy-dafny and checks that the output matches what's checked in.
name: Library Code Generation
on:
pull_request:
push:
branches:
- main

jobs:
code-generation:
strategy:
fail-fast: false
matrix:
library:
[
DynamoDbEncryption,
TestVectors
]
# Note dotnet is only used for formatting generated code
# in this workflow
dotnet-version: ["6.0.x"]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: 1
steps:
- name: Support longpaths
run: |
git config --global core.longpaths true

- uses: actions/checkout@v3
with:
submodules: recursive

# Only used to format generated code
# and to translate version strings such as "nightly-latest"
# to an actual DAFNY_VERSION.
- name: Setup Dafny
uses: dafny-lang/[email protected]
with:
dafny-version: 4.2.0

- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ matrix.dotnet-version }}

- uses: ./.github/actions/polymorph_codegen
with:
dafny: ${{ env.DAFNY_VERSION }}
library: ${{ matrix.library }}
diff-generated-code: true
9 changes: 9 additions & 0 deletions .github/workflows/ci_test_java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ jobs:
# A && B || C is the closest thing to an if .. then ... else ... or ?: expression the GitHub Actions syntax supports.
dafny-version: ${{ (github.event_name == 'schedule' || inputs.nightly) && 'nightly-latest' || '4.2.0' }}

- name: Regenerate code using smithy-dafny if necessary
if: ${{ inputs.nightly }}
uses: ./.github/actions/polymorph_codegen
with:
dafny: ${{ env.DAFNY_VERSION }}
library: ${{ matrix.library }}
diff-generated-code: false
update-and-regenerate-mpl: true

- name: Setup Java ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/ci_test_net.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ jobs:
# A && B || C is the closest thing to an if .. then ... else ... or ?: expression the GitHub Actions syntax supports.
dafny-version: ${{ (github.event_name == 'schedule' || inputs.nightly) && 'nightly-latest' || '4.2.0' }}

- name: Regenerate code using smithy-dafny if necessary
if: ${{ inputs.nightly }}
uses: ./.github/actions/polymorph_codegen
with:
dafny: ${{ env.DAFNY_VERSION }}
library: ${{ matrix.library }}
diff-generated-code: false
update-and-regenerate-mpl: true

- name: Download Dependencies
working-directory: ./${{ matrix.library }}
run: make setup_net
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/ci_verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
# Don't run the nightly build on forks
if: github.event_name != 'schedule' || github.repository_owner == 'aws'
strategy:
fail-fast: false
matrix:
# Break up verification between namespaces over multiple
# actions to take advantage of parallelization
Expand All @@ -51,8 +52,17 @@ jobs:
with:
# A && B || C is the closest thing to an if .. then ... else ... or ?: expression the GitHub Actions syntax supports.
dafny-version: ${{ (github.event_name == 'schedule' || inputs.nightly) && 'nightly-latest' || '4.2.0' }}

- name: Regenerate code using smithy-dafny if necessary
if: ${{ inputs.nightly }}
uses: ./.github/actions/polymorph_codegen
with:
dafny: ${{ env.DAFNY_VERSION }}
library: DynamoDbEncryption
diff-generated-code: false
update-and-regenerate-mpl: true

- name: Verify ${{ matrix.library }} Dafny code
- name: Verify ${{ matrix.service }} Dafny code
shell: bash
working-directory: ./DynamoDbEncryption
run: |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
diff --git b/DynamoDbEncryption/runtimes/net/Generated/DynamoDbEncryption/TypeConversion.cs a/DynamoDbEncryption/runtimes/net/Generated/DynamoDbEncryption/TypeConversion.cs
index 9a951767..5c0cee33 100644
--- b/DynamoDbEncryption/runtimes/net/Generated/DynamoDbEncryption/TypeConversion.cs
+++ a/DynamoDbEncryption/runtimes/net/Generated/DynamoDbEncryption/TypeConversion.cs
@@ -7,6 +7,43 @@ namespace AWS.Cryptography.DbEncryptionSDK.DynamoDb
{
public static class TypeConversion
{
+ // BEGIN MANUAL EDIT
+ public static AWS.Cryptography.KeyStore.KeyStore FromDafny_N3_aws__N12_cryptography__N15_dbEncryptionSdk__N8_dynamoDb__S17_KeyStoreReference(software.amazon.cryptography.keystore.internaldafny.types.IKeyStoreClient value)
+ {
+ if (value is software.amazon.cryptography.keystore.internaldafny.types.IKeyStoreClient dafnyValue)
+ {
+ return new AWS.Cryptography.KeyStore.KeyStore(dafnyValue);
+ }
+ throw new System.ArgumentException("Custom implementations of AWS.Cryptography.KeyStore.KeyStore are not supported yet");
+ }
+ public static software.amazon.cryptography.keystore.internaldafny.types.IKeyStoreClient ToDafny_N3_aws__N12_cryptography__N15_dbEncryptionSdk__N8_dynamoDb__S17_KeyStoreReference(AWS.Cryptography.KeyStore.KeyStore value)
+ {
+ if (value is AWS.Cryptography.KeyStore.KeyStore nativeValue)
+ {
+ return nativeValue.impl();
+ }
+ throw new System.ArgumentException("Custom implementations of AWS.Cryptography.KeyStore.KeyStore are not supported yet");
+ }
+ public static AWS.Cryptography.DbEncryptionSDK.DynamoDb.ILegacyDynamoDbEncryptor FromDafny_N3_aws__N12_cryptography__N15_dbEncryptionSdk__N8_dynamoDb__S32_LegacyDynamoDbEncryptorReference(software.amazon.cryptography.dbencryptionsdk.dynamodb.internaldafny.types.ILegacyDynamoDbEncryptor value)
+ {
+ if (value is NativeWrapper_LegacyDynamoDbEncryptor nativeWrapper) return nativeWrapper._impl;
+ return new LegacyDynamoDbEncryptor(value);
+
+ }
+ public static software.amazon.cryptography.dbencryptionsdk.dynamodb.internaldafny.types.ILegacyDynamoDbEncryptor ToDafny_N3_aws__N12_cryptography__N15_dbEncryptionSdk__N8_dynamoDb__S32_LegacyDynamoDbEncryptorReference(AWS.Cryptography.DbEncryptionSDK.DynamoDb.ILegacyDynamoDbEncryptor value)
+ {
+ switch (value)
+ {
+ case LegacyDynamoDbEncryptor valueWithImpl:
+ return valueWithImpl._impl;
+ case LegacyDynamoDbEncryptorBase nativeImpl:
+ return new NativeWrapper_LegacyDynamoDbEncryptor(nativeImpl);
+ default:
+ throw new System.ArgumentException(
+ "Custom implementations of LegacyDynamoDbEncryptor must extend LegacyDynamoDbEncryptorBase.");
+ }
+ }
+ // END MANUAL EDIT
public static AWS.Cryptography.DbEncryptionSDK.DynamoDb.BeaconKeySource FromDafny_N3_aws__N12_cryptography__N15_dbEncryptionSdk__N8_dynamoDb__S15_BeaconKeySource(software.amazon.cryptography.dbencryptionsdk.dynamodb.internaldafny.types._IBeaconKeySource value)
{
software.amazon.cryptography.dbencryptionsdk.dynamodb.internaldafny.types.BeaconKeySource concrete = (software.amazon.cryptography.dbencryptionsdk.dynamodb.internaldafny.types.BeaconKeySource)value;
Original file line number Diff line number Diff line change
Expand Up @@ -453,17 +453,17 @@ abstract module AbstractAwsCryptographyDbEncryptionSdkDynamoDbService
import Operations : AbstractAwsCryptographyDbEncryptionSdkDynamoDbOperations
function method DefaultDynamoDbEncryptionConfig(): DynamoDbEncryptionConfig
method DynamoDbEncryption(config: DynamoDbEncryptionConfig := DefaultDynamoDbEncryptionConfig())
returns (res: Result<IDynamoDbEncryptionClient, Error>)
returns (res: Result<DynamoDbEncryptionClient, Error>)
ensures res.Success? ==>
&& fresh(res.value)
&& fresh(res.value.Modifies)
&& fresh(res.value.History)
&& res.value.ValidState()

// Helper function for the benefit of native code to create a Success(client) without referring to Dafny internals
// Helper functions for the benefit of native code to create a Success(client) without referring to Dafny internals
function method CreateSuccessOfClient(client: IDynamoDbEncryptionClient): Result<IDynamoDbEncryptionClient, Error> {
Success(client)
} // Helper function for the benefit of native code to create a Failure(error) without referring to Dafny internals
}
function method CreateFailureOfError(error: Error): Result<IDynamoDbEncryptionClient, Error> {
Failure(error)
}
Expand Down
13 changes: 0 additions & 13 deletions DynamoDbEncryption/dafny/DynamoDbEncryption/src/Beacon.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -439,17 +439,4 @@ module BaseBeacon {
else
[HexChar(TruncateNibble(bytes[0] % 16, topBits))] + ToHexString(bytes[1..])
}

lemma {:vcs_split_on_every_assert} CheckBytesToHex()
ensures
&& var bytes := [1,2,3,4,5,6,7,0xb7];
&& BytesToHex(bytes, 1) == "1"
&& BytesToHex(bytes, 2) == "3"
&& BytesToHex(bytes, 3) == "7"
&& BytesToHex(bytes, 4) == "7"
&& BytesToHex(bytes, 5) == "17"
&& BytesToHex(bytes, 6) == "37"
&& BytesToHex(bytes, 7) == "37"
&& BytesToHex(bytes, 8) == "b7"
{}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module
}

method DynamoDbEncryption(config: DynamoDbEncryptionConfig)
returns (res: Result<IDynamoDbEncryptionClient, Error>)
returns (res: Result<DynamoDbEncryptionClient, Error>)
ensures res.Success? ==> res.value is DynamoDbEncryptionClient
{
var internalConfig := Operations.Config();
Expand Down
16 changes: 16 additions & 0 deletions DynamoDbEncryption/dafny/DynamoDbEncryption/test/Beacon.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -739,4 +739,20 @@ module TestBaseBeacon {
var src := GetLiteralSource([1,2,3,4,5], version);
var bv :- expect C.ConvertVersionWithSource(FullTableConfig, version, src);
}

method {:test} CheckBytesToHex()
{
var bytes := [1,2,3,4,5,6,7,0xb7];
// These could be asserted instead,
// but they get too expensive
// on more recent versions of Dafny.
expect BytesToHex(bytes, 1) == "1";
expect BytesToHex(bytes, 2) == "3";
expect BytesToHex(bytes, 3) == "7";
expect BytesToHex(bytes, 4) == "7";
expect BytesToHex(bytes, 5) == "17";
expect BytesToHex(bytes, 6) == "37";
expect BytesToHex(bytes, 7) == "37";
expect BytesToHex(bytes, 8) == "b7";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ module BeaconTestFixtures {
ensures fresh(output.client.Modifies)
{
var client :- expect Primitives.AtomicPrimitives();

var keyNameSet := set b <- version.standardBeacons :: b.name;
var keyNames := SortedSets.ComputeSetToOrderedSequence2(keyNameSet, CharLess);
var keys :- expect SI.GetHmacKeys(client, keyNames, keyNames, key);
Expand Down
Loading
Loading