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

Create ai image #153

Merged
merged 15 commits into from
Jun 4, 2024
52 changes: 52 additions & 0 deletions .github/workflows/test-with-code-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Test with code coverage

on:
push:
branches:
- '**'

env:
DOTNET_INSTALL_DIR: "./.dotnet"

jobs:
test:
runs-on: ubuntu-20.04
permissions:
pull-requests: write
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0'

- name: 'Download AElf build tools'
run: bash scripts/download_binary.sh

- name: 'Install protobuf'
run: bash scripts/install.sh

- name: Install dependencies
run: dotnet restore --verbosity quiet

- name: Build
run: dotnet build --no-restore /clp:ErrorsOnly /p:GeneratePackageOnBuild=false --verbosity quiet

- name: Test
run: |
for name in $(ls ./test/*.Tests/*.csproj | awk '{print $NF}')
do
echo "Running tests for $name..."
dotnet test $name --no-restore --no-build --logger trx --settings CodeCoverage.runsettings --results-directory coverage --collect:"XPlat Code Coverage"
echo "Finished running tests for $name."
done

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
files: coverage/*/coverage.cobertura.xml
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3"/>
Expand Down
40 changes: 40 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
#trigger:
# branches:
# include:
# - master
#pr:
# branches:
# include:
# - release/1.8.0
#jobs:
# # All tasks on macOS
# - job: build_all_darwin
# displayName: Build all tasks (macOS)
# timeoutInMinutes: 120
# pool:
# vmImage: macos-latest
# variables:
# CI_TEST: true
# steps:
# - task: UseDotNet@2
# displayName: 'Install .NET Core SDK'
# inputs:
# version: 6.0.x
# - script: bash scripts/install_protobuf.sh
# - script: bash scripts/download_binary.sh
# - script: bash build.sh --target=Test-with-Codecov
# displayName: 'Build and Test'
# - task: PublishTestResults@2
# condition: always()
# inputs:
# testRunner: VSTest
# testResultsFiles: '**/*.trx'
# - task: reportgenerator@5
# displayName: ReportGenerator
# inputs:
# reports: '$(Build.SourcesDirectory)/test/*/TestResults/*/coverage.cobertura.xml'
# targetdir: '$(Build.SourcesDirectory)/CodeCoverage'
# reporttypes: 'Cobertura'
# assemblyfilters: '-xunit*'
# - script: bash build.sh --target=Upload-Coverage-Azure
# displayName: 'Upload data to Codecov'
trigger:
branches:
include:
Expand Down
115 changes: 114 additions & 1 deletion contract/Forest/ForestContract.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AElf.Contracts.MultiToken;
using AElf.Sdk.CSharp;
using AElf.CSharp.Core;
using AElf.Types;
using Google.Protobuf.WellKnownTypes;

Expand Down Expand Up @@ -53,7 +54,6 @@ public override Empty SetServiceFee(SetServiceFeeInput input)
State.ServiceFeeReceiver.Value = input.ServiceFeeReceiver ?? State.Admin.Value;
return new Empty();
}

public override Empty SetGlobalTokenWhiteList(StringList input)
{
AssertSenderIsAdmin();
Expand Down Expand Up @@ -126,5 +126,118 @@ public override Empty SetOfferTotalAmount(SetOfferTotalAmountInput input)
State.OfferTotalAmountMap[input.Address][input.PriceSymbol] = input.TotalAmount;
return new Empty();
}

public override Empty SetAIServiceFee(SetAIServiceFeeInput input)
{
AssertSenderIsAdmin();
Assert(input is { Price: { Amount: >= 0, Symbol: AIServiceFeeToken } } && input.ServiceFeeReceiver != null, "Invalid AIServiceFeeRate");
State.AIServiceFeeConfig.Value = input.Price;
State.AIServiceFeeReceiver.Value = input.ServiceFeeReceiver;
return new Empty();
}

public override Empty AddAIImageSize(StringValue input)
{
AssertSenderIsAdmin();
Assert(input is { Value: { } } && input.Value != "", "Invalid input");
var sizeList = State.AIImageSizeList.Value;
if (sizeList == null)
{
State.AIImageSizeList.Value = new StringList()
{
Value = { input.Value }
};
return new Empty();
}

Assert(!sizeList.Value.Contains(input.Value), "input size Already exists");

sizeList.Value.Add(input.Value);
State.AIImageSizeList.Value = new StringList
{
Value = { sizeList.Value }
};
return new Empty();
}

public override Empty RemoveAIImageSize(StringValue input)
{
AssertSenderIsAdmin();
Assert(input is { Value: { } } && input.Value != "", "Invalid input");
var sizeList = State.AIImageSizeList.Value;
if (sizeList?.Value == null)
{
return new Empty();
}
Assert(sizeList.Value.Contains(input.Value), "input size not exists");
sizeList.Value.Remove(input.Value);
State.AIImageSizeList.Value = new StringList
{
Value = { sizeList.Value }
};
return new Empty();
}

public override Empty CreateArt(CreateArtInput input)
{
AssertContractInitialized();
RequireContractAIServiceFeeConfigSet();
RequireContractAIImageSizeListSet();
CheckCreateArtParams(input);
var aiServiceFeeConfig = State.AIServiceFeeConfig.Value;
var balance = State.TokenContract.GetBalance.Call(new GetBalanceInput
{
Symbol = aiServiceFeeConfig.Symbol,
Owner = Context.Sender
});
var serviceFee = aiServiceFeeConfig.Amount.Mul(input.Number);
Assert(balance.Balance >= serviceFee, "Check sender balance not enough.");
AssertAllowanceInsufficient(aiServiceFeeConfig.Symbol, Context.Sender, serviceFee);
if (serviceFee > 0)
{
State.TokenContract.TransferFrom.Send(new TransferFromInput
{
From = Context.Sender,
To = State.AIServiceFeeReceiver.Value,
Symbol = aiServiceFeeConfig.Symbol,
Amount = serviceFee
});
}

State.CreateArtInfoMap[Context.Sender][Context.OriginTransactionId.ToHex()] = new CreateArtInfo()
{
Promt = input.Promt,
NegativePrompt = input.NegativePrompt,
Model = input.Model,
Quality = input.Quality,
Style = input.Style,
Size = input.Size,
Number = input.Number,
CostPrice = new Price()
{
Symbol = aiServiceFeeConfig.Symbol,
Amount = serviceFee
},
PaintingStyle = input.PaintingStyle
};

Context.Fire(new ArtCreated()
{
Promt = input.Promt,
NegativePrompt = input.NegativePrompt,
Model = input.Model,
Quality = input.Quality,
Style = input.Style,
Size = input.Size,
Number = input.Number,
CostPrice = new Price()
{
Symbol = aiServiceFeeConfig.Symbol,
Amount = serviceFee
},
PaintingStyle = input.PaintingStyle
});
return new Empty();
}
}
}
6 changes: 6 additions & 0 deletions contract/Forest/ForestContractConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ public partial class ForestContract
public const int NumberZero = 0;
public const int NumberOne = 1;
public const int NumberTen = 10;
public const string AIServiceFeeToken = "ELF";
public const int DefaultAIServiceFeeAmount = 10000000;
public const string DefaultAIImageSize1024 = "1024x1024";
public const string DefaultAIImageSize512 = "512x512";
public const string DefaultAIImageSize256 = "256x256";

}
9 changes: 9 additions & 0 deletions contract/Forest/ForestContractState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,14 @@ public partial class ForestContractState : ContractState
/// </summary>
public MappedState<Address, string, long> OfferTotalAmountMap { get; set; }

public SingletonState<Price> AIServiceFeeConfig { get; set; }
public SingletonState<Address> AIServiceFeeReceiver { get; set; }

public SingletonState<StringList> AIImageSizeList { get; set; }
/// <summary>
/// Symbol -> Address TxId -> CreateArtInfo
/// </summary>
public MappedState<Address, string, CreateArtInfo> CreateArtInfoMap { get; set; }

}
}
33 changes: 33 additions & 0 deletions contract/Forest/ForestContract_Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,37 @@ private long GetAllowance(Address address, string symbol)
});
return allowance?.Allowance ?? 0;
}

private void RequireContractAIServiceFeeConfigSet()
{
if (State.AIServiceFeeConfig?.Value == null)
{
State.AIServiceFeeConfig.Value = new Price
{
Symbol = AIServiceFeeToken,
Amount = DefaultAIServiceFeeAmount
};
}

if (State.AIServiceFeeReceiver == null || State.AIServiceFeeReceiver.Value == null)
{
State.AIServiceFeeReceiver.Value = State.ServiceFeeReceiver.Value ?? State.Admin.Value;
}
}

private void RequireContractAIImageSizeListSet()
{
State.AIImageSizeList.Value ??= new StringList()
{
Value = { DefaultAIImageSize1024, DefaultAIImageSize512, DefaultAIImageSize256 }
};
}

private void CheckCreateArtParams(CreateArtInput input)
{
Assert(input != null, $"Invalid input");
Assert(input.Number > 0, $"Invalid input number");
var size = State.AIImageSizeList.Value.Value;
Assert(State.AIImageSizeList.Value.Value.Contains(input.Size), $"Invalid input size");
}
}
22 changes: 19 additions & 3 deletions contract/Forest/ForestContract_Views.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using AElf.Contracts.MultiToken;
using AElf.CSharp.Core;
using AElf.CSharp.Core.Extension;
using AElf.Types;
using Google.Protobuf.WellKnownTypes;

Expand Down Expand Up @@ -130,5 +127,24 @@ public override GetTotalEffectiveListedNFTAmountOutput GetTotalEffectiveListedNF

return getTotalEffectiveListedNftAmountOutput;
}
public override AIServiceFeeInfo GetAIServiceFee(Empty input)
{
return new AIServiceFeeInfo
{
Price = State.AIServiceFeeConfig.Value,
ServiceFeeReceiver = State.AIServiceFeeReceiver.Value
};
}

public override StringList GetAIImageSizes(Empty input)
{
return State.AIImageSizeList?.Value;
}


public override CreateArtInfo GetCreateArtInfo(GetCreateArtInfoInput input)
{
Assert(input != null, "Invalid TransactionId");
return State.CreateArtInfoMap[input.Address ?? Context.Sender][input.TransactionId];
}
}
Loading
Loading